diff --git a/.copilot/AGENT_GUIDE.md b/.copilot/AGENT_GUIDE.md index a963ae107..1da6dcf81 100644 --- a/.copilot/AGENT_GUIDE.md +++ b/.copilot/AGENT_GUIDE.md @@ -51,4 +51,6 @@ The setup runner profile selects placement; it does not install the project's la Declare reviewed version prefixes in `.copilot/verification-prerequisites.json` (schemaVersion 1, runtimes such as java 17, node 24, pnpm 10). Copilot checks declared versions in the credential-free verification environment before each configured verification command; a missing or incompatible runtime blocks publication. Without this optional declaration, existing verification behavior remains and no language is inferred. Java provisioning may use `actions/setup-java`; `JAVA_HOME` and `PATH` survive isolation, while agent credentials and tool-option injection variables do not. Do not add an unreviewed bootstrap or weaken verification to work around a missing runtime. Read [verification prerequisites and same-job setup](https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-verification-prerequisites). +The optional repository-owned composite action prepares each candidate before verification. Setup creates .github/actions/copilot-verification-setup/action.yml only if missing and preserves an existing consumer action and its assets. The shared terminal/web assistant offers explicit activation, disabled by default. Customize the generated failing placeholder before enabling; setup generation and installer PRs do not prove runtime readiness. Review `.github/actions/copilot-verification-setup/action.yml` and its assets onto trusted main, update generated workflows, then enable `VERIFICATION_SETUP=true` (Action input `verification-setup`, disabled by default). GitHub Actions executes the trusted snapshot before each command with a fresh private HOME; candidate changes cannot replace it. Native post steps finish before profile cleanup. Setup failure blocks verification and commit/push. The local CLI cannot execute composite actions and fails closed when opted in. Read [repository-owned setup](https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-owned-setup). + For the full contributor flow, read [repository collaboration](https://github.com/vypdev/copilot/blob/master/docs/agents/repository-collaboration.mdx). For drift and recovery, read [guidance troubleshooting](https://github.com/vypdev/copilot/blob/master/docs/agents/repository-guidance-troubleshooting.mdx). diff --git a/.copilot/setup-manifest.json b/.copilot/setup-manifest.json index b94212fbe..dd9956cc0 100644 --- a/.copilot/setup-manifest.json +++ b/.copilot/setup-manifest.json @@ -12,7 +12,7 @@ }, ".copilot/AGENT_GUIDE.md": { "role": "guide", - "sha256": "07ef187d584f4da868a6cebe6b6d7c7654b057af703e0d10ede11f768ba64674" + "sha256": "c3bd0df4bfdcbba2a007b1596a93480a3bb3145a6285e0a91809f3a93c3fbcd0" }, ".copilot/repository-profile.json": { "role": "profile", diff --git a/.github/actions/copilot-native-cleanup-check/action.yml b/.github/actions/copilot-native-cleanup-check/action.yml new file mode 100644 index 000000000..e23989c47 --- /dev/null +++ b/.github/actions/copilot-native-cleanup-check/action.yml @@ -0,0 +1,6 @@ +name: Verify native setup cleanup +runs: + using: node24 + main: main.cjs + post: post.cjs + post-if: always() diff --git a/.github/actions/copilot-native-cleanup-check/main.cjs b/.github/actions/copilot-native-cleanup-check/main.cjs new file mode 100644 index 000000000..e036784e6 --- /dev/null +++ b/.github/actions/copilot-native-cleanup-check/main.cjs @@ -0,0 +1,2 @@ +const fs = require('node:fs'); +fs.appendFileSync(process.env.GITHUB_STATE, `workspace=${fs.realpathSync(process.cwd())}\n`); diff --git a/.github/actions/copilot-native-cleanup-check/post.cjs b/.github/actions/copilot-native-cleanup-check/post.cjs new file mode 100644 index 000000000..5e7aec929 --- /dev/null +++ b/.github/actions/copilot-native-cleanup-check/post.cjs @@ -0,0 +1,10 @@ +const fs = require('node:fs'); +const path = require('node:path'); +const workspace = process.env.STATE_workspace; +// Keep the poisoned candidate bundle through every deferred post step, then remove +// only this job's ignored generated fixture output so subsequent runs start clean. +fs.rmSync(path.join(workspace, '.github/actions/copilot-native-fixture/dist'), { recursive: true, force: true }); +for (const file of [path.join(workspace, '.git/copilot-verification-setup'), path.join(path.dirname(workspace), '.copilot-native-fixture-runtime')]) { + if (fs.existsSync(file)) throw new Error('Native acceptance left owned staging or runtime snapshots after post cleanup.'); +} +console.log('Native acceptance cleanup passed after all deferred post steps.'); diff --git a/.github/actions/copilot-native-fixture/action.yml b/.github/actions/copilot-native-fixture/action.yml new file mode 100644 index 000000000..165ffd61b --- /dev/null +++ b/.github/actions/copilot-native-fixture/action.yml @@ -0,0 +1,10 @@ +name: Copilot native verification acceptance +inputs: + verification-setup: + default: 'true' + description: Exercise the native verification bridge +runs: + using: node24 + main: dist/index.js + post: dist/index.js + post-if: always() && env.COPILOT_NATIVE_PHASE != '' diff --git a/.github/workflows/copilot_comment_runtime.yml b/.github/workflows/copilot_comment_runtime.yml new file mode 100644 index 000000000..b17c4d3a3 --- /dev/null +++ b/.github/workflows/copilot_comment_runtime.yml @@ -0,0 +1,738 @@ +# Generated by scripts/generate-native-verification-workflows.cjs +name: Copilot - Comment Runtime +'on': + workflow_call: + inputs: + runs-on: + description: JSON runner labels or group retained by setup. + type: string + default: '"ubuntu-latest"' + issue-managed-branches: + description: Optional issue-managed-branches override; otherwise use the caller repository Variable. + type: string + default: '' + pre-branch-sdd: + description: Optional pre-branch-sdd override; otherwise use the caller repository Variable. + type: string + default: '' + ai-ignore-files: + description: Optional ai-ignore-files override; otherwise use the caller repository Variable. + type: string + default: '' + prepare-source-verification: + description: Retain Copilot source-repository verification prerequisites; ignored in consumer repositories. + type: boolean + default: false + secrets: + PAT: + required: false + OPENCODE_API_KEY: + required: false + OPENAI_API_KEY: + required: false + ANTHROPIC_API_KEY: + required: false + GOOGLE_API_KEY: + required: false + OPENROUTER_API_KEY: + required: false + CURSOR_API_KEY: + required: false + CODEX_API_KEY: + required: false +jobs: + copilot: + name: Copilot + if: ${{ (vars.COPILOT_BOT_LOGIN == '' || github.actor != vars.COPILOT_BOT_LOGIN) && (github.event_name == 'issue_comment' || (github.event_name == 'pull_request_review_comment' && github.event.pull_request.head.repo.full_name == github.repository)) }} + runs-on: ${{ fromJSON(inputs.runs-on) }} + timeout-minutes: 120 + permissions: + checks: write + contents: read + env: + COPILOT_PREPARE_VERIFICATION: ${{ github.repository == 'vypdev/copilot' && inputs.prepare-source-verification && vars.BUGBOT_AUTOFIX_VERIFY_COMMANDS != '' && ((contains(github.event.comment.body, '/copilot') && ((contains(github.event.comment.body, 'sync-branch') && !contains(github.event.comment.body, '--dry-run')) || contains(github.event.comment.body, 'implement') || contains(github.event.comment.body, 'fix') || contains(github.event.comment.body, 'remember'))) || (vars.COPILOT_BOT_LOGIN != '' && contains(github.event.comment.body, format('@{0}', vars.COPILOT_BOT_LOGIN)) && !contains(github.event.comment.body, '--dry-run'))) }} + steps: + - name: Checkout Repository + uses: actions/checkout@v5 + with: + persist-credentials: false + fetch-depth: 0 + - name: Prepare repository pnpm + if: env.COPILOT_PREPARE_VERIFICATION == 'true' + uses: pnpm/action-setup@v5 + with: + version: 10.12.4 + standalone: false + dest: ${{ runner.temp }}/setup-pnpm-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.job }} + - name: Prepare repository Node + if: env.COPILOT_PREPARE_VERIFICATION == 'true' + uses: actions/setup-node@v7 + with: + node-version: 24.x + - name: Install repository verification dependencies + if: env.COPILOT_PREPARE_VERIFICATION == 'true' + run: pnpm install --frozen-lockfile --ignore-scripts + shell: bash + - name: Run Copilot + id: copilot + uses: $/ + with: &ref_0 + repository-locale: ${{ vars.REPOSITORY_LOCALE || 'en-US' }} + issues-locale: ${{ vars.ISSUES_LOCALE || '' }} + pull-requests-locale: ${{ vars.PULL_REQUESTS_LOCALE || '' }} + ai-ignore-files: ${{ inputs.ai-ignore-files || vars.AI_IGNORE_FILES || 'build/*' }} + debug: ${{ vars.DEBUG }} + main-branch: ${{ vars.MAIN_BRANCH || 'master' }} + development-branch: ${{ vars.DEVELOPMENT_BRANCH || 'develop' }} + feature-tree: ${{ vars.FEATURE_TREE || 'feature' }} + bugfix-tree: ${{ vars.BUGFIX_TREE || 'bugfix' }} + hotfix-tree: ${{ vars.HOTFIX_TREE || 'hotfix' }} + release-tree: ${{ vars.RELEASE_TREE || 'release' }} + docs-tree: ${{ vars.DOCS_TREE || 'docs' }} + chore-tree: ${{ vars.CHORE_TREE || 'chore' }} + issue-managed-branches: ${{ inputs.issue-managed-branches || vars.ISSUE_MANAGED_BRANCHES || 'true' }} + pre-branch-sdd: ${{ inputs.pre-branch-sdd || vars.PRE_BRANCH_SDD || 'false' }} + verification-setup: ${{ vars.VERIFICATION_SETUP || 'false' }} + issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }} + reopen-issue-on-push: ${{ vars.REOPEN_ISSUE_ON_PUSH || 'true' }} + desired-assignees-count: ${{ vars.DESIRED_ASSIGNEES_COUNT || '1' }} + desired-reviewers-count: ${{ vars.DESIRED_REVIEWERS_COUNT || '1' }} + commit-prefix-transforms: ${{ vars.COMMIT_PREFIX_TRANSFORMS || 'replace-slash' }} + ai-pull-request-description-mode: ${{ vars.AI_PULL_REQUEST_DESCRIPTION_MODE || 'replace' }} + ai-members-only: ${{ vars.AI_MEMBERS_ONLY || 'false' }} + ai-include-reasoning: ${{ vars.AI_INCLUDE_REASONING || 'false' }} + bugbot-severity: ${{ vars.BUGBOT_SEVERITY || 'low' }} + bugbot-comment-limit: ${{ vars.BUGBOT_COMMENT_LIMIT || '20' }} + bugbot-fix-verify-commands: ${{ vars.BUGBOT_AUTOFIX_VERIFY_COMMANDS }} + bugbot-dry-run: ${{ vars.BUGBOT_DRY_RUN || 'false' }} + bugbot-effort: ${{ vars.BUGBOT_EFFORT || 'smart' }} + bugbot-review-drafts: ${{ vars.BUGBOT_REVIEW_DRAFTS || 'false' }} + bugbot-trace-rules: ${{ vars.BUGBOT_TRACE_RULES || 'false' }} + bugbot-suggested-changes: ${{ vars.BUGBOT_SUGGESTED_CHANGES || 'true' }} + bugbot-telemetry: ${{ vars.BUGBOT_TELEMETRY || 'true' }} + bugbot-fail-on-unresolved: ${{ vars.BUGBOT_FAIL_ON_UNRESOLVED || 'false' }} + bugbot-organization-rules: ${{ vars.BUGBOT_ORGANIZATION_RULES }} + project-column-issue-created: ${{ vars.PROJECT_COLUMN_ISSUE_CREATED || 'Todo' }} + project-column-pull-request-created: ${{ vars.PROJECT_COLUMN_PULL_REQUEST_CREATED || 'In Progress' }} + project-column-issue-in-progress: ${{ vars.PROJECT_COLUMN_ISSUE_IN_PROGRESS || 'In Progress' }} + project-column-pull-request-in-progress: ${{ vars.PROJECT_COLUMN_PULL_REQUEST_IN_PROGRESS || 'In Progress' }} + agent-provider: ${{ vars.AGENT_PROVIDER || 'codex' }} + agent-model-provider: ${{ vars.AGENT_MODEL_PROVIDER || 'openai' }} + agent-model: ${{ vars.AGENT_MODEL || 'gpt-6-luna' }} + agent-effort: ${{ vars.AGENT_EFFORT }} + agent-executable: ${{ vars.AGENT_EXECUTABLE }} + findings-provider: ${{ vars.FINDINGS_PROVIDER }} + findings-model-provider: ${{ vars.FINDINGS_MODEL_PROVIDER }} + findings-model: ${{ vars.FINDINGS_MODEL }} + findings-effort: ${{ vars.FINDINGS_EFFORT }} + findings-executable: ${{ vars.FINDINGS_EXECUTABLE }} + fixer-provider: ${{ vars.FIXER_PROVIDER }} + fixer-model-provider: ${{ vars.FIXER_MODEL_PROVIDER }} + fixer-model: ${{ vars.FIXER_MODEL }} + fixer-effort: ${{ vars.FIXER_EFFORT }} + fixer-executable: ${{ vars.FIXER_EXECUTABLE }} + planner-provider: ${{ vars.PLANNER_PROVIDER }} + planner-model-provider: ${{ vars.PLANNER_MODEL_PROVIDER }} + planner-model: ${{ vars.PLANNER_MODEL }} + planner-effort: ${{ vars.PLANNER_EFFORT }} + planner-executable: ${{ vars.PLANNER_EXECUTABLE }} + reviewer-provider: ${{ vars.REVIEWER_PROVIDER }} + reviewer-model-provider: ${{ vars.REVIEWER_MODEL_PROVIDER }} + reviewer-model: ${{ vars.REVIEWER_MODEL }} + reviewer-effort: ${{ vars.REVIEWER_EFFORT }} + reviewer-executable: ${{ vars.REVIEWER_EXECUTABLE }} + tester-provider: ${{ vars.TESTER_PROVIDER }} + tester-model-provider: ${{ vars.TESTER_MODEL_PROVIDER }} + tester-model: ${{ vars.TESTER_MODEL }} + tester-effort: ${{ vars.TESTER_EFFORT }} + tester-executable: ${{ vars.TESTER_EXECUTABLE }} + project-ids: ${{ vars.PROJECT_IDS }} + token: ${{ secrets.PAT }} + env: + COPILOT_NATIVE_PHASE: prepare + AGENT_PROVIDER: ${{ vars.AGENT_PROVIDER || 'codex' }} + AGENT_MODEL_PROVIDER: ${{ vars.AGENT_MODEL_PROVIDER || 'openai' }} + AGENT_MODEL: ${{ vars.AGENT_MODEL }} + AGENT_EFFORT: ${{ vars.AGENT_EFFORT }} + AGENT_EXECUTABLE: ${{ vars.AGENT_EXECUTABLE }} + AGENT_ALLOWED_MODEL_PROVIDERS: ${{ vars.AGENT_ALLOWED_MODEL_PROVIDERS || 'openai' }} + AGENT_ALLOWED_MODELS: ${{ vars.AGENT_ALLOWED_MODELS || 'openai/gpt-6-luna' }} + OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} + OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} + CURSOR_API_KEY: ${{ (vars.AGENT_PROVIDER == 'cursor' || vars.FINDINGS_PROVIDER == 'cursor' || vars.FIXER_PROVIDER == 'cursor' || vars.PLANNER_PROVIDER == 'cursor' || vars.REVIEWER_PROVIDER == 'cursor' || vars.TESTER_PROVIDER == 'cursor') && secrets.CURSOR_API_KEY || '' }} + CODEX_API_KEY: ${{ secrets.CODEX_API_KEY }} + COPILOT_EVIDENCE_TOKEN: ${{ github.token }} + - name: Prepare repository verification 1 + id: verification_setup_1 + if: ${{ !cancelled() && steps.copilot.outcome == 'success' && steps.copilot.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.copilot.outputs.verification-home }} + USERPROFILE: ${{ steps.copilot.outputs.verification-userprofile }} + APPDATA: ${{ steps.copilot.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.copilot.outputs.verification-localappdata }} + PATH: ${{ steps.copilot.outputs.verification-path }} + JAVA_HOME: ${{ steps.copilot.outputs.verification-java_home }} + TMP: ${{ steps.copilot.outputs.verification-tmp }} + TEMP: ${{ steps.copilot.outputs.verification-temp }} + TMPDIR: ${{ steps.copilot.outputs.verification-tmpdir }} + - name: Continue repository verification 1 + id: verification_continue_1 + if: ${{ always() && steps.copilot.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.copilot.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_1.outcome }} + - name: Prepare repository verification 2 + id: verification_setup_2 + if: ${{ !cancelled() && steps.verification_continue_1.outcome == 'success' && steps.verification_continue_1.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_1.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_1.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_1.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_1.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_1.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_1.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_1.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_1.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_1.outputs.verification-tmpdir }} + - name: Continue repository verification 2 + id: verification_continue_2 + if: ${{ always() && steps.verification_continue_1.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_1.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_2.outcome }} + - name: Prepare repository verification 3 + id: verification_setup_3 + if: ${{ !cancelled() && steps.verification_continue_2.outcome == 'success' && steps.verification_continue_2.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_2.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_2.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_2.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_2.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_2.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_2.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_2.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_2.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_2.outputs.verification-tmpdir }} + - name: Continue repository verification 3 + id: verification_continue_3 + if: ${{ always() && steps.verification_continue_2.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_2.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_3.outcome }} + - name: Prepare repository verification 4 + id: verification_setup_4 + if: ${{ !cancelled() && steps.verification_continue_3.outcome == 'success' && steps.verification_continue_3.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_3.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_3.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_3.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_3.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_3.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_3.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_3.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_3.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_3.outputs.verification-tmpdir }} + - name: Continue repository verification 4 + id: verification_continue_4 + if: ${{ always() && steps.verification_continue_3.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_3.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_4.outcome }} + - name: Prepare repository verification 5 + id: verification_setup_5 + if: ${{ !cancelled() && steps.verification_continue_4.outcome == 'success' && steps.verification_continue_4.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_4.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_4.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_4.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_4.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_4.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_4.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_4.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_4.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_4.outputs.verification-tmpdir }} + - name: Continue repository verification 5 + id: verification_continue_5 + if: ${{ always() && steps.verification_continue_4.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_4.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_5.outcome }} + - name: Prepare repository verification 6 + id: verification_setup_6 + if: ${{ !cancelled() && steps.verification_continue_5.outcome == 'success' && steps.verification_continue_5.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_5.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_5.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_5.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_5.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_5.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_5.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_5.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_5.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_5.outputs.verification-tmpdir }} + - name: Continue repository verification 6 + id: verification_continue_6 + if: ${{ always() && steps.verification_continue_5.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_5.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_6.outcome }} + - name: Prepare repository verification 7 + id: verification_setup_7 + if: ${{ !cancelled() && steps.verification_continue_6.outcome == 'success' && steps.verification_continue_6.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_6.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_6.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_6.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_6.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_6.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_6.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_6.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_6.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_6.outputs.verification-tmpdir }} + - name: Continue repository verification 7 + id: verification_continue_7 + if: ${{ always() && steps.verification_continue_6.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_6.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_7.outcome }} + - name: Prepare repository verification 8 + id: verification_setup_8 + if: ${{ !cancelled() && steps.verification_continue_7.outcome == 'success' && steps.verification_continue_7.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_7.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_7.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_7.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_7.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_7.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_7.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_7.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_7.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_7.outputs.verification-tmpdir }} + - name: Continue repository verification 8 + id: verification_continue_8 + if: ${{ always() && steps.verification_continue_7.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_7.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_8.outcome }} + - name: Prepare repository verification 9 + id: verification_setup_9 + if: ${{ !cancelled() && steps.verification_continue_8.outcome == 'success' && steps.verification_continue_8.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_8.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_8.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_8.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_8.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_8.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_8.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_8.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_8.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_8.outputs.verification-tmpdir }} + - name: Continue repository verification 9 + id: verification_continue_9 + if: ${{ always() && steps.verification_continue_8.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_8.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_9.outcome }} + - name: Prepare repository verification 10 + id: verification_setup_10 + if: ${{ !cancelled() && steps.verification_continue_9.outcome == 'success' && steps.verification_continue_9.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_9.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_9.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_9.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_9.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_9.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_9.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_9.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_9.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_9.outputs.verification-tmpdir }} + - name: Continue repository verification 10 + id: verification_continue_10 + if: ${{ always() && steps.verification_continue_9.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_9.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_10.outcome }} + - name: Prepare repository verification 11 + id: verification_setup_11 + if: ${{ !cancelled() && steps.verification_continue_10.outcome == 'success' && steps.verification_continue_10.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_10.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_10.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_10.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_10.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_10.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_10.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_10.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_10.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_10.outputs.verification-tmpdir }} + - name: Continue repository verification 11 + id: verification_continue_11 + if: ${{ always() && steps.verification_continue_10.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_10.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_11.outcome }} + - name: Prepare repository verification 12 + id: verification_setup_12 + if: ${{ !cancelled() && steps.verification_continue_11.outcome == 'success' && steps.verification_continue_11.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_11.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_11.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_11.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_11.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_11.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_11.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_11.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_11.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_11.outputs.verification-tmpdir }} + - name: Continue repository verification 12 + id: verification_continue_12 + if: ${{ always() && steps.verification_continue_11.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_11.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_12.outcome }} + - name: Prepare repository verification 13 + id: verification_setup_13 + if: ${{ !cancelled() && steps.verification_continue_12.outcome == 'success' && steps.verification_continue_12.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_12.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_12.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_12.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_12.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_12.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_12.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_12.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_12.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_12.outputs.verification-tmpdir }} + - name: Continue repository verification 13 + id: verification_continue_13 + if: ${{ always() && steps.verification_continue_12.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_12.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_13.outcome }} + - name: Prepare repository verification 14 + id: verification_setup_14 + if: ${{ !cancelled() && steps.verification_continue_13.outcome == 'success' && steps.verification_continue_13.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_13.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_13.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_13.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_13.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_13.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_13.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_13.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_13.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_13.outputs.verification-tmpdir }} + - name: Continue repository verification 14 + id: verification_continue_14 + if: ${{ always() && steps.verification_continue_13.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_13.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_14.outcome }} + - name: Prepare repository verification 15 + id: verification_setup_15 + if: ${{ !cancelled() && steps.verification_continue_14.outcome == 'success' && steps.verification_continue_14.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_14.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_14.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_14.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_14.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_14.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_14.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_14.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_14.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_14.outputs.verification-tmpdir }} + - name: Continue repository verification 15 + id: verification_continue_15 + if: ${{ always() && steps.verification_continue_14.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_14.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_15.outcome }} + - name: Prepare repository verification 16 + id: verification_setup_16 + if: ${{ !cancelled() && steps.verification_continue_15.outcome == 'success' && steps.verification_continue_15.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_15.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_15.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_15.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_15.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_15.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_15.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_15.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_15.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_15.outputs.verification-tmpdir }} + - name: Continue repository verification 16 + id: verification_continue_16 + if: ${{ always() && steps.verification_continue_15.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_15.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_16.outcome }} + - name: Prepare repository verification 17 + id: verification_setup_17 + if: ${{ !cancelled() && steps.verification_continue_16.outcome == 'success' && steps.verification_continue_16.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_16.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_16.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_16.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_16.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_16.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_16.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_16.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_16.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_16.outputs.verification-tmpdir }} + - name: Continue repository verification 17 + id: verification_continue_17 + if: ${{ always() && steps.verification_continue_16.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_16.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_17.outcome }} + - name: Prepare repository verification 18 + id: verification_setup_18 + if: ${{ !cancelled() && steps.verification_continue_17.outcome == 'success' && steps.verification_continue_17.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_17.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_17.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_17.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_17.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_17.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_17.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_17.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_17.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_17.outputs.verification-tmpdir }} + - name: Continue repository verification 18 + id: verification_continue_18 + if: ${{ always() && steps.verification_continue_17.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_17.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_18.outcome }} + - name: Prepare repository verification 19 + id: verification_setup_19 + if: ${{ !cancelled() && steps.verification_continue_18.outcome == 'success' && steps.verification_continue_18.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_18.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_18.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_18.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_18.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_18.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_18.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_18.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_18.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_18.outputs.verification-tmpdir }} + - name: Continue repository verification 19 + id: verification_continue_19 + if: ${{ always() && steps.verification_continue_18.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_18.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_19.outcome }} + - name: Prepare repository verification 20 + id: verification_setup_20 + if: ${{ !cancelled() && steps.verification_continue_19.outcome == 'success' && steps.verification_continue_19.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_19.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_19.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_19.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_19.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_19.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_19.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_19.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_19.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_19.outputs.verification-tmpdir }} + - name: Continue repository verification 20 + id: verification_continue_20 + if: ${{ always() && steps.verification_continue_19.outputs.verification-setup-pending == 'true' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_19.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_20.outcome }} + - name: Complete repository verification + id: verification_complete + if: ${{ always() && steps.copilot.outputs.verification-ticket != '' }} + uses: $/ + with: *ref_0 + env: + COPILOT_NATIVE_PHASE: finish + COPILOT_NATIVE_SOURCE: ${{ steps.copilot.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot.outputs.verification-ticket }} diff --git a/.github/workflows/copilot_commit.yml b/.github/workflows/copilot_commit.yml index f1a263b89..dbdfdd087 100644 --- a/.github/workflows/copilot_commit.yml +++ b/.github/workflows/copilot_commit.yml @@ -51,6 +51,7 @@ jobs: issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }} issue-managed-branches: true pre-branch-sdd: true + verification-setup: ${{ vars.VERIFICATION_SETUP || 'false' }} debug: ${{ vars.DEBUG }} bugbot-severity: ${{ vars.BUGBOT_SEVERITY || 'low' }} bugbot-comment-limit: ${{ vars.BUGBOT_COMMENT_LIMIT || '20' }} diff --git a/.github/workflows/copilot_issue.yml b/.github/workflows/copilot_issue.yml index 789458199..beef7c2a3 100644 --- a/.github/workflows/copilot_issue.yml +++ b/.github/workflows/copilot_issue.yml @@ -26,6 +26,7 @@ jobs: issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }} issue-managed-branches: true pre-branch-sdd: true + verification-setup: ${{ vars.VERIFICATION_SETUP || 'false' }} ai-ignore-files: build/*,specs/CATALOG.md bugbot-dry-run: ${{ vars.BUGBOT_DRY_RUN || 'false' }} bugbot-effort: ${{ vars.BUGBOT_EFFORT || 'smart' }} diff --git a/.github/workflows/copilot_issue_comment.yml b/.github/workflows/copilot_issue_comment.yml index 8fde2a2dc..2cc07d44c 100644 --- a/.github/workflows/copilot_issue_comment.yml +++ b/.github/workflows/copilot_issue_comment.yml @@ -1,111 +1,32 @@ +# Generated by scripts/generate-native-verification-workflows.cjs +# Project runtimes: .copilot/verification-prerequisites.json +# Dependencies: .github/actions/copilot-verification-setup/action.yml +# https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-verification-prerequisites name: Copilot - Issue Comment - -on: +'on': issue_comment: - types: [created, edited] - + types: + - created + - edited jobs: copilot-issues: if: ${{ vars.COPILOT_BOT_LOGIN == '' || github.actor != vars.COPILOT_BOT_LOGIN }} - name: Copilot - Issue Comment - runs-on: [self-hosted, codex, Linux] - timeout-minutes: 120 + uses: $/.github/workflows/copilot_comment_runtime.yml permissions: checks: write contents: read - env: - # Preparation covers parser whitespace and mentions; authorization stays in the Action. - COPILOT_PREPARE_VERIFICATION: ${{ vars.BUGBOT_AUTOFIX_VERIFY_COMMANDS != '' && ((contains(github.event.comment.body, '/copilot') && ((contains(github.event.comment.body, 'sync-branch') && !contains(github.event.comment.body, '--dry-run')) || contains(github.event.comment.body, 'implement') || contains(github.event.comment.body, 'fix') || contains(github.event.comment.body, 'remember'))) || (vars.COPILOT_BOT_LOGIN != '' && contains(github.event.comment.body, format('@{0}', vars.COPILOT_BOT_LOGIN)) && !contains(github.event.comment.body, '--dry-run'))) }} - steps: - - name: Checkout Repository - uses: actions/checkout@v5 - with: - persist-credentials: false - fetch-depth: 0 - - - name: Prepare repository pnpm - if: env.COPILOT_PREPARE_VERIFICATION == 'true' - uses: pnpm/action-setup@v5 - with: - version: 10.12.4 - standalone: false - dest: ${{ runner.temp }}/setup-pnpm-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.job }} - - - name: Prepare repository Node - if: env.COPILOT_PREPARE_VERIFICATION == 'true' - uses: actions/setup-node@v7 - with: - node-version: '24.x' - - - name: Install repository verification dependencies - if: env.COPILOT_PREPARE_VERIFICATION == 'true' - shell: bash - run: pnpm install --frozen-lockfile --ignore-scripts - - - uses: ./ - with: - repository-locale: ${{ vars.REPOSITORY_LOCALE || 'en-US' }} - issues-locale: ${{ vars.ISSUES_LOCALE || '' }} - pull-requests-locale: ${{ vars.PULL_REQUESTS_LOCALE || '' }} - issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }} - issue-managed-branches: true - pre-branch-sdd: true - ai-ignore-files: build/*,specs/CATALOG.md - debug: ${{ vars.DEBUG }} - agent-provider: ${{ vars.AGENT_PROVIDER || 'codex' }} - agent-model-provider: ${{ vars.AGENT_MODEL_PROVIDER || 'openai' }} - agent-model: ${{ vars.AGENT_MODEL || 'gpt-6-luna' }} - agent-effort: ${{ vars.AGENT_EFFORT }} - agent-executable: ${{ vars.AGENT_EXECUTABLE }} - findings-provider: ${{ vars.FINDINGS_PROVIDER }} - findings-model-provider: ${{ vars.FINDINGS_MODEL_PROVIDER }} - findings-model: ${{ vars.FINDINGS_MODEL }} - findings-effort: ${{ vars.FINDINGS_EFFORT }} - findings-executable: ${{ vars.FINDINGS_EXECUTABLE }} - fixer-provider: ${{ vars.FIXER_PROVIDER }} - fixer-model-provider: ${{ vars.FIXER_MODEL_PROVIDER }} - fixer-model: ${{ vars.FIXER_MODEL }} - fixer-effort: ${{ vars.FIXER_EFFORT }} - fixer-executable: ${{ vars.FIXER_EXECUTABLE }} - planner-provider: ${{ vars.PLANNER_PROVIDER }} - planner-model-provider: ${{ vars.PLANNER_MODEL_PROVIDER }} - planner-model: ${{ vars.PLANNER_MODEL }} - planner-effort: ${{ vars.PLANNER_EFFORT }} - planner-executable: ${{ vars.PLANNER_EXECUTABLE }} - reviewer-provider: ${{ vars.REVIEWER_PROVIDER }} - reviewer-model-provider: ${{ vars.REVIEWER_MODEL_PROVIDER }} - reviewer-model: ${{ vars.REVIEWER_MODEL }} - reviewer-effort: ${{ vars.REVIEWER_EFFORT }} - reviewer-executable: ${{ vars.REVIEWER_EXECUTABLE }} - tester-provider: ${{ vars.TESTER_PROVIDER }} - tester-model-provider: ${{ vars.TESTER_MODEL_PROVIDER }} - tester-model: ${{ vars.TESTER_MODEL }} - tester-effort: ${{ vars.TESTER_EFFORT }} - tester-executable: ${{ vars.TESTER_EXECUTABLE }} - project-ids: ${{ vars.PROJECT_IDS }} - token: ${{ secrets.PAT }} - bugbot-fix-verify-commands: ${{ vars.BUGBOT_AUTOFIX_VERIFY_COMMANDS }} - bugbot-dry-run: ${{ vars.BUGBOT_DRY_RUN || 'false' }} - bugbot-effort: ${{ vars.BUGBOT_EFFORT || 'smart' }} - bugbot-review-drafts: ${{ vars.BUGBOT_REVIEW_DRAFTS || 'false' }} - bugbot-trace-rules: ${{ vars.BUGBOT_TRACE_RULES || 'false' }} - bugbot-suggested-changes: ${{ vars.BUGBOT_SUGGESTED_CHANGES || 'true' }} - bugbot-telemetry: ${{ vars.BUGBOT_TELEMETRY || 'true' }} - bugbot-fail-on-unresolved: ${{ vars.BUGBOT_FAIL_ON_UNRESOLVED || 'false' }} - bugbot-organization-rules: ${{ vars.BUGBOT_ORGANIZATION_RULES }} - env: - AGENT_PROVIDER: ${{ vars.AGENT_PROVIDER || 'codex' }} - AGENT_MODEL_PROVIDER: ${{ vars.AGENT_MODEL_PROVIDER || 'openai' }} - AGENT_MODEL: ${{ vars.AGENT_MODEL }} - AGENT_EFFORT: ${{ vars.AGENT_EFFORT }} - AGENT_ALLOWED_MODEL_PROVIDERS: ${{ vars.AGENT_ALLOWED_MODEL_PROVIDERS || 'openai' }} - AGENT_ALLOWED_MODELS: ${{ vars.AGENT_ALLOWED_MODELS || 'openai/gpt-6-luna' }} - AGENT_EXECUTABLE: ${{ vars.AGENT_EXECUTABLE }} - OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} - GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} - OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} - CURSOR_API_KEY: ${{ (vars.AGENT_PROVIDER == 'cursor' || vars.FINDINGS_PROVIDER == 'cursor' || vars.FIXER_PROVIDER == 'cursor' || vars.PLANNER_PROVIDER == 'cursor' || vars.REVIEWER_PROVIDER == 'cursor' || vars.TESTER_PROVIDER == 'cursor') && secrets.CURSOR_API_KEY || '' }} - CODEX_API_KEY: ${{ secrets.CODEX_API_KEY }} - COPILOT_EVIDENCE_TOKEN: ${{ github.token }} + with: + runs-on: '["self-hosted","codex","Linux"]' + issue-managed-branches: 'true' + pre-branch-sdd: 'true' + ai-ignore-files: build/*,specs/CATALOG.md + prepare-source-verification: true + secrets: + PAT: ${{ secrets.PAT }} + OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} + OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} + CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} + CODEX_API_KEY: ${{ secrets.CODEX_API_KEY }} diff --git a/.github/workflows/copilot_pull_request.yml b/.github/workflows/copilot_pull_request.yml index d63827d47..928453a51 100644 --- a/.github/workflows/copilot_pull_request.yml +++ b/.github/workflows/copilot_pull_request.yml @@ -48,6 +48,7 @@ jobs: issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }} issue-managed-branches: true pre-branch-sdd: true + verification-setup: ${{ vars.VERIFICATION_SETUP || 'false' }} ai-ignore-files: build/*,specs/CATALOG.md bugbot-severity: ${{ vars.BUGBOT_SEVERITY || 'low' }} bugbot-comment-limit: ${{ vars.BUGBOT_COMMENT_LIMIT || '20' }} diff --git a/.github/workflows/copilot_pull_request_comment.yml b/.github/workflows/copilot_pull_request_comment.yml index 0b2fdd06d..77b1e3694 100644 --- a/.github/workflows/copilot_pull_request_comment.yml +++ b/.github/workflows/copilot_pull_request_comment.yml @@ -1,111 +1,32 @@ +# Generated by scripts/generate-native-verification-workflows.cjs +# Project runtimes: .copilot/verification-prerequisites.json +# Dependencies: .github/actions/copilot-verification-setup/action.yml +# https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-verification-prerequisites name: Copilot - Pull Request Comment - -on: +'on': pull_request_review_comment: - types: [created, edited] - + types: + - created + - edited jobs: copilot-pull-requests: if: ${{ (vars.COPILOT_BOT_LOGIN == '' || github.actor != vars.COPILOT_BOT_LOGIN) && github.event.pull_request.head.repo.full_name == github.repository }} - name: Copilot - Pull Request Comment - runs-on: [self-hosted, codex, Linux] - timeout-minutes: 120 + uses: $/.github/workflows/copilot_comment_runtime.yml permissions: checks: write contents: read - env: - # Preparation covers parser whitespace and mentions; authorization stays in the Action. - COPILOT_PREPARE_VERIFICATION: ${{ vars.BUGBOT_AUTOFIX_VERIFY_COMMANDS != '' && ((contains(github.event.comment.body, '/copilot') && ((contains(github.event.comment.body, 'sync-branch') && !contains(github.event.comment.body, '--dry-run')) || contains(github.event.comment.body, 'implement') || contains(github.event.comment.body, 'fix') || contains(github.event.comment.body, 'remember'))) || (vars.COPILOT_BOT_LOGIN != '' && contains(github.event.comment.body, format('@{0}', vars.COPILOT_BOT_LOGIN)) && !contains(github.event.comment.body, '--dry-run'))) }} - steps: - - name: Checkout Repository - uses: actions/checkout@v5 - with: - persist-credentials: false - fetch-depth: 0 - - - name: Prepare repository pnpm - if: env.COPILOT_PREPARE_VERIFICATION == 'true' - uses: pnpm/action-setup@v5 - with: - version: 10.12.4 - standalone: false - dest: ${{ runner.temp }}/setup-pnpm-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.job }} - - - name: Prepare repository Node - if: env.COPILOT_PREPARE_VERIFICATION == 'true' - uses: actions/setup-node@v7 - with: - node-version: '24.x' - - - name: Install repository verification dependencies - if: env.COPILOT_PREPARE_VERIFICATION == 'true' - shell: bash - run: pnpm install --frozen-lockfile --ignore-scripts - - - uses: ./ - with: - repository-locale: ${{ vars.REPOSITORY_LOCALE || 'en-US' }} - issues-locale: ${{ vars.ISSUES_LOCALE || '' }} - pull-requests-locale: ${{ vars.PULL_REQUESTS_LOCALE || '' }} - issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }} - issue-managed-branches: true - pre-branch-sdd: true - ai-ignore-files: build/*,specs/CATALOG.md - debug: ${{ vars.DEBUG }} - agent-provider: ${{ vars.AGENT_PROVIDER || 'codex' }} - agent-model-provider: ${{ vars.AGENT_MODEL_PROVIDER || 'openai' }} - agent-model: ${{ vars.AGENT_MODEL || 'gpt-6-luna' }} - agent-effort: ${{ vars.AGENT_EFFORT }} - agent-executable: ${{ vars.AGENT_EXECUTABLE }} - findings-provider: ${{ vars.FINDINGS_PROVIDER }} - findings-model-provider: ${{ vars.FINDINGS_MODEL_PROVIDER }} - findings-model: ${{ vars.FINDINGS_MODEL }} - findings-effort: ${{ vars.FINDINGS_EFFORT }} - findings-executable: ${{ vars.FINDINGS_EXECUTABLE }} - fixer-provider: ${{ vars.FIXER_PROVIDER }} - fixer-model-provider: ${{ vars.FIXER_MODEL_PROVIDER }} - fixer-model: ${{ vars.FIXER_MODEL }} - fixer-effort: ${{ vars.FIXER_EFFORT }} - fixer-executable: ${{ vars.FIXER_EXECUTABLE }} - reviewer-provider: ${{ vars.REVIEWER_PROVIDER }} - reviewer-model-provider: ${{ vars.REVIEWER_MODEL_PROVIDER }} - reviewer-model: ${{ vars.REVIEWER_MODEL }} - reviewer-effort: ${{ vars.REVIEWER_EFFORT }} - reviewer-executable: ${{ vars.REVIEWER_EXECUTABLE }} - planner-provider: ${{ vars.PLANNER_PROVIDER }} - planner-model-provider: ${{ vars.PLANNER_MODEL_PROVIDER }} - planner-model: ${{ vars.PLANNER_MODEL }} - planner-effort: ${{ vars.PLANNER_EFFORT }} - planner-executable: ${{ vars.PLANNER_EXECUTABLE }} - tester-provider: ${{ vars.TESTER_PROVIDER }} - tester-model-provider: ${{ vars.TESTER_MODEL_PROVIDER }} - tester-model: ${{ vars.TESTER_MODEL }} - tester-effort: ${{ vars.TESTER_EFFORT }} - tester-executable: ${{ vars.TESTER_EXECUTABLE }} - project-ids: ${{ vars.PROJECT_IDS }} - token: ${{ secrets.PAT }} - bugbot-fix-verify-commands: ${{ vars.BUGBOT_AUTOFIX_VERIFY_COMMANDS }} - bugbot-dry-run: ${{ vars.BUGBOT_DRY_RUN || 'false' }} - bugbot-effort: ${{ vars.BUGBOT_EFFORT || 'smart' }} - bugbot-review-drafts: ${{ vars.BUGBOT_REVIEW_DRAFTS || 'false' }} - bugbot-trace-rules: ${{ vars.BUGBOT_TRACE_RULES || 'false' }} - bugbot-suggested-changes: ${{ vars.BUGBOT_SUGGESTED_CHANGES || 'true' }} - bugbot-telemetry: ${{ vars.BUGBOT_TELEMETRY || 'true' }} - bugbot-fail-on-unresolved: ${{ vars.BUGBOT_FAIL_ON_UNRESOLVED || 'false' }} - bugbot-organization-rules: ${{ vars.BUGBOT_ORGANIZATION_RULES }} - env: - AGENT_PROVIDER: ${{ vars.AGENT_PROVIDER || 'codex' }} - AGENT_MODEL_PROVIDER: ${{ vars.AGENT_MODEL_PROVIDER || 'openai' }} - AGENT_MODEL: ${{ vars.AGENT_MODEL }} - AGENT_EFFORT: ${{ vars.AGENT_EFFORT }} - AGENT_ALLOWED_MODEL_PROVIDERS: ${{ vars.AGENT_ALLOWED_MODEL_PROVIDERS || 'openai' }} - AGENT_ALLOWED_MODELS: ${{ vars.AGENT_ALLOWED_MODELS || 'openai/gpt-6-luna' }} - AGENT_EXECUTABLE: ${{ vars.AGENT_EXECUTABLE }} - OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} - GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} - OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} - CURSOR_API_KEY: ${{ (vars.AGENT_PROVIDER == 'cursor' || vars.FINDINGS_PROVIDER == 'cursor' || vars.FIXER_PROVIDER == 'cursor' || vars.PLANNER_PROVIDER == 'cursor' || vars.REVIEWER_PROVIDER == 'cursor' || vars.TESTER_PROVIDER == 'cursor') && secrets.CURSOR_API_KEY || '' }} - CODEX_API_KEY: ${{ secrets.CODEX_API_KEY }} - COPILOT_EVIDENCE_TOKEN: ${{ github.token }} + with: + runs-on: '["self-hosted","codex","Linux"]' + issue-managed-branches: 'true' + pre-branch-sdd: 'true' + ai-ignore-files: build/*,specs/CATALOG.md + prepare-source-verification: true + secrets: + PAT: ${{ secrets.PAT }} + OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} + OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} + CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} + CODEX_API_KEY: ${{ secrets.CODEX_API_KEY }} diff --git a/.github/workflows/copilot_pull_request_review_state.yml b/.github/workflows/copilot_pull_request_review_state.yml index 4d77d0bda..eb5879069 100644 --- a/.github/workflows/copilot_pull_request_review_state.yml +++ b/.github/workflows/copilot_pull_request_review_state.yml @@ -33,6 +33,7 @@ jobs: issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }} issue-managed-branches: true pre-branch-sdd: true + verification-setup: ${{ vars.VERIFICATION_SETUP || 'false' }} ai-ignore-files: build/*,specs/CATALOG.md bugbot-severity: ${{ vars.BUGBOT_SEVERITY || 'low' }} bugbot-comment-limit: ${{ vars.BUGBOT_COMMENT_LIMIT || '20' }} diff --git a/.github/workflows/hotfix_workflow.yml b/.github/workflows/hotfix_workflow.yml index 5ba20c1f7..a0dc50735 100644 --- a/.github/workflows/hotfix_workflow.yml +++ b/.github/workflows/hotfix_workflow.yml @@ -365,6 +365,7 @@ jobs: uses: ./ with: single-action: published_deployment_action + merge-queue-check-attestations: ${{ vars.MERGE_QUEUE_CHECK_ATTESTATIONS || '[]' }} single-action-issue: ${{ inputs.issue }} issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }} single-action-operation-id: ${{ inputs.operation-id }} diff --git a/.github/workflows/release_workflow.yml b/.github/workflows/release_workflow.yml index 54805a236..688b8f8d5 100644 --- a/.github/workflows/release_workflow.yml +++ b/.github/workflows/release_workflow.yml @@ -365,6 +365,7 @@ jobs: uses: ./ with: single-action: published_deployment_action + merge-queue-check-attestations: ${{ vars.MERGE_QUEUE_CHECK_ATTESTATIONS || '[]' }} single-action-issue: ${{ inputs.issue }} issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }} single-action-operation-id: ${{ inputs.operation-id }} diff --git a/.github/workflows/repowise.yml b/.github/workflows/repowise.yml index 02c7efed0..7ee5cd04a 100644 --- a/.github/workflows/repowise.yml +++ b/.github/workflows/repowise.yml @@ -1,32 +1,27 @@ name: RepoWise Code Health on: - push: - branches: [master] - pull_request: - types: [opened, synchronize, reopened] - merge_group: - types: [checks_requested] workflow_dispatch: concurrency: - group: repowise-${{ github.event.pull_request.number || github.ref }} + group: repowise-${{ github.ref }} cancel-in-progress: true permissions: contents: read +defaults: + run: + shell: bash + jobs: code-health: name: RepoWise code health - # A merge group can contain fork code without exposing the originating PR here. - runs-on: ${{ fromJSON((github.event_name == 'merge_group' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository)) && '["ubuntu-latest"]' || '["self-hosted","codex","Linux"]') }} - timeout-minutes: 30 + runs-on: [self-hosted, codex, Linux] + timeout-minutes: 40 env: REPOWISE_VENV_NAME: repowise-venv-${{ github.run_id }}-${{ github.run_attempt }}-code-health REPOWISE_REPORT_NAME: repowise-report-${{ github.run_id }}-${{ github.run_attempt }}-code-health - REPOWISE_BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before || '' }} - REPOWISE_EVENT_NAME: ${{ github.event_name }} steps: - name: Verify Ubuntu runner shell: bash @@ -57,61 +52,22 @@ jobs: "$RUNNER_TEMP/$REPOWISE_VENV_NAME/bin/python" -m pip install \ --disable-pip-version-check \ --no-cache-dir \ - 'repowise==0.45.0' + 'repowise==0.58.0' - name: Generate RepoWise reports env: REPOWISE_SKIP_EDITOR_SETUP: '1' run: | set -euo pipefail report_dir="$RUNNER_TEMP/$REPOWISE_REPORT_NAME" - repowise_bin="$RUNNER_TEMP/$REPOWISE_VENV_NAME/bin/repowise" - mkdir -p "$report_dir" + python_bin="$RUNNER_TEMP/$REPOWISE_VENV_NAME/bin/python" cleanup() { rm -rf .repowise .mcp.json rm -f .vscode/mcp.json .vscode/extensions.json rmdir .vscode 2>/dev/null || true } trap cleanup EXIT - "$repowise_bin" init \ - --no-prose --no-claude-md --no-codex --no-editor-setup \ - --no-onboarding --no-distill-hook --no-workspace . > "$report_dir/index.log" - "$repowise_bin" health --no-workspace --refactoring-targets --format md . | tee "$report_dir/health.md" - "$repowise_bin" health --no-workspace --refactoring-targets --format json . > "$report_dir/health.json" - advisory_scan() { - local name="$1" - shift - if (ulimit -v 2097152; timeout --kill-after=10s 90s "$@") > "$report_dir/$name.json"; then - printf '%s: complete\n' "$name" >> "$report_dir/advisory-status.txt" - else - local status="$?" - rm -f "$report_dir/$name.json" - printf '%s: incomplete (exit %s)\n' "$name" "$status" >> "$report_dir/advisory-status.txt" - echo "::warning::RepoWise $name advisory scan incomplete (exit $status); completed health reports remain available." - fi - } - advisory_scan dead-code "$repowise_bin" dead-code --safe-only --no-workspace --format json . - if [ "$REPOWISE_EVENT_NAME" = workflow_dispatch ]; then - echo 'security scope: full reachable history (manual dispatch)' >> "$report_dir/advisory-status.txt" - advisory_scan security "$repowise_bin" security scan --history --path . --format json - elif [[ "$REPOWISE_BASE_SHA" =~ ^[0-9a-f]{40}$ ]] \ - && git cat-file -e "$REPOWISE_BASE_SHA^{commit}" \ - && git merge-base --is-ancestor "$REPOWISE_BASE_SHA" HEAD; then - printf 'security scope: %s..%s\n' "$REPOWISE_BASE_SHA" "$(git rev-parse HEAD)" >> "$report_dir/advisory-status.txt" - advisory_scan security "$repowise_bin" security scan --history --since "$REPOWISE_BASE_SHA" --to HEAD --path . --format json - else - echo 'security: incomplete (event base unavailable or not an ancestor)' >> "$report_dir/advisory-status.txt" - echo '::warning::RepoWise security advisory scope could not be verified; no full-history fallback was attempted.' - fi - { - echo '## RepoWise code health' - echo - echo 'Advisory reports are retained as workflow artifacts for this commit.' - echo - sed -n '1,100p' "$report_dir/health.md" - echo - echo '### Advisory scan status' - cat "$report_dir/advisory-status.txt" - } >> "$GITHUB_STEP_SUMMARY" + "$python_bin" -m unittest discover -s scripts/tests -p 'test_repowise*.py' -v + "$python_bin" scripts/repowise_reports.py --report-dir "$report_dir" - name: Upload RepoWise reports if: ${{ always() }} uses: actions/upload-artifact@v6 diff --git a/.github/workflows/setup_platform_smoke.yml b/.github/workflows/setup_platform_smoke.yml index 251118abb..f6bb0cadd 100644 --- a/.github/workflows/setup_platform_smoke.yml +++ b/.github/workflows/setup_platform_smoke.yml @@ -41,7 +41,7 @@ jobs: if: ${{ github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && (inputs.windows_startup_probe != true || inputs.upload_windows_coverage == true)) }} name: Setup package and local session (${{ matrix.os }}) runs-on: ${{ matrix.os }} - timeout-minutes: 20 + timeout-minutes: ${{ matrix.os == 'windows-latest' && 30 || 20 }} strategy: fail-fast: false matrix: @@ -63,6 +63,592 @@ jobs: if: runner.os == 'Windows' run: node scripts/verify-windows-job-npm.cjs - run: pnpm install --frozen-lockfile + - name: Register native post cleanup acceptance + uses: ./.github/actions/copilot-native-cleanup-check + - name: Build native verification acceptance fixture + run: pnpm exec ncc build src/tooling/__tests__/fixtures/verification_native_fixture.ts -o .github/actions/copilot-native-fixture/dist + - name: Snapshot native fixture runtime + id: prepare_native_fixture_runtime + run: node scripts/prepare-native-source-action.cjs --fixture + - name: Prepare native verification acceptance + id: copilot_native_fixture + uses: ./../.copilot-native-fixture-runtime + with: &native-fixture-inputs + verification-setup: 'true' + env: + COPILOT_NATIVE_PHASE: prepare + COPILOT_NATIVE_RUNTIME_CACHE: ${{ steps.prepare_native_fixture_runtime.outputs.path }} + - name: Prepare repository verification 1 + id: verification_setup_1 + if: ${{ !cancelled() && steps.copilot_native_fixture.outcome == 'success' && steps.copilot_native_fixture.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.copilot_native_fixture.outputs.verification-home }} + USERPROFILE: ${{ steps.copilot_native_fixture.outputs.verification-userprofile }} + APPDATA: ${{ steps.copilot_native_fixture.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.copilot_native_fixture.outputs.verification-localappdata }} + PATH: ${{ steps.copilot_native_fixture.outputs.verification-path }} + JAVA_HOME: ${{ steps.copilot_native_fixture.outputs.verification-java_home }} + TMP: ${{ steps.copilot_native_fixture.outputs.verification-tmp }} + TEMP: ${{ steps.copilot_native_fixture.outputs.verification-temp }} + TMPDIR: ${{ steps.copilot_native_fixture.outputs.verification-tmpdir }} + - name: Continue repository verification 1 + id: verification_continue_1 + if: ${{ always() && steps.copilot_native_fixture.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.copilot_native_fixture.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_1.outcome }} + - name: Prepare repository verification 2 + id: verification_setup_2 + if: ${{ !cancelled() && steps.verification_continue_1.outcome == 'success' && steps.verification_continue_1.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_1.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_1.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_1.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_1.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_1.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_1.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_1.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_1.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_1.outputs.verification-tmpdir }} + - name: Continue repository verification 2 + id: verification_continue_2 + if: ${{ always() && steps.verification_continue_1.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_1.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_2.outcome }} + - name: Prepare repository verification 3 + id: verification_setup_3 + if: ${{ !cancelled() && steps.verification_continue_2.outcome == 'success' && steps.verification_continue_2.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_2.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_2.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_2.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_2.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_2.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_2.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_2.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_2.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_2.outputs.verification-tmpdir }} + - name: Continue repository verification 3 + id: verification_continue_3 + if: ${{ always() && steps.verification_continue_2.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_2.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_3.outcome }} + - name: Prepare repository verification 4 + id: verification_setup_4 + if: ${{ !cancelled() && steps.verification_continue_3.outcome == 'success' && steps.verification_continue_3.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_3.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_3.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_3.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_3.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_3.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_3.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_3.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_3.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_3.outputs.verification-tmpdir }} + - name: Continue repository verification 4 + id: verification_continue_4 + if: ${{ always() && steps.verification_continue_3.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_3.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_4.outcome }} + - name: Prepare repository verification 5 + id: verification_setup_5 + if: ${{ !cancelled() && steps.verification_continue_4.outcome == 'success' && steps.verification_continue_4.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_4.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_4.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_4.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_4.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_4.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_4.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_4.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_4.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_4.outputs.verification-tmpdir }} + - name: Continue repository verification 5 + id: verification_continue_5 + if: ${{ always() && steps.verification_continue_4.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_4.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_5.outcome }} + - name: Prepare repository verification 6 + id: verification_setup_6 + if: ${{ !cancelled() && steps.verification_continue_5.outcome == 'success' && steps.verification_continue_5.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_5.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_5.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_5.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_5.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_5.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_5.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_5.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_5.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_5.outputs.verification-tmpdir }} + - name: Continue repository verification 6 + id: verification_continue_6 + if: ${{ always() && steps.verification_continue_5.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_5.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_6.outcome }} + - name: Prepare repository verification 7 + id: verification_setup_7 + if: ${{ !cancelled() && steps.verification_continue_6.outcome == 'success' && steps.verification_continue_6.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_6.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_6.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_6.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_6.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_6.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_6.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_6.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_6.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_6.outputs.verification-tmpdir }} + - name: Continue repository verification 7 + id: verification_continue_7 + if: ${{ always() && steps.verification_continue_6.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_6.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_7.outcome }} + - name: Prepare repository verification 8 + id: verification_setup_8 + if: ${{ !cancelled() && steps.verification_continue_7.outcome == 'success' && steps.verification_continue_7.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_7.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_7.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_7.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_7.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_7.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_7.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_7.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_7.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_7.outputs.verification-tmpdir }} + - name: Continue repository verification 8 + id: verification_continue_8 + if: ${{ always() && steps.verification_continue_7.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_7.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_8.outcome }} + - name: Prepare repository verification 9 + id: verification_setup_9 + if: ${{ !cancelled() && steps.verification_continue_8.outcome == 'success' && steps.verification_continue_8.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_8.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_8.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_8.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_8.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_8.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_8.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_8.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_8.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_8.outputs.verification-tmpdir }} + - name: Continue repository verification 9 + id: verification_continue_9 + if: ${{ always() && steps.verification_continue_8.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_8.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_9.outcome }} + - name: Prepare repository verification 10 + id: verification_setup_10 + if: ${{ !cancelled() && steps.verification_continue_9.outcome == 'success' && steps.verification_continue_9.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_9.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_9.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_9.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_9.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_9.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_9.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_9.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_9.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_9.outputs.verification-tmpdir }} + - name: Continue repository verification 10 + id: verification_continue_10 + if: ${{ always() && steps.verification_continue_9.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_9.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_10.outcome }} + - name: Prepare repository verification 11 + id: verification_setup_11 + if: ${{ !cancelled() && steps.verification_continue_10.outcome == 'success' && steps.verification_continue_10.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_10.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_10.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_10.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_10.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_10.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_10.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_10.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_10.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_10.outputs.verification-tmpdir }} + - name: Continue repository verification 11 + id: verification_continue_11 + if: ${{ always() && steps.verification_continue_10.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_10.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_11.outcome }} + - name: Prepare repository verification 12 + id: verification_setup_12 + if: ${{ !cancelled() && steps.verification_continue_11.outcome == 'success' && steps.verification_continue_11.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_11.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_11.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_11.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_11.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_11.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_11.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_11.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_11.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_11.outputs.verification-tmpdir }} + - name: Continue repository verification 12 + id: verification_continue_12 + if: ${{ always() && steps.verification_continue_11.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_11.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_12.outcome }} + - name: Prepare repository verification 13 + id: verification_setup_13 + if: ${{ !cancelled() && steps.verification_continue_12.outcome == 'success' && steps.verification_continue_12.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_12.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_12.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_12.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_12.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_12.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_12.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_12.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_12.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_12.outputs.verification-tmpdir }} + - name: Continue repository verification 13 + id: verification_continue_13 + if: ${{ always() && steps.verification_continue_12.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_12.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_13.outcome }} + - name: Prepare repository verification 14 + id: verification_setup_14 + if: ${{ !cancelled() && steps.verification_continue_13.outcome == 'success' && steps.verification_continue_13.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_13.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_13.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_13.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_13.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_13.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_13.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_13.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_13.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_13.outputs.verification-tmpdir }} + - name: Continue repository verification 14 + id: verification_continue_14 + if: ${{ always() && steps.verification_continue_13.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_13.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_14.outcome }} + - name: Prepare repository verification 15 + id: verification_setup_15 + if: ${{ !cancelled() && steps.verification_continue_14.outcome == 'success' && steps.verification_continue_14.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_14.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_14.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_14.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_14.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_14.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_14.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_14.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_14.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_14.outputs.verification-tmpdir }} + - name: Continue repository verification 15 + id: verification_continue_15 + if: ${{ always() && steps.verification_continue_14.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_14.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_15.outcome }} + - name: Prepare repository verification 16 + id: verification_setup_16 + if: ${{ !cancelled() && steps.verification_continue_15.outcome == 'success' && steps.verification_continue_15.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_15.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_15.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_15.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_15.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_15.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_15.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_15.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_15.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_15.outputs.verification-tmpdir }} + - name: Continue repository verification 16 + id: verification_continue_16 + if: ${{ always() && steps.verification_continue_15.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_15.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_16.outcome }} + - name: Prepare repository verification 17 + id: verification_setup_17 + if: ${{ !cancelled() && steps.verification_continue_16.outcome == 'success' && steps.verification_continue_16.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_16.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_16.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_16.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_16.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_16.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_16.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_16.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_16.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_16.outputs.verification-tmpdir }} + - name: Continue repository verification 17 + id: verification_continue_17 + if: ${{ always() && steps.verification_continue_16.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_16.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_17.outcome }} + - name: Prepare repository verification 18 + id: verification_setup_18 + if: ${{ !cancelled() && steps.verification_continue_17.outcome == 'success' && steps.verification_continue_17.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_17.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_17.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_17.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_17.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_17.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_17.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_17.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_17.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_17.outputs.verification-tmpdir }} + - name: Continue repository verification 18 + id: verification_continue_18 + if: ${{ always() && steps.verification_continue_17.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_17.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_18.outcome }} + - name: Prepare repository verification 19 + id: verification_setup_19 + if: ${{ !cancelled() && steps.verification_continue_18.outcome == 'success' && steps.verification_continue_18.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_18.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_18.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_18.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_18.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_18.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_18.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_18.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_18.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_18.outputs.verification-tmpdir }} + - name: Continue repository verification 19 + id: verification_continue_19 + if: ${{ always() && steps.verification_continue_18.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_18.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_19.outcome }} + - name: Prepare repository verification 20 + id: verification_setup_20 + if: ${{ !cancelled() && steps.verification_continue_19.outcome == 'success' && steps.verification_continue_19.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_19.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_19.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_19.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_19.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_19.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_19.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_19.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_19.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_19.outputs.verification-tmpdir }} + - name: Continue repository verification 20 + id: verification_continue_20 + if: ${{ always() && steps.verification_continue_19.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_19.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_20.outcome }} + - name: Complete repository verification + id: verification_complete + if: ${{ always() && steps.copilot_native_fixture.outputs.verification-ticket != '' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: finish + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} - run: pnpm run build # Checked-in ncc bundles are generated on Unix; Windows output differs. - if: runner.os != 'Windows' @@ -157,6 +743,592 @@ jobs: run: | git ls-files --eol -- .copilot/repository-profile.json .copilot/AGENT_GUIDE.md .agents/skills/copilot-repository-workflow/SKILL.md pnpm run validate:agent-docs + - name: Register native post cleanup acceptance + uses: ./.github/actions/copilot-native-cleanup-check + - name: Build native verification acceptance fixture + run: pnpm exec ncc build src/tooling/__tests__/fixtures/verification_native_fixture.ts -o .github/actions/copilot-native-fixture/dist + - name: Snapshot native fixture runtime + id: prepare_native_fixture_runtime + run: node scripts/prepare-native-source-action.cjs --fixture + - name: Prepare native verification acceptance + id: copilot_native_fixture + uses: ./../.copilot-native-fixture-runtime + with: &native-fixture-inputs + verification-setup: 'true' + env: + COPILOT_NATIVE_PHASE: prepare + COPILOT_NATIVE_RUNTIME_CACHE: ${{ steps.prepare_native_fixture_runtime.outputs.path }} + - name: Prepare repository verification 1 + id: verification_setup_1 + if: ${{ !cancelled() && steps.copilot_native_fixture.outcome == 'success' && steps.copilot_native_fixture.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.copilot_native_fixture.outputs.verification-home }} + USERPROFILE: ${{ steps.copilot_native_fixture.outputs.verification-userprofile }} + APPDATA: ${{ steps.copilot_native_fixture.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.copilot_native_fixture.outputs.verification-localappdata }} + PATH: ${{ steps.copilot_native_fixture.outputs.verification-path }} + JAVA_HOME: ${{ steps.copilot_native_fixture.outputs.verification-java_home }} + TMP: ${{ steps.copilot_native_fixture.outputs.verification-tmp }} + TEMP: ${{ steps.copilot_native_fixture.outputs.verification-temp }} + TMPDIR: ${{ steps.copilot_native_fixture.outputs.verification-tmpdir }} + - name: Continue repository verification 1 + id: verification_continue_1 + if: ${{ always() && steps.copilot_native_fixture.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.copilot_native_fixture.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_1.outcome }} + - name: Prepare repository verification 2 + id: verification_setup_2 + if: ${{ !cancelled() && steps.verification_continue_1.outcome == 'success' && steps.verification_continue_1.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_1.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_1.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_1.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_1.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_1.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_1.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_1.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_1.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_1.outputs.verification-tmpdir }} + - name: Continue repository verification 2 + id: verification_continue_2 + if: ${{ always() && steps.verification_continue_1.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_1.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_2.outcome }} + - name: Prepare repository verification 3 + id: verification_setup_3 + if: ${{ !cancelled() && steps.verification_continue_2.outcome == 'success' && steps.verification_continue_2.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_2.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_2.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_2.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_2.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_2.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_2.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_2.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_2.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_2.outputs.verification-tmpdir }} + - name: Continue repository verification 3 + id: verification_continue_3 + if: ${{ always() && steps.verification_continue_2.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_2.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_3.outcome }} + - name: Prepare repository verification 4 + id: verification_setup_4 + if: ${{ !cancelled() && steps.verification_continue_3.outcome == 'success' && steps.verification_continue_3.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_3.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_3.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_3.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_3.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_3.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_3.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_3.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_3.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_3.outputs.verification-tmpdir }} + - name: Continue repository verification 4 + id: verification_continue_4 + if: ${{ always() && steps.verification_continue_3.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_3.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_4.outcome }} + - name: Prepare repository verification 5 + id: verification_setup_5 + if: ${{ !cancelled() && steps.verification_continue_4.outcome == 'success' && steps.verification_continue_4.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_4.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_4.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_4.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_4.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_4.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_4.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_4.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_4.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_4.outputs.verification-tmpdir }} + - name: Continue repository verification 5 + id: verification_continue_5 + if: ${{ always() && steps.verification_continue_4.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_4.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_5.outcome }} + - name: Prepare repository verification 6 + id: verification_setup_6 + if: ${{ !cancelled() && steps.verification_continue_5.outcome == 'success' && steps.verification_continue_5.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_5.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_5.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_5.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_5.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_5.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_5.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_5.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_5.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_5.outputs.verification-tmpdir }} + - name: Continue repository verification 6 + id: verification_continue_6 + if: ${{ always() && steps.verification_continue_5.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_5.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_6.outcome }} + - name: Prepare repository verification 7 + id: verification_setup_7 + if: ${{ !cancelled() && steps.verification_continue_6.outcome == 'success' && steps.verification_continue_6.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_6.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_6.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_6.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_6.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_6.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_6.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_6.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_6.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_6.outputs.verification-tmpdir }} + - name: Continue repository verification 7 + id: verification_continue_7 + if: ${{ always() && steps.verification_continue_6.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_6.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_7.outcome }} + - name: Prepare repository verification 8 + id: verification_setup_8 + if: ${{ !cancelled() && steps.verification_continue_7.outcome == 'success' && steps.verification_continue_7.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_7.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_7.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_7.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_7.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_7.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_7.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_7.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_7.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_7.outputs.verification-tmpdir }} + - name: Continue repository verification 8 + id: verification_continue_8 + if: ${{ always() && steps.verification_continue_7.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_7.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_8.outcome }} + - name: Prepare repository verification 9 + id: verification_setup_9 + if: ${{ !cancelled() && steps.verification_continue_8.outcome == 'success' && steps.verification_continue_8.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_8.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_8.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_8.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_8.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_8.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_8.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_8.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_8.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_8.outputs.verification-tmpdir }} + - name: Continue repository verification 9 + id: verification_continue_9 + if: ${{ always() && steps.verification_continue_8.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_8.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_9.outcome }} + - name: Prepare repository verification 10 + id: verification_setup_10 + if: ${{ !cancelled() && steps.verification_continue_9.outcome == 'success' && steps.verification_continue_9.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_9.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_9.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_9.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_9.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_9.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_9.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_9.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_9.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_9.outputs.verification-tmpdir }} + - name: Continue repository verification 10 + id: verification_continue_10 + if: ${{ always() && steps.verification_continue_9.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_9.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_10.outcome }} + - name: Prepare repository verification 11 + id: verification_setup_11 + if: ${{ !cancelled() && steps.verification_continue_10.outcome == 'success' && steps.verification_continue_10.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_10.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_10.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_10.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_10.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_10.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_10.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_10.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_10.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_10.outputs.verification-tmpdir }} + - name: Continue repository verification 11 + id: verification_continue_11 + if: ${{ always() && steps.verification_continue_10.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_10.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_11.outcome }} + - name: Prepare repository verification 12 + id: verification_setup_12 + if: ${{ !cancelled() && steps.verification_continue_11.outcome == 'success' && steps.verification_continue_11.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_11.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_11.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_11.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_11.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_11.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_11.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_11.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_11.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_11.outputs.verification-tmpdir }} + - name: Continue repository verification 12 + id: verification_continue_12 + if: ${{ always() && steps.verification_continue_11.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_11.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_12.outcome }} + - name: Prepare repository verification 13 + id: verification_setup_13 + if: ${{ !cancelled() && steps.verification_continue_12.outcome == 'success' && steps.verification_continue_12.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_12.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_12.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_12.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_12.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_12.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_12.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_12.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_12.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_12.outputs.verification-tmpdir }} + - name: Continue repository verification 13 + id: verification_continue_13 + if: ${{ always() && steps.verification_continue_12.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_12.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_13.outcome }} + - name: Prepare repository verification 14 + id: verification_setup_14 + if: ${{ !cancelled() && steps.verification_continue_13.outcome == 'success' && steps.verification_continue_13.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_13.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_13.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_13.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_13.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_13.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_13.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_13.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_13.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_13.outputs.verification-tmpdir }} + - name: Continue repository verification 14 + id: verification_continue_14 + if: ${{ always() && steps.verification_continue_13.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_13.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_14.outcome }} + - name: Prepare repository verification 15 + id: verification_setup_15 + if: ${{ !cancelled() && steps.verification_continue_14.outcome == 'success' && steps.verification_continue_14.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_14.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_14.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_14.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_14.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_14.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_14.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_14.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_14.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_14.outputs.verification-tmpdir }} + - name: Continue repository verification 15 + id: verification_continue_15 + if: ${{ always() && steps.verification_continue_14.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_14.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_15.outcome }} + - name: Prepare repository verification 16 + id: verification_setup_16 + if: ${{ !cancelled() && steps.verification_continue_15.outcome == 'success' && steps.verification_continue_15.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_15.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_15.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_15.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_15.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_15.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_15.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_15.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_15.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_15.outputs.verification-tmpdir }} + - name: Continue repository verification 16 + id: verification_continue_16 + if: ${{ always() && steps.verification_continue_15.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_15.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_16.outcome }} + - name: Prepare repository verification 17 + id: verification_setup_17 + if: ${{ !cancelled() && steps.verification_continue_16.outcome == 'success' && steps.verification_continue_16.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_16.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_16.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_16.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_16.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_16.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_16.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_16.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_16.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_16.outputs.verification-tmpdir }} + - name: Continue repository verification 17 + id: verification_continue_17 + if: ${{ always() && steps.verification_continue_16.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_16.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_17.outcome }} + - name: Prepare repository verification 18 + id: verification_setup_18 + if: ${{ !cancelled() && steps.verification_continue_17.outcome == 'success' && steps.verification_continue_17.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_17.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_17.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_17.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_17.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_17.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_17.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_17.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_17.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_17.outputs.verification-tmpdir }} + - name: Continue repository verification 18 + id: verification_continue_18 + if: ${{ always() && steps.verification_continue_17.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_17.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_18.outcome }} + - name: Prepare repository verification 19 + id: verification_setup_19 + if: ${{ !cancelled() && steps.verification_continue_18.outcome == 'success' && steps.verification_continue_18.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_18.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_18.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_18.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_18.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_18.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_18.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_18.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_18.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_18.outputs.verification-tmpdir }} + - name: Continue repository verification 19 + id: verification_continue_19 + if: ${{ always() && steps.verification_continue_18.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_18.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_19.outcome }} + - name: Prepare repository verification 20 + id: verification_setup_20 + if: ${{ !cancelled() && steps.verification_continue_19.outcome == 'success' && steps.verification_continue_19.outputs.verification-setup-pending == 'true' }} + uses: ./.git/copilot-verification-setup + timeout-minutes: 5 + env: + HOME: ${{ steps.verification_continue_19.outputs.verification-home }} + USERPROFILE: ${{ steps.verification_continue_19.outputs.verification-userprofile }} + APPDATA: ${{ steps.verification_continue_19.outputs.verification-appdata }} + LOCALAPPDATA: ${{ steps.verification_continue_19.outputs.verification-localappdata }} + PATH: ${{ steps.verification_continue_19.outputs.verification-path }} + JAVA_HOME: ${{ steps.verification_continue_19.outputs.verification-java_home }} + TMP: ${{ steps.verification_continue_19.outputs.verification-tmp }} + TEMP: ${{ steps.verification_continue_19.outputs.verification-temp }} + TMPDIR: ${{ steps.verification_continue_19.outputs.verification-tmpdir }} + - name: Continue repository verification 20 + id: verification_continue_20 + if: ${{ always() && steps.verification_continue_19.outputs.verification-setup-pending == 'true' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: continue + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} + COPILOT_NATIVE_REQUEST: ${{ steps.verification_continue_19.outputs.verification-request }} + COPILOT_NATIVE_OUTCOME: ${{ steps.verification_setup_20.outcome }} + - name: Complete repository verification + id: verification_complete + if: ${{ always() && steps.copilot_native_fixture.outputs.verification-ticket != '' }} + uses: ./../.copilot-native-fixture-runtime + with: *native-fixture-inputs + env: + COPILOT_NATIVE_PHASE: finish + COPILOT_NATIVE_SOURCE: ${{ steps.copilot_native_fixture.outputs.verification-source }} + COPILOT_NATIVE_DIGEST: ${{ steps.copilot_native_fixture.outputs.verification-digest }} + COPILOT_NATIVE_GIT: ${{ steps.copilot_native_fixture.outputs.verification-git }} + COPILOT_NATIVE_TICKET: ${{ steps.copilot_native_fixture.outputs.verification-ticket }} - run: pnpm run build - run: pnpm run validate:build - run: pnpm run typecheck diff --git a/.gitignore b/.gitignore index 9a83bca90..80f4da40e 100644 --- a/.gitignore +++ b/.gitignore @@ -147,3 +147,9 @@ opencode.json # Repository-local scratch output, including sandboxed Jest transform caches .tmp/ + +# Python analysis tooling +__pycache__/ + +# Native Actions acceptance bundle is built only by the platform smoke job. +.github/actions/copilot-native-fixture/dist/ diff --git a/action.yml b/action.yml index 8c30c4230..9772d06bf 100644 --- a/action.yml +++ b/action.yml @@ -53,6 +53,9 @@ inputs: pre-branch-sdd: description: "Require a validated SDD first commit for started feature and contract-change issues. Requires issue-managed-branches." default: "false" + verification-setup: + description: "Run the trusted repository composite action before repository verification in generated workflows. Disabled by default." + default: "false" issue-workflow-profile: description: "JSON profile of enabled issue workflows." default: "" @@ -558,6 +561,8 @@ outputs: runs: using: "node24" main: "build/github_action/index.js" + post: "build/github_action/index.js" + post-if: "always() && env.COPILOT_NATIVE_PHASE != ''" branding: icon: "cpu" color: "blue" diff --git a/build/api/index.js b/build/api/index.js index ca974bedf..46e8d4d35 100644 --- a/build/api/index.js +++ b/build/api/index.js @@ -68,6 +68,45 @@ function runAtApplicationErrorBoundary(operation) { } +/***/ }), + +/***/ 2937: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.BugbotMutationError = void 0; +exports.bugbotMutationError = bugbotMutationError; +const application_error_1 = __nccwpck_require__(5999); +const pull_request_review_errors_1 = __nccwpck_require__(6445); +class BugbotMutationError extends application_error_1.ApplicationError { + constructor(diagnostic) { + super(diagnostic.errorCode, `Bugbot ${diagnostic.stage} failed: operation=${diagnostic.operation}; finding=${diagnostic.findingId}; affected=${diagnostic.affectedCount}; ${diagnostic.providerStatus}; provider-reference=${diagnostic.providerReference}. Completed effects are retained; correct the named cause and recheck the same target.`); + this.diagnostic = diagnostic; + } +} +exports.BugbotMutationError = BugbotMutationError; +function bugbotMutationError(cause, stage, findingIds, fallback, affectedCount = findingIds.length) { + if (cause instanceof BugbotMutationError) + return cause; + const provider = cause instanceof pull_request_review_errors_1.PullRequestReviewOperationError ? cause : undefined; + const status = provider?.providerStatus; + const errorCode = status === 401 ? 'authorization.credential-invalid' : status === 403 ? 'authorization.denied' + : status === 404 ? 'provider.not-found' : status === 409 ? 'provider.conflict' + : status === 429 ? 'provider.rate-limited' + : status === 408 || status === 425 ? 'provider.unavailable' + : status && status < 500 ? 'provider.contract-invalid' : 'provider.unavailable'; + const first = findingIds[0]; + return new BugbotMutationError(Object.freeze({ + stage, operation: provider?.operation ?? fallback, + findingId: typeof first === 'string' && /^[A-Za-z0-9_./:-]{1,200}$/.test(first) ? first : 'unavailable', + affectedCount: Math.min(affectedCount, 10000), + providerStatus: status ? `http-${status}` : 'http-unavailable', + providerReference: provider?.providerReference ?? 'unavailable', errorCode, + })); +} + + /***/ }), /***/ 601: @@ -796,6 +835,7 @@ exports.BUGBOT_MESSAGE_IDS = Object.freeze([ 'bugbot.overflow.body', 'bugbot.common.more', 'bugbot.diagnostic.operationFailed', + 'bugbot.diagnostic.findingMutationFailed', 'bugbot.diagnostic.identityUnavailable', 'bugbot.diagnostic.pullRequestCommentsFailed', 'bugbot.diagnostic.reviewThreadsFailed', @@ -881,6 +921,7 @@ const ENGLISH_MESSAGES = Object.freeze({ 'bugbot.overflow.heading': 'More findings (comment limit)', 'bugbot.overflow.body': Object.freeze({ one: 'There is {count} more finding that was not published as an individual comment. Review locally or in the full diff to see the list.', other: 'There are {count} more findings that were not published as individual comments. Review locally or in the full diff to see the list.' }), 'bugbot.common.more': Object.freeze({ one: 'and {count} more.', other: 'and {count} more.' }), + 'bugbot.diagnostic.findingMutationFailed': 'Finding mutation failed: stage={stage}; operation={operation}; finding={findingId}; affected={affectedCount}; {providerStatus}; provider reference={providerReference}. Completed effects are retained. Correct access/contract errors before retrying; for transient failures restore provider availability, then recheck the same PR. Recheck reconciles existing reviews and threads.', 'bugbot.diagnostic.operationFailed': 'Bugbot could not complete one or more finding mutations.', 'bugbot.diagnostic.identityUnavailable': 'The authenticated Bugbot identity is unavailable.', 'bugbot.diagnostic.pullRequestCommentsFailed': 'Unable to re-read pull request review comments.', @@ -970,6 +1011,7 @@ const SPANISH_MESSAGES = Object.freeze({ 'bugbot.overflow.heading': 'Más hallazgos (límite de comentarios)', 'bugbot.overflow.body': Object.freeze({ one: 'Hay {count} hallazgo más que no se publicó como comentario individual. Revísalo localmente o en el diff completo para consultar la lista.', many: 'Hay {count} hallazgos más que no se publicaron como comentarios individuales. Revísalos localmente o en el diff completo para consultar la lista.', other: 'Hay {count} hallazgos más que no se publicaron como comentarios individuales. Revísalos localmente o en el diff completo para consultar la lista.' }), 'bugbot.common.more': Object.freeze({ one: 'y {count} más.', many: 'y {count} más.', other: 'y {count} más.' }), + 'bugbot.diagnostic.findingMutationFailed': 'Falló una mutación: fase={stage}; operación={operation}; hallazgo={findingId}; afectados={affectedCount}; {providerStatus}; referencia del proveedor={providerReference}. Se conservan los efectos completados. Corrige acceso/contrato antes de reintentar; para fallos transitorios restaura el proveedor y revisa la misma PR. La revisión reconcilia comentarios e hilos existentes.', 'bugbot.diagnostic.operationFailed': 'Bugbot no pudo completar una o más mutaciones de hallazgos.', 'bugbot.diagnostic.identityUnavailable': 'La identidad autenticada de Bugbot no está disponible.', 'bugbot.diagnostic.pullRequestCommentsFailed': 'No se pudieron volver a leer los comentarios del review del pull request.', @@ -1009,6 +1051,7 @@ async function resolveBugbotCatalog(locale, configuration, resolver) { } function renderBugbotDiagnostic(diagnostic, catalog) { switch (diagnostic.code) { + case 'finding-mutation-failed': return catalog.message('bugbot.diagnostic.findingMutationFailed', { ...diagnostic.mutation }); case 'operation-failed': return catalog.message('bugbot.diagnostic.operationFailed'); case 'identity-unavailable': return catalog.message('bugbot.diagnostic.identityUnavailable'); case 'snapshot-pull-request-comments-failed': return catalog.message('bugbot.diagnostic.pullRequestCommentsFailed'); @@ -1558,6 +1601,10 @@ function renderBugbotStatusCard(projection, catalogOrLocale, links) { facts.push(catalog.message('bugbot.coverage.omitted', { count: source.omittedItems })); if (source.truncatedItems > 0) facts.push(catalog.message('bugbot.coverage.truncated', { count: source.truncatedItems })); + const truncatedIds = source.truncatedItemIds?.slice(0, 50) + .filter(id => /^(?:issue:[0-9]+|review:[A-Za-z0-9_=-]+)$/.test(id) && id.length <= 160); + if (truncatedIds?.length) + facts.push(`truncated-source-ids=${truncatedIds.join(', ')}`); if (source.providerLimitReached) facts.push(catalog.message('bugbot.coverage.providerLimit')); return `- ${source.source}: ${source.status}; ${facts.join(', ')}`; @@ -1647,9 +1694,21 @@ function normalizeHistoricalSnapshot(originalBody, analyzedHeadSha, catalog) { function renderFindingRow(finding) { const label = (0, github_comment_publication_policy_1.sanitizeAgentMarkdown)(finding.title || finding.id, 500).replace(/[\r\n]+/gu, ' '); const state = stateLabel(finding.state); + const identity = finding.state === 'unknown' + ? ` — ${renderFindingId(finding.id)}` + : ''; return finding.url - ? `- ${state} — [${label}](${finding.url})` - : `- ${state} — ${label}`; + ? `- ${state} — [${label}](${finding.url})${identity}` + : `- ${state} — ${label}${identity}`; +} +function renderFindingId(value) { + const id = (0, github_comment_publication_policy_1.sanitizeAgentMarkdown)(value, 200).replace(/[\r\n]+/gu, ' '); + // A delimiter longer than every embedded backtick run keeps links, images + // and HTML inert even when the marker permits arbitrary Markdown punctuation. + let delimiter = '`'; + while (id.includes(delimiter)) + delimiter += '`'; + return `${delimiter} ${id} ${delimiter}`; } function stateLabel(state) { return `[ ] ${state}`; @@ -2136,6 +2195,13 @@ class PullRequestReviewOperationError extends Error { super(buildMessage(operation, context)); this.name = "PullRequestReviewOperationError"; this.operation = operation; + const status = context?.providerStatus; + if (typeof status === 'number' && Number.isInteger(status) && status >= 400 && status <= 599) { + this.providerStatus = status; + } + if (typeof context?.providerReference === 'string' && /^[A-Za-z0-9:-]{1,64}$/.test(context.providerReference)) { + this.providerReference = context.providerReference; + } } } exports.PullRequestReviewOperationError = PullRequestReviewOperationError; @@ -2235,7 +2301,7 @@ function partitionFailureCategory(error) { return error instanceof Error ? error.name : 'unknown'; } function suppressDismissedFindings(execution, context, prepared) { - const activeFindings = (prepared.activeFindings ?? prepared.toPublish).filter((finding) => { + const activeFindings = (0, finding_1.retainExistingFindingIds)(prepared.activeFindings ?? prepared.toPublish, context.existingByFindingId).filter((finding) => { const existing = (0, finding_1.findExistingFindingInfo)(context.existingByFindingId, finding); return existing?.issue?.resolution !== 'dismissed' && existing?.pullRequest?.resolution !== 'dismissed'; }); @@ -2254,6 +2320,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.applyDetectedFindings = applyDetectedFindings; const mark_findings_resolved_use_case_1 = __nccwpck_require__(6963); const publish_findings_use_case_1 = __nccwpck_require__(8442); +const bugbot_mutation_error_1 = __nccwpck_require__(2937); const pull_request_review_errors_1 = __nccwpck_require__(6445); async function applyDetectedFindings(operation, context, prepared, publicationPorts, resolutionPorts, catalog) { try { @@ -2269,7 +2336,7 @@ async function applyDetectedFindings(operation, context, prepared, publicationPo }); } catch (error) { - const publicationError = error instanceof pull_request_review_errors_1.PullRequestReviewOperationError + const publicationError = error instanceof bugbot_mutation_error_1.BugbotMutationError || error instanceof pull_request_review_errors_1.PullRequestReviewOperationError ? error : new Error("Unable to publish findings."); return [publicationError]; @@ -2540,6 +2607,7 @@ function buildPreviousFindingsContext(previousFindings) { `; const suffix = ` **Your task 2:** For each finding above, analyze the current code and decide: +- Trace the original failure precondition through current callers, validation helpers and effective configuration, including modules outside the original anchor. A retained finding is not proof that its old explanation is still true. Reuse its exact id if reporting the same defect again; do not create a second report for it. - If the problem **still exists** (same code or same issue present): do **not** include it in \`resolved_findings\`. - If the problem **no longer applies** (e.g. that code was removed or refactored away): include \`{ "id": "", "resolution": "obsolete" }\` in \`resolved_findings\`. - If the problem **has been fixed** (code was changed and the issue is resolved): include \`{ "id": "", "resolution": "fixed" }\` in \`resolved_findings\`. @@ -2658,6 +2726,10 @@ function buildReviewConversationContext(issueComments, commentsByPullRequest, bo omitted, truncated: chronological.filter((entry) => entry.truncated).length, retained: chronological.length, + ...(chronological.some(entry => entry.truncated) ? { + truncatedItemIds: chronological.filter(entry => entry.truncated) + .map(entry => entry.providerId).filter(id => /^(?:issue:[0-9]+|review:[A-Za-z0-9_=-]+)$/.test(id) && id.length <= 160), + } : {}), }; } function appendConversationEntry(entries, author, kind, body, createdAt, providerId) { @@ -3339,6 +3411,7 @@ async function loadBugbotContext(request, ports, resolvedPreflight) { itemsFetched: conversationContext.retained + conversationContext.omitted, omittedItems: conversationContext.omitted, truncatedItems: conversationContext.truncated, + ...(conversationContext.truncatedItemIds ? { truncatedItemIds: conversationContext.truncatedItemIds } : {}), limitReached: conversationContext.omitted > 0 || conversationContext.truncated > 0, }, { @@ -3537,11 +3610,11 @@ Object.defineProperty(exports, "markFindingsResolved", ({ enumerable: true, get: Object.defineProperty(exports, "__esModule", ({ value: true })); exports.markFindingsResolved = markFindingsResolved; -const pull_request_review_errors_1 = __nccwpck_require__(6445); const logging_ports_1 = __nccwpck_require__(6152); const resolve_issue_finding_1 = __nccwpck_require__(5300); const resolve_pull_request_finding_1 = __nccwpck_require__(4567); const review_state_1 = __nccwpck_require__(9200); +const bugbot_mutation_error_1 = __nccwpck_require__(2937); const application_error_1 = __nccwpck_require__(5999); async function markFindingsResolved(param) { const errors = []; @@ -3569,8 +3642,8 @@ async function repairExistingPullRequestFinding(ports, operation, findingId, des try { await ports.pullRequestComments.unresolvePullRequestReviewThread(destination.pullRequestNumber, destination.commentIdentity); } - catch { - addResolutionError(errors, 'pull request'); + catch (cause) { + addResolutionError(errors, 'pull request', findingId, cause); } } } @@ -3584,7 +3657,7 @@ async function resolveIssueIfNeeded(param, findingId, destination, errors) { return; const comment = param.context.issueComments.find(item => item.id === destination.commentId); if (comment?.body == null) { - addResolutionError(errors, 'issue'); + addResolutionError(errors, 'issue', findingId); return; } try { @@ -3595,8 +3668,8 @@ async function resolveIssueIfNeeded(param, findingId, destination, errors) { resolution: param.resolvedFindingResolutions?.get(findingId), }, param.catalog); } - catch { - addResolutionError(errors, 'issue'); + catch (cause) { + addResolutionError(errors, 'issue', findingId, cause); } } async function tryResolvePullRequestFinding(ports, findingId, destination, errors, resolution, catalog) { @@ -3608,17 +3681,14 @@ async function tryResolvePullRequestFinding(ports, findingId, destination, error resolution, }, catalog); } - catch { - addResolutionError(errors, 'pull request'); + catch (cause) { + addResolutionError(errors, 'pull request', findingId, cause); } } -function addResolutionError(errors, destination) { - const cause = destination === 'pull request' - ? new pull_request_review_errors_1.PullRequestReviewOperationError('mark-resolved') - : new Error('Unable to mark an issue finding as resolved.'); - const semanticError = new application_error_1.ApplicationError('provider.unavailable', destination === 'pull request' - ? 'Unable to mark a pull request finding as resolved.' - : 'Unable to mark an issue finding as resolved.', { cause }); +function addResolutionError(errors, destination, findingId, cause) { + const semanticError = destination === 'pull request' + ? (0, bugbot_mutation_error_1.bugbotMutationError)(cause, 'resolution', [findingId], 'mark-resolved') + : new application_error_1.ApplicationError('provider.unavailable', 'Unable to mark an issue finding as resolved.'); (0, logging_ports_1.logError)(semanticError); errors.push(semanticError); } @@ -3867,6 +3937,7 @@ function isRecord(value) { */ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.publishFindings = publishFindings; +const bugbot_mutation_error_1 = __nccwpck_require__(2937); const finding_1 = __nccwpck_require__(1011); const publish_issue_finding_comment_1 = __nccwpck_require__(4950); const publish_pr_review_comments_1 = __nccwpck_require__(352); @@ -3885,12 +3956,17 @@ async function publishFindings(param) { catalog, }) : undefined; - for (const finding of findings) { + for (const finding of (0, finding_1.retainExistingFindingIds)(findings, existingByFindingId)) { if (operation.target.issueNumber > 0 && !reviewPublisher) { await (0, publish_issue_finding_comment_1.publishIssueFindingComment)(ports.issueComments, operation.target.issueNumber, finding, (0, finding_1.findExistingFindingInfo)(existingByFindingId, finding), commitSha, catalog); } if (reviewPublisher) { - await reviewPublisher.publish(finding, (0, finding_1.findExistingFindingInfo)(existingByFindingId, finding)); + try { + await reviewPublisher.publish(finding, (0, finding_1.findExistingFindingInfo)(existingByFindingId, finding)); + } + catch (cause) { + throw (0, bugbot_mutation_error_1.bugbotMutationError)(cause, 'publication', [finding.id], 'publish-comments'); + } } } await reviewPublisher?.flush(overflowCount, overflowTitles); @@ -3959,6 +4035,7 @@ ${catalog.message('bugbot.overflow.body', { count: `**${overflowCount}**` }, ove Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestReviewCommentPublisher = void 0; +const bugbot_mutation_error_1 = __nccwpck_require__(2937); const bugbot_finding_marker_policy_1 = __nccwpck_require__(8024); const path_validation_1 = __nccwpck_require__(124); const logging_ports_1 = __nccwpck_require__(6152); @@ -4030,11 +4107,16 @@ class PullRequestReviewCommentPublisher { if (this.findingsToCreate.length === 0 && overflowCount === 0) return; const { repository, operation, openPrNumber, prContext } = this.options; - await repository.createReviewWithComments(openPrNumber, prContext.prHeadSha, buildReviewSummary(this.findingsToCreate, this.commentsToCreate.length, this.unanchoredBodies, overflowCount, overflowTitles, operation.analysis.reviewConfiguration.traceRules - ? this.options.ruleSources ?? [] - : [], operation.analysis.reviewConfiguration.traceRules - ? this.options.omittedRuleCount ?? 0 - : 0, prContext.prHeadSha, this.catalog), this.commentsToCreate); + try { + await repository.createReviewWithComments(openPrNumber, prContext.prHeadSha, buildReviewSummary(this.findingsToCreate, this.commentsToCreate.length, this.unanchoredBodies, overflowCount, overflowTitles, operation.analysis.reviewConfiguration.traceRules + ? this.options.ruleSources ?? [] + : [], operation.analysis.reviewConfiguration.traceRules + ? this.options.omittedRuleCount ?? 0 + : 0, prContext.prHeadSha, this.catalog), this.commentsToCreate); + } + catch (cause) { + throw (0, bugbot_mutation_error_1.bugbotMutationError)(cause, 'publication', this.findingsToCreate.map(finding => finding.id), 'publish-comments', this.findingsToCreate.length + overflowCount); + } } get catalog() { return this.options.catalog ?? (0, bugbot_message_catalog_1.resolveStaticBugbotCatalog)(this.options.operation.locale.pullRequest); @@ -4188,6 +4270,8 @@ async function queryBugbotPartitionFindings(repository, configuration, prompt, t Object.defineProperty(exports, "__esModule", ({ value: true })); exports.reconcileBugbotReviewState = reconcileBugbotReviewState; +const bugbot_mutation_error_1 = __nccwpck_require__(2937); +const finding_1 = __nccwpck_require__(1011); const review_projection_1 = __nccwpck_require__(859); const bugbot_reconciliation_policy_1 = __nccwpck_require__(8128); const bugbot_provider_projection_policy_1 = __nccwpck_require__(5821); @@ -4218,11 +4302,12 @@ async function reconcileBugbotReviewState(input) { }; } const snapshot = snapshotResult.snapshot; + const activeFindings = (0, finding_1.retainExistingFindingIds)(input.activeFindings, input.loadedContext.existingByFindingId); + const expectedPublishedFindings = (0, finding_1.retainExistingFindingIds)(input.expectedPublishedFindings ?? input.activeFindings, input.loadedContext.existingByFindingId); const diagnostics = [ - ...(input.mutationErrors ?? []).map((error) => ({ - code: 'operation-failed', - operatorMessage: toSafeOperationMessage(error), - })), + ...(input.mutationErrors ?? []).map((error) => error instanceof bugbot_mutation_error_1.BugbotMutationError + ? { code: 'finding-mutation-failed', mutation: error.diagnostic } + : { code: 'operation-failed', operatorMessage: toSafeOperationMessage(error) }), ...(!input.target.trustedAuthorLogin?.trim() ? [{ code: 'identity-unavailable' }] : []), @@ -4231,7 +4316,7 @@ async function reconcileBugbotReviewState(input) { const providerProjection = (0, bugbot_provider_projection_policy_1.projectBugbotProviderEvidence)({ snapshot, trustedAuthorLogin: input.target.trustedAuthorLogin, - activeFindings: input.activeFindings, + activeFindings, existingByFindingId: input.loadedContext.existingByFindingId, }); const plan = (0, bugbot_reconciliation_policy_1.buildBugbotReconciliationPlan)({ @@ -4241,8 +4326,8 @@ async function reconcileBugbotReviewState(input) { id, (0, bugbot_finding_marker_policy_1.extractTitleFromBody)(fullBody) || id, ])), - activeFindings: input.activeFindings, - expectedPublishedFindings: input.expectedPublishedFindings ?? input.activeFindings, + activeFindings, + expectedPublishedFindings, diagnostics, coverage: input.loadedContext.coverage, }); @@ -4697,14 +4782,16 @@ function toPresentationFailure(diagnostic) { const message = (0, bugbot_message_catalog_1.bugbotDiagnosticOperatorMessage)(diagnostic); return { diagnostic, - error: diagnostic.code === 'review-updates-pending' - ? new application_error_1.ApplicationError('workflow.presentation-pending', message, { - recovery: { - id: 'bugbot-review-blocks-pending', - variables: { pendingCount: diagnostic.count }, - }, - }) - : new Error(message), + error: diagnostic.code === 'finding-mutation-failed' + ? new application_error_1.ApplicationError(diagnostic.mutation.errorCode, message) + : diagnostic.code === 'review-updates-pending' + ? new application_error_1.ApplicationError('workflow.presentation-pending', message, { + recovery: { + id: 'bugbot-review-blocks-pending', + variables: { pendingCount: diagnostic.count }, + }, + }) + : new Error(message), }; } function report(projection, reviewUpdates, pendingReviewUpdates, statusCardOperation, errors) { @@ -5168,9 +5255,16 @@ exports.APPLICATION_ERROR_RECOVERY_IDS = Object.freeze([ 'branch-sync-resolution-invalid', 'sdd-draft-size-exceeded', 'sdd-draft-format-invalid', + 'sdd-draft-case-identity-invalid', + 'sdd-draft-case-budget-invalid', + 'sdd-draft-requirement-mapping-invalid', + 'sdd-draft-repository-path-invalid', 'workspace-changes-rejected', 'closed-issue-reconciliation-failed', 'approval-evidence-read-failed', + 'stored-configuration-schema-missing', + 'stored-configuration-schema-unsupported', + 'stored-configuration-invalid', ]); const PRESERVED_STATE = 'Existing persisted state and completed external effects were preserved.'; const UNCHANGED_STATE = 'No new state or external effect was created.'; @@ -5362,6 +5456,9 @@ class ApplicationError extends Error { exports.ApplicationError = ApplicationError; _ApplicationError_cause = new WeakMap(); const RECOVERY_VARIABLE_KEYS = Object.freeze({ + 'stored-configuration-schema-missing': Object.freeze(['issueNumber', 'expectedVersion']), + 'stored-configuration-schema-unsupported': Object.freeze(['issueNumber', 'expectedVersion', 'actualVersion']), + 'stored-configuration-invalid': Object.freeze(['issueNumber', 'expectedVersion']), 'closed-issue-reconciliation-failed': Object.freeze(['resultId', 'phase', 'state', 'reason', 'changed', 'remaining']), 'approval-evidence-read-failed': Object.freeze(['operation', 'reason', 'permission']), 'pull-request-link-restored': Object.freeze([]), @@ -5376,6 +5473,10 @@ const RECOVERY_VARIABLE_KEYS = Object.freeze({ 'branch-sync-resolution-invalid': Object.freeze(['validationCode', 'command']), 'sdd-draft-size-exceeded': Object.freeze([]), 'sdd-draft-format-invalid': Object.freeze([]), + 'sdd-draft-case-identity-invalid': Object.freeze([]), + 'sdd-draft-case-budget-invalid': Object.freeze([]), + 'sdd-draft-requirement-mapping-invalid': Object.freeze([]), + 'sdd-draft-repository-path-invalid': Object.freeze([]), 'workspace-changes-rejected': Object.freeze([]), }); function normalizeApplicationErrorRecovery(recovery) { @@ -5391,6 +5492,13 @@ function normalizeApplicationErrorRecovery(recovery) { || actualKeys.some((key, index) => key !== expectedKeys[index])) { throw new TypeError(`Application error recovery variables are invalid for ${recovery.id}.`); } + if (recovery.id.startsWith('stored-configuration-') + && (![variables.issueNumber, variables.expectedVersion].every(value => typeof value === 'number' && Number.isSafeInteger(value) && value > 0) + || (recovery.id === 'stored-configuration-schema-unsupported' + && !(typeof variables.actualVersion === 'number' + && Number.isSafeInteger(variables.actualVersion) && variables.actualVersion >= 0)))) { + throw new TypeError('Stored configuration diagnostic is invalid.'); + } if (recovery.id === 'managed-branch-enrichment-failed' && (typeof variables.branchName !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9._/-]{0,254}$/u.test(variables.branchName))) { @@ -5642,9 +5750,14 @@ function matchesConstrainedHead(target, candidate) { /***/ }), /***/ 1011: -/***/ ((__unused_webpack_module, exports) => { +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isExistingFindingFullyResolved = isExistingFindingFullyResolved; +exports.findExistingFindingInfo = findExistingFindingInfo; +exports.findExistingFindingMatch = findExistingFindingMatch; +exports.retainExistingFindingIds = retainExistingFindingIds; /** * Provider-neutral Bugbot finding and durable identity contracts. * @@ -5652,9 +5765,7 @@ function matchesConstrainedHead(target, candidate) { * them in the domain prevents policies from depending on a particular use-case * folder and gives every adapter one stable semantic vocabulary. */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.isExistingFindingFullyResolved = isExistingFindingFullyResolved; -exports.findExistingFindingInfo = findExistingFindingInfo; +const finding_identity_1 = __nccwpck_require__(1853); function isExistingFindingFullyResolved(finding) { const destinations = [finding.issue, finding.pullRequest].filter((destination) => destination != null); return (destinations.length > 0 && @@ -5662,21 +5773,62 @@ function isExistingFindingFullyResolved(finding) { finding.pullRequest?.verificationRequired !== true); } function findExistingFindingInfo(existingByFindingId, finding) { + return findExistingFindingMatch(existingByFindingId, finding)?.info; +} +/** A match carries its durable key so updating a comment cannot re-key it. */ +function findExistingFindingMatch(existingByFindingId, finding) { const direct = existingByFindingId[finding.id]; if (direct && identitiesAreCompatible(direct, finding)) - return direct; - const candidates = Object.values(existingByFindingId); + return { id: finding.id, info: direct }; + const candidates = Object.entries(existingByFindingId); if (finding.fingerprint) { - const locationMatch = candidates.find((candidate) => candidate.issue?.fingerprint === finding.fingerprint + const locationMatches = candidates.filter(([, candidate]) => candidate.issue?.fingerprint === finding.fingerprint || candidate.pullRequest?.fingerprint === finding.fingerprint); - if (locationMatch) - return locationMatch; + if (locationMatches.length > 0) + return uniqueFindingMatch(locationMatches); } if (!finding.semanticFingerprint) return undefined; - const semanticMatches = candidates.filter((candidate) => candidate.issue?.semanticFingerprint === finding.semanticFingerprint + const semanticMatches = candidates.filter(([, candidate]) => candidate.issue?.semanticFingerprint === finding.semanticFingerprint || candidate.pullRequest?.semanticFingerprint === finding.semanticFingerprint); - return semanticMatches.length === 1 ? semanticMatches[0] : undefined; + return uniqueFindingMatch(semanticMatches); +} +/** + * Preserve trusted IDs across title/location changes, before limits, publication + * and final projection. Multiple reports of one uniquely matched durable finding + * share one record; unmatched or ambiguous reports remain independent evidence. + */ +function retainExistingFindingIds(findings, existingByFindingId) { + const retained = new Set(); + const durableIds = new Set(Object.keys(existingByFindingId)); + // Reserve the whole input up front so a generated ID cannot take another + // report's ID, including one that occurs later in the response. + const reservedIds = new Set([...durableIds, ...findings.map((finding) => finding.id)]); + const emittedIds = new Set(); + return findings.flatMap((finding) => { + const match = findExistingFindingMatch(existingByFindingId, finding); + if (!match) { + let id = finding.id; + if (durableIds.has(id) || emittedIds.has(id)) { + const base = `candidate-${(0, finding_identity_1.buildFindingFingerprint)(finding)}`; + id = base; + let suffix = 0; + while (reservedIds.has(id)) + id = `${base}-${++suffix}`; + reservedIds.add(id); + } + emittedIds.add(id); + return [id === finding.id ? finding : { ...finding, id }]; + } + if (retained.has(match.id)) + return []; + retained.add(match.id); + emittedIds.add(match.id); + return [finding.id === match.id ? finding : { ...finding, id: match.id }]; + }); +} +function uniqueFindingMatch(matches) { + return matches.length === 1 ? { id: matches[0][0], info: matches[0][1] } : undefined; } function identitiesAreCompatible(existing, finding) { const existingFingerprints = [ @@ -6539,11 +6691,13 @@ function getAnswerIssueHelpPrompt(params) { Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.BUGBOT_FINDING_GROUNDING_INSTRUCTION = void 0; exports.getBugbotPrompt = getBugbotPrompt; /** * Prompt for Bugbot detection (detect potential problems on push). */ const fill_1 = __nccwpck_require__(2559); +exports.BUGBOT_FINDING_GROUNDING_INSTRUCTION = 'Before returning a finding, try to disprove it against the exact reviewed source. Read effective repository configuration and inherited library/protocol defaults before inferring behavior from a missing command flag. Trace short-circuit guards, validation helpers and the actual caller/render path before claiming that an unsafe branch is reachable or that separate call sites coexist. Recompute arithmetic and check cited line numbers against the current file/diff. If your evidence refutes the alleged defect, withdraw the finding entirely; do not publish a contradictory or self-refuting report. These checks apply equally to low/info severity. Report a confirmed failure when those protections are absent; do not assume they exist.'; const TEMPLATE = `You are analyzing the latest code changes for potential bugs and issues. Write every human-readable finding title, description, evidence, and suggestion in {{targetLocale}}. Preserve identifiers, code, symbols, paths, refs, commands, and URLs verbatim. Echo \`outputLocale\` exactly as \`{{targetLocale}}\`. @@ -6579,6 +6733,8 @@ For every finding: - include the nearest stable \`symbol\` and a minimal exact \`codeSnippet\` when available so the finding can survive rebases, line movement, and file renames. - when a fix is a safe replacement of exactly the reported line range, include only the replacement text in \`suggestedCode\`; otherwise omit it. +${exports.BUGBOT_FINDING_GROUNDING_INSTRUCTION} + Return every finding field required by the response schema. Use null for file, line, endLine, severity, confidence, category, evidence, suggestion, symbol, codeSnippet, or suggestedCode when that value does not safely apply. Only include files outside the ignore list. {{previousBlock}} diff --git a/build/api/src/data/model/application_error.d.ts b/build/api/src/data/model/application_error.d.ts index bd017218f..1fabf91cc 100644 --- a/build/api/src/data/model/application_error.d.ts +++ b/build/api/src/data/model/application_error.d.ts @@ -3,9 +3,22 @@ import { type ApprovalEvidenceDiagnostic } from '../../domain/approval_evidence_ import { type BranchSyncValidationCode } from '../../domain/branch_sync_validation'; export type ApplicationErrorKind = 'configuration' | 'authorization' | 'provider' | 'agent' | 'validation' | 'workflow' | 'unknown'; export type ApplicationErrorCode = 'configuration.invalid' | 'configuration.unsupported' | 'authorization.denied' | 'authorization.credential-invalid' | 'provider.not-found' | 'provider.conflict' | 'provider.rate-limited' | 'provider.unavailable' | 'provider.contract-invalid' | 'agent.policy-rejected' | 'agent.failed' | 'locale.output-invalid' | 'locale.translation-failed' | 'validation.invalid-input' | 'validation.evidence-too-large' | 'validation.evidence-unavailable' | 'workflow.invalid-event' | 'workflow.stale' | 'workflow.cancelled' | 'workflow.failed' | 'workflow.presentation-pending' | 'timeout' | 'unexpected'; -export declare const APPLICATION_ERROR_RECOVERY_IDS: readonly ["pull-request-link-restored", "pull-request-link-base-retained", "pull-request-link-reference-retained", "pull-request-link-base-and-reference-retained", "managed-branch-enrichment-failed", "inactivity-explanation-failed", "bugbot-review-blocks-pending", "branch-sync-agent-disabled", "branch-sync-fixer-unavailable", "branch-sync-resolution-invalid", "sdd-draft-size-exceeded", "sdd-draft-format-invalid", "workspace-changes-rejected", "closed-issue-reconciliation-failed", "approval-evidence-read-failed"]; +export declare const APPLICATION_ERROR_RECOVERY_IDS: readonly ["pull-request-link-restored", "pull-request-link-base-retained", "pull-request-link-reference-retained", "pull-request-link-base-and-reference-retained", "managed-branch-enrichment-failed", "inactivity-explanation-failed", "bugbot-review-blocks-pending", "branch-sync-agent-disabled", "branch-sync-fixer-unavailable", "branch-sync-resolution-invalid", "sdd-draft-size-exceeded", "sdd-draft-format-invalid", "sdd-draft-case-identity-invalid", "sdd-draft-case-budget-invalid", "sdd-draft-requirement-mapping-invalid", "sdd-draft-repository-path-invalid", "workspace-changes-rejected", "closed-issue-reconciliation-failed", "approval-evidence-read-failed", "stored-configuration-schema-missing", "stored-configuration-schema-unsupported", "stored-configuration-invalid"]; export type ApplicationErrorRecoveryId = typeof APPLICATION_ERROR_RECOVERY_IDS[number]; interface ApplicationErrorRecoveryVariables { + readonly 'stored-configuration-schema-missing': Readonly<{ + issueNumber: number; + expectedVersion: number; + }>; + readonly 'stored-configuration-schema-unsupported': Readonly<{ + issueNumber: number; + expectedVersion: number; + actualVersion: number; + }>; + readonly 'stored-configuration-invalid': Readonly<{ + issueNumber: number; + expectedVersion: number; + }>; readonly 'closed-issue-reconciliation-failed': ClosedIssueReconciliationFacts; readonly 'approval-evidence-read-failed': ApprovalEvidenceDiagnostic; readonly 'pull-request-link-restored': Readonly>; @@ -33,6 +46,10 @@ interface ApplicationErrorRecoveryVariables { }>; readonly 'sdd-draft-size-exceeded': Readonly>; readonly 'sdd-draft-format-invalid': Readonly>; + readonly 'sdd-draft-case-identity-invalid': Readonly>; + readonly 'sdd-draft-case-budget-invalid': Readonly>; + readonly 'sdd-draft-requirement-mapping-invalid': Readonly>; + readonly 'sdd-draft-repository-path-invalid': Readonly>; readonly 'workspace-changes-rejected': Readonly>; } export type ApplicationErrorRecovery = { diff --git a/build/api/src/domain/bugbot/context.d.ts b/build/api/src/domain/bugbot/context.d.ts index f4ee3769b..144b133c7 100644 --- a/build/api/src/domain/bugbot/context.d.ts +++ b/build/api/src/domain/bugbot/context.d.ts @@ -8,6 +8,8 @@ export interface BugbotSourceCoverage { readonly itemsRetained: number; readonly omittedItems: number; readonly truncatedItems: number; + /** Exact bounded provider identities of retained conversation items truncated by the prompt. */ + readonly truncatedItemIds?: readonly string[]; readonly limitReached: boolean; /** True when a provider page cap hides an unknown number of older records. */ readonly providerLimitReached?: boolean; diff --git a/build/api/src/domain/bugbot/finding.d.ts b/build/api/src/domain/bugbot/finding.d.ts index d14ac8b82..97380ce35 100644 --- a/build/api/src/domain/bugbot/finding.d.ts +++ b/build/api/src/domain/bugbot/finding.d.ts @@ -1,10 +1,3 @@ -/** - * Provider-neutral Bugbot finding and durable identity contracts. - * - * These types are shared by analysis, reconciliation, and publication. Keeping - * them in the domain prevents policies from depending on a particular use-case - * folder and gives every adapter one stable semantic vocabulary. - */ export interface BugbotFinding { id: string; title: string; @@ -59,3 +52,14 @@ export interface ExistingFindingInfo { export type ExistingByFindingId = Record; export declare function isExistingFindingFullyResolved(finding: ExistingFindingInfo): boolean; export declare function findExistingFindingInfo(existingByFindingId: ExistingByFindingId, finding: Pick): ExistingFindingInfo | undefined; +/** A match carries its durable key so updating a comment cannot re-key it. */ +export declare function findExistingFindingMatch(existingByFindingId: ExistingByFindingId, finding: Pick): { + id: string; + info: ExistingFindingInfo; +} | undefined; +/** + * Preserve trusted IDs across title/location changes, before limits, publication + * and final projection. Multiple reports of one uniquely matched durable finding + * share one record; unmatched or ambiguous reports remain independent evidence. + */ +export declare function retainExistingFindingIds(findings: readonly BugbotFinding[], existingByFindingId: ExistingByFindingId): BugbotFinding[]; diff --git a/build/cli/index.js b/build/cli/index.js index c85895d11..f3be1315e 100755 --- a/build/cli/index.js +++ b/build/cli/index.js @@ -37179,6 +37179,7 @@ function readLocalWorkflowConfiguration(additionalParams, actionInputs) { commitPrefixBuilder: read(input_keys_1.INPUT_KEYS.COMMIT_PREFIX_TRANSFORMS) || 'replace-slash', issueManagedBranches: (0, input_boolean_policy_1.parseIssueWorkflowBoolean)(read(input_keys_1.INPUT_KEYS.ISSUE_MANAGED_BRANCHES), input_keys_1.INPUT_KEYS.ISSUE_MANAGED_BRANCHES, true), preBranchSdd: (0, input_boolean_policy_1.parseIssueWorkflowBoolean)(read(input_keys_1.INPUT_KEYS.PRE_BRANCH_SDD), input_keys_1.INPUT_KEYS.PRE_BRANCH_SDD, false), + verificationSetup: (0, input_boolean_policy_1.parseIssueWorkflowBoolean)(read(input_keys_1.INPUT_KEYS.VERIFICATION_SETUP), input_keys_1.INPUT_KEYS.VERIFICATION_SETUP, false), reopenIssueOnPush: (0, input_boolean_policy_1.isEnabledInput)(read(input_keys_1.INPUT_KEYS.REOPEN_ISSUE_ON_PUSH)), issueDesiredAssigneesCount: (0, input_number_policy_1.parseIntegerInput)(read(input_keys_1.INPUT_KEYS.DESIRED_ASSIGNEES_COUNT), 0), pullRequestDesiredAssigneesCount: (0, input_number_policy_1.parseIntegerInput)(read(input_keys_1.INPUT_KEYS.PULL_REQUEST_DESIRED_ASSIGNEES_COUNT), 0), @@ -37212,7 +37213,7 @@ const configuration_builders_1 = __nccwpck_require__(19094); const branches_builder_1 = __nccwpck_require__(30085); const size_threshold_builder_1 = __nccwpck_require__(39757); function buildLocalActionExecution(configuration, additionalParams) { - const { debug, singleAction, singleActionIssue, singleActionVersion, singleActionTitle, singleActionChangelog, singleActionMessage, singleActionCommentId, singleActionCommentMode, singleActionOperationId, inactivityThresholdHours, commitPrefixBuilder, issueManagedBranches, preBranchSdd, reopenIssueOnPush, issueDesiredAssigneesCount, pullRequestDesiredAssigneesCount, pullRequestDesiredReviewersCount, titleEmoji, branchManagementEmoji, token, agentModel, aiPullRequestDescriptionMode, aiMembersOnly, aiIgnoreFiles, aiIncludeReasoning, bugbotSeverity, bugbotCommentLimit, bugbotFixVerifyCommands, bugbotReviewConfiguration, agentTasks, bugLabel, bugfixLabel, hotfixLabel, enhancementLabel, featureLabel, releaseLabel, questionLabel, helpLabel, deployLabel, deployedLabel, docsLabel, documentationLabel, choreLabel, maintenanceLabel, priorityHighLabel, priorityMediumLabel, priorityLowLabel, priorityNoneLabel, sizeXxlLabel, sizeXlLabel, sizeLLabel, sizeMLabel, sizeSLabel, sizeXsLabel, lifecycle, issueTypeTask, issueTypeTaskDescription, issueTypeTaskColor, issueTypeBug, issueTypeBugDescription, issueTypeBugColor, issueTypeFeature, issueTypeFeatureDescription, issueTypeFeatureColor, issueTypeDocumentation, issueTypeDocumentationDescription, issueTypeDocumentationColor, issueTypeMaintenance, issueTypeMaintenanceDescription, issueTypeMaintenanceColor, issueTypeHotfix, issueTypeHotfixDescription, issueTypeHotfixColor, issueTypeRelease, issueTypeReleaseDescription, issueTypeReleaseColor, issueTypeQuestion, issueTypeQuestionDescription, issueTypeQuestionColor, issueTypeHelp, issueTypeHelpDescription, issueTypeHelpColor, repositoryLocale, issueLocale, pullRequestLocale, sizeXxlThresholdLines, sizeXxlThresholdFiles, sizeXxlThresholdCommits, sizeXlThresholdLines, sizeXlThresholdFiles, sizeXlThresholdCommits, sizeLThresholdLines, sizeLThresholdFiles, sizeLThresholdCommits, sizeMThresholdLines, sizeMThresholdFiles, sizeMThresholdCommits, sizeSThresholdLines, sizeSThresholdFiles, sizeSThresholdCommits, sizeXsThresholdLines, sizeXsThresholdFiles, sizeXsThresholdCommits, mainBranch, developmentBranch, featureTree, bugfixTree, hotfixTree, releaseTree, docsTree, choreTree, releaseWorkflow, hotfixWorkflow, projects, projectColumnIssueCreated, projectColumnPullRequestCreated, projectColumnIssueInProgress, projectColumnPullRequestInProgress, welcomeTitle, welcomeMessages, deployment, } = configuration; + const { debug, singleAction, singleActionIssue, singleActionVersion, singleActionTitle, singleActionChangelog, singleActionMessage, singleActionCommentId, singleActionCommentMode, singleActionOperationId, inactivityThresholdHours, commitPrefixBuilder, issueManagedBranches, preBranchSdd, verificationSetup, reopenIssueOnPush, issueDesiredAssigneesCount, pullRequestDesiredAssigneesCount, pullRequestDesiredReviewersCount, titleEmoji, branchManagementEmoji, token, agentModel, aiPullRequestDescriptionMode, aiMembersOnly, aiIgnoreFiles, aiIncludeReasoning, bugbotSeverity, bugbotCommentLimit, bugbotFixVerifyCommands, bugbotReviewConfiguration, agentTasks, bugLabel, bugfixLabel, hotfixLabel, enhancementLabel, featureLabel, releaseLabel, questionLabel, helpLabel, deployLabel, deployedLabel, docsLabel, documentationLabel, choreLabel, maintenanceLabel, priorityHighLabel, priorityMediumLabel, priorityLowLabel, priorityNoneLabel, sizeXxlLabel, sizeXlLabel, sizeLLabel, sizeMLabel, sizeSLabel, sizeXsLabel, lifecycle, issueTypeTask, issueTypeTaskDescription, issueTypeTaskColor, issueTypeBug, issueTypeBugDescription, issueTypeBugColor, issueTypeFeature, issueTypeFeatureDescription, issueTypeFeatureColor, issueTypeDocumentation, issueTypeDocumentationDescription, issueTypeDocumentationColor, issueTypeMaintenance, issueTypeMaintenanceDescription, issueTypeMaintenanceColor, issueTypeHotfix, issueTypeHotfixDescription, issueTypeHotfixColor, issueTypeRelease, issueTypeReleaseDescription, issueTypeReleaseColor, issueTypeQuestion, issueTypeQuestionDescription, issueTypeQuestionColor, issueTypeHelp, issueTypeHelpDescription, issueTypeHelpColor, repositoryLocale, issueLocale, pullRequestLocale, sizeXxlThresholdLines, sizeXxlThresholdFiles, sizeXxlThresholdCommits, sizeXlThresholdLines, sizeXlThresholdFiles, sizeXlThresholdCommits, sizeLThresholdLines, sizeLThresholdFiles, sizeLThresholdCommits, sizeMThresholdLines, sizeMThresholdFiles, sizeMThresholdCommits, sizeSThresholdLines, sizeSThresholdFiles, sizeSThresholdCommits, sizeXsThresholdLines, sizeXsThresholdFiles, sizeXsThresholdCommits, mainBranch, developmentBranch, featureTree, bugfixTree, hotfixTree, releaseTree, docsTree, choreTree, releaseWorkflow, hotfixWorkflow, projects, projectColumnIssueCreated, projectColumnPullRequestCreated, projectColumnIssueInProgress, projectColumnPullRequestInProgress, welcomeTitle, welcomeMessages, deployment, } = configuration; return (0, execution_builder_1.buildExecution)({ debug, inactivityThresholdHours, @@ -37220,6 +37221,7 @@ function buildLocalActionExecution(configuration, additionalParams) { commitPrefixBuilder, issue: (0, configuration_builders_1.buildIssue)(issueManagedBranches, reopenIssueOnPush, issueDesiredAssigneesCount, additionalParams), preBranchSdd, + verificationSetup, pullRequest: (0, configuration_builders_1.buildPullRequest)(pullRequestDesiredAssigneesCount, pullRequestDesiredReviewersCount, additionalParams), emoji: (0, configuration_builders_1.buildEmoji)(titleEmoji, branchManagementEmoji), tokens: (0, configuration_builders_1.buildTokens)(token), @@ -37982,6 +37984,7 @@ exports.INPUT_KEYS = { // Issue ISSUE_MANAGED_BRANCHES: 'issue-managed-branches', PRE_BRANCH_SDD: 'pre-branch-sdd', + VERIFICATION_SETUP: 'verification-setup', REOPEN_ISSUE_ON_PUSH: 'reopen-issue-on-push', DESIRED_ASSIGNEES_COUNT: 'desired-assignees-count', // Pull Request @@ -38016,6 +38019,7 @@ exports.SETUP_DOCUMENTATION = { tutorial: 'https://docs.page/vypdev/copilot/setup-web', firstWorkflow: 'https://docs.page/vypdev/copilot/first-workflow', recovery: 'https://docs.page/vypdev/copilot/security-operations/operations/troubleshooting', + verification: 'https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-owned-setup', }; @@ -38119,6 +38123,46 @@ function approvalDiagnosticError(diagnostic) { } +/***/ }), + +/***/ 82937: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.BugbotMutationError = void 0; +exports.bugbotMutationError = bugbotMutationError; +const application_error_1 = __nccwpck_require__(75999); +const pull_request_review_errors_1 = __nccwpck_require__(46445); +class BugbotMutationError extends application_error_1.ApplicationError { + constructor(diagnostic) { + super(diagnostic.errorCode, `Bugbot ${diagnostic.stage} failed: operation=${diagnostic.operation}; finding=${diagnostic.findingId}; affected=${diagnostic.affectedCount}; ${diagnostic.providerStatus}; provider-reference=${diagnostic.providerReference}. Completed effects are retained; correct the named cause and recheck the same target.`); + this.diagnostic = diagnostic; + } +} +exports.BugbotMutationError = BugbotMutationError; +function bugbotMutationError(cause, stage, findingIds, fallback, affectedCount = findingIds.length) { + if (cause instanceof BugbotMutationError) + return cause; + const provider = cause instanceof pull_request_review_errors_1.PullRequestReviewOperationError ? cause : undefined; + const status = provider?.providerStatus; + const errorCode = status === 401 ? 'authorization.credential-invalid' : status === 403 ? 'authorization.denied' + : status === 404 ? 'provider.not-found' : status === 409 ? 'provider.conflict' + : status === 429 ? 'provider.rate-limited' + : status === 408 || status === 425 ? 'provider.unavailable' + : status && status < 500 ? 'provider.contract-invalid' : 'provider.unavailable'; + const first = findingIds[0]; + return new BugbotMutationError(Object.freeze({ + stage, operation: provider?.operation ?? fallback, + findingId: typeof first === 'string' && /^[A-Za-z0-9_./:-]{1,200}$/.test(first) ? first : 'unavailable', + affectedCount: Math.min(affectedCount, 10000), + providerStatus: status ? `http-${status}` : 'http-unavailable', + providerReference: provider?.providerReference ?? 'unavailable', errorCode, + })); +} + + /***/ }), /***/ 12183: @@ -39313,7 +39357,26 @@ const SPANISH_CONTENT = Object.freeze({ retainedState: PRESERVED_STATE_ES, }), }); +const STORED_CONFIGURATION_ACTION_EN = 'A maintainer must review {recoveryGuide}. Preserve a copy before removing only a verified obsolete unmanaged block. If managed branch, release, hotfix or orchestration state may exist, stop and restore verified supported state with a maintainer. Do not just add a schema version or delete managed state. Correct the configuration before rerunning; retrying unchanged state will fail again.'; +const STORED_CONFIGURATION_ACTION_ES = 'Un mantenedor debe revisar {recoveryGuide}. Conserva una copia antes de retirar solo un bloque obsoleto confirmado como no gestionado. Si puede existir estado gestionado de ramas, releases, hotfixes u orquestación, detente y restaura estado compatible verificado con un mantenedor. No añadas simplemente una versión de esquema ni borres estado gestionado. Corrige la configuración antes de reejecutar; el mismo estado volverá a fallar.'; +const STORED_CONFIGURATION_RETAINED_EN = 'The issue/PR description and stored configuration were not changed by this read.'; +const STORED_CONFIGURATION_RETAINED_ES = 'Esta lectura no modificó la descripción de la issue/PR ni su configuración almacenada.'; const ENGLISH_RECOVERY_CONTENT = Object.freeze({ + 'stored-configuration-schema-missing': Object.freeze({ + impact: 'Automation stopped for issue/PR #{issueNumber}: the stored configuration has no schema version; version {expectedVersion} is required.', + action: STORED_CONFIGURATION_ACTION_EN, + retainedState: STORED_CONFIGURATION_RETAINED_EN, + }), + 'stored-configuration-schema-unsupported': Object.freeze({ + impact: 'Automation stopped for issue/PR #{issueNumber}: stored schema version {actualVersion} is unsupported; version {expectedVersion} is required.', + action: STORED_CONFIGURATION_ACTION_EN, + retainedState: STORED_CONFIGURATION_RETAINED_EN, + }), + 'stored-configuration-invalid': Object.freeze({ + impact: 'Automation stopped for issue/PR #{issueNumber}: the stored configuration, markers or schema value are malformed; valid schema version {expectedVersion} is required.', + action: STORED_CONFIGURATION_ACTION_EN, + retainedState: STORED_CONFIGURATION_RETAINED_EN, + }), 'closed-issue-reconciliation-failed': Object.freeze({ impact: 'Issue cleanup remains unverified: {resultId}, phase {phase}; native state {state}, reason {reason}.', action: 'Inspect the closed-issue or merged-PR run and current native state. Retry cleanup only if the issue is still closed with the intended reason; leave reopened work open. Resolve the named failure before retrying.', @@ -39329,6 +39392,26 @@ const ENGLISH_RECOVERY_CONTENT = Object.freeze({ action: 'Inspect the rejected paths in the workflow and correct the workspace before retrying.', retainedState: 'The normal commit and push steps were skipped. Verify the current state before retrying.', }), + 'sdd-draft-case-identity-invalid': Object.freeze({ + impact: 'SDD publication stopped after one automatic repair: case IDs collide with an owning SDD or are ambiguous.', + action: 'Review the draft tables; use distinct fully qualified case IDs and preserve the baseline inventory. Retry the same issue workflow.', + retainedState: 'Existing answers and published SDDs were preserved; no draft was published. Publication checks do not establish runtime acceptance.', + }), + 'sdd-draft-case-budget-invalid': Object.freeze({ + impact: 'SDD publication stopped after one automatic repair: per-area allocations disagree with the distinct case inventory.', + action: 'Review the draft tables; reconcile each area and the total with the enumerated cases. Retry the same issue workflow.', + retainedState: 'Existing answers and published SDDs were preserved; no draft was published. Publication checks do not establish runtime acceptance.', + }), + 'sdd-draft-requirement-mapping-invalid': Object.freeze({ + impact: 'SDD publication stopped after one automatic repair: requirements and case mappings are incomplete or inconsistent.', + action: 'Review the draft tables; map every requirement to defined cases and match the reverse links. Retry the same issue workflow.', + retainedState: 'Existing answers and published SDDs were preserved; no draft was published. Publication checks do not establish runtime acceptance.', + }), + 'sdd-draft-repository-path-invalid': Object.freeze({ + impact: 'SDD publication stopped after one automatic repair: cited repository paths cannot be verified at the immutable base.', + action: 'Review the draft tables; correct existing paths or explicitly declare intended new files. Retry the same issue workflow.', + retainedState: 'Existing answers and published SDDs were preserved; no draft was published. Publication checks do not establish runtime acceptance.', + }), 'sdd-draft-format-invalid': Object.freeze({ impact: 'SDD preparation stopped because the draft still lacked required headings or a numeric test budget after one automatic repair.', action: 'Retry SDD preparation with the canonical specification template and the explicit acceptance requirements.', @@ -39391,6 +39474,21 @@ const ENGLISH_RECOVERY_CONTENT = Object.freeze({ }), }); const SPANISH_RECOVERY_CONTENT = Object.freeze({ + 'stored-configuration-schema-missing': Object.freeze({ + impact: 'La automatización se detuvo para la issue/PR #{issueNumber}: la configuración almacenada no tiene versión de esquema; se requiere la versión {expectedVersion}.', + action: STORED_CONFIGURATION_ACTION_ES, + retainedState: STORED_CONFIGURATION_RETAINED_ES, + }), + 'stored-configuration-schema-unsupported': Object.freeze({ + impact: 'La automatización se detuvo para la issue/PR #{issueNumber}: la versión de esquema almacenada {actualVersion} no es compatible; se requiere la versión {expectedVersion}.', + action: STORED_CONFIGURATION_ACTION_ES, + retainedState: STORED_CONFIGURATION_RETAINED_ES, + }), + 'stored-configuration-invalid': Object.freeze({ + impact: 'La automatización se detuvo para la issue/PR #{issueNumber}: la configuración almacenada, sus delimitadores o el valor del esquema no son válidos; se requiere un esquema válido de versión {expectedVersion}.', + action: STORED_CONFIGURATION_ACTION_ES, + retainedState: STORED_CONFIGURATION_RETAINED_ES, + }), 'closed-issue-reconciliation-failed': Object.freeze({ impact: 'La limpieza de la issue sigue sin verificarse: {resultId}, fase {phase}; estado nativo {state}, motivo {reason}.', action: 'Revisa la ejecución de cierre o de la PR fusionada y el estado nativo actual. Reintenta la limpieza solo si la issue sigue cerrada con el motivo previsto; conserva abierto el trabajo reabierto. Resuelve el fallo indicado antes de reintentar.', @@ -39406,6 +39504,26 @@ const SPANISH_RECOVERY_CONTENT = Object.freeze({ action: 'Revisa las rutas rechazadas en la ejecución y corrige el espacio de trabajo antes de reintentar.', retainedState: 'Se omitieron los pasos normales de commit y push. Comprueba el estado actual antes de reintentar.', }), + 'sdd-draft-case-identity-invalid': Object.freeze({ + impact: 'La publicación del SDD se detuvo tras un intento automático de corrección: los identificadores de casos coinciden con un SDD existente o son ambiguos.', + action: 'Revisa las tablas del borrador; usa identificadores completos y distintos y conserva el inventario original. Reintenta el workflow de la misma incidencia.', + retainedState: 'Se conservaron las respuestas y los SDD publicados; no se publicó ningún borrador. Estas comprobaciones no demuestran la aceptación en ejecución.', + }), + 'sdd-draft-case-budget-invalid': Object.freeze({ + impact: 'La publicación del SDD se detuvo tras un intento automático de corrección: las asignaciones por área no coinciden con el inventario de casos distintos.', + action: 'Revisa las tablas del borrador; reconcilia cada área y el total con los casos enumerados. Reintenta el workflow de la misma incidencia.', + retainedState: 'Se conservaron las respuestas y los SDD publicados; no se publicó ningún borrador. Estas comprobaciones no demuestran la aceptación en ejecución.', + }), + 'sdd-draft-requirement-mapping-invalid': Object.freeze({ + impact: 'La publicación del SDD se detuvo tras un intento automático de corrección: los requisitos y sus casos están incompletos o son inconsistentes.', + action: 'Revisa las tablas del borrador; vincula cada requisito a casos definidos y comprueba los enlaces inversos. Reintenta el workflow de la misma incidencia.', + retainedState: 'Se conservaron las respuestas y los SDD publicados; no se publicó ningún borrador. Estas comprobaciones no demuestran la aceptación en ejecución.', + }), + 'sdd-draft-repository-path-invalid': Object.freeze({ + impact: 'La publicación del SDD se detuvo tras un intento automático de corrección: no se pueden verificar las rutas citadas en la revisión base inmutable.', + action: 'Revisa las tablas del borrador; corrige las rutas existentes o declara explícitamente los archivos nuevos previstos. Reintenta el workflow de la misma incidencia.', + retainedState: 'Se conservaron las respuestas y los SDD publicados; no se publicó ningún borrador. Estas comprobaciones no demuestran la aceptación en ejecución.', + }), 'sdd-draft-format-invalid': Object.freeze({ impact: 'La preparación del SDD se detuvo porque seguían faltando secciones obligatorias o un presupuesto numérico de pruebas tras un intento automático de corrección.', action: 'Reintenta la preparación del SDD con la plantilla canónica y los criterios de aceptación explícitos.', @@ -39520,12 +39638,16 @@ exports.buildApplicationErrorPresentation = buildApplicationErrorPresentation; exports.renderApplicationErrorText = renderApplicationErrorText; exports.renderApplicationErrorMarkdown = renderApplicationErrorMarkdown; const application_error_message_catalog_1 = __nccwpck_require__(64809); +// This trusted destination is inserted after localization, never supplied by a body or translation. +const STORED_CONFIGURATION_RECOVERY_URL = 'https://docs.page/vypdev/copilot/security-operations/operations/troubleshooting#unsupported-stored-configuration'; /** Shared semantic view model for terminal, GitHub, and API presentation. */ function buildApplicationErrorPresentation(error, message = application_error_message_catalog_1.readEnglishApplicationErrorMessage) { const descriptor = error.recovery ? `error.recovery.${error.recovery.id}` : `error.${error.code}`; - const variables = error.recovery?.variables; + const variables = error.recovery?.id.startsWith('stored-configuration-') + ? { ...error.recovery.variables, recoveryGuide: STORED_CONFIGURATION_RECOVERY_URL } + : error.recovery?.variables; return { impact: message(`${descriptor}.impact`, variables), code: error.code, @@ -40641,6 +40763,7 @@ exports.BUGBOT_MESSAGE_IDS = Object.freeze([ 'bugbot.overflow.body', 'bugbot.common.more', 'bugbot.diagnostic.operationFailed', + 'bugbot.diagnostic.findingMutationFailed', 'bugbot.diagnostic.identityUnavailable', 'bugbot.diagnostic.pullRequestCommentsFailed', 'bugbot.diagnostic.reviewThreadsFailed', @@ -40726,6 +40849,7 @@ const ENGLISH_MESSAGES = Object.freeze({ 'bugbot.overflow.heading': 'More findings (comment limit)', 'bugbot.overflow.body': Object.freeze({ one: 'There is {count} more finding that was not published as an individual comment. Review locally or in the full diff to see the list.', other: 'There are {count} more findings that were not published as individual comments. Review locally or in the full diff to see the list.' }), 'bugbot.common.more': Object.freeze({ one: 'and {count} more.', other: 'and {count} more.' }), + 'bugbot.diagnostic.findingMutationFailed': 'Finding mutation failed: stage={stage}; operation={operation}; finding={findingId}; affected={affectedCount}; {providerStatus}; provider reference={providerReference}. Completed effects are retained. Correct access/contract errors before retrying; for transient failures restore provider availability, then recheck the same PR. Recheck reconciles existing reviews and threads.', 'bugbot.diagnostic.operationFailed': 'Bugbot could not complete one or more finding mutations.', 'bugbot.diagnostic.identityUnavailable': 'The authenticated Bugbot identity is unavailable.', 'bugbot.diagnostic.pullRequestCommentsFailed': 'Unable to re-read pull request review comments.', @@ -40815,6 +40939,7 @@ const SPANISH_MESSAGES = Object.freeze({ 'bugbot.overflow.heading': 'Más hallazgos (límite de comentarios)', 'bugbot.overflow.body': Object.freeze({ one: 'Hay {count} hallazgo más que no se publicó como comentario individual. Revísalo localmente o en el diff completo para consultar la lista.', many: 'Hay {count} hallazgos más que no se publicaron como comentarios individuales. Revísalos localmente o en el diff completo para consultar la lista.', other: 'Hay {count} hallazgos más que no se publicaron como comentarios individuales. Revísalos localmente o en el diff completo para consultar la lista.' }), 'bugbot.common.more': Object.freeze({ one: 'y {count} más.', many: 'y {count} más.', other: 'y {count} más.' }), + 'bugbot.diagnostic.findingMutationFailed': 'Falló una mutación: fase={stage}; operación={operation}; hallazgo={findingId}; afectados={affectedCount}; {providerStatus}; referencia del proveedor={providerReference}. Se conservan los efectos completados. Corrige acceso/contrato antes de reintentar; para fallos transitorios restaura el proveedor y revisa la misma PR. La revisión reconcilia comentarios e hilos existentes.', 'bugbot.diagnostic.operationFailed': 'Bugbot no pudo completar una o más mutaciones de hallazgos.', 'bugbot.diagnostic.identityUnavailable': 'La identidad autenticada de Bugbot no está disponible.', 'bugbot.diagnostic.pullRequestCommentsFailed': 'No se pudieron volver a leer los comentarios del review del pull request.', @@ -40854,6 +40979,7 @@ async function resolveBugbotCatalog(locale, configuration, resolver) { } function renderBugbotDiagnostic(diagnostic, catalog) { switch (diagnostic.code) { + case 'finding-mutation-failed': return catalog.message('bugbot.diagnostic.findingMutationFailed', { ...diagnostic.mutation }); case 'operation-failed': return catalog.message('bugbot.diagnostic.operationFailed'); case 'identity-unavailable': return catalog.message('bugbot.diagnostic.identityUnavailable'); case 'snapshot-pull-request-comments-failed': return catalog.message('bugbot.diagnostic.pullRequestCommentsFailed'); @@ -41481,6 +41607,10 @@ function renderBugbotStatusCard(projection, catalogOrLocale, links) { facts.push(catalog.message('bugbot.coverage.omitted', { count: source.omittedItems })); if (source.truncatedItems > 0) facts.push(catalog.message('bugbot.coverage.truncated', { count: source.truncatedItems })); + const truncatedIds = source.truncatedItemIds?.slice(0, 50) + .filter(id => /^(?:issue:[0-9]+|review:[A-Za-z0-9_=-]+)$/.test(id) && id.length <= 160); + if (truncatedIds?.length) + facts.push(`truncated-source-ids=${truncatedIds.join(', ')}`); if (source.providerLimitReached) facts.push(catalog.message('bugbot.coverage.providerLimit')); return `- ${source.source}: ${source.status}; ${facts.join(', ')}`; @@ -41570,9 +41700,21 @@ function normalizeHistoricalSnapshot(originalBody, analyzedHeadSha, catalog) { function renderFindingRow(finding) { const label = (0, github_comment_publication_policy_1.sanitizeAgentMarkdown)(finding.title || finding.id, 500).replace(/[\r\n]+/gu, ' '); const state = stateLabel(finding.state); + const identity = finding.state === 'unknown' + ? ` — ${renderFindingId(finding.id)}` + : ''; return finding.url - ? `- ${state} — [${label}](${finding.url})` - : `- ${state} — ${label}`; + ? `- ${state} — [${label}](${finding.url})${identity}` + : `- ${state} — ${label}${identity}`; +} +function renderFindingId(value) { + const id = (0, github_comment_publication_policy_1.sanitizeAgentMarkdown)(value, 200).replace(/[\r\n]+/gu, ' '); + // A delimiter longer than every embedded backtick run keeps links, images + // and HTML inert even when the marker permits arbitrary Markdown punctuation. + let delimiter = '`'; + while (id.includes(delimiter)) + delimiter += '`'; + return `${delimiter} ${id} ${delimiter}`; } function stateLabel(state) { return `[ ] ${state}`; @@ -46173,6 +46315,8 @@ The setup runner profile selects placement; it does not install the project's la Declare reviewed version prefixes in \`.copilot/verification-prerequisites.json\` (schemaVersion 1, runtimes such as java 17, node 24, pnpm 10). Copilot checks declared versions in the credential-free verification environment before each configured verification command; a missing or incompatible runtime blocks publication. Without this optional declaration, existing verification behavior remains and no language is inferred. Java provisioning may use \`actions/setup-java\`; \`JAVA_HOME\` and \`PATH\` survive isolation, while agent credentials and tool-option injection variables do not. Do not add an unreviewed bootstrap or weaken verification to work around a missing runtime. Read [verification prerequisites and same-job setup](https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-verification-prerequisites). +The optional repository-owned composite action prepares each candidate before verification. Setup creates .github/actions/copilot-verification-setup/action.yml only if missing and preserves an existing consumer action and its assets. The shared terminal/web assistant offers explicit activation, disabled by default. Customize the generated failing placeholder before enabling; setup generation and installer PRs do not prove runtime readiness. Review \`.github/actions/copilot-verification-setup/action.yml\` and its assets onto trusted main, update generated workflows, then enable \`VERIFICATION_SETUP=true\` (Action input \`verification-setup\`, disabled by default). GitHub Actions executes the trusted snapshot before each command with a fresh private HOME; candidate changes cannot replace it. Native post steps finish before profile cleanup. Setup failure blocks verification and commit/push. The local CLI cannot execute composite actions and fails closed when opted in. Read [repository-owned setup](https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-owned-setup). + For the full contributor flow, read [repository collaboration](https://github.com/vypdev/copilot/blob/master/docs/agents/repository-collaboration.mdx). For drift and recovery, read [guidance troubleshooting](https://github.com/vypdev/copilot/blob/master/docs/agents/repository-guidance-troubleshooting.mdx). `; } @@ -46392,6 +46536,40 @@ function calculateReviewersStillNeeded(desiredCount, currentCount, confirmedCoun } +/***/ }), + +/***/ 81053: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.sddAnalysisStatusMarker = sddAnalysisStatusMarker; +exports.renderSddAnalysisStatus = renderSddAnalysisStatus; +function sddAnalysisStatusMarker(issueNumber) { + return ``; +} +const reasons = { + 'update-owner-mismatch': ['The update path does not belong to the selected catalog owner.', 'La ruta de actualización no pertenece al propietario seleccionado del catálogo.'], + 'companion-owner-unknown': ['The companion owner is absent from the catalog.', 'El propietario del SDD complementario no existe en el catálogo.'], + 'companion-path-registered': ['The companion path is already registered in the catalog.', 'La ruta del SDD complementario ya está registrada en el catálogo.'], + 'new-owner-registered': ['The proposed new capability already exists in the catalog.', 'La capacidad propuesta como nueva ya existe en el catálogo.'], + 'new-path-registered': ['The proposed new SDD path is already registered in the catalog.', 'La ruta propuesta como nueva ya está registrada en el catálogo.'], +}; +/** Stateless diagnostic, deliberately separate from the validated readiness record. */ +function renderSddAnalysisStatus(issueNumber, locale, reason) { + const spanish = /^es(?:-|$)/i.test(locale ?? ''); + const marker = sddAnalysisStatusMarker(issueNumber); + if (!reason) + return spanish + ? `## Estado del análisis del SDD\n\nEl análisis posterior ha validado la propiedad. La publicación y la preparación de la rama siguen pendientes de sus comprobaciones.\n\n${marker}` + : `## SDD analysis status\n\nA subsequent analysis validated ownership. Publication and branch readiness remain subject to their checks.\n\n${marker}`; + return spanish + ? `## Estado del SDD: análisis bloqueado\n\nNo se ha preparado ningún borrador ni publicación nueva. ${reasons[reason][1]}\n\n**Acción de mantenimiento:** Aclara en la misma issue el ID de capacidad del catálogo y la ruta: una actualización usa una ruta de ese propietario; un complemento usa un propietario existente y una ruta nueva; una capacidad nueva necesita ID y ruta sin registrar. Después vuelve a ejecutar el workflow original. Cada ejecución hace un solo análisis; no hay reparación ni reintento automático. Se conservan las respuestas, los SDD y las publicaciones anteriores.\n\n**Diagnóstico:** \`${reason}\`. La decisión rechazada no autoriza una rama ni la etiqueta de preparación.\n\n${marker}` + : `## SDD work status: analysis blocked\n\nNo draft or new publication was prepared. ${reasons[reason][0]}\n\n**Maintainer action:** Clarify the catalog capability ID and path in this same issue: an update uses a path owned by that capability; a companion uses an existing owner and a new path; a new capability needs an unregistered ID and path. Then rerun the original workflow. Each invocation performs one analysis; there is no automatic repair or retry. Existing answers, SDDs and publications are retained.\n\n**Diagnostic:** \`${reason}\`. The rejected decision authorizes no branch or readiness label.\n\n${marker}`; +} + + /***/ }), /***/ 2230: @@ -47487,6 +47665,7 @@ exports.isSetupBatchInstallationReceipt = isSetupBatchInstallationReceipt; exports.parseSetupBatchOperation = parseSetupBatchOperation; exports.validSetupBatchAssetPath = validSetupBatchAssetPath; const setup_batch_1 = __nccwpck_require__(88308); +const setup_verification_action_1 = __nccwpck_require__(33156); const uuid = /^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/u; const sha = /^[a-f0-9]{40}$/u; const digest = /^[a-f0-9]{64}$/u; @@ -47592,6 +47771,7 @@ function validSetupBatchAssetPath(path) { if (path.length > 240 || path.split('/').some(part => !part || part === '.' || part === '..') || /[^A-Za-z0-9_./-]/u.test(path)) return false; return path === 'AGENTS.md' || path === '.agents/skills/copilot-repository-workflow/SKILL.md' + || path === setup_verification_action_1.SETUP_VERIFICATION_ACTION_PATH || /^\.github\/(?:workflows|ISSUE_TEMPLATE)\/[A-Za-z0-9_.-]+\.(?:yml|yaml)$/u.test(path) || path === '.github/pull_request_template.md' || /^\.copilot\/(?:repository-profile|setup-manifest|runner-profile)\.json$/u.test(path) || path === '.copilot/AGENT_GUIDE.md' || path.startsWith('.copilot/setup-backups/'); @@ -47856,6 +48036,7 @@ function createDefaultSetupConfiguration() { choreTree: 'chore', issueManagedBranches: true, preBranchSdd: false, + verificationSetup: false, reopenIssueOnPush: true, desiredAssigneesCount: 1, desiredReviewersCount: 1, @@ -48012,6 +48193,7 @@ Object.defineProperty(exports, "buildSetupCredentialRequirements", ({ enumerable const locale_1 = __nccwpck_require__(15386); const issue_workflow_profile_1 = __nccwpck_require__(26744); const setup_issue_workflow_policy_1 = __nccwpck_require__(81182); +const setup_verification_action_1 = __nccwpck_require__(33156); const repository_agent_guidance_policy_1 = __nccwpck_require__(67402); function buildSetupPlan(configuration, mergeQueueReadiness = [], approvalReadiness = []) { const workflowFiles = (0, setup_workflow_catalog_1.enabledSetupWorkflowFiles)((0, setup_issue_workflow_policy_1.effectiveIssueWorkflowFeatures)(configuration)) @@ -48023,6 +48205,7 @@ function buildSetupPlan(configuration, mergeQueueReadiness = [], approvalReadine .filter(file => configuration.features.release !== false || file !== 'release.yml') .filter(file => configuration.features.hotfix !== false || file !== 'hotfix.yml'); const selectedFiles = [ + setup_verification_action_1.SETUP_VERIFICATION_ACTION_PATH, ...(configuration.runners && configuration.runners.mode !== 'retain' ? ['.copilot/runner-profile.json'] : []), ...workflowFiles.map(file => `workflows/${file}`), ...issueTemplateFiles.map(file => `ISSUE_TEMPLATE/${file}`), @@ -48123,6 +48306,7 @@ function buildSetupRepositoryVariables(configuration) { add('CHORE_TREE', repository.choreTree); add('ISSUE_MANAGED_BRANCHES', repository.issueManagedBranches); add('PRE_BRANCH_SDD', repository.preBranchSdd); + add('VERIFICATION_SETUP', repository.verificationSetup ?? false); add('REOPEN_ISSUE_ON_PUSH', repository.reopenIssueOnPush); add('DESIRED_ASSIGNEES_COUNT', repository.desiredAssigneesCount); add('DESIRED_REVIEWERS_COUNT', repository.desiredReviewersCount); @@ -48185,6 +48369,7 @@ function buildSetupActionInputs(configuration) { 'chore-tree': repository.choreTree, 'issue-managed-branches': String(repository.issueManagedBranches), 'pre-branch-sdd': String(repository.preBranchSdd), + 'verification-setup': String(repository.verificationSetup ?? false), 'reopen-issue-on-push': String(repository.reopenIssueOnPush), 'desired-assignees-count': String(repository.desiredAssigneesCount), 'desired-reviewers-count': String(repository.desiredReviewersCount), @@ -48630,6 +48815,9 @@ function validateSetupConfiguration(configuration, options = {}) { || typeof configuration.repository.preBranchSdd !== 'boolean') { errors.push('issue-managed-branches and pre-branch-sdd must be boolean values.'); } + if (configuration.repository.verificationSetup !== undefined && typeof configuration.repository.verificationSetup !== 'boolean') { + errors.push('verification-setup must be a boolean value.'); + } if (configuration.repository.preBranchSdd && !configuration.repository.issueManagedBranches) { errors.push('pre-branch-sdd requires issue-managed-branches.'); } @@ -49861,6 +50049,7 @@ const repositoryFields = [ ['HOTFIX_TREE', 'hotfixTree'], ['RELEASE_TREE', 'releaseTree'], ['DOCS_TREE', 'docsTree'], ['CHORE_TREE', 'choreTree'], ['ISSUE_MANAGED_BRANCHES', 'issueManagedBranches'], ['PRE_BRANCH_SDD', 'preBranchSdd'], + ['VERIFICATION_SETUP', 'verificationSetup'], ['REOPEN_ISSUE_ON_PUSH', 'reopenIssueOnPush'], ['DESIRED_ASSIGNEES_COUNT', 'desiredAssigneesCount'], ['DESIRED_REVIEWERS_COUNT', 'desiredReviewersCount'], ['INACTIVITY_THRESHOLD_HOURS', 'inactivityThresholdHours'], ['REPOSITORY_LOCALE', 'repositoryLocale'], ['ISSUES_LOCALE', 'issueLocale'], @@ -50325,6 +50514,8 @@ function setupQuestionDocumentation(question) { return docs.branchManagement; if (id === 'repository.preBranchSdd') return docs.preBranchSdd; + if (id === 'repository.verificationSetup') + return { title: 'Repository-owned verification setup', url: 'https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-owned-setup' }; if (id === 'repository.inactivityThresholdHours' || id === 'features.inactiveIssueClosure') return docs.issueLifecycle; if (id === 'repository.desiredAssigneesCount' || id === 'repository.desiredReviewersCount') @@ -50405,6 +50596,7 @@ const section = { storage: { summary: 'Choisissez où résident les Variables et Secrets GitHub Actions.', when: 'Ce réglage s’applique quand leur création est activée.', example: 'Le dépôt est le périmètre par défaut le plus simple.', effect: 'Il change la visibilité, les autorisations et l’ordre de priorité.', verify: 'Examinez le périmètre et les avertissements de masquage dans le plan.' }, }; const special = { + 'repository.verificationSetup': { summary: 'Activez l’action composite du projet avant chaque commande de vérification réelle.', when: 'Gardez cette option désactivée avant de définir et revoir les dépendances sur MAIN_BRANCH.', example: 'Non garde VERIFICATION_SETUP=false ; Oui active le hook sans installer de dépendances maintenant.', effect: 'Setup crée .github/actions/copilot-verification-setup/action.yml seulement si absent et conserve le fichier existant. Le modèle échoue avant personnalisation.', verify: 'Personnalisez, révisez et fusionnez sur MAIN_BRANCH, puis lancez une vraie vérification. Une PR d’installation ne prouve pas le fonctionnement.' }, 'agents.findings.executable': { summary: 'Choisissez la commande de l’agent sur le runner GitHub Actions, pas sur cet ordinateur.', when: 'Ne la changez que si un agent personnalisé est délibérément installé sur le runner.', example: 'Laissez vide pour codex, opencode ou agent selon le fournisseur.', effect: 'Le chemin personnalisé est utilisé pour les tâches choisies et n’est jamais installé automatiquement.', verify: 'Vérifiez que le runner possède exactement cet exécutable avant d’activer le workflow.' }, 'ai.includeReasoning': { summary: 'Demandez des explications supplémentaires si la réponse du fournisseur les contient.', when: 'Réservé aux diagnostics avancés ; le parcours CLI actuel ne fournit pas de parties de raisonnement séparées.', example: 'Laissez désactivé pour une configuration normale.', effect: 'Cela peut ajouter du texte du fournisseur, sans garantir des métadonnées brèves.', verify: 'Inspectez une réponse structurée contrôlée ; ne supposez pas que l’option a produit plus de texte.' }, 'ai.bugbotDryRun': { summary: 'Gardez Bugbot en mode analyse seule pour ses futures exécutions.', when: 'Utile pour une évaluation ; incompatible avec les preuves nécessaires à l’approbation.', example: 'Choisissez Non pour publier les revues normales.', effect: 'Bugbot analyse sans publier de résultat ni modifier le dépôt. Ce n’est pas setup --dry-run.', verify: 'Inspectez le résultat du workflow Bugbot : le mode analyse seule ne publie ni revue ni vérification.' }, @@ -50481,6 +50673,10 @@ const location = { storage: { en: 'GitHub Actions stores these resources at repository or organization scope; the scope changes visibility and required PAT grants.', es: 'GitHub Actions guarda estos recursos en el repositorio o la organización; el ámbito cambia la visibilidad y los permisos del PAT.' }, }; const special = { + 'repository.verificationSetup': { + en: { summary: 'Enable the project-owned composite action before each real verification command.', when: 'Leave disabled until your project dependencies are defined and reviewed on the configured MAIN_BRANCH.', example: 'No keeps VERIFICATION_SETUP=false. Yes enables the existing hook; it does not infer or install dependencies now.', effect: 'Setup creates .github/actions/copilot-verification-setup/action.yml only if missing and preserves existing actions. The starter fails until customized.', verify: 'Customize the placeholder, review and merge on MAIN_BRANCH, then run an authorized modification or sync with verification. An installer PR is not runtime proof.' }, + es: { summary: 'Activa la acción compuesta del proyecto antes de cada comando real de verificación.', when: 'Déjala desactivada hasta definir y revisar las dependencias en la MAIN_BRANCH configurada.', example: 'No conserva VERIFICATION_SETUP=false. Sí activa el hook existente; ahora no se deducen ni instalan dependencias.', effect: 'Setup crea .github/actions/copilot-verification-setup/action.yml solo si falta y conserva las acciones existentes. La plantilla falla hasta personalizarla.', verify: 'Personaliza la plantilla, revisa y fusiona en MAIN_BRANCH y ejecuta una modificación o sincronización autorizada con verificación. Una PR de instalación no demuestra que el entorno funcione.' }, + }, 'agents.findings.executable': { en: { summary: 'Choose the agent command used on the GitHub Actions runner, not on this computer.', when: 'Only change this for a runner with a deliberately installed custom agent binary.', example: 'Leave empty for codex, opencode, or agent according to the provider.', effect: 'A custom path is shared unless a task has its own override; it is never installed automatically.', verify: 'Check the runner has this exact executable before enabling the workflow.' }, es: { summary: 'Elige el comando del agente en el runner de GitHub Actions, no en este ordenador.', when: 'Cámbialo solo si el runner tiene instalado expresamente otro binario.', example: 'Déjalo vacío para usar codex, opencode o agent según el proveedor.', effect: 'La ruta personalizada se comparte salvo que una tarea tenga su propia excepción; nunca se instala automáticamente.', verify: 'Comprueba que el runner tiene exactamente ese ejecutable.' }, @@ -50631,6 +50827,7 @@ const section = { storage: { summary: 'Escolha onde ficam as Variables e Secrets do GitHub Actions.', when: 'Aplica-se quando a sua criação está ativa.', example: 'O âmbito do repositório é a opção predefinida mais simples.', effect: 'Altera visibilidade, permissões e precedência.', verify: 'Confirme o âmbito e os avisos de sobreposição no plano.' }, }; const special = { + 'repository.verificationSetup': { summary: 'Ative a ação composta do projeto antes de cada comando real de verificação.', when: 'Mantenha desativado até definir e rever as dependências na MAIN_BRANCH configurada.', example: 'Não mantém VERIFICATION_SETUP=false; Sim ativa o hook sem instalar dependências agora.', effect: 'Setup cria .github/actions/copilot-verification-setup/action.yml só se faltar e preserva o existente. O modelo falha até ser personalizado.', verify: 'Personalize, reveja e faça merge na MAIN_BRANCH, depois execute uma verificação real. Uma PR de instalação não comprova o funcionamento.' }, 'agents.findings.executable': { summary: 'Escolha o comando do agente no runner GitHub Actions, não neste computador.', when: 'Altere-o apenas se tiver instalado deliberadamente outro agente no runner.', example: 'Deixe vazio para codex, opencode ou agent, conforme o fornecedor.', effect: 'O caminho personalizado é usado pelas tarefas escolhidas e nunca é instalado automaticamente.', verify: 'Confirme que o runner tem exatamente este executável antes de ativar o fluxo.' }, 'ai.includeReasoning': { summary: 'Peça explicações adicionais se a resposta do fornecedor as disponibilizar.', when: 'Só para diagnóstico avançado; o percurso CLI atual não fornece partes de raciocínio separadas.', example: 'Mantenha desativado numa configuração normal.', effect: 'Pode acrescentar texto do fornecedor, sem garantir metadados breves.', verify: 'Inspecione uma resposta estruturada controlada; não presuma que a opção produziu texto adicional.' }, 'ai.bugbotDryRun': { summary: 'Mantenha o Bugbot em modo apenas de análise nas próximas execuções.', when: 'Útil numa avaliação; incompatível com provas de aprovação.', example: 'Escolha Não para publicar revisões normais.', effect: 'O Bugbot analisa sem publicar resultados nem alterar o repositório. Não é setup --dry-run.', verify: 'Inspecione o resultado do fluxo Bugbot: a simulação não publica revisão nem verificação.' }, @@ -50689,6 +50886,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.questionLabelsFr = void 0; /** French presentation labels; semantic question IDs remain unchanged. */ exports.questionLabelsFr = { + 'repository.verificationSetup': 'Préparer les dépendances avec l’action de vérification du dépôt ?', 'features.issues': 'Automatiser les tickets : branches, étiquettes, projets et cycle de vie', 'features.pullRequests': 'Automatiser les pull requests : revue, description et cycle de vie', 'features.commits': 'Automatiser les commits : progression, taille et analyse Bugbot', @@ -50782,6 +50980,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.questionLabelsPt = void 0; /** Portuguese presentation labels; semantic question IDs remain unchanged. */ exports.questionLabelsPt = { + 'repository.verificationSetup': 'Preparar dependências com a ação de verificação do repositório?', 'features.issues': 'Automatizar questões: ramos, etiquetas, projetos e ciclo de vida', 'features.pullRequests': 'Automatizar pull requests: revisão, descrição e ciclo de vida', 'features.commits': 'Automatizar commits: progresso, tamanho e análise do Bugbot', @@ -50922,6 +51121,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.purposesFr = void 0; /** French question-specific purposes. */ exports.purposesFr = { + 'repository.verificationSetup': 'Activez la préparation des dépendances du dépôt avant la vérification ; personnalisez et révisez le modèle sur MAIN_BRANCH au préalable.', 'issueWorkflows.enabled': 'Choisissez les workflows de ticket que Copilot pourra exécuter ; chacun agit différemment sur les branches, étiquettes et automatisations.', 'repositoryAgentGuidance.enabled': 'Générez des instructions pour aider les agents IA à travailler en sécurité dans ce projet.', 'repositoryAgentGuidance.agentsPointer': 'Décidez si le fichier AGENTS.md racine renvoie aux instructions générées, est créé s’il manque, ou reste intact.', @@ -50983,6 +51183,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.purposesPt = void 0; /** Portuguese question-specific purposes. */ exports.purposesPt = { + 'repository.verificationSetup': 'Ative a preparação das dependências antes da verificação; personalize e reveja o modelo na MAIN_BRANCH primeiro.', 'issueWorkflows.enabled': 'Escolha os fluxos de questões que o Copilot poderá executar; cada um afeta de forma diferente ramos, etiquetas e automatizações.', 'repositoryAgentGuidance.enabled': 'Gere instruções para ajudar os agentes de IA a trabalhar com segurança neste projeto.', 'repositoryAgentGuidance.agentsPointer': 'Decida se o AGENTS.md da raiz aponta para as instruções geradas, é criado se faltar ou permanece intacto.', @@ -51114,6 +51315,7 @@ exports.setupQuestionPurpose = setupQuestionPurpose; const setup_runner_guidance_policy_1 = __nccwpck_require__(10741); /** Field-specific meaning for choices whose label alone is easy to misinterpret. */ exports.setupQuestionPurposes = { + 'repository.verificationSetup': { en: 'Enable the repository-owned dependency setup before verification. The starter must be customized and reviewed on MAIN_BRANCH first.', es: 'Activa la preparación de dependencias del repositorio antes de verificar. Primero personaliza y revisa la plantilla en MAIN_BRANCH.' }, 'issueWorkflows.enabled': { en: 'Choose the issue workflows Copilot may run; each type has different branch, label and automation effects.', es: 'Elige los flujos de issues que podrá ejecutar Copilot; cada tipo tiene efectos distintos sobre ramas, etiquetas y automatización.' }, 'repositoryAgentGuidance.enabled': { en: 'Generate repository instructions that tell AI agents how to work safely in this project.', es: 'Genera instrucciones para que los agentes de IA trabajen con seguridad en este proyecto.' }, 'repositoryAgentGuidance.agentsPointer': { en: 'Choose whether the root AGENTS.md points to generated instructions, is created if missing, or stays untouched.', es: 'Elige si el AGENTS.md raíz apunta a las instrucciones generadas, se crea si falta o permanece intacto.' }, @@ -51236,6 +51438,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.spanishQuestionLabels = void 0; exports.spanishQuestionLabel = spanishQuestionLabel; exports.spanishQuestionLabels = { + 'repository.verificationSetup': '¿Preparar dependencias con la acción de verificación del repositorio?', 'features.issues': 'Automatizar issues: ramas, etiquetas, proyectos y ciclo de vida', 'features.pullRequests': 'Automatizar pull requests: revisión, descripción y ciclo de vida', 'features.commits': 'Automatizar commits: progreso, tamaño y análisis de Bugbot', @@ -51681,6 +51884,7 @@ function repositoryQuestions() { ['choreTree', 'Chore branch prefix', 'text'], ['issueManagedBranches', 'Let the Action create linked branches after in-progress?', 'boolean'], ['preBranchSdd', 'Require an SDD before feature and contract-change branches?', 'boolean'], + ['verificationSetup', 'Prepare dependencies with the repository verification setup action?', 'boolean'], ['reopenIssueOnPush', 'Reopen closed issues when a related branch receives a push?', 'boolean'], ['desiredAssigneesCount', 'Desired issue assignees (0 disables automatic assignment)', 'number'], ['desiredReviewersCount', 'Desired pull-request reviewers (0 disables automatic assignment)', 'number'], @@ -51857,6 +52061,8 @@ function toQuestion(definition, draft, context) { }, context); } function readPath(configuration, path, allowedNames) { + if (path === 'repository.verificationSetup') + return configuration.repository.verificationSetup ?? false; const value = path.split('.').reduce((current, key) => current[key], configuration); if (path.endsWith('.overrides')) { const overrides = value; @@ -52251,6 +52457,7 @@ function setupRunnerGuidance(question) { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.setupRunnerInstallationSummary = setupRunnerInstallationSummary; const setup_runner_policy_1 = __nccwpck_require__(91027); +const setup_verification_action_summary_policy_1 = __nccwpck_require__(15818); function routeBlock(route) { const json = JSON.stringify(route, null, 2); const longest = (json.match(/`+/g) ?? []).reduce((length, run) => Math.max(length, run.length), 2); @@ -52274,6 +52481,7 @@ function setupRunnerInstallationSummary(plan) { `**Parity:** ${assets.filter(asset => asset.status === 'source-only').length} source extensions; ${assets.filter(asset => asset.status === 'missing').length} missing assets (including disabled optional capabilities); ${assets.filter(asset => asset.status === 'customized').length} customized; ${assets.filter(asset => asset.status === 'incompatible').length} incompatible metadata retained or blocked before regeneration.`, 'Inspect the complete Files changed view and `.copilot/runner-profile.json`. Any replacements retain setup backups under `.copilot/setup-backups/`.', 'Runner access, capacity and agent authentication are separate. Selection grants no group access and never falls back to another runner. Human merge and actual trusted workflow verification remain pending.', + ...(0, setup_verification_action_summary_policy_1.setupVerificationActionSummary)(review?.verificationSetup), ].join('\n'); } @@ -53025,6 +53233,27 @@ function levelRank(level) { } +/***/ }), + +/***/ 15818: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.setupVerificationActionSummary = setupVerificationActionSummary; +const setup_verification_action_1 = __nccwpck_require__(33156); +/** Shared terminal/installation-PR copy contains no repository-controlled Markdown. */ +function setupVerificationActionSummary(review) { + if (!review) + return []; + const outcomes = { create: 'Create the starter only if missing', preserve: 'Preserve the existing consumer action byte-for-byte', blocked: 'Blocked: inspect the unsafe action path' }; + return ['Verification setup', `${outcomes[review.action]}: ${setup_verification_action_1.SETUP_VERIFICATION_ACTION_PATH}.`, + `VERIFICATION_SETUP=${review.enabled ? 'true (enabled)' : 'false (disabled)'}.`, + 'The generated placeholder fails until customized. Review and merge project dependency setup onto configured MAIN_BRANCH, then run a real verification. Setup or an installer PR does not establish runtime readiness.']; +} + + /***/ }), /***/ 3449: @@ -53256,6 +53485,58 @@ function verificationRuntimeMatches(required, observed) { } +/***/ }), + +/***/ 65326: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.VerificationSetupError = exports.VERIFICATION_SETUP_HELP = exports.VERIFICATION_SETUP_LIMITS = exports.VERIFICATION_SETUP_PATH = exports.VERIFICATION_SETUP_DIRECTORY = void 0; +exports.parseVerificationSetupResult = parseVerificationSetupResult; +exports.VERIFICATION_SETUP_DIRECTORY = '.github/actions/copilot-verification-setup'; +exports.VERIFICATION_SETUP_PATH = `${exports.VERIFICATION_SETUP_DIRECTORY}/action.yml`; +exports.VERIFICATION_SETUP_LIMITS = Object.freeze({ timeoutMs: 300000, resultBytes: 16384, scriptBytes: 65536, snapshotBytes: 262144, files: 32, requests: 20 }); +exports.VERIFICATION_SETUP_HELP = 'https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-owned-setup'; +/** Closed facts only. Provider/helper output and raw exception causes never cross this boundary. */ +class VerificationSetupError extends Error { + constructor(reason, sourceSha, exitCode) { + const sha = sourceSha && /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/u.test(sourceSha) ? sourceSha : 'unavailable'; + const exit = Number.isInteger(exitCode) && exitCode >= 0 && exitCode <= 255 ? ` Exit status: ${exitCode}.` : ''; + const action = reason === 'native-workflow-required' + ? 'Update the generated Copilot workflows and run this operation in GitHub Actions; the local CLI cannot execute composite actions.' + : `Review ${exports.VERIFICATION_SETUP_PATH} on the trusted main branch and rerun.`; + super(`Repository setup blocked verification (${reason}). ${action} Trusted source SHA: ${sha}.${exit} Verification, commit and push are withheld. Help: ${exports.VERIFICATION_SETUP_HELP}`); + this.reason = reason; + this.exitCode = exitCode; + this.name = 'VerificationSetupError'; + } +} +exports.VerificationSetupError = VerificationSetupError; +function record(value) { + return !!value && typeof value === 'object' && !Array.isArray(value); +} +function pathString(value) { + return typeof value === 'string' && value.length > 0 && value.length <= 2048 + && ![...value].some(character => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127); +} +/** Filesystem containment is checked by the adapter, after this closed schema is parsed. */ +function parseVerificationSetupResult(value) { + if (!record(value) || value.schemaVersion !== 1 || Object.keys(value).some(key => !['schemaVersion', 'path', 'environment'].includes(key))) { + throw new VerificationSetupError('result-invalid'); + } + const paths = value.path === undefined ? [] : value.path; + const environment = value.environment === undefined ? {} : value.environment; + if (!Array.isArray(paths) || paths.length > 8 || !paths.every(pathString) || new Set(paths).size !== paths.length + || !record(environment) || Object.keys(environment).some(key => key !== 'JAVA_HOME') + || ('JAVA_HOME' in environment && !pathString(environment.JAVA_HOME))) { + throw new VerificationSetupError('result-invalid'); + } + return Object.freeze({ path: Object.freeze([...paths]), ...(environment.JAVA_HOME ? { javaHome: environment.JAVA_HOME } : {}) }); +} + + /***/ }), /***/ 43193: @@ -53421,6 +53702,13 @@ class PullRequestReviewOperationError extends Error { super(buildMessage(operation, context)); this.name = "PullRequestReviewOperationError"; this.operation = operation; + const status = context?.providerStatus; + if (typeof status === 'number' && Number.isInteger(status) && status >= 400 && status <= 599) { + this.providerStatus = status; + } + if (typeof context?.providerReference === 'string' && /^[A-Za-z0-9:-]{1,64}$/.test(context.providerReference)) { + this.providerReference = context.providerReference; + } } } exports.PullRequestReviewOperationError = PullRequestReviewOperationError; @@ -53461,6 +53749,18 @@ function bindSddEvidenceReadPorts(ports) { } +/***/ }), + +/***/ 26509: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.DISABLED_VERIFICATION_SETUP = void 0; +exports.DISABLED_VERIFICATION_SETUP = Object.freeze({ kind: 'disabled' }); + + /***/ }), /***/ 84387: @@ -55371,6 +55671,7 @@ async function runInitialSetupWorkflow(request, dependencies) { } (0, logging_ports_1.logInfo)('📋 Ensuring .github and copying setup files...'); const workspaceSelection = { + ...(request.verificationActionState ? { verificationActionState: request.verificationActionState } : {}), features: setupConfiguration?.features, setupConfiguration, ...(request.workflowUpdates.length > 0 ? { @@ -55382,6 +55683,8 @@ async function runInitialSetupWorkflow(request, dependencies) { const filesResult = dependencies.setupWorkspacePort.prepare(workspaceSelection); mark('files', filesResult.copied > 0 ? 'completed' : 'skipped'); steps.push(`✅ Setup files: ${filesResult.copied} copied, ${filesResult.skipped} already existed`); + if (request.verificationActionState) + steps.push(`✅ Verification setup action ${request.verificationActionState === 'create' ? 'created' : 'preserved'}; VERIFICATION_SETUP=${setupConfiguration?.repository.verificationSetup ?? false}. Customize and review on MAIN_BRANCH, then run a real verification.`); if (setupConfiguration?.manageRepositorySecrets && secretValues > 0) mark('secrets', 'in-progress'); const secrets = await (0, setup_resource_provisioning_1.ensureRepositorySecrets)(request, dependencies, setupConfiguration, remoteConfiguration); @@ -60099,6 +60402,8 @@ function projectInitialSetupContext(source) { ...(credentials ? { setupCredentials: deepFreezeCopy(credentials) } : {}), ...(remote ? { setupRemoteConfiguration: deepFreezeCopy(remote) } : {}), workflowUpdates: Object.freeze(asStringArray(source.inputs?.setupWorkflowUpdates)), + ...(source.inputs?.setupVerificationActionState === 'create' || source.inputs?.setupVerificationActionState === 'preserve' + ? { verificationActionState: source.inputs.setupVerificationActionState } : {}), }); } function projectIssueCommentActionContext(source) { @@ -60604,6 +60909,7 @@ exports.draftSddMarkdown = draftSddMarkdown; const application_error_1 = __nccwpck_require__(75999); const pre_branch_sdd_1 = __nccwpck_require__(34730); const agent_response_length_failure_1 = __nccwpck_require__(28528); +const sdd_draft_consistency_1 = __nccwpck_require__(27910); /** Size and typed format failures share one regeneration; the writer still validates every candidate. */ async function draftSddMarkdown(agent, configuration, plan, prompt, validate) { const maximum = plan.action === 'update' ? pre_branch_sdd_1.SDD_MAX_UPDATE_CHARACTERS : pre_branch_sdd_1.SDD_MAX_DRAFT_CHARACTERS; @@ -60615,13 +60921,13 @@ async function draftSddMarkdown(agent, configuration, plan, prompt, validate) { }; let problem = 'size'; let formatReason = 'required-heading'; - const contractPrompt = `${prompt}\n\nDraft contract: keep the complete draft within ${maximum} characters; aim for ${target} characters. Preserve the same owner, decisions and requirements. Include these literal canonical heading prefixes as Markdown headings, with the shown capitalization:\n${pre_branch_sdd_1.SDD_REQUIRED_HEADINGS.join('\n')}\nUse the canonical numeric test-budget table in section 14: Area | Minimum distinct cases | Behaviors/risks covered. Every allocation and the Total must be a positive integer, and the Total must equal the sum of the allocations. A justified positive integer sentence of distinct tests or cases is also accepted. Return only the required JSON.`; + const contractPrompt = `${prompt}\n\nDraft contract: keep the complete draft within ${maximum} characters; aim for ${target} characters. Preserve the same owner, decisions and requirements. Include these literal canonical heading prefixes as Markdown headings, with the shown capitalization:\n${pre_branch_sdd_1.SDD_REQUIRED_HEADINGS.join('\n')}\nUse the canonical numeric test-budget table in section 14: Area | Minimum distinct cases | Behaviors/risks covered. Every allocation and the Total must be a positive integer, and the Total must equal the sum of the allocations. Return only the required JSON.`; for (let attempt = 0; attempt < 2; attempt++) { let value; try { value = await agent.query({ configuration, agentId: 'pre-branch-sdd-draft', - prompt: attempt === 0 ? contractPrompt : `${contractPrompt}\n\n${problem === 'size' ? `The previous response exceeded the ${maximum}-character draft limit.` : `The previous response failed the required SDD ${formatReason} contract.`} Regenerate a concise complete draft for this same owner and plan. Use the exact numbered canonical headings from the supplied template. Preserve all resolved requirements, architecture, documentation and acceptance. Do not change ownership or truncate a requirement.`, + prompt: `${attempt === 0 ? contractPrompt : `${contractPrompt}\n\n${problem === 'size' ? `The previous response exceeded the ${maximum}-character draft limit.` : `The previous response failed the required SDD ${formatReason} contract.`} Regenerate a concise complete draft for this same owner and plan. Use the exact numbered canonical headings from the supplied template. Preserve all resolved requirements, architecture, documentation and acceptance. Do not change ownership or truncate a requirement.`}\n\n${sdd_draft_consistency_1.SDD_CONSISTENCY_PROMPT}`, options: { expectJson: true, schemaName: 'pre_branch_sdd_draft', schema }, }); } @@ -60655,12 +60961,21 @@ async function draftSddMarkdown(agent, configuration, plan, prompt, validate) { } if (problem === 'format') throw new application_error_1.ApplicationError('validation.invalid-input', `The SDD draft still violates its ${formatReason} format contract after one bounded repair.`, { - recovery: { id: 'sdd-draft-format-invalid', variables: {} }, + recovery: { id: consistencyRecovery(formatReason), variables: {} }, }); throw new application_error_1.ApplicationError('validation.invalid-input', 'The SDD draft exceeded its size limit after one bounded repair.', { recovery: { id: 'sdd-draft-size-exceeded', variables: {} }, }); } +function consistencyRecovery(reason) { + switch (reason) { + case 'case-identity': return 'sdd-draft-case-identity-invalid'; + case 'case-budget': return 'sdd-draft-case-budget-invalid'; + case 'requirement-mapping': return 'sdd-draft-requirement-mapping-invalid'; + case 'repository-path': return 'sdd-draft-repository-path-invalid'; + default: return 'sdd-draft-format-invalid'; + } +} /***/ }), @@ -60678,8 +60993,10 @@ const issue_start_policy_1 = __nccwpck_require__(90332); const pre_branch_sdd_1 = __nccwpck_require__(34730); const recommendation_policy_1 = __nccwpck_require__(39410); const logging_ports_1 = __nccwpck_require__(6152); +const sdd_analysis_status_policy_1 = __nccwpck_require__(81053); const application_error_1 = __nccwpck_require__(75999); const pre_branch_sdd_draft_workflow_1 = __nccwpck_require__(93454); +const sdd_draft_consistency_1 = __nccwpck_require__(27910); const ANALYSIS_SCHEMA = { type: 'object', properties: { @@ -60800,11 +61117,21 @@ class PreBranchSddGateUseCase { }); const analysisValue = asRecord(analysis); const owners = new Map(snapshot.capabilities.map(capability => [capability.id, capability.specs])); - const plan = (0, pre_branch_sdd_1.parseSddPlan)(analysisValue, owners); + let plan; + try { + plan = (0, pre_branch_sdd_1.parseSddPlan)(analysisValue, owners); + } + catch (error) { + if (!(error instanceof pre_branch_sdd_1.SddOwnershipFailure)) + throw error; + await this.writeAnalysisStatus(context, allComments, error.reason); + throw new application_error_1.ApplicationError('provider.contract-invalid', `${error.message} Clarify the catalog owner/path in the same issue and rerun the original workflow. No automatic retry was attempted.`); + } if (card?.record.branchName && (plan.action !== 'update' || plan.path !== card.record.plan.path || plan.capabilityId !== card.record.plan.capabilityId)) { throw new Error('An existing linked branch can only revise its owning SDD on the same path.'); } + await this.writeAnalysisStatus(context, allComments); const round = publicationRetry ? card.record.round : card?.record.phase === 'awaiting-answer' && card.record.issueDigest === digest && !staleAwaiting ? card.record.round + (plan.questions.length > 0 ? 1 : 0) : 1; @@ -60824,9 +61151,19 @@ class PreBranchSddGateUseCase { const currentSdd = plan.action === 'update' ? await this.workspace.readSdd(snapshot.baseSha, plan.path) : undefined; if (plan.action === 'update' && !currentSdd) throw new Error('The catalogued SDD owner is missing from the selected base.'); + const ownerDocuments = []; + for (const path of snapshot.capabilities.find(capability => capability.id === plan.capabilityId)?.specs ?? []) { + const markdown = path === plan.path && currentSdd ? currentSdd : await this.workspace.readSdd(snapshot.baseSha, path); + if (!markdown) + throw new Error('A catalogued owning SDD is unavailable at the selected immutable base.'); + ownerDocuments.push({ path, markdown }); + } + const reservedCases = JSON.stringify((0, sdd_draft_consistency_1.reservedSddCaseIds)(ownerDocuments)); + if (reservedCases.length > 30000) + throw new Error('The owning SDD case inventory exceeds the bounded drafting context; maintainer review is required.'); const newCapability = plan.action === 'new' ? parseNewCapability(analysisValue.newCapability, plan) : undefined; let prepared; - await (0, pre_branch_sdd_draft_workflow_1.draftSddMarkdown)(this.agent, context.agentConfiguration, plan, buildDraftPrompt(context, snapshot, plan, answers, currentSdd), async (markdown) => { + await (0, pre_branch_sdd_draft_workflow_1.draftSddMarkdown)(this.agent, context.agentConfiguration, plan, `${buildDraftPrompt(context, snapshot, plan, answers, currentSdd)}\n\nCase IDs reserved across every owning SDD at ${snapshot.baseSha}:\n${reservedCases}`, async (markdown) => { prepared = await this.workspace.validateDraft(snapshot, plan, markdown, newCapability); }); if (!prepared) @@ -60916,6 +61253,20 @@ class PreBranchSddGateUseCase { else await this.comments.updateComment(issueNumber, cardId, body); } + async writeAnalysisStatus(context, comments, reason) { + const marker = (0, sdd_analysis_status_policy_1.sddAnalysisStatusMarker)(context.issueNumber); + const prior = comments.filter(comment => comment.user?.login?.toLowerCase() === context.tokenUser.toLowerCase() + && comment.body?.includes(marker)).sort((a, b) => b.id - a.id)[0]; + if (!reason && !prior) + return; + const body = (0, sdd_analysis_status_policy_1.renderSddAnalysisStatus)(context.issueNumber, context.issueLocale, reason); + if (prior) { + if (prior.body !== body) + await this.comments.updateComment(context.issueNumber, prior.id, body); + } + else + await this.comments.addComment(context.issueNumber, body); + } async assertFresh(context, expectedBaseSha, sourceBranch) { const [liveBody, liveTitle, snapshot] = await Promise.all([ this.descriptions.getDescription(context.issueNumber), @@ -64488,7 +64839,7 @@ function partitionFailureCategory(error) { return error instanceof Error ? error.name : 'unknown'; } function suppressDismissedFindings(execution, context, prepared) { - const activeFindings = (prepared.activeFindings ?? prepared.toPublish).filter((finding) => { + const activeFindings = (0, finding_1.retainExistingFindingIds)(prepared.activeFindings ?? prepared.toPublish, context.existingByFindingId).filter((finding) => { const existing = (0, finding_1.findExistingFindingInfo)(context.existingByFindingId, finding); return existing?.issue?.resolution !== 'dismissed' && existing?.pullRequest?.resolution !== 'dismissed'; }); @@ -64508,6 +64859,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.applyDetectedFindings = applyDetectedFindings; const mark_findings_resolved_use_case_1 = __nccwpck_require__(96963); const publish_findings_use_case_1 = __nccwpck_require__(88442); +const bugbot_mutation_error_1 = __nccwpck_require__(82937); const pull_request_review_errors_1 = __nccwpck_require__(46445); async function applyDetectedFindings(operation, context, prepared, publicationPorts, resolutionPorts, catalog) { try { @@ -64523,7 +64875,7 @@ async function applyDetectedFindings(operation, context, prepared, publicationPo }); } catch (error) { - const publicationError = error instanceof pull_request_review_errors_1.PullRequestReviewOperationError + const publicationError = error instanceof bugbot_mutation_error_1.BugbotMutationError || error instanceof pull_request_review_errors_1.PullRequestReviewOperationError ? error : new Error("Unable to publish findings."); return [publicationError]; @@ -65074,6 +65426,7 @@ function buildPreviousFindingsContext(previousFindings) { `; const suffix = ` **Your task 2:** For each finding above, analyze the current code and decide: +- Trace the original failure precondition through current callers, validation helpers and effective configuration, including modules outside the original anchor. A retained finding is not proof that its old explanation is still true. Reuse its exact id if reporting the same defect again; do not create a second report for it. - If the problem **still exists** (same code or same issue present): do **not** include it in \`resolved_findings\`. - If the problem **no longer applies** (e.g. that code was removed or refactored away): include \`{ "id": "", "resolution": "obsolete" }\` in \`resolved_findings\`. - If the problem **has been fixed** (code was changed and the issue is resolved): include \`{ "id": "", "resolution": "fixed" }\` in \`resolved_findings\`. @@ -65193,6 +65546,10 @@ function buildReviewConversationContext(issueComments, commentsByPullRequest, bo omitted, truncated: chronological.filter((entry) => entry.truncated).length, retained: chronological.length, + ...(chronological.some(entry => entry.truncated) ? { + truncatedItemIds: chronological.filter(entry => entry.truncated) + .map(entry => entry.providerId).filter(id => /^(?:issue:[0-9]+|review:[A-Za-z0-9_=-]+)$/.test(id) && id.length <= 160), + } : {}), }; } function appendConversationEntry(entries, author, kind, body, createdAt, providerId) { @@ -66684,6 +67041,7 @@ async function loadBugbotContext(request, ports, resolvedPreflight) { itemsFetched: conversationContext.retained + conversationContext.omitted, omittedItems: conversationContext.omitted, truncatedItems: conversationContext.truncated, + ...(conversationContext.truncatedItemIds ? { truncatedItemIds: conversationContext.truncatedItemIds } : {}), limitReached: conversationContext.omitted > 0 || conversationContext.truncated > 0, }, { @@ -66885,11 +67243,11 @@ Object.defineProperty(exports, "markFindingsResolved", ({ enumerable: true, get: Object.defineProperty(exports, "__esModule", ({ value: true })); exports.markFindingsResolved = markFindingsResolved; -const pull_request_review_errors_1 = __nccwpck_require__(46445); const logging_ports_1 = __nccwpck_require__(6152); const resolve_issue_finding_1 = __nccwpck_require__(35300); const resolve_pull_request_finding_1 = __nccwpck_require__(64567); const review_state_1 = __nccwpck_require__(79200); +const bugbot_mutation_error_1 = __nccwpck_require__(82937); const application_error_1 = __nccwpck_require__(75999); async function markFindingsResolved(param) { const errors = []; @@ -66917,8 +67275,8 @@ async function repairExistingPullRequestFinding(ports, operation, findingId, des try { await ports.pullRequestComments.unresolvePullRequestReviewThread(destination.pullRequestNumber, destination.commentIdentity); } - catch { - addResolutionError(errors, 'pull request'); + catch (cause) { + addResolutionError(errors, 'pull request', findingId, cause); } } } @@ -66932,7 +67290,7 @@ async function resolveIssueIfNeeded(param, findingId, destination, errors) { return; const comment = param.context.issueComments.find(item => item.id === destination.commentId); if (comment?.body == null) { - addResolutionError(errors, 'issue'); + addResolutionError(errors, 'issue', findingId); return; } try { @@ -66943,8 +67301,8 @@ async function resolveIssueIfNeeded(param, findingId, destination, errors) { resolution: param.resolvedFindingResolutions?.get(findingId), }, param.catalog); } - catch { - addResolutionError(errors, 'issue'); + catch (cause) { + addResolutionError(errors, 'issue', findingId, cause); } } async function tryResolvePullRequestFinding(ports, findingId, destination, errors, resolution, catalog) { @@ -66956,17 +67314,14 @@ async function tryResolvePullRequestFinding(ports, findingId, destination, error resolution, }, catalog); } - catch { - addResolutionError(errors, 'pull request'); + catch (cause) { + addResolutionError(errors, 'pull request', findingId, cause); } } -function addResolutionError(errors, destination) { - const cause = destination === 'pull request' - ? new pull_request_review_errors_1.PullRequestReviewOperationError('mark-resolved') - : new Error('Unable to mark an issue finding as resolved.'); - const semanticError = new application_error_1.ApplicationError('provider.unavailable', destination === 'pull request' - ? 'Unable to mark a pull request finding as resolved.' - : 'Unable to mark an issue finding as resolved.', { cause }); +function addResolutionError(errors, destination, findingId, cause) { + const semanticError = destination === 'pull request' + ? (0, bugbot_mutation_error_1.bugbotMutationError)(cause, 'resolution', [findingId], 'mark-resolved') + : new application_error_1.ApplicationError('provider.unavailable', 'Unable to mark an issue finding as resolved.'); (0, logging_ports_1.logError)(semanticError); errors.push(semanticError); } @@ -67219,6 +67574,7 @@ function isRecord(value) { */ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.publishFindings = publishFindings; +const bugbot_mutation_error_1 = __nccwpck_require__(82937); const finding_1 = __nccwpck_require__(31011); const publish_issue_finding_comment_1 = __nccwpck_require__(84950); const publish_pr_review_comments_1 = __nccwpck_require__(50352); @@ -67237,12 +67593,17 @@ async function publishFindings(param) { catalog, }) : undefined; - for (const finding of findings) { + for (const finding of (0, finding_1.retainExistingFindingIds)(findings, existingByFindingId)) { if (operation.target.issueNumber > 0 && !reviewPublisher) { await (0, publish_issue_finding_comment_1.publishIssueFindingComment)(ports.issueComments, operation.target.issueNumber, finding, (0, finding_1.findExistingFindingInfo)(existingByFindingId, finding), commitSha, catalog); } if (reviewPublisher) { - await reviewPublisher.publish(finding, (0, finding_1.findExistingFindingInfo)(existingByFindingId, finding)); + try { + await reviewPublisher.publish(finding, (0, finding_1.findExistingFindingInfo)(existingByFindingId, finding)); + } + catch (cause) { + throw (0, bugbot_mutation_error_1.bugbotMutationError)(cause, 'publication', [finding.id], 'publish-comments'); + } } } await reviewPublisher?.flush(overflowCount, overflowTitles); @@ -67314,6 +67675,7 @@ ${catalog.message('bugbot.overflow.body', { count: `**${overflowCount}**` }, ove Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestReviewCommentPublisher = void 0; +const bugbot_mutation_error_1 = __nccwpck_require__(82937); const bugbot_finding_marker_policy_1 = __nccwpck_require__(98024); const path_validation_1 = __nccwpck_require__(70124); const logging_ports_1 = __nccwpck_require__(6152); @@ -67385,11 +67747,16 @@ class PullRequestReviewCommentPublisher { if (this.findingsToCreate.length === 0 && overflowCount === 0) return; const { repository, operation, openPrNumber, prContext } = this.options; - await repository.createReviewWithComments(openPrNumber, prContext.prHeadSha, buildReviewSummary(this.findingsToCreate, this.commentsToCreate.length, this.unanchoredBodies, overflowCount, overflowTitles, operation.analysis.reviewConfiguration.traceRules - ? this.options.ruleSources ?? [] - : [], operation.analysis.reviewConfiguration.traceRules - ? this.options.omittedRuleCount ?? 0 - : 0, prContext.prHeadSha, this.catalog), this.commentsToCreate); + try { + await repository.createReviewWithComments(openPrNumber, prContext.prHeadSha, buildReviewSummary(this.findingsToCreate, this.commentsToCreate.length, this.unanchoredBodies, overflowCount, overflowTitles, operation.analysis.reviewConfiguration.traceRules + ? this.options.ruleSources ?? [] + : [], operation.analysis.reviewConfiguration.traceRules + ? this.options.omittedRuleCount ?? 0 + : 0, prContext.prHeadSha, this.catalog), this.commentsToCreate); + } + catch (cause) { + throw (0, bugbot_mutation_error_1.bugbotMutationError)(cause, 'publication', this.findingsToCreate.map(finding => finding.id), 'publish-comments', this.findingsToCreate.length + overflowCount); + } } get catalog() { return this.options.catalog ?? (0, bugbot_message_catalog_1.resolveStaticBugbotCatalog)(this.options.operation.locale.pullRequest); @@ -67545,6 +67912,8 @@ async function queryBugbotPartitionFindings(repository, configuration, prompt, t Object.defineProperty(exports, "__esModule", ({ value: true })); exports.reconcileBugbotReviewState = reconcileBugbotReviewState; +const bugbot_mutation_error_1 = __nccwpck_require__(82937); +const finding_1 = __nccwpck_require__(31011); const review_projection_1 = __nccwpck_require__(80859); const bugbot_reconciliation_policy_1 = __nccwpck_require__(78128); const bugbot_provider_projection_policy_1 = __nccwpck_require__(85821); @@ -67575,11 +67944,12 @@ async function reconcileBugbotReviewState(input) { }; } const snapshot = snapshotResult.snapshot; + const activeFindings = (0, finding_1.retainExistingFindingIds)(input.activeFindings, input.loadedContext.existingByFindingId); + const expectedPublishedFindings = (0, finding_1.retainExistingFindingIds)(input.expectedPublishedFindings ?? input.activeFindings, input.loadedContext.existingByFindingId); const diagnostics = [ - ...(input.mutationErrors ?? []).map((error) => ({ - code: 'operation-failed', - operatorMessage: toSafeOperationMessage(error), - })), + ...(input.mutationErrors ?? []).map((error) => error instanceof bugbot_mutation_error_1.BugbotMutationError + ? { code: 'finding-mutation-failed', mutation: error.diagnostic } + : { code: 'operation-failed', operatorMessage: toSafeOperationMessage(error) }), ...(!input.target.trustedAuthorLogin?.trim() ? [{ code: 'identity-unavailable' }] : []), @@ -67588,7 +67958,7 @@ async function reconcileBugbotReviewState(input) { const providerProjection = (0, bugbot_provider_projection_policy_1.projectBugbotProviderEvidence)({ snapshot, trustedAuthorLogin: input.target.trustedAuthorLogin, - activeFindings: input.activeFindings, + activeFindings, existingByFindingId: input.loadedContext.existingByFindingId, }); const plan = (0, bugbot_reconciliation_policy_1.buildBugbotReconciliationPlan)({ @@ -67598,8 +67968,8 @@ async function reconcileBugbotReviewState(input) { id, (0, bugbot_finding_marker_policy_1.extractTitleFromBody)(fullBody) || id, ])), - activeFindings: input.activeFindings, - expectedPublishedFindings: input.expectedPublishedFindings ?? input.activeFindings, + activeFindings, + expectedPublishedFindings, diagnostics, coverage: input.loadedContext.coverage, }); @@ -68103,14 +68473,16 @@ function toPresentationFailure(diagnostic) { const message = (0, bugbot_message_catalog_1.bugbotDiagnosticOperatorMessage)(diagnostic); return { diagnostic, - error: diagnostic.code === 'review-updates-pending' - ? new application_error_1.ApplicationError('workflow.presentation-pending', message, { - recovery: { - id: 'bugbot-review-blocks-pending', - variables: { pendingCount: diagnostic.count }, - }, - }) - : new Error(message), + error: diagnostic.code === 'finding-mutation-failed' + ? new application_error_1.ApplicationError(diagnostic.mutation.errorCode, message) + : diagnostic.code === 'review-updates-pending' + ? new application_error_1.ApplicationError('workflow.presentation-pending', message, { + recovery: { + id: 'bugbot-review-blocks-pending', + variables: { pendingCount: diagnostic.count }, + }, + }) + : new Error(message), }; } function report(projection, reviewUpdates, pendingReviewUpdates, statusCardOperation, errors) { @@ -68223,6 +68595,7 @@ exports.runVerifyCommands = runVerifyCommands; const logging_ports_1 = __nccwpck_require__(6152); const verify_command_policy_1 = __nccwpck_require__(96031); const verification_runtime_policy_1 = __nccwpck_require__(89347); +const verification_setup_policy_1 = __nccwpck_require__(65326); async function runVerifyCommands(commands, execute) { for (const command of commands) { const result = await executeVerifyCommand(command, execute); @@ -68242,7 +68615,7 @@ async function executeVerifyCommand(command, execute) { : { success: false, failedCommand: formatCommandForDiagnostics(parsed) }; } catch (error) { - if (error instanceof verification_runtime_policy_1.VerificationPrerequisiteError) { + if (error instanceof verification_runtime_policy_1.VerificationPrerequisiteError || error instanceof verification_setup_policy_1.VerificationSetupError) { return { success: false, failedCommand: formatCommandForDiagnostics(parsed), error: `${error.message} Verification command: ${formatCommandForDiagnostics(parsed)}.` }; } @@ -73862,7 +74235,7 @@ function registerSetupCommand(program) { .option('--update-workflows', 'Allow setup-managed workflows already in the repository to be updated', false) .option('--workflow-pat ', 'Workflow PAT for the bot account (prefer the hidden interactive prompt)') .option('--secret ', 'Secret value for non-interactive setup; repeat for each API key', setup_command_options_1.collectSecret, {}) - .addHelpText('after', `\nGuides (open only when you choose):\n Web setup tutorial: ${setup_documentation_1.SETUP_DOCUMENTATION.tutorial}\n First issue-to-PR workflow: ${setup_documentation_1.SETUP_DOCUMENTATION.firstWorkflow}\n Troubleshooting: ${setup_documentation_1.SETUP_DOCUMENTATION.recovery}\n\nDuring interactive setup, type ? for question help and :back to revisit an answer.\n`) + .addHelpText('after', `\nGuides (open only when you choose):\n Web setup tutorial: ${setup_documentation_1.SETUP_DOCUMENTATION.tutorial}\n First issue-to-PR workflow: ${setup_documentation_1.SETUP_DOCUMENTATION.firstWorkflow}\n Troubleshooting: ${setup_documentation_1.SETUP_DOCUMENTATION.recovery}\n Verification setup: ${setup_documentation_1.SETUP_DOCUMENTATION.verification}\n\nDuring interactive setup, type ? for question help and :back to revisit an answer.\n`) .action(setup_execution_1.executeSetupCommand); } @@ -73963,6 +74336,7 @@ async function executeSetupCommand(options) { let guardedFiles; let webApplySnapshot; let approvedWorkflowFiles = []; + let verificationActionState; let credentialsCollection; try { if (options.confirmUnverifiableWritePermissions) { @@ -74209,6 +74583,8 @@ async function executeSetupCommand(options) { return 'blocked'; } configuration = result.configuration; + const reviewedAction = result.plan.installationReview?.verificationSetup?.action; + verificationActionState = reviewedAction === 'create' || reviewedAction === 'preserve' ? reviewedAction : undefined; remoteConfiguration = result.remoteConfiguration; guardedFiles = webBridge ? (0, setup_configuration_plan_1.setupPlanGuardPaths)(result.plan) : undefined; webApplySnapshot = guardedFiles ? (0, setup_apply_snapshot_1.captureSetupApplySnapshot)(checkoutRoot, guardedFiles) : undefined; @@ -74249,7 +74625,7 @@ async function executeSetupCommand(options) { }, apply: async (report) => { (0, logger_1.logInfo)('⚙️ Applying the approved setup plan...'); - const params = (0, setup_policy_1.buildSetupParams)(options, gitInfo, token ?? '', configuration, credentialsCollection, approvedWorkflowFiles, remoteConfiguration, configurationSource); + const params = (0, setup_policy_1.buildSetupParams)(options, gitInfo, token ?? '', configuration, credentialsCollection, approvedWorkflowFiles, remoteConfiguration, configurationSource, verificationActionState); setupMutationStarted = true; setupApplyStarted = true; const actionResults = await (0, local_action_1.runLocalAction)(params, { @@ -74327,7 +74703,7 @@ exports.buildSetupParams = buildSetupParams; const action_types_1 = __nccwpck_require__(19625); const input_keys_1 = __nccwpck_require__(88539); const setup_configuration_policy_1 = __nccwpck_require__(56637); -function buildSetupParams(options, gitInfo, token, configuration, credentials, approvedWorkflowFiles = [], remoteConfiguration, configurationSource) { +function buildSetupParams(options, gitInfo, token, configuration, credentials, approvedWorkflowFiles = [], remoteConfiguration, configurationSource, verificationActionState) { return { ...(configuration ? (0, setup_configuration_policy_1.buildSetupActionInputs)(configuration) : {}), [input_keys_1.INPUT_KEYS.DEBUG]: options.debug?.toString() ?? 'false', @@ -74344,6 +74720,7 @@ function buildSetupParams(options, gitInfo, token, configuration, credentials, a ...(remoteConfiguration ? { setupRemoteConfiguration: remoteConfiguration } : {}), ...(configurationSource ? { setupConfigurationSource: configurationSource } : {}), setupWorkflowUpdates: approvedWorkflowFiles, + ...(verificationActionState ? { setupVerificationActionState: verificationActionState } : {}), }; } @@ -75013,7 +75390,7 @@ const REPOSITORY_STRING_KEYS = new Set([ 'orchestrationPresentationMode', 'orchestrationCommentMode', ]); -const REPOSITORY_BOOLEAN_KEYS = new Set(['issueManagedBranches', 'preBranchSdd', 'reopenIssueOnPush', 'orchestrationDiagrams']); +const REPOSITORY_BOOLEAN_KEYS = new Set(['issueManagedBranches', 'preBranchSdd', 'verificationSetup', 'reopenIssueOnPush', 'orchestrationDiagrams']); const REPOSITORY_NUMBER_KEYS = new Set(['desiredAssigneesCount', 'desiredReviewersCount', 'inactivityThresholdHours']); const REPOSITORY_STRUCTURED_KEYS = new Set(['mergeQueueCheckAttestations']); const AI_STRING_KEYS = new Set(['ignoreFiles', 'pullRequestDescriptionMode', 'bugbotSeverity', 'bugbotFixVerifyCommands', 'bugbotEffort', 'bugbotOrganizationRules', 'provisioningMode']); @@ -75752,8 +76129,11 @@ function doctorCheckLabel(id, catalog = (0, setup_doctor_message_catalog_1.resol Object.defineProperty(exports, "__esModule", ({ value: true })); exports.renderSetupInstallationReview = renderSetupInstallationReview; const setup_terminal_choice_policy_1 = __nccwpck_require__(64662); +const setup_verification_action_summary_policy_1 = __nccwpck_require__(15818); function renderSetupInstallationReview(review) { - return ['Runner routing and installation parity', + return [...(0, setup_verification_action_summary_policy_1.setupVerificationActionSummary)(review.verificationSetup), + ...(review.verificationSetup ? [`Trusted main branch: ${(0, setup_terminal_choice_policy_1.safeTerminalChoiceText)(review.verificationSetup.mainBranch)}`] : []), + 'Runner routing and installation parity', 'Access and capacity are observations, not runner authentication or runtime verification. Unknown access needs administrator verification; busy/offline keeps the route and waits for capacity.', ...review.jobs.map(job => ` ${(0, setup_terminal_choice_policy_1.safeTerminalChoiceText)(job.file)} / ${(0, setup_terminal_choice_policy_1.safeTerminalChoiceText)(job.job)}: ${job.role} · ${job.status}${job.retained ? ' · retained' : ''}\n runs-on: ${(0, setup_terminal_choice_policy_1.safeTerminalChoiceText)(JSON.stringify(job.runsOn))}`), 'Asset inventory (disabled optional capabilities remain visible):', @@ -75781,6 +76161,7 @@ class ConsoleSetupJourneyPresenter { present(view) { console.log(renderSetupJourney(view)); if (view.outcome === 'complete') { + console.log(`Verification setup: inspect .github/actions/copilot-verification-setup/action.yml. Setup creates it only if missing and preserves existing actions. Customize and review on MAIN_BRANCH before enabling VERIFICATION_SETUP, then run a real verification: ${setup_documentation_1.SETUP_DOCUMENTATION.verification}`); console.log(`Next: install the reviewed files, then verify your first workflow: ${setup_documentation_1.SETUP_DOCUMENTATION.firstWorkflow}`); } else if (view.outcome === 'blocked' || view.outcome === 'partial') { @@ -78370,9 +78751,16 @@ exports.APPLICATION_ERROR_RECOVERY_IDS = Object.freeze([ 'branch-sync-resolution-invalid', 'sdd-draft-size-exceeded', 'sdd-draft-format-invalid', + 'sdd-draft-case-identity-invalid', + 'sdd-draft-case-budget-invalid', + 'sdd-draft-requirement-mapping-invalid', + 'sdd-draft-repository-path-invalid', 'workspace-changes-rejected', 'closed-issue-reconciliation-failed', 'approval-evidence-read-failed', + 'stored-configuration-schema-missing', + 'stored-configuration-schema-unsupported', + 'stored-configuration-invalid', ]); const PRESERVED_STATE = 'Existing persisted state and completed external effects were preserved.'; const UNCHANGED_STATE = 'No new state or external effect was created.'; @@ -78564,6 +78952,9 @@ class ApplicationError extends Error { exports.ApplicationError = ApplicationError; _ApplicationError_cause = new WeakMap(); const RECOVERY_VARIABLE_KEYS = Object.freeze({ + 'stored-configuration-schema-missing': Object.freeze(['issueNumber', 'expectedVersion']), + 'stored-configuration-schema-unsupported': Object.freeze(['issueNumber', 'expectedVersion', 'actualVersion']), + 'stored-configuration-invalid': Object.freeze(['issueNumber', 'expectedVersion']), 'closed-issue-reconciliation-failed': Object.freeze(['resultId', 'phase', 'state', 'reason', 'changed', 'remaining']), 'approval-evidence-read-failed': Object.freeze(['operation', 'reason', 'permission']), 'pull-request-link-restored': Object.freeze([]), @@ -78578,6 +78969,10 @@ const RECOVERY_VARIABLE_KEYS = Object.freeze({ 'branch-sync-resolution-invalid': Object.freeze(['validationCode', 'command']), 'sdd-draft-size-exceeded': Object.freeze([]), 'sdd-draft-format-invalid': Object.freeze([]), + 'sdd-draft-case-identity-invalid': Object.freeze([]), + 'sdd-draft-case-budget-invalid': Object.freeze([]), + 'sdd-draft-requirement-mapping-invalid': Object.freeze([]), + 'sdd-draft-repository-path-invalid': Object.freeze([]), 'workspace-changes-rejected': Object.freeze([]), }); function normalizeApplicationErrorRecovery(recovery) { @@ -78593,6 +78988,13 @@ function normalizeApplicationErrorRecovery(recovery) { || actualKeys.some((key, index) => key !== expectedKeys[index])) { throw new TypeError(`Application error recovery variables are invalid for ${recovery.id}.`); } + if (recovery.id.startsWith('stored-configuration-') + && (![variables.issueNumber, variables.expectedVersion].every(value => typeof value === 'number' && Number.isSafeInteger(value) && value > 0) + || (recovery.id === 'stored-configuration-schema-unsupported' + && !(typeof variables.actualVersion === 'number' + && Number.isSafeInteger(variables.actualVersion) && variables.actualVersion >= 0)))) { + throw new TypeError('Stored configuration diagnostic is invalid.'); + } if (recovery.id === 'managed-branch-enrichment-failed' && (typeof variables.branchName !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9._/-]{0,254}$/u.test(variables.branchName))) { @@ -78974,6 +79376,7 @@ class Execution { this.currentIssueWorkflowAdmission = components.issueWorkflowAdmission; this.currentConfiguration.issueWorkflowProfileDigest = components.issueWorkflowProfileDigest; this.preBranchSdd = components.preBranchSdd ?? false; + this.verificationSetup = components.verificationSetup ?? false; } } exports.Execution = Execution; @@ -83899,6 +84302,7 @@ function combineOrganizationAccess(secrets, variables) { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.isGithubAlreadyExists = exports.isGithubPermissionDenied = exports.isGithubRateLimited = exports.isGithubNotFound = exports.getGithubErrorStatus = void 0; +exports.githubReadErrorCode = githubReadErrorCode; const getGithubErrorStatus = (error) => { if (typeof error !== "object" || error === null) return undefined; @@ -83908,6 +84312,23 @@ const getGithubErrorStatus = (error) => { exports.getGithubErrorStatus = getGithubErrorStatus; const isGithubNotFound = (error) => (0, exports.getGithubErrorStatus)(error) === 404; exports.isGithubNotFound = isGithubNotFound; +/** Maps failed metadata reads without copying untrusted provider text. */ +function githubReadErrorCode(error) { + const status = (0, exports.getGithubErrorStatus)(error); + if (status === 401) + return 'authorization.credential-invalid'; + if ((0, exports.isGithubRateLimited)(error)) + return 'provider.rate-limited'; + if (status === 403) + return 'authorization.denied'; + if (status === 404) + return 'provider.not-found'; + if (status === 409 || status === 412) + return 'provider.conflict'; + if (status === 400 || status === 422) + return 'provider.contract-invalid'; + return 'provider.unavailable'; +} const isGithubRateLimited = (error) => { const status = (0, exports.getGithubErrorStatus)(error); if (status === 429) @@ -84618,8 +85039,9 @@ class IssueContentRepository { return issue.body ?? ''; } catch (error) { - (0, logger_1.logError)((0, application_error_1.toApplicationError)(error, 'provider.unavailable', `Unable to read issue #${issueNumber} description.`)); - throw error; + const semanticError = (0, application_error_1.toApplicationError)(error, (0, github_error_policy_1.githubReadErrorCode)(error), 'Unable to read the issue or pull-request description.'); + (0, logger_1.logError)(semanticError); + throw semanticError; } }; this.getIssueDescription = async (owner, repository, issueNumber, token) => { @@ -86981,8 +87403,8 @@ function collectDiagnostic(diagnostics, cause) { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestChangesRepository = void 0; +const pull_request_review_error_metadata_1 = __nccwpck_require__(54354); const logger_1 = __nccwpck_require__(91151); -const pull_request_review_errors_1 = __nccwpck_require__(46445); const github_pagination_policy_1 = __nccwpck_require__(44812); const application_error_1 = __nccwpck_require__(75999); class PullRequestChangesRepository { @@ -86995,7 +87417,7 @@ class PullRequestChangesRepository { } catch (error) { (0, logger_1.logError)((0, application_error_1.toApplicationError)(error, 'provider.unavailable', 'Unable to read the pull request review diff.')); - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'list-files'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'list-files'); } }; this.getBoundedBugbotReviewDiffSnapshot = async (owner, repository, pullNumber, token) => { @@ -87037,7 +87459,7 @@ class PullRequestChangesRepository { } catch (error) { (0, logger_1.logError)((0, application_error_1.toApplicationError)(error, 'provider.unavailable', 'Unable to read the pull request review diff.')); - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'list-files'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'list-files'); } }; /** Head commit SHA of the PR (for creating review). */ @@ -87056,7 +87478,7 @@ class PullRequestChangesRepository { } catch (error) { (0, logger_1.logError)((0, application_error_1.toApplicationError)(error, 'provider.unavailable', 'Unable to read the pull request head SHA.')); - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "get-head-sha"); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "get-head-sha"); } }; } @@ -87399,6 +87821,7 @@ function toBugbotPullRequestIdentity(value) { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestReviewCommentCommandRepository = void 0; +const pull_request_review_error_metadata_1 = __nccwpck_require__(54354); const pull_request_review_errors_1 = __nccwpck_require__(46445); const github_pagination_policy_1 = __nccwpck_require__(44812); class PullRequestReviewCommentCommandRepository { @@ -87467,7 +87890,7 @@ class PullRequestReviewCommentCommandRepository { const context = comments.length > 0 ? { failedCount: comments.length, totalCount: comments.length } : undefined; - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "publish-comments", context); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "publish-comments", context); } } async updatePullRequestReview(owner, repository, pullRequestNumber, reviewIdentity, body, token) { @@ -87488,7 +87911,7 @@ class PullRequestReviewCommentCommandRepository { throw new pull_request_review_errors_1.PullRequestReviewOperationError('update-review'); } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'update-review'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'update-review'); } } async updatePullRequestReviewComment(_owner, _repository, commentIdentity, body, token) { @@ -87507,7 +87930,7 @@ class PullRequestReviewCommentCommandRepository { } } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "update-comment"); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "update-comment"); } } } @@ -87523,7 +87946,7 @@ exports.PullRequestReviewCommentCommandRepository = PullRequestReviewCommentComm Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestReviewCommentQueryRepository = void 0; -const pull_request_review_errors_1 = __nccwpck_require__(46445); +const pull_request_review_error_metadata_1 = __nccwpck_require__(54354); const github_pagination_policy_1 = __nccwpck_require__(44812); function toReviewComment(comment) { if (typeof comment.node_id !== "string" || comment.node_id.length === 0) { @@ -87579,7 +88002,7 @@ class PullRequestReviewCommentQueryRepository { return comments; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "list-comments"); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "list-comments"); } } async listBugbotPullRequestReviewCommentsBounded(owner, repository, pullRequestNumber, token) { @@ -87622,7 +88045,7 @@ class PullRequestReviewCommentQueryRepository { }; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "list-comments"); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "list-comments"); } } async listPullRequestReviews(owner, repository, pullRequestNumber, token) { @@ -87636,7 +88059,7 @@ class PullRequestReviewCommentQueryRepository { return reviews; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'list-reviews'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'list-reviews'); } } async getPullRequestReviewCommentBody(owner, repository, _pullRequestNumber, commentId, token) { @@ -87650,13 +88073,37 @@ class PullRequestReviewCommentQueryRepository { return data.body ?? null; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "get-comment"); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "get-comment"); } } } exports.PullRequestReviewCommentQueryRepository = PullRequestReviewCommentQueryRepository; +/***/ }), + +/***/ 54354: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toPullRequestReviewOperationError = toPullRequestReviewOperationError; +const pull_request_review_errors_1 = __nccwpck_require__(46445); +/** Only safe HTTP metadata crosses the provider boundary; provider prose never does. */ +function toPullRequestReviewOperationError(error, operation, context) { + if (!error || typeof error !== 'object') + return (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, operation, context); + const record = error; + return (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, operation, { + ...context, + ...(typeof record.status === 'number' ? { providerStatus: record.status } : {}), + ...(typeof record.response?.headers?.['x-github-request-id'] === 'string' + ? { providerReference: record.response.headers['x-github-request-id'] } : {}), + }); +} + + /***/ }), /***/ 2307: @@ -87767,6 +88214,7 @@ function nextConnectionCursor(pageInfo, seenCursors) { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestReviewThreadRepository = void 0; +const pull_request_review_error_metadata_1 = __nccwpck_require__(54354); const logger_1 = __nccwpck_require__(91151); const pull_request_review_errors_1 = __nccwpck_require__(46445); const pull_request_review_thread_locator_1 = __nccwpck_require__(2307); @@ -87814,7 +88262,7 @@ class PullRequestReviewThreadRepository { return states; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'list-threads'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'list-threads'); } }; this.listBugbotPullRequestReviewThreadStatesBounded = async (owner, repository, pullNumber, token) => { @@ -87883,7 +88331,7 @@ class PullRequestReviewThreadRepository { }; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'list-threads'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'list-threads'); } }; this.resolvePullRequestReviewThread = async (owner, repository, pullNumber, commentIdentity, token) => { @@ -87907,7 +88355,7 @@ class PullRequestReviewThreadRepository { (0, logger_1.logDebugInfo)('Resolved pull request review thread.'); } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'resolve-thread'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'resolve-thread'); } }; this.unresolvePullRequestReviewThread = async (owner, repository, pullNumber, commentIdentity, token) => { @@ -87931,7 +88379,7 @@ class PullRequestReviewThreadRepository { (0, logger_1.logDebugInfo)('Reopened pull request review thread.'); } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'unresolve-thread'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'unresolve-thread'); } }; } @@ -87948,7 +88396,7 @@ exports.PullRequestReviewThreadRepository = PullRequestReviewThreadRepository; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestReviewerRepository = void 0; -const pull_request_review_errors_1 = __nccwpck_require__(46445); +const pull_request_review_error_metadata_1 = __nccwpck_require__(54354); const github_pagination_policy_1 = __nccwpck_require__(44812); const COMPLETED_REVIEW_STATES = new Set([ "APPROVED", @@ -87981,7 +88429,7 @@ class PullRequestReviewerRepository { return [...reviewers.values()]; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "list-reviewers"); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "list-reviewers"); } } async addReviewersToPullRequest(owner, repository, pullRequestNumber, reviewers, token) { @@ -88006,7 +88454,7 @@ class PullRequestReviewerRepository { return [...confirmed.values()]; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "request-reviewers"); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "request-reviewers"); } } async listRequestedReviewers(client, parameters) { @@ -89424,10 +89872,15 @@ function matchesConstrainedHead(target, candidate) { /***/ }), /***/ 31011: -/***/ ((__unused_webpack_module, exports) => { +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isExistingFindingFullyResolved = isExistingFindingFullyResolved; +exports.findExistingFindingInfo = findExistingFindingInfo; +exports.findExistingFindingMatch = findExistingFindingMatch; +exports.retainExistingFindingIds = retainExistingFindingIds; /** * Provider-neutral Bugbot finding and durable identity contracts. * @@ -89435,9 +89888,7 @@ function matchesConstrainedHead(target, candidate) { * them in the domain prevents policies from depending on a particular use-case * folder and gives every adapter one stable semantic vocabulary. */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.isExistingFindingFullyResolved = isExistingFindingFullyResolved; -exports.findExistingFindingInfo = findExistingFindingInfo; +const finding_identity_1 = __nccwpck_require__(91853); function isExistingFindingFullyResolved(finding) { const destinations = [finding.issue, finding.pullRequest].filter((destination) => destination != null); return (destinations.length > 0 && @@ -89445,21 +89896,62 @@ function isExistingFindingFullyResolved(finding) { finding.pullRequest?.verificationRequired !== true); } function findExistingFindingInfo(existingByFindingId, finding) { + return findExistingFindingMatch(existingByFindingId, finding)?.info; +} +/** A match carries its durable key so updating a comment cannot re-key it. */ +function findExistingFindingMatch(existingByFindingId, finding) { const direct = existingByFindingId[finding.id]; if (direct && identitiesAreCompatible(direct, finding)) - return direct; - const candidates = Object.values(existingByFindingId); + return { id: finding.id, info: direct }; + const candidates = Object.entries(existingByFindingId); if (finding.fingerprint) { - const locationMatch = candidates.find((candidate) => candidate.issue?.fingerprint === finding.fingerprint + const locationMatches = candidates.filter(([, candidate]) => candidate.issue?.fingerprint === finding.fingerprint || candidate.pullRequest?.fingerprint === finding.fingerprint); - if (locationMatch) - return locationMatch; + if (locationMatches.length > 0) + return uniqueFindingMatch(locationMatches); } if (!finding.semanticFingerprint) return undefined; - const semanticMatches = candidates.filter((candidate) => candidate.issue?.semanticFingerprint === finding.semanticFingerprint + const semanticMatches = candidates.filter(([, candidate]) => candidate.issue?.semanticFingerprint === finding.semanticFingerprint || candidate.pullRequest?.semanticFingerprint === finding.semanticFingerprint); - return semanticMatches.length === 1 ? semanticMatches[0] : undefined; + return uniqueFindingMatch(semanticMatches); +} +/** + * Preserve trusted IDs across title/location changes, before limits, publication + * and final projection. Multiple reports of one uniquely matched durable finding + * share one record; unmatched or ambiguous reports remain independent evidence. + */ +function retainExistingFindingIds(findings, existingByFindingId) { + const retained = new Set(); + const durableIds = new Set(Object.keys(existingByFindingId)); + // Reserve the whole input up front so a generated ID cannot take another + // report's ID, including one that occurs later in the response. + const reservedIds = new Set([...durableIds, ...findings.map((finding) => finding.id)]); + const emittedIds = new Set(); + return findings.flatMap((finding) => { + const match = findExistingFindingMatch(existingByFindingId, finding); + if (!match) { + let id = finding.id; + if (durableIds.has(id) || emittedIds.has(id)) { + const base = `candidate-${(0, finding_identity_1.buildFindingFingerprint)(finding)}`; + id = base; + let suffix = 0; + while (reservedIds.has(id)) + id = `${base}-${++suffix}`; + reservedIds.add(id); + } + emittedIds.add(id); + return [id === finding.id ? finding : { ...finding, id }]; + } + if (retained.has(match.id)) + return []; + retained.add(match.id); + emittedIds.add(match.id); + return [finding.id === match.id ? finding : { ...finding, id: match.id }]; + }); +} +function uniqueFindingMatch(matches) { + return matches.length === 1 ? { id: matches[0][0], info: matches[0][1] } : undefined; } function identitiesAreCompatible(existing, finding) { const existingFingerprints = [ @@ -90069,6 +90561,63 @@ function isCopilotCommentRequest(commentBody, botLogin) { } +/***/ }), + +/***/ 33430: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.COPILOT_COMMENT_REMOTE_WORKFLOW = exports.COPILOT_COMMENT_SELF_WORKFLOW = exports.COPILOT_COMMENT_RUNTIME = void 0; +exports.isCopilotCommentWorkflow = isCopilotCommentWorkflow; +exports.isCopilotCommentRunner = isCopilotCommentRunner; +exports.copilotCommentRunner = copilotCommentRunner; +/** The comment coordinator is a versioned Copilot workflow, not an arbitrary reusable job. */ +exports.COPILOT_COMMENT_RUNTIME = 'copilot_comment_runtime.yml'; +exports.COPILOT_COMMENT_SELF_WORKFLOW = `$/.github/workflows/${exports.COPILOT_COMMENT_RUNTIME}`; +exports.COPILOT_COMMENT_REMOTE_WORKFLOW = `vypdev/copilot/.github/workflows/${exports.COPILOT_COMMENT_RUNTIME}@v3`; +function isCopilotCommentWorkflow(value) { + return typeof value === 'string' && (value === exports.COPILOT_COMMENT_SELF_WORKFLOW + || /^vypdev\/copilot\/\.github\/workflows\/copilot_comment_runtime\.yml@(?:v3(?:\.[0-9]+\.[0-9]+)?|[a-f0-9]{40})$/u.test(value)); +} +const literal = (value) => typeof value === 'string' && value.length > 0 && value.length <= 100 + && value === value.trim() && !/[\p{Cc}\p{Cf}${}<>]/u.test(value); +const labels = (value) => literal(value) || Array.isArray(value) && value.length > 0 && value.length <= 10 + && value.every(literal) && new Set(value.map(label => label.toLowerCase())).size === value.length; +/** Runner routing is literal data; expressions need their original full workflow reviewed. */ +function isCopilotCommentRunner(value) { + if (labels(value)) + return true; + if (!value || typeof value !== 'object' || Array.isArray(value)) + return false; + const route = value; + const keys = Object.keys(route); + return keys.length > 0 && (route.group !== undefined || route.labels !== undefined) + && keys.every(key => key === 'group' || key === 'labels') + && (route.group === undefined || literal(route.group)) + && (route.labels === undefined || labels(route.labels)); +} +function copilotCommentRunner(job) { + if (!job || !isCopilotCommentWorkflow(job.uses)) + return job?.['runs-on']; + const inputs = job.with; + if (typeof inputs?.['runs-on'] !== 'string') + throw new Error('Comment workflow runner JSON is unavailable; review the workflow separately.'); + try { + if (inputs['runs-on'].length > 16000) + throw new Error('Runner JSON exceeds its bound.'); + const route = JSON.parse(inputs['runs-on']); + if (!isCopilotCommentRunner(route)) + throw new Error('Unsupported execution route.'); + return route; + } + catch { + throw new Error('Comment workflow runner JSON is invalid; review the workflow separately.'); + } +} + + /***/ }), /***/ 72418: @@ -91873,7 +92422,7 @@ function parsePositiveSafeInteger(value) { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.SDD_REQUIRED_HEADINGS = exports.SddOwnerFormatFailure = exports.SddDraftFormatFailure = exports.SDD_MAX_UPDATE_CHARACTERS = exports.SDD_MAX_DRAFT_CHARACTERS = exports.SDD_MIN_DRAFT_CHARACTERS = exports.SDD_GATE_MARKER = void 0; +exports.SDD_REQUIRED_HEADINGS = exports.SddOwnerFormatFailure = exports.SddDraftFormatFailure = exports.SddOwnershipFailure = exports.SDD_MAX_UPDATE_CHARACTERS = exports.SDD_MAX_DRAFT_CHARACTERS = exports.SDD_MIN_DRAFT_CHARACTERS = exports.SDD_GATE_MARKER = void 0; exports.retainSddAnswers = retainSddAnswers; exports.normalizeSddIssueTitle = normalizeSddIssueTitle; exports.isSafeSddPath = isSafeSddPath; @@ -91884,6 +92433,7 @@ exports.isSddAnswerComment = isSddAnswerComment; exports.parseSddAnswer = parseSddAnswer; exports.validateSddMarkdown = validateSddMarkdown; exports.composeSddUpdate = composeSddUpdate; +exports.recoverSddUpdate = recoverSddUpdate; exports.SDD_GATE_MARKER = 'copilot:sdd-gate:v1'; exports.SDD_MIN_DRAFT_CHARACTERS = 1800; exports.SDD_MAX_DRAFT_CHARACTERS = 70000; @@ -91911,6 +92461,15 @@ function normalizeSddIssueTitle(title) { function isSafeSddPath(path) { return SDD_PATH.test(path) && !['specs/CATALOG.md', 'specs/_template.md'].includes(path); } +/** Closed diagnostics contain no model-selected identifiers or provider text. */ +class SddOwnershipFailure extends Error { + constructor(reason) { + super(`SDD ownership analysis rejected (${reason}).`); + this.reason = reason; + this.name = 'SddOwnershipFailure'; + } +} +exports.SddOwnershipFailure = SddOwnershipFailure; /** The agent may propose ownership but cannot invent a catalogued owner or arbitrary path. */ function parseSddPlan(value, catalog) { if (!isRecord(value)) @@ -91928,14 +92487,16 @@ function parseSddPlan(value, catalog) { const ownerPaths = catalog.get(capabilityId); const registered = [...catalog.values()].some(paths => paths.includes(path)); if (action === 'update' && (!ownerPaths?.includes(path) || !registered)) { - throw new Error('The requested SDD update is not owned by the selected catalog capability.'); - } - if (action === 'companion' && (!ownerPaths || registered)) { - throw new Error('A companion SDD requires an existing owner and a new path.'); - } - if (action === 'new' && (ownerPaths || registered)) { - throw new Error('A new SDD requires an unregistered capability and path.'); - } + throw new SddOwnershipFailure('update-owner-mismatch'); + } + if (action === 'companion' && !ownerPaths) + throw new SddOwnershipFailure('companion-owner-unknown'); + if (action === 'companion' && registered) + throw new SddOwnershipFailure('companion-path-registered'); + if (action === 'new' && ownerPaths) + throw new SddOwnershipFailure('new-owner-registered'); + if (action === 'new' && registered) + throw new SddOwnershipFailure('new-path-registered'); if (!Array.isArray(value.questions) || value.questions.length > 8) { throw new Error('The SDD analysis must contain at most eight blocking questions.'); } @@ -92176,8 +92737,24 @@ function composeSddUpdate(existing, change) { validateSddMarkdown(change); if (change.length > exports.SDD_MAX_UPDATE_CHARACTERS) throw new Error('An SDD update appendix exceeds 18000 characters; use a proportional change or a companion SDD.'); + const appendix = shiftSddHeadings(change, 1); + const merged = `${existing.trimEnd()}\n\n${appendix.trim()}\n`; + validateSddMarkdown(merged); + return merged; +} +/** Recovery validates the original candidate, not a second copy of its retained baseline. */ +function recoverSddUpdate(existing, published) { + const prefix = `${existing.trimEnd()}\n\n`; + if (!published.startsWith(prefix)) + return undefined; + // Composition normalizes outer whitespace and adds a publication newline. + // Reconstruct an equivalent candidate inside the original size bounds. + const change = shiftSddHeadings(published.slice(prefix.length), -1).trim().padEnd(exports.SDD_MIN_DRAFT_CHARACTERS, '\n'); + return composeSddUpdate(existing, change) === published ? change : undefined; +} +function shiftSddHeadings(source, direction) { let fence; - const appendix = change.split('\n').map(line => { + return source.split('\n').map(line => { const boundary = line.match(/^\s*(`{3,}|~{3,})/); if (boundary) { if (!fence) @@ -92186,11 +92763,11 @@ function composeSddUpdate(existing, change) { fence = undefined; return line; } - return !fence && /^#{1,5} /.test(line) ? `#${line}` : line; + if (fence) + return line; + return direction === 1 ? (/^#{1,5} /.test(line) ? `#${line}` : line) + : (/^#{2,6} /.test(line) ? line.slice(1) : line); }).join('\n'); - const merged = `${existing.trimEnd()}\n\n${appendix.trim()}\n`; - validateSddMarkdown(merged); - return merged; } function serializeSddGateValue(value) { // Human answer text must never terminate its hidden state comment. @@ -92787,6 +93364,254 @@ function replyRequestBodyDigest(body) { } +/***/ }), + +/***/ 27910: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.SDD_CONSISTENCY_PROMPT = void 0; +exports.reservedSddCaseIds = reservedSddCaseIds; +exports.validateSddDraftConsistency = validateSddDraftConsistency; +const pre_branch_sdd_1 = __nccwpck_require__(34730); +const CASE = /\b(?:[A-Za-z][A-Za-z0-9]*-)+C\d+\b/gu; +const CASE_ID = /^(?:[A-Za-z][A-Za-z0-9]*-)+C\d+$/u; +const REQUIREMENT_ID = /^[A-Za-z][A-Za-z0-9]*(?:-[A-Za-z0-9]+)+$/u; +/** Generated candidates use visible tables; retained legacy owners are never reformatted. */ +exports.SDD_CONSISTENCY_PROMPT = `Consistency contract for the proposed draft/appendix (not the retained owner): +In section 4 include one table: Requirement | Behavior. Give every goal a stable requirement ID. +In section 14 include one budget table: Area | Minimum distinct cases | Behaviors/risks covered; positive integers and one Total. +Also in section 14 include one inventory table: Case ID | Area | Requirements | Scenario. +Each row is one distinct executable case with a fully qualified ID such as capability-change-C01, one exact budget area, comma-separated requirement IDs and an observable scenario. Never use shorthand C01, ranges or redefine an ID found in any owning SDD. Reference retained baseline cases in prose using their full IDs; count only the new inventory. +In section 17 include one table: Requirement | Cases. List comma-separated full case IDs for every requirement. Its links must exactly match the case inventory in both directions, with no undefined or generic documentation checks. +In section 15 include one table: Path | Change. Change is update, reference or create. Include the selected SDD path itself with update for an existing SDD or create for a new/companion SDD. Use existing immutable-base files for update/reference. Only explicitly proposed new files may use create; never mark a missing current document as an existing artifact. Cite repository files as full repository-relative paths in backticks, or relative Markdown file links. Put every planned new file in this table. These tables are publication consistency checks, not runtime/security acceptance.`; +function fail(reason) { + // Closed diagnostics: rejected Markdown and repository text never become repair instructions. + throw new pre_branch_sdd_1.SddDraftFormatFailure(reason, `The SDD draft violates its ${reason} consistency contract.`); +} +/** Excludes examples and hidden records from the contract. */ +function visible(source) { + let fence; + let comment = false; + return source.replace(/\r\n/gu, '\n').split('\n').map(line => { + const boundary = /^\s*(`{3,}|~{3,})/u.exec(line); + if (fence) { + // Comment syntax inside code is literal; only the original line can close it. + if (boundary && boundary[1][0] === fence[0] && boundary[1].length >= fence.length + && /^ {0,3}(?:`+|~+)[ \t]*$/u.test(line)) + fence = undefined; + return ''; + } + if (!comment && boundary) { + fence = boundary[1]; + return ''; + } + let result = ''; + let offset = 0; + while (offset < line.length) { + const marker = comment ? '-->' : ''; +/** Owned delimiters begin a line; ordinary mentions are not state. Complete legacy fenced records remain readable. */ +function readConfigurationBlock(description) { + if (description === undefined) + return { kind: 'absent' }; + let fence; + let fencedMarker = false; + let fencedStart; + let nestedFencedStart = false; + let start; + let contentStart = 0; + let block; + let offset = 0; + for (const line of description.match(/[^\n]*(?:\n|$)/gu) ?? []) { + const text = line.replace(/\r?\n$/u, ''); + const starts = /^ {0,3}[ \t]*$/u.test(text); + const boundary = /^ {0,3}(`{3,}|~{3,})(.*)$/u.exec(text); + if (fence) { + fencedMarker || (fencedMarker = starts || ends); + if (starts) { + if (fencedStart !== undefined) + nestedFencedStart = true; + else + fencedStart = offset + text.indexOf(exports.CONFIGURATION_START); + } + const end = text.indexOf(exports.CONFIGURATION_END); + if (fencedStart !== undefined && end >= 0 && !text.slice(end + exports.CONFIGURATION_END.length).trim()) { + if (block || nestedFencedStart) + return { kind: 'invalid' }; + block = { kind: 'present', start: fencedStart, end: offset + end + exports.CONFIGURATION_END.length, + content: description.slice(fencedStart + exports.CONFIGURATION_START.length, offset + end) }; + fencedStart = undefined; + } + if (boundary && boundary[1][0] === fence[0] && boundary[1].length >= fence.length && !boundary[2].trim()) { + fence = undefined; + fencedMarker = false; + fencedStart = undefined; + nestedFencedStart = false; + } + } + else if (start !== undefined || starts) { + if (starts) { + if (start !== undefined || block) + return { kind: 'invalid' }; + start = offset + text.indexOf(exports.CONFIGURATION_START); + contentStart = start + exports.CONFIGURATION_START.length; + } + const end = text.indexOf(exports.CONFIGURATION_END); + if (end >= 0 && !text.slice(end + exports.CONFIGURATION_END.length).trim()) { + block = { kind: 'present', start: start, end: offset + end + exports.CONFIGURATION_END.length, + content: description.slice(contentStart, offset + end) }; + start = undefined; + } + } + else if (ends) + return { kind: 'invalid' }; + else if (boundary && (boundary[1][0] !== '`' || !boundary[2].includes('`'))) + fence = boundary[1]; + offset += line.length; + } + // A legacy block behind an unclosed fence is ambiguous: never silently discard its state. + if (start !== undefined || fence && fencedMarker) + return { kind: 'invalid' }; + return block ?? { kind: 'absent', ...(fence ? { closingFence: fence } : {}) }; +} +function writeConfigurationBlock(description, content) { + const block = readConfigurationBlock(description); + if (block.kind === 'invalid') + return undefined; + const replacement = `${exports.CONFIGURATION_START}\n${content}\n${exports.CONFIGURATION_END}`; + if (block.kind === 'present') + return description.slice(0, block.start) + replacement + description.slice(block.end); + // Closing an otherwise empty dangling example preserves its rendered text and keeps new state outside it. + return `${description}\n\n${block.closingFence ? `${block.closingFence}\n\n` : ''}${replacement}`; +} + + /***/ }), /***/ 58043: @@ -102907,11 +104666,13 @@ function getBranchSyncConflictsPrompt(params) { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.BUGBOT_FINDING_GROUNDING_INSTRUCTION = void 0; exports.getBugbotPrompt = getBugbotPrompt; /** * Prompt for Bugbot detection (detect potential problems on push). */ const fill_1 = __nccwpck_require__(2559); +exports.BUGBOT_FINDING_GROUNDING_INSTRUCTION = 'Before returning a finding, try to disprove it against the exact reviewed source. Read effective repository configuration and inherited library/protocol defaults before inferring behavior from a missing command flag. Trace short-circuit guards, validation helpers and the actual caller/render path before claiming that an unsafe branch is reachable or that separate call sites coexist. Recompute arithmetic and check cited line numbers against the current file/diff. If your evidence refutes the alleged defect, withdraw the finding entirely; do not publish a contradictory or self-refuting report. These checks apply equally to low/info severity. Report a confirmed failure when those protections are absent; do not assume they exist.'; const TEMPLATE = `You are analyzing the latest code changes for potential bugs and issues. Write every human-readable finding title, description, evidence, and suggestion in {{targetLocale}}. Preserve identifiers, code, symbols, paths, refs, commands, and URLs verbatim. Echo \`outputLocale\` exactly as \`{{targetLocale}}\`. @@ -102947,6 +104708,8 @@ For every finding: - include the nearest stable \`symbol\` and a minimal exact \`codeSnippet\` when available so the finding can survive rebases, line movement, and file renames. - when a fix is a safe replacement of exactly the reported line range, include only the replacement text in \`suggestedCode\`; otherwise omit it. +${exports.BUGBOT_FINDING_GROUNDING_INSTRUCTION} + Return every finding field required by the response schema. Use null for file, line, endLine, severity, confidence, category, evidence, suggestion, symbol, codeSnippet, or suggestedCode when that value does not safely apply. Only include files outside the ignore list. {{previousBlock}} @@ -103850,6 +105613,7 @@ exports.buildBugbotBenchmarkPrompt = buildBugbotBenchmarkPrompt; const schema_1 = __nccwpck_require__(16808); const untrusted_content_1 = __nccwpck_require__(67057); const prepare_bugbot_findings_policy_1 = __nccwpck_require__(3496); +const bugbot_1 = __nccwpck_require__(56998); const MAX_BENCHMARK_CASES = 200; /** Executes the real configured findings agent against every case, sequentially. */ async function runBugbotBenchmarkAgent(corpus, agent, configuration) { @@ -103877,6 +105641,8 @@ function buildBugbotBenchmarkPrompt(testCase) { You are running a controlled Bugbot quality benchmark. Review only the supplied synthetic diff. Report actionable defects caused by added or changed code; do not report style, pre-existing issues, or speculative concerns. Return an empty findings array when the change is safe. +${bugbot_1.BUGBOT_FINDING_GROUNDING_INSTRUCTION} + Language: ${testCase.language} Repository-relative file: ${testCase.file} First displayed line: ${testCase.startLine} @@ -104919,11 +106685,13 @@ const setup_approval_workflow_1 = __nccwpck_require__(9512); const setup_workflow_upgrade_1 = __nccwpck_require__(85493); const setup_installation_review_1 = __nccwpck_require__(23799); const repository_agent_guidance_policy_1 = __nccwpck_require__(67402); +const setup_verification_action_1 = __nccwpck_require__(12471); /** * Ensure .github, .github/workflows and .github/ISSUE_TEMPLATE exist; create them if missing. * @param cwd - Directory (repo root) */ function ensureGitHubDirs(cwd) { + (0, setup_verification_action_1.inspectSetupVerificationActionPath)(cwd); const githubDir = path.join(cwd, '.github'); const workflowsDir = path.join(cwd, '.github', 'workflows'); const issueTemplateDir = path.join(cwd, '.github', 'ISSUE_TEMPLATE'); @@ -104956,6 +106724,7 @@ function copySetupFiles(cwd, setupDirOverride, features, options = {}) { const installationReview = options.setupConfiguration && (0, setup_installation_review_1.inspectSetupInstallation)(cwd, options.setupConfiguration, setupDir); if (installationReview?.blockers.length) throw new Error(installationReview.blockers.join(' ')); + const verificationAction = (0, setup_verification_action_1.createSetupVerificationAction)(cwd, options.verificationActionState); const preserveSourceGuidance = installationReview?.assets.some(asset => asset.path === repository_agent_guidance_policy_1.REPOSITORY_AGENT_GUIDE_PATH && asset.status === 'source-only'); const sourceInstallation = installationReview?.assets.some(asset => asset.path.startsWith('.github/workflows/') && asset.status === 'source-only'); const snapshotContent = options.setupConfiguration && (0, setup_installation_review_1.renderSetupRunnerSnapshot)(options.setupConfiguration); @@ -105010,7 +106779,7 @@ function copySetupFiles(cwd, setupDirOverride, features, options = {}) { snapshot.copied++; } } - return [retired, workflows, approvalWorkflow, issueTemplates, pullRequestTemplate, guidance, snapshot].reduce((total, current) => ({ + return [verificationAction, retired, workflows, approvalWorkflow, issueTemplates, pullRequestTemplate, guidance, snapshot].reduce((total, current) => ({ copied: total.copied + current.copied, skipped: total.skipped + current.skipped, }), { copied: 0, skipped: 0 }); @@ -105224,6 +106993,9 @@ const setup_workflow_upgrade_1 = __nccwpck_require__(85493); const setup_approval_workflow_1 = __nccwpck_require__(9512); const sensitive_text_1 = __nccwpck_require__(47122); const repository_agent_guidance_policy_1 = __nccwpck_require__(67402); +const setup_verification_action_1 = __nccwpck_require__(33156); +const setup_verification_action_2 = __nccwpck_require__(12471); +const copilot_comment_workflow_1 = __nccwpck_require__(33430); exports.SETUP_RUNNER_SNAPSHOT = '.copilot/runner-profile.json'; const object = (value) => value !== null && typeof value === 'object' && !Array.isArray(value) ? value : undefined; @@ -105265,6 +107037,22 @@ function inspectSetupInstallation(root, configuration, setup = (0, node_path_1.j const jobs = []; const changes = []; const blockers = []; + let action; + try { + action = (0, setup_verification_action_2.inspectSetupVerificationActionPath)(root); + } + catch (error) { + action = 'blocked'; + blockers.push(error instanceof Error ? error.message : 'Verification setup path could not be inspected.'); + } + const verificationSetup = { action, enabled: configuration.repository.verificationSetup ?? false, + mainBranch: configuration.repository.mainBranch }; + assets.push({ path: setup_verification_action_1.SETUP_VERIFICATION_ACTION_PATH, enabled: verificationSetup.enabled, + status: action === 'create' ? 'missing' : action === 'preserve' ? 'customized' : 'incompatible' }); + if (action === 'blocked') + return { assets, jobs, changes, blockers, verificationSetup }; + if (action === 'create') + changes.push({ path: setup_verification_action_1.SETUP_VERIFICATION_ACTION_PATH, before: null, after: (0, setup_verification_action_2.readSetupVerificationActionStarter)() }); const addJobs = (file, content, retained) => { const documents = (0, js_yaml_1.loadAll)(content); if (documents.length !== 1) @@ -105273,7 +107061,7 @@ function inspectSetupInstallation(root, configuration, setup = (0, node_path_1.j if (!parsedJobs) throw new Error('Workflow jobs are unavailable for review.'); for (const [job, raw] of Object.entries(parsedJobs)) { - const runsOn = object(raw)?.['runs-on']; + const runsOn = (0, copilot_comment_workflow_1.copilotCommentRunner)(object(raw)); if (runsOn === undefined) continue; // reusable workflow calls have no runner jobs.push({ file, job, role: (0, setup_runner_policy_1.setupRunnerRole)(file, job) ?? 'validation', @@ -105361,7 +107149,7 @@ function inspectSetupInstallation(root, configuration, setup = (0, node_path_1.j before: before === undefined ? null : (0, sensitive_text_1.redactSensitiveText)(before), after: (0, sensitive_text_1.redactSensitiveText)(after) }); if (after !== undefined && before !== undefined && !compatibleSetupRunnerSnapshot(before)) blockers.push('Runner snapshot is incompatible. Retain it or restore a supported version before replacing routing.'); - return { assets, jobs, changes, blockers }; + return { assets, jobs, changes, blockers, verificationSetup }; } @@ -105380,6 +107168,7 @@ const js_yaml_1 = __nccwpck_require__(783); const node_util_1 = __nccwpck_require__(47261); const setup_runner_policy_1 = __nccwpck_require__(91027); const action_types_1 = __nccwpck_require__(19625); +const copilot_comment_workflow_1 = __nccwpck_require__(33430); const object = (value) => value !== null && typeof value === 'object' && !Array.isArray(value) ? value : undefined; const document = (value) => { try { @@ -105401,6 +107190,8 @@ const runner = (value) => labels(value) || !!object(value) && (object(value).labels === undefined || labels(object(value).labels)); const copilotCommands = new Set(Object.values(action_types_1.ACTIONS)); const callsRootAction = (jobs) => !!jobs && Object.values(jobs).some(job => { + if (object(job)?.uses === copilot_comment_workflow_1.COPILOT_COMMENT_SELF_WORKFLOW) + return true; const steps = object(job)?.steps; return Array.isArray(steps) && steps.some(step => { const invocation = object(step); @@ -105463,6 +107254,32 @@ function renderSetupWorkflowUpgrade(template, existing, selection) { const templateJobs = object(document(template)?.jobs); if (!previousJobs || !templateJobs) throw new Error('Workflow jobs cannot be inspected; review the workflow separately.'); + if (Object.values(templateJobs).some(job => (0, copilot_comment_workflow_1.isCopilotCommentWorkflow)(object(job)?.uses))) { + const parsed = document(template); + const jobs = object(parsed.jobs); + let changed = false; + for (const [name, value] of Object.entries(jobs)) { + const job = object(value); + if (!(0, copilot_comment_workflow_1.isCopilotCommentWorkflow)(job.uses)) + throw new Error('Mixed comment workflow jobs require separate workflow review before setup.'); + const previousJob = object(previousJobs[name]); + if (Array.isArray(previousJob?.steps) && previousJob.steps.some(raw => { + const uses = object(raw)?.uses; + return typeof uses !== 'string' || !(uses.startsWith('actions/checkout@') + || /^vypdev\/copilot@[^\s]+$/u.test(uses) || uses === './.git/copilot-verification-setup'); + })) + throw new Error('Custom comment job steps require migration to the reviewed repository verification setup action before switching to the reusable workflow. Review the workflow separately.'); + const retained = (0, setup_runner_policy_1.selectedSetupRunsOn)(selection?.runners, selection && (0, setup_runner_policy_1.setupRunnerRole)(selection.file, name)) + ?? (0, copilot_comment_workflow_1.copilotCommentRunner)(previousJob) ?? (0, copilot_comment_workflow_1.copilotCommentRunner)(job); + if (!runner(retained)) + throw new Error('Existing runner selection is invalid; review the workflow separately.'); + if (JSON.stringify(retained).includes('${{') && existing !== template) + throw new Error('Dynamic runner selection requires separate workflow review before setup.'); + changed || (changed = !(0, node_util_1.isDeepStrictEqual)(retained, (0, copilot_comment_workflow_1.copilotCommentRunner)(job))); + job.with = { ...object(job.with), 'runs-on': JSON.stringify(retained) }; + } + return changed ? (0, js_yaml_1.dump)(parsed, { noRefs: true, lineWidth: -1 }) : template; + } const lines = template.split('\n'); let job = ''; let insideJobs = false; @@ -117293,6 +119110,14 @@ module.exports = JSON.parse('{"single":{"topLeft":"┌","top":"─","topRight":" "use strict"; module.exports = JSON.parse('{"revision":"2026-10-02.standalone.1","providers":{"codex":{"executable":"codex","reviewedVersion":"codex-cli 0.156.1","legacyNpmPackage":"@openai/codex","installation":{"unixScript":"https://chatgpt.com/codex/install.sh","windowsScript":"https://chatgpt.com/codex/install.ps1"}},"opencode":{"executable":"opencode","reviewedVersion":"1.18.3","legacyNpmPackage":"opencode-ai","installation":{"unixScript":"https://opencode.ai/install","windowsReleaseApi":"https://api.github.com/repos/anomalyco/opencode/releases/latest"}},"cursor":{"executable":"agent","reviewedVersion":"2026.09.10-fd3934a","installation":{"unixScript":"https://cursor.com/install","windowsScript":"https://cursor.com/install?win32=true"}}}}'); +/***/ }), + +/***/ 78593: +/***/ ((module) => { + +"use strict"; +module.exports = JSON.parse('{"repository-locale":"${{ vars.REPOSITORY_LOCALE || \'en-US\' }}","issues-locale":"${{ vars.ISSUES_LOCALE || \'\' }}","pull-requests-locale":"${{ vars.PULL_REQUESTS_LOCALE || \'\' }}","ai-ignore-files":"${{ vars.AI_IGNORE_FILES || \'build/*\' }}","debug":"${{ vars.DEBUG }}","main-branch":"${{ vars.MAIN_BRANCH || \'master\' }}","development-branch":"${{ vars.DEVELOPMENT_BRANCH || \'develop\' }}","feature-tree":"${{ vars.FEATURE_TREE || \'feature\' }}","bugfix-tree":"${{ vars.BUGFIX_TREE || \'bugfix\' }}","hotfix-tree":"${{ vars.HOTFIX_TREE || \'hotfix\' }}","release-tree":"${{ vars.RELEASE_TREE || \'release\' }}","docs-tree":"${{ vars.DOCS_TREE || \'docs\' }}","chore-tree":"${{ vars.CHORE_TREE || \'chore\' }}","issue-managed-branches":"${{ vars.ISSUE_MANAGED_BRANCHES || \'true\' }}","pre-branch-sdd":"${{ vars.PRE_BRANCH_SDD || \'false\' }}","verification-setup":"${{ vars.VERIFICATION_SETUP || \'false\' }}","issue-workflow-profile":"${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || \'\' }}","reopen-issue-on-push":"${{ vars.REOPEN_ISSUE_ON_PUSH || \'true\' }}","desired-assignees-count":"${{ vars.DESIRED_ASSIGNEES_COUNT || \'1\' }}","desired-reviewers-count":"${{ vars.DESIRED_REVIEWERS_COUNT || \'1\' }}","commit-prefix-transforms":"${{ vars.COMMIT_PREFIX_TRANSFORMS || \'replace-slash\' }}","ai-pull-request-description-mode":"${{ vars.AI_PULL_REQUEST_DESCRIPTION_MODE || \'replace\' }}","ai-members-only":"${{ vars.AI_MEMBERS_ONLY || \'false\' }}","ai-include-reasoning":"${{ vars.AI_INCLUDE_REASONING || \'false\' }}","bugbot-severity":"${{ vars.BUGBOT_SEVERITY || \'low\' }}","bugbot-comment-limit":"${{ vars.BUGBOT_COMMENT_LIMIT || \'20\' }}","bugbot-fix-verify-commands":"${{ vars.BUGBOT_AUTOFIX_VERIFY_COMMANDS }}","bugbot-dry-run":"${{ vars.BUGBOT_DRY_RUN || \'false\' }}","bugbot-effort":"${{ vars.BUGBOT_EFFORT || \'smart\' }}","bugbot-review-drafts":"${{ vars.BUGBOT_REVIEW_DRAFTS || \'false\' }}","bugbot-trace-rules":"${{ vars.BUGBOT_TRACE_RULES || \'false\' }}","bugbot-suggested-changes":"${{ vars.BUGBOT_SUGGESTED_CHANGES || \'true\' }}","bugbot-telemetry":"${{ vars.BUGBOT_TELEMETRY || \'true\' }}","bugbot-fail-on-unresolved":"${{ vars.BUGBOT_FAIL_ON_UNRESOLVED || \'false\' }}","bugbot-organization-rules":"${{ vars.BUGBOT_ORGANIZATION_RULES }}","project-column-issue-created":"${{ vars.PROJECT_COLUMN_ISSUE_CREATED || \'Todo\' }}","project-column-pull-request-created":"${{ vars.PROJECT_COLUMN_PULL_REQUEST_CREATED || \'In Progress\' }}","project-column-issue-in-progress":"${{ vars.PROJECT_COLUMN_ISSUE_IN_PROGRESS || \'In Progress\' }}","project-column-pull-request-in-progress":"${{ vars.PROJECT_COLUMN_PULL_REQUEST_IN_PROGRESS || \'In Progress\' }}","agent-provider":"${{ vars.AGENT_PROVIDER || \'codex\' }}","agent-model-provider":"${{ vars.AGENT_MODEL_PROVIDER || \'openai\' }}","agent-model":"${{ vars.AGENT_MODEL || \'gpt-6-luna\' }}","agent-effort":"${{ vars.AGENT_EFFORT }}","agent-executable":"${{ vars.AGENT_EXECUTABLE }}","findings-provider":"${{ vars.FINDINGS_PROVIDER }}","findings-model-provider":"${{ vars.FINDINGS_MODEL_PROVIDER }}","findings-model":"${{ vars.FINDINGS_MODEL }}","findings-effort":"${{ vars.FINDINGS_EFFORT }}","findings-executable":"${{ vars.FINDINGS_EXECUTABLE }}","fixer-provider":"${{ vars.FIXER_PROVIDER }}","fixer-model-provider":"${{ vars.FIXER_MODEL_PROVIDER }}","fixer-model":"${{ vars.FIXER_MODEL }}","fixer-effort":"${{ vars.FIXER_EFFORT }}","fixer-executable":"${{ vars.FIXER_EXECUTABLE }}","planner-provider":"${{ vars.PLANNER_PROVIDER }}","planner-model-provider":"${{ vars.PLANNER_MODEL_PROVIDER }}","planner-model":"${{ vars.PLANNER_MODEL }}","planner-effort":"${{ vars.PLANNER_EFFORT }}","planner-executable":"${{ vars.PLANNER_EXECUTABLE }}","reviewer-provider":"${{ vars.REVIEWER_PROVIDER }}","reviewer-model-provider":"${{ vars.REVIEWER_MODEL_PROVIDER }}","reviewer-model":"${{ vars.REVIEWER_MODEL }}","reviewer-effort":"${{ vars.REVIEWER_EFFORT }}","reviewer-executable":"${{ vars.REVIEWER_EXECUTABLE }}","tester-provider":"${{ vars.TESTER_PROVIDER }}","tester-model-provider":"${{ vars.TESTER_MODEL_PROVIDER }}","tester-model":"${{ vars.TESTER_MODEL }}","tester-effort":"${{ vars.TESTER_EFFORT }}","tester-executable":"${{ vars.TESTER_EXECUTABLE }}","project-ids":"${{ vars.PROJECT_IDS }}"}'); + /***/ }) /******/ }); diff --git a/build/github_action/index.js b/build/github_action/index.js index fc8a49c6b..1d4d40ac2 100644 --- a/build/github_action/index.js +++ b/build/github_action/index.js @@ -36897,6 +36897,7 @@ var __importStar = (this && this.__importStar) || (function () { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.runGitHubAction = runGitHubAction; exports.runGitHubActionEntry = runGitHubActionEntry; +const native_verification_controller_1 = __nccwpck_require__(71046); const issue_completion_composition_root_1 = __nccwpck_require__(63719); const core = __importStar(__nccwpck_require__(75855)); const github = __importStar(__nccwpck_require__(78227)); @@ -37081,7 +37082,16 @@ async function runGitHubActionEntry(run = runGitHubAction) { catch (cause) { const semanticError = (0, application_error_1.toApplicationError)(cause, 'workflow.failed', 'GitHub Action execution failed.'); (0, logger_1.logError)(semanticError); - core.setFailed((0, application_error_presentation_policy_1.renderApplicationErrorText)(semanticError, earlyGithubActionErrorMessage())); + const message = earlyGithubActionErrorMessage(); + core.setFailed((0, application_error_presentation_policy_1.renderApplicationErrorText)(semanticError, message)); + if (semanticError.recovery?.id.startsWith('stored-configuration-')) { + try { + await (0, github_action_summary_composition_root_1.createGithubActionSummaryCompositionRoot)().publish((0, application_error_presentation_policy_1.renderApplicationErrorMarkdown)(semanticError, message)); + } + catch (summaryCause) { + (0, logger_1.logError)((0, application_error_1.toApplicationError)(summaryCause, 'provider.unavailable', 'Unable to publish the configuration failure summary.')); + } + } } }); } @@ -37097,7 +37107,7 @@ function earlyGithubActionErrorMessage() { // Only auto-run when executed as the action entry (not when imported by tests) /* istanbul ignore next -- the bundled production entry is covered by the Action smoke path. */ if (typeof process.env.JEST_WORKER_ID === 'undefined') { - void runGitHubActionEntry(); + void runGitHubActionEntry(() => (0, native_verification_controller_1.runNativeVerificationEntry)(runGitHubActionEntry)); } @@ -37522,6 +37532,7 @@ async function buildGithubActionExecution(input) { commitPrefixBuilder: getCommitPrefixBuilder(getInput), issue: (0, configuration_builders_1.buildIssue)((0, input_boolean_policy_1.parseIssueWorkflowBoolean)(getInput(input_keys_1.INPUT_KEYS.ISSUE_MANAGED_BRANCHES), input_keys_1.INPUT_KEYS.ISSUE_MANAGED_BRANCHES, true), (0, input_boolean_policy_1.isEnabledInput)(getInput(input_keys_1.INPUT_KEYS.REOPEN_ISSUE_ON_PUSH)), (0, input_number_policy_1.parseIntegerInput)(getInput(input_keys_1.INPUT_KEYS.DESIRED_ASSIGNEES_COUNT), 0), eventInputs), preBranchSdd: (0, input_boolean_policy_1.parseIssueWorkflowBoolean)(getInput(input_keys_1.INPUT_KEYS.PRE_BRANCH_SDD), input_keys_1.INPUT_KEYS.PRE_BRANCH_SDD, false), + verificationSetup: (0, input_boolean_policy_1.parseIssueWorkflowBoolean)(getInput(input_keys_1.INPUT_KEYS.VERIFICATION_SETUP), input_keys_1.INPUT_KEYS.VERIFICATION_SETUP, false), pullRequest: (0, configuration_builders_1.buildPullRequest)((0, input_number_policy_1.parseIntegerInput)(getInput(input_keys_1.INPUT_KEYS.PULL_REQUEST_DESIRED_ASSIGNEES_COUNT), 0), (0, input_number_policy_1.parseIntegerInput)(getInput(input_keys_1.INPUT_KEYS.PULL_REQUEST_DESIRED_REVIEWERS_COUNT), 0), eventInputs), emoji: (0, configuration_builders_1.buildEmoji)(getInput(input_keys_1.INPUT_KEYS.EMOJI_LABELED_TITLE) === 'true', getInput(input_keys_1.INPUT_KEYS.BRANCH_MANAGEMENT_EMOJI)), tokens: (0, configuration_builders_1.buildTokens)(token), @@ -38737,6 +38748,7 @@ exports.INPUT_KEYS = { // Issue ISSUE_MANAGED_BRANCHES: 'issue-managed-branches', PRE_BRANCH_SDD: 'pre-branch-sdd', + VERIFICATION_SETUP: 'verification-setup', REOPEN_ISSUE_ON_PUSH: 'reopen-issue-on-push', DESIRED_ASSIGNEES_COUNT: 'desired-assignees-count', // Pull Request @@ -38857,6 +38869,46 @@ function approvalDiagnosticError(diagnostic) { } +/***/ }), + +/***/ 82937: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.BugbotMutationError = void 0; +exports.bugbotMutationError = bugbotMutationError; +const application_error_1 = __nccwpck_require__(75999); +const pull_request_review_errors_1 = __nccwpck_require__(46445); +class BugbotMutationError extends application_error_1.ApplicationError { + constructor(diagnostic) { + super(diagnostic.errorCode, `Bugbot ${diagnostic.stage} failed: operation=${diagnostic.operation}; finding=${diagnostic.findingId}; affected=${diagnostic.affectedCount}; ${diagnostic.providerStatus}; provider-reference=${diagnostic.providerReference}. Completed effects are retained; correct the named cause and recheck the same target.`); + this.diagnostic = diagnostic; + } +} +exports.BugbotMutationError = BugbotMutationError; +function bugbotMutationError(cause, stage, findingIds, fallback, affectedCount = findingIds.length) { + if (cause instanceof BugbotMutationError) + return cause; + const provider = cause instanceof pull_request_review_errors_1.PullRequestReviewOperationError ? cause : undefined; + const status = provider?.providerStatus; + const errorCode = status === 401 ? 'authorization.credential-invalid' : status === 403 ? 'authorization.denied' + : status === 404 ? 'provider.not-found' : status === 409 ? 'provider.conflict' + : status === 429 ? 'provider.rate-limited' + : status === 408 || status === 425 ? 'provider.unavailable' + : status && status < 500 ? 'provider.contract-invalid' : 'provider.unavailable'; + const first = findingIds[0]; + return new BugbotMutationError(Object.freeze({ + stage, operation: provider?.operation ?? fallback, + findingId: typeof first === 'string' && /^[A-Za-z0-9_./:-]{1,200}$/.test(first) ? first : 'unavailable', + affectedCount: Math.min(affectedCount, 10000), + providerStatus: status ? `http-${status}` : 'http-unavailable', + providerReference: provider?.providerReference ?? 'unavailable', errorCode, + })); +} + + /***/ }), /***/ 12183: @@ -40666,7 +40718,26 @@ const SPANISH_CONTENT = Object.freeze({ retainedState: PRESERVED_STATE_ES, }), }); +const STORED_CONFIGURATION_ACTION_EN = 'A maintainer must review {recoveryGuide}. Preserve a copy before removing only a verified obsolete unmanaged block. If managed branch, release, hotfix or orchestration state may exist, stop and restore verified supported state with a maintainer. Do not just add a schema version or delete managed state. Correct the configuration before rerunning; retrying unchanged state will fail again.'; +const STORED_CONFIGURATION_ACTION_ES = 'Un mantenedor debe revisar {recoveryGuide}. Conserva una copia antes de retirar solo un bloque obsoleto confirmado como no gestionado. Si puede existir estado gestionado de ramas, releases, hotfixes u orquestación, detente y restaura estado compatible verificado con un mantenedor. No añadas simplemente una versión de esquema ni borres estado gestionado. Corrige la configuración antes de reejecutar; el mismo estado volverá a fallar.'; +const STORED_CONFIGURATION_RETAINED_EN = 'The issue/PR description and stored configuration were not changed by this read.'; +const STORED_CONFIGURATION_RETAINED_ES = 'Esta lectura no modificó la descripción de la issue/PR ni su configuración almacenada.'; const ENGLISH_RECOVERY_CONTENT = Object.freeze({ + 'stored-configuration-schema-missing': Object.freeze({ + impact: 'Automation stopped for issue/PR #{issueNumber}: the stored configuration has no schema version; version {expectedVersion} is required.', + action: STORED_CONFIGURATION_ACTION_EN, + retainedState: STORED_CONFIGURATION_RETAINED_EN, + }), + 'stored-configuration-schema-unsupported': Object.freeze({ + impact: 'Automation stopped for issue/PR #{issueNumber}: stored schema version {actualVersion} is unsupported; version {expectedVersion} is required.', + action: STORED_CONFIGURATION_ACTION_EN, + retainedState: STORED_CONFIGURATION_RETAINED_EN, + }), + 'stored-configuration-invalid': Object.freeze({ + impact: 'Automation stopped for issue/PR #{issueNumber}: the stored configuration, markers or schema value are malformed; valid schema version {expectedVersion} is required.', + action: STORED_CONFIGURATION_ACTION_EN, + retainedState: STORED_CONFIGURATION_RETAINED_EN, + }), 'closed-issue-reconciliation-failed': Object.freeze({ impact: 'Issue cleanup remains unverified: {resultId}, phase {phase}; native state {state}, reason {reason}.', action: 'Inspect the closed-issue or merged-PR run and current native state. Retry cleanup only if the issue is still closed with the intended reason; leave reopened work open. Resolve the named failure before retrying.', @@ -40682,6 +40753,26 @@ const ENGLISH_RECOVERY_CONTENT = Object.freeze({ action: 'Inspect the rejected paths in the workflow and correct the workspace before retrying.', retainedState: 'The normal commit and push steps were skipped. Verify the current state before retrying.', }), + 'sdd-draft-case-identity-invalid': Object.freeze({ + impact: 'SDD publication stopped after one automatic repair: case IDs collide with an owning SDD or are ambiguous.', + action: 'Review the draft tables; use distinct fully qualified case IDs and preserve the baseline inventory. Retry the same issue workflow.', + retainedState: 'Existing answers and published SDDs were preserved; no draft was published. Publication checks do not establish runtime acceptance.', + }), + 'sdd-draft-case-budget-invalid': Object.freeze({ + impact: 'SDD publication stopped after one automatic repair: per-area allocations disagree with the distinct case inventory.', + action: 'Review the draft tables; reconcile each area and the total with the enumerated cases. Retry the same issue workflow.', + retainedState: 'Existing answers and published SDDs were preserved; no draft was published. Publication checks do not establish runtime acceptance.', + }), + 'sdd-draft-requirement-mapping-invalid': Object.freeze({ + impact: 'SDD publication stopped after one automatic repair: requirements and case mappings are incomplete or inconsistent.', + action: 'Review the draft tables; map every requirement to defined cases and match the reverse links. Retry the same issue workflow.', + retainedState: 'Existing answers and published SDDs were preserved; no draft was published. Publication checks do not establish runtime acceptance.', + }), + 'sdd-draft-repository-path-invalid': Object.freeze({ + impact: 'SDD publication stopped after one automatic repair: cited repository paths cannot be verified at the immutable base.', + action: 'Review the draft tables; correct existing paths or explicitly declare intended new files. Retry the same issue workflow.', + retainedState: 'Existing answers and published SDDs were preserved; no draft was published. Publication checks do not establish runtime acceptance.', + }), 'sdd-draft-format-invalid': Object.freeze({ impact: 'SDD preparation stopped because the draft still lacked required headings or a numeric test budget after one automatic repair.', action: 'Retry SDD preparation with the canonical specification template and the explicit acceptance requirements.', @@ -40744,6 +40835,21 @@ const ENGLISH_RECOVERY_CONTENT = Object.freeze({ }), }); const SPANISH_RECOVERY_CONTENT = Object.freeze({ + 'stored-configuration-schema-missing': Object.freeze({ + impact: 'La automatización se detuvo para la issue/PR #{issueNumber}: la configuración almacenada no tiene versión de esquema; se requiere la versión {expectedVersion}.', + action: STORED_CONFIGURATION_ACTION_ES, + retainedState: STORED_CONFIGURATION_RETAINED_ES, + }), + 'stored-configuration-schema-unsupported': Object.freeze({ + impact: 'La automatización se detuvo para la issue/PR #{issueNumber}: la versión de esquema almacenada {actualVersion} no es compatible; se requiere la versión {expectedVersion}.', + action: STORED_CONFIGURATION_ACTION_ES, + retainedState: STORED_CONFIGURATION_RETAINED_ES, + }), + 'stored-configuration-invalid': Object.freeze({ + impact: 'La automatización se detuvo para la issue/PR #{issueNumber}: la configuración almacenada, sus delimitadores o el valor del esquema no son válidos; se requiere un esquema válido de versión {expectedVersion}.', + action: STORED_CONFIGURATION_ACTION_ES, + retainedState: STORED_CONFIGURATION_RETAINED_ES, + }), 'closed-issue-reconciliation-failed': Object.freeze({ impact: 'La limpieza de la issue sigue sin verificarse: {resultId}, fase {phase}; estado nativo {state}, motivo {reason}.', action: 'Revisa la ejecución de cierre o de la PR fusionada y el estado nativo actual. Reintenta la limpieza solo si la issue sigue cerrada con el motivo previsto; conserva abierto el trabajo reabierto. Resuelve el fallo indicado antes de reintentar.', @@ -40759,6 +40865,26 @@ const SPANISH_RECOVERY_CONTENT = Object.freeze({ action: 'Revisa las rutas rechazadas en la ejecución y corrige el espacio de trabajo antes de reintentar.', retainedState: 'Se omitieron los pasos normales de commit y push. Comprueba el estado actual antes de reintentar.', }), + 'sdd-draft-case-identity-invalid': Object.freeze({ + impact: 'La publicación del SDD se detuvo tras un intento automático de corrección: los identificadores de casos coinciden con un SDD existente o son ambiguos.', + action: 'Revisa las tablas del borrador; usa identificadores completos y distintos y conserva el inventario original. Reintenta el workflow de la misma incidencia.', + retainedState: 'Se conservaron las respuestas y los SDD publicados; no se publicó ningún borrador. Estas comprobaciones no demuestran la aceptación en ejecución.', + }), + 'sdd-draft-case-budget-invalid': Object.freeze({ + impact: 'La publicación del SDD se detuvo tras un intento automático de corrección: las asignaciones por área no coinciden con el inventario de casos distintos.', + action: 'Revisa las tablas del borrador; reconcilia cada área y el total con los casos enumerados. Reintenta el workflow de la misma incidencia.', + retainedState: 'Se conservaron las respuestas y los SDD publicados; no se publicó ningún borrador. Estas comprobaciones no demuestran la aceptación en ejecución.', + }), + 'sdd-draft-requirement-mapping-invalid': Object.freeze({ + impact: 'La publicación del SDD se detuvo tras un intento automático de corrección: los requisitos y sus casos están incompletos o son inconsistentes.', + action: 'Revisa las tablas del borrador; vincula cada requisito a casos definidos y comprueba los enlaces inversos. Reintenta el workflow de la misma incidencia.', + retainedState: 'Se conservaron las respuestas y los SDD publicados; no se publicó ningún borrador. Estas comprobaciones no demuestran la aceptación en ejecución.', + }), + 'sdd-draft-repository-path-invalid': Object.freeze({ + impact: 'La publicación del SDD se detuvo tras un intento automático de corrección: no se pueden verificar las rutas citadas en la revisión base inmutable.', + action: 'Revisa las tablas del borrador; corrige las rutas existentes o declara explícitamente los archivos nuevos previstos. Reintenta el workflow de la misma incidencia.', + retainedState: 'Se conservaron las respuestas y los SDD publicados; no se publicó ningún borrador. Estas comprobaciones no demuestran la aceptación en ejecución.', + }), 'sdd-draft-format-invalid': Object.freeze({ impact: 'La preparación del SDD se detuvo porque seguían faltando secciones obligatorias o un presupuesto numérico de pruebas tras un intento automático de corrección.', action: 'Reintenta la preparación del SDD con la plantilla canónica y los criterios de aceptación explícitos.', @@ -40873,12 +40999,16 @@ exports.buildApplicationErrorPresentation = buildApplicationErrorPresentation; exports.renderApplicationErrorText = renderApplicationErrorText; exports.renderApplicationErrorMarkdown = renderApplicationErrorMarkdown; const application_error_message_catalog_1 = __nccwpck_require__(64809); +// This trusted destination is inserted after localization, never supplied by a body or translation. +const STORED_CONFIGURATION_RECOVERY_URL = 'https://docs.page/vypdev/copilot/security-operations/operations/troubleshooting#unsupported-stored-configuration'; /** Shared semantic view model for terminal, GitHub, and API presentation. */ function buildApplicationErrorPresentation(error, message = application_error_message_catalog_1.readEnglishApplicationErrorMessage) { const descriptor = error.recovery ? `error.recovery.${error.recovery.id}` : `error.${error.code}`; - const variables = error.recovery?.variables; + const variables = error.recovery?.id.startsWith('stored-configuration-') + ? { ...error.recovery.variables, recoveryGuide: STORED_CONFIGURATION_RECOVERY_URL } + : error.recovery?.variables; return { impact: message(`${descriptor}.impact`, variables), code: error.code, @@ -41920,6 +42050,7 @@ exports.BUGBOT_MESSAGE_IDS = Object.freeze([ 'bugbot.overflow.body', 'bugbot.common.more', 'bugbot.diagnostic.operationFailed', + 'bugbot.diagnostic.findingMutationFailed', 'bugbot.diagnostic.identityUnavailable', 'bugbot.diagnostic.pullRequestCommentsFailed', 'bugbot.diagnostic.reviewThreadsFailed', @@ -42005,6 +42136,7 @@ const ENGLISH_MESSAGES = Object.freeze({ 'bugbot.overflow.heading': 'More findings (comment limit)', 'bugbot.overflow.body': Object.freeze({ one: 'There is {count} more finding that was not published as an individual comment. Review locally or in the full diff to see the list.', other: 'There are {count} more findings that were not published as individual comments. Review locally or in the full diff to see the list.' }), 'bugbot.common.more': Object.freeze({ one: 'and {count} more.', other: 'and {count} more.' }), + 'bugbot.diagnostic.findingMutationFailed': 'Finding mutation failed: stage={stage}; operation={operation}; finding={findingId}; affected={affectedCount}; {providerStatus}; provider reference={providerReference}. Completed effects are retained. Correct access/contract errors before retrying; for transient failures restore provider availability, then recheck the same PR. Recheck reconciles existing reviews and threads.', 'bugbot.diagnostic.operationFailed': 'Bugbot could not complete one or more finding mutations.', 'bugbot.diagnostic.identityUnavailable': 'The authenticated Bugbot identity is unavailable.', 'bugbot.diagnostic.pullRequestCommentsFailed': 'Unable to re-read pull request review comments.', @@ -42094,6 +42226,7 @@ const SPANISH_MESSAGES = Object.freeze({ 'bugbot.overflow.heading': 'Más hallazgos (límite de comentarios)', 'bugbot.overflow.body': Object.freeze({ one: 'Hay {count} hallazgo más que no se publicó como comentario individual. Revísalo localmente o en el diff completo para consultar la lista.', many: 'Hay {count} hallazgos más que no se publicaron como comentarios individuales. Revísalos localmente o en el diff completo para consultar la lista.', other: 'Hay {count} hallazgos más que no se publicaron como comentarios individuales. Revísalos localmente o en el diff completo para consultar la lista.' }), 'bugbot.common.more': Object.freeze({ one: 'y {count} más.', many: 'y {count} más.', other: 'y {count} más.' }), + 'bugbot.diagnostic.findingMutationFailed': 'Falló una mutación: fase={stage}; operación={operation}; hallazgo={findingId}; afectados={affectedCount}; {providerStatus}; referencia del proveedor={providerReference}. Se conservan los efectos completados. Corrige acceso/contrato antes de reintentar; para fallos transitorios restaura el proveedor y revisa la misma PR. La revisión reconcilia comentarios e hilos existentes.', 'bugbot.diagnostic.operationFailed': 'Bugbot no pudo completar una o más mutaciones de hallazgos.', 'bugbot.diagnostic.identityUnavailable': 'La identidad autenticada de Bugbot no está disponible.', 'bugbot.diagnostic.pullRequestCommentsFailed': 'No se pudieron volver a leer los comentarios del review del pull request.', @@ -42133,6 +42266,7 @@ async function resolveBugbotCatalog(locale, configuration, resolver) { } function renderBugbotDiagnostic(diagnostic, catalog) { switch (diagnostic.code) { + case 'finding-mutation-failed': return catalog.message('bugbot.diagnostic.findingMutationFailed', { ...diagnostic.mutation }); case 'operation-failed': return catalog.message('bugbot.diagnostic.operationFailed'); case 'identity-unavailable': return catalog.message('bugbot.diagnostic.identityUnavailable'); case 'snapshot-pull-request-comments-failed': return catalog.message('bugbot.diagnostic.pullRequestCommentsFailed'); @@ -42760,6 +42894,10 @@ function renderBugbotStatusCard(projection, catalogOrLocale, links) { facts.push(catalog.message('bugbot.coverage.omitted', { count: source.omittedItems })); if (source.truncatedItems > 0) facts.push(catalog.message('bugbot.coverage.truncated', { count: source.truncatedItems })); + const truncatedIds = source.truncatedItemIds?.slice(0, 50) + .filter(id => /^(?:issue:[0-9]+|review:[A-Za-z0-9_=-]+)$/.test(id) && id.length <= 160); + if (truncatedIds?.length) + facts.push(`truncated-source-ids=${truncatedIds.join(', ')}`); if (source.providerLimitReached) facts.push(catalog.message('bugbot.coverage.providerLimit')); return `- ${source.source}: ${source.status}; ${facts.join(', ')}`; @@ -42849,9 +42987,21 @@ function normalizeHistoricalSnapshot(originalBody, analyzedHeadSha, catalog) { function renderFindingRow(finding) { const label = (0, github_comment_publication_policy_1.sanitizeAgentMarkdown)(finding.title || finding.id, 500).replace(/[\r\n]+/gu, ' '); const state = stateLabel(finding.state); + const identity = finding.state === 'unknown' + ? ` — ${renderFindingId(finding.id)}` + : ''; return finding.url - ? `- ${state} — [${label}](${finding.url})` - : `- ${state} — ${label}`; + ? `- ${state} — [${label}](${finding.url})${identity}` + : `- ${state} — ${label}${identity}`; +} +function renderFindingId(value) { + const id = (0, github_comment_publication_policy_1.sanitizeAgentMarkdown)(value, 200).replace(/[\r\n]+/gu, ' '); + // A delimiter longer than every embedded backtick run keeps links, images + // and HTML inert even when the marker permits arbitrary Markdown punctuation. + let delimiter = '`'; + while (id.includes(delimiter)) + delimiter += '`'; + return `${delimiter} ${id} ${delimiter}`; } function stateLabel(state) { return `[ ] ${state}`; @@ -47706,6 +47856,8 @@ The setup runner profile selects placement; it does not install the project's la Declare reviewed version prefixes in \`.copilot/verification-prerequisites.json\` (schemaVersion 1, runtimes such as java 17, node 24, pnpm 10). Copilot checks declared versions in the credential-free verification environment before each configured verification command; a missing or incompatible runtime blocks publication. Without this optional declaration, existing verification behavior remains and no language is inferred. Java provisioning may use \`actions/setup-java\`; \`JAVA_HOME\` and \`PATH\` survive isolation, while agent credentials and tool-option injection variables do not. Do not add an unreviewed bootstrap or weaken verification to work around a missing runtime. Read [verification prerequisites and same-job setup](https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-verification-prerequisites). +The optional repository-owned composite action prepares each candidate before verification. Setup creates .github/actions/copilot-verification-setup/action.yml only if missing and preserves an existing consumer action and its assets. The shared terminal/web assistant offers explicit activation, disabled by default. Customize the generated failing placeholder before enabling; setup generation and installer PRs do not prove runtime readiness. Review \`.github/actions/copilot-verification-setup/action.yml\` and its assets onto trusted main, update generated workflows, then enable \`VERIFICATION_SETUP=true\` (Action input \`verification-setup\`, disabled by default). GitHub Actions executes the trusted snapshot before each command with a fresh private HOME; candidate changes cannot replace it. Native post steps finish before profile cleanup. Setup failure blocks verification and commit/push. The local CLI cannot execute composite actions and fails closed when opted in. Read [repository-owned setup](https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-owned-setup). + For the full contributor flow, read [repository collaboration](https://github.com/vypdev/copilot/blob/master/docs/agents/repository-collaboration.mdx). For drift and recovery, read [guidance troubleshooting](https://github.com/vypdev/copilot/blob/master/docs/agents/repository-guidance-troubleshooting.mdx). `; } @@ -47925,6 +48077,40 @@ function calculateReviewersStillNeeded(desiredCount, currentCount, confirmedCoun } +/***/ }), + +/***/ 81053: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.sddAnalysisStatusMarker = sddAnalysisStatusMarker; +exports.renderSddAnalysisStatus = renderSddAnalysisStatus; +function sddAnalysisStatusMarker(issueNumber) { + return ``; +} +const reasons = { + 'update-owner-mismatch': ['The update path does not belong to the selected catalog owner.', 'La ruta de actualización no pertenece al propietario seleccionado del catálogo.'], + 'companion-owner-unknown': ['The companion owner is absent from the catalog.', 'El propietario del SDD complementario no existe en el catálogo.'], + 'companion-path-registered': ['The companion path is already registered in the catalog.', 'La ruta del SDD complementario ya está registrada en el catálogo.'], + 'new-owner-registered': ['The proposed new capability already exists in the catalog.', 'La capacidad propuesta como nueva ya existe en el catálogo.'], + 'new-path-registered': ['The proposed new SDD path is already registered in the catalog.', 'La ruta propuesta como nueva ya está registrada en el catálogo.'], +}; +/** Stateless diagnostic, deliberately separate from the validated readiness record. */ +function renderSddAnalysisStatus(issueNumber, locale, reason) { + const spanish = /^es(?:-|$)/i.test(locale ?? ''); + const marker = sddAnalysisStatusMarker(issueNumber); + if (!reason) + return spanish + ? `## Estado del análisis del SDD\n\nEl análisis posterior ha validado la propiedad. La publicación y la preparación de la rama siguen pendientes de sus comprobaciones.\n\n${marker}` + : `## SDD analysis status\n\nA subsequent analysis validated ownership. Publication and branch readiness remain subject to their checks.\n\n${marker}`; + return spanish + ? `## Estado del SDD: análisis bloqueado\n\nNo se ha preparado ningún borrador ni publicación nueva. ${reasons[reason][1]}\n\n**Acción de mantenimiento:** Aclara en la misma issue el ID de capacidad del catálogo y la ruta: una actualización usa una ruta de ese propietario; un complemento usa un propietario existente y una ruta nueva; una capacidad nueva necesita ID y ruta sin registrar. Después vuelve a ejecutar el workflow original. Cada ejecución hace un solo análisis; no hay reparación ni reintento automático. Se conservan las respuestas, los SDD y las publicaciones anteriores.\n\n**Diagnóstico:** \`${reason}\`. La decisión rechazada no autoriza una rama ni la etiqueta de preparación.\n\n${marker}` + : `## SDD work status: analysis blocked\n\nNo draft or new publication was prepared. ${reasons[reason][0]}\n\n**Maintainer action:** Clarify the catalog capability ID and path in this same issue: an update uses a path owned by that capability; a companion uses an existing owner and a new path; a new capability needs an unregistered ID and path. Then rerun the original workflow. Each invocation performs one analysis; there is no automatic repair or retry. Existing answers, SDDs and publications are retained.\n\n**Diagnostic:** \`${reason}\`. The rejected decision authorizes no branch or readiness label.\n\n${marker}`; +} + + /***/ }), /***/ 2230: @@ -48876,6 +49062,7 @@ exports.isSetupBatchInstallationReceipt = isSetupBatchInstallationReceipt; exports.parseSetupBatchOperation = parseSetupBatchOperation; exports.validSetupBatchAssetPath = validSetupBatchAssetPath; const setup_batch_1 = __nccwpck_require__(88308); +const setup_verification_action_1 = __nccwpck_require__(33156); const uuid = /^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/u; const sha = /^[a-f0-9]{40}$/u; const digest = /^[a-f0-9]{64}$/u; @@ -48981,6 +49168,7 @@ function validSetupBatchAssetPath(path) { if (path.length > 240 || path.split('/').some(part => !part || part === '.' || part === '..') || /[^A-Za-z0-9_./-]/u.test(path)) return false; return path === 'AGENTS.md' || path === '.agents/skills/copilot-repository-workflow/SKILL.md' + || path === setup_verification_action_1.SETUP_VERIFICATION_ACTION_PATH || /^\.github\/(?:workflows|ISSUE_TEMPLATE)\/[A-Za-z0-9_.-]+\.(?:yml|yaml)$/u.test(path) || path === '.github/pull_request_template.md' || /^\.copilot\/(?:repository-profile|setup-manifest|runner-profile)\.json$/u.test(path) || path === '.copilot/AGENT_GUIDE.md' || path.startsWith('.copilot/setup-backups/'); @@ -49087,6 +49275,7 @@ function createDefaultSetupConfiguration() { choreTree: 'chore', issueManagedBranches: true, preBranchSdd: false, + verificationSetup: false, reopenIssueOnPush: true, desiredAssigneesCount: 1, desiredReviewersCount: 1, @@ -49243,6 +49432,7 @@ Object.defineProperty(exports, "buildSetupCredentialRequirements", ({ enumerable const locale_1 = __nccwpck_require__(15386); const issue_workflow_profile_1 = __nccwpck_require__(26744); const setup_issue_workflow_policy_1 = __nccwpck_require__(81182); +const setup_verification_action_1 = __nccwpck_require__(33156); const repository_agent_guidance_policy_1 = __nccwpck_require__(67402); function buildSetupPlan(configuration, mergeQueueReadiness = [], approvalReadiness = []) { const workflowFiles = (0, setup_workflow_catalog_1.enabledSetupWorkflowFiles)((0, setup_issue_workflow_policy_1.effectiveIssueWorkflowFeatures)(configuration)) @@ -49254,6 +49444,7 @@ function buildSetupPlan(configuration, mergeQueueReadiness = [], approvalReadine .filter(file => configuration.features.release !== false || file !== 'release.yml') .filter(file => configuration.features.hotfix !== false || file !== 'hotfix.yml'); const selectedFiles = [ + setup_verification_action_1.SETUP_VERIFICATION_ACTION_PATH, ...(configuration.runners && configuration.runners.mode !== 'retain' ? ['.copilot/runner-profile.json'] : []), ...workflowFiles.map(file => `workflows/${file}`), ...issueTemplateFiles.map(file => `ISSUE_TEMPLATE/${file}`), @@ -49354,6 +49545,7 @@ function buildSetupRepositoryVariables(configuration) { add('CHORE_TREE', repository.choreTree); add('ISSUE_MANAGED_BRANCHES', repository.issueManagedBranches); add('PRE_BRANCH_SDD', repository.preBranchSdd); + add('VERIFICATION_SETUP', repository.verificationSetup ?? false); add('REOPEN_ISSUE_ON_PUSH', repository.reopenIssueOnPush); add('DESIRED_ASSIGNEES_COUNT', repository.desiredAssigneesCount); add('DESIRED_REVIEWERS_COUNT', repository.desiredReviewersCount); @@ -49416,6 +49608,7 @@ function buildSetupActionInputs(configuration) { 'chore-tree': repository.choreTree, 'issue-managed-branches': String(repository.issueManagedBranches), 'pre-branch-sdd': String(repository.preBranchSdd), + 'verification-setup': String(repository.verificationSetup ?? false), 'reopen-issue-on-push': String(repository.reopenIssueOnPush), 'desired-assignees-count': String(repository.desiredAssigneesCount), 'desired-reviewers-count': String(repository.desiredReviewersCount), @@ -49861,6 +50054,9 @@ function validateSetupConfiguration(configuration, options = {}) { || typeof configuration.repository.preBranchSdd !== 'boolean') { errors.push('issue-managed-branches and pre-branch-sdd must be boolean values.'); } + if (configuration.repository.verificationSetup !== undefined && typeof configuration.repository.verificationSetup !== 'boolean') { + errors.push('verification-setup must be a boolean value.'); + } if (configuration.repository.preBranchSdd && !configuration.repository.issueManagedBranches) { errors.push('pre-branch-sdd requires issue-managed-branches.'); } @@ -50263,6 +50459,7 @@ const repositoryFields = [ ['HOTFIX_TREE', 'hotfixTree'], ['RELEASE_TREE', 'releaseTree'], ['DOCS_TREE', 'docsTree'], ['CHORE_TREE', 'choreTree'], ['ISSUE_MANAGED_BRANCHES', 'issueManagedBranches'], ['PRE_BRANCH_SDD', 'preBranchSdd'], + ['VERIFICATION_SETUP', 'verificationSetup'], ['REOPEN_ISSUE_ON_PUSH', 'reopenIssueOnPush'], ['DESIRED_ASSIGNEES_COUNT', 'desiredAssigneesCount'], ['DESIRED_REVIEWERS_COUNT', 'desiredReviewersCount'], ['INACTIVITY_THRESHOLD_HOURS', 'inactivityThresholdHours'], ['REPOSITORY_LOCALE', 'repositoryLocale'], ['ISSUES_LOCALE', 'issueLocale'], @@ -50993,6 +51190,58 @@ function verificationRuntimeMatches(required, observed) { } +/***/ }), + +/***/ 65326: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.VerificationSetupError = exports.VERIFICATION_SETUP_HELP = exports.VERIFICATION_SETUP_LIMITS = exports.VERIFICATION_SETUP_PATH = exports.VERIFICATION_SETUP_DIRECTORY = void 0; +exports.parseVerificationSetupResult = parseVerificationSetupResult; +exports.VERIFICATION_SETUP_DIRECTORY = '.github/actions/copilot-verification-setup'; +exports.VERIFICATION_SETUP_PATH = `${exports.VERIFICATION_SETUP_DIRECTORY}/action.yml`; +exports.VERIFICATION_SETUP_LIMITS = Object.freeze({ timeoutMs: 300000, resultBytes: 16384, scriptBytes: 65536, snapshotBytes: 262144, files: 32, requests: 20 }); +exports.VERIFICATION_SETUP_HELP = 'https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-owned-setup'; +/** Closed facts only. Provider/helper output and raw exception causes never cross this boundary. */ +class VerificationSetupError extends Error { + constructor(reason, sourceSha, exitCode) { + const sha = sourceSha && /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/u.test(sourceSha) ? sourceSha : 'unavailable'; + const exit = Number.isInteger(exitCode) && exitCode >= 0 && exitCode <= 255 ? ` Exit status: ${exitCode}.` : ''; + const action = reason === 'native-workflow-required' + ? 'Update the generated Copilot workflows and run this operation in GitHub Actions; the local CLI cannot execute composite actions.' + : `Review ${exports.VERIFICATION_SETUP_PATH} on the trusted main branch and rerun.`; + super(`Repository setup blocked verification (${reason}). ${action} Trusted source SHA: ${sha}.${exit} Verification, commit and push are withheld. Help: ${exports.VERIFICATION_SETUP_HELP}`); + this.reason = reason; + this.exitCode = exitCode; + this.name = 'VerificationSetupError'; + } +} +exports.VerificationSetupError = VerificationSetupError; +function record(value) { + return !!value && typeof value === 'object' && !Array.isArray(value); +} +function pathString(value) { + return typeof value === 'string' && value.length > 0 && value.length <= 2048 + && ![...value].some(character => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127); +} +/** Filesystem containment is checked by the adapter, after this closed schema is parsed. */ +function parseVerificationSetupResult(value) { + if (!record(value) || value.schemaVersion !== 1 || Object.keys(value).some(key => !['schemaVersion', 'path', 'environment'].includes(key))) { + throw new VerificationSetupError('result-invalid'); + } + const paths = value.path === undefined ? [] : value.path; + const environment = value.environment === undefined ? {} : value.environment; + if (!Array.isArray(paths) || paths.length > 8 || !paths.every(pathString) || new Set(paths).size !== paths.length + || !record(environment) || Object.keys(environment).some(key => key !== 'JAVA_HOME') + || ('JAVA_HOME' in environment && !pathString(environment.JAVA_HOME))) { + throw new VerificationSetupError('result-invalid'); + } + return Object.freeze({ path: Object.freeze([...paths]), ...(environment.JAVA_HOME ? { javaHome: environment.JAVA_HOME } : {}) }); +} + + /***/ }), /***/ 43193: @@ -51158,6 +51407,13 @@ class PullRequestReviewOperationError extends Error { super(buildMessage(operation, context)); this.name = "PullRequestReviewOperationError"; this.operation = operation; + const status = context?.providerStatus; + if (typeof status === 'number' && Number.isInteger(status) && status >= 400 && status <= 599) { + this.providerStatus = status; + } + if (typeof context?.providerReference === 'string' && /^[A-Za-z0-9:-]{1,64}$/.test(context.providerReference)) { + this.providerReference = context.providerReference; + } } } exports.PullRequestReviewOperationError = PullRequestReviewOperationError; @@ -51198,6 +51454,18 @@ function bindSddEvidenceReadPorts(ports) { } +/***/ }), + +/***/ 26509: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.DISABLED_VERIFICATION_SETUP = void 0; +exports.DISABLED_VERIFICATION_SETUP = Object.freeze({ kind: 'disabled' }); + + /***/ }), /***/ 84387: @@ -53108,6 +53376,7 @@ async function runInitialSetupWorkflow(request, dependencies) { } (0, logging_ports_1.logInfo)('📋 Ensuring .github and copying setup files...'); const workspaceSelection = { + ...(request.verificationActionState ? { verificationActionState: request.verificationActionState } : {}), features: setupConfiguration?.features, setupConfiguration, ...(request.workflowUpdates.length > 0 ? { @@ -53119,6 +53388,8 @@ async function runInitialSetupWorkflow(request, dependencies) { const filesResult = dependencies.setupWorkspacePort.prepare(workspaceSelection); mark('files', filesResult.copied > 0 ? 'completed' : 'skipped'); steps.push(`✅ Setup files: ${filesResult.copied} copied, ${filesResult.skipped} already existed`); + if (request.verificationActionState) + steps.push(`✅ Verification setup action ${request.verificationActionState === 'create' ? 'created' : 'preserved'}; VERIFICATION_SETUP=${setupConfiguration?.repository.verificationSetup ?? false}. Customize and review on MAIN_BRANCH, then run a real verification.`); if (setupConfiguration?.manageRepositorySecrets && secretValues > 0) mark('secrets', 'in-progress'); const secrets = await (0, setup_resource_provisioning_1.ensureRepositorySecrets)(request, dependencies, setupConfiguration, remoteConfiguration); @@ -58131,6 +58402,8 @@ function projectInitialSetupContext(source) { ...(credentials ? { setupCredentials: deepFreezeCopy(credentials) } : {}), ...(remote ? { setupRemoteConfiguration: deepFreezeCopy(remote) } : {}), workflowUpdates: Object.freeze(asStringArray(source.inputs?.setupWorkflowUpdates)), + ...(source.inputs?.setupVerificationActionState === 'create' || source.inputs?.setupVerificationActionState === 'preserve' + ? { verificationActionState: source.inputs.setupVerificationActionState } : {}), }); } function projectIssueCommentActionContext(source) { @@ -58636,6 +58909,7 @@ exports.draftSddMarkdown = draftSddMarkdown; const application_error_1 = __nccwpck_require__(75999); const pre_branch_sdd_1 = __nccwpck_require__(34730); const agent_response_length_failure_1 = __nccwpck_require__(28528); +const sdd_draft_consistency_1 = __nccwpck_require__(27910); /** Size and typed format failures share one regeneration; the writer still validates every candidate. */ async function draftSddMarkdown(agent, configuration, plan, prompt, validate) { const maximum = plan.action === 'update' ? pre_branch_sdd_1.SDD_MAX_UPDATE_CHARACTERS : pre_branch_sdd_1.SDD_MAX_DRAFT_CHARACTERS; @@ -58647,13 +58921,13 @@ async function draftSddMarkdown(agent, configuration, plan, prompt, validate) { }; let problem = 'size'; let formatReason = 'required-heading'; - const contractPrompt = `${prompt}\n\nDraft contract: keep the complete draft within ${maximum} characters; aim for ${target} characters. Preserve the same owner, decisions and requirements. Include these literal canonical heading prefixes as Markdown headings, with the shown capitalization:\n${pre_branch_sdd_1.SDD_REQUIRED_HEADINGS.join('\n')}\nUse the canonical numeric test-budget table in section 14: Area | Minimum distinct cases | Behaviors/risks covered. Every allocation and the Total must be a positive integer, and the Total must equal the sum of the allocations. A justified positive integer sentence of distinct tests or cases is also accepted. Return only the required JSON.`; + const contractPrompt = `${prompt}\n\nDraft contract: keep the complete draft within ${maximum} characters; aim for ${target} characters. Preserve the same owner, decisions and requirements. Include these literal canonical heading prefixes as Markdown headings, with the shown capitalization:\n${pre_branch_sdd_1.SDD_REQUIRED_HEADINGS.join('\n')}\nUse the canonical numeric test-budget table in section 14: Area | Minimum distinct cases | Behaviors/risks covered. Every allocation and the Total must be a positive integer, and the Total must equal the sum of the allocations. Return only the required JSON.`; for (let attempt = 0; attempt < 2; attempt++) { let value; try { value = await agent.query({ configuration, agentId: 'pre-branch-sdd-draft', - prompt: attempt === 0 ? contractPrompt : `${contractPrompt}\n\n${problem === 'size' ? `The previous response exceeded the ${maximum}-character draft limit.` : `The previous response failed the required SDD ${formatReason} contract.`} Regenerate a concise complete draft for this same owner and plan. Use the exact numbered canonical headings from the supplied template. Preserve all resolved requirements, architecture, documentation and acceptance. Do not change ownership or truncate a requirement.`, + prompt: `${attempt === 0 ? contractPrompt : `${contractPrompt}\n\n${problem === 'size' ? `The previous response exceeded the ${maximum}-character draft limit.` : `The previous response failed the required SDD ${formatReason} contract.`} Regenerate a concise complete draft for this same owner and plan. Use the exact numbered canonical headings from the supplied template. Preserve all resolved requirements, architecture, documentation and acceptance. Do not change ownership or truncate a requirement.`}\n\n${sdd_draft_consistency_1.SDD_CONSISTENCY_PROMPT}`, options: { expectJson: true, schemaName: 'pre_branch_sdd_draft', schema }, }); } @@ -58687,12 +58961,21 @@ async function draftSddMarkdown(agent, configuration, plan, prompt, validate) { } if (problem === 'format') throw new application_error_1.ApplicationError('validation.invalid-input', `The SDD draft still violates its ${formatReason} format contract after one bounded repair.`, { - recovery: { id: 'sdd-draft-format-invalid', variables: {} }, + recovery: { id: consistencyRecovery(formatReason), variables: {} }, }); throw new application_error_1.ApplicationError('validation.invalid-input', 'The SDD draft exceeded its size limit after one bounded repair.', { recovery: { id: 'sdd-draft-size-exceeded', variables: {} }, }); } +function consistencyRecovery(reason) { + switch (reason) { + case 'case-identity': return 'sdd-draft-case-identity-invalid'; + case 'case-budget': return 'sdd-draft-case-budget-invalid'; + case 'requirement-mapping': return 'sdd-draft-requirement-mapping-invalid'; + case 'repository-path': return 'sdd-draft-repository-path-invalid'; + default: return 'sdd-draft-format-invalid'; + } +} /***/ }), @@ -58710,8 +58993,10 @@ const issue_start_policy_1 = __nccwpck_require__(90332); const pre_branch_sdd_1 = __nccwpck_require__(34730); const recommendation_policy_1 = __nccwpck_require__(39410); const logging_ports_1 = __nccwpck_require__(6152); +const sdd_analysis_status_policy_1 = __nccwpck_require__(81053); const application_error_1 = __nccwpck_require__(75999); const pre_branch_sdd_draft_workflow_1 = __nccwpck_require__(93454); +const sdd_draft_consistency_1 = __nccwpck_require__(27910); const ANALYSIS_SCHEMA = { type: 'object', properties: { @@ -58832,11 +59117,21 @@ class PreBranchSddGateUseCase { }); const analysisValue = asRecord(analysis); const owners = new Map(snapshot.capabilities.map(capability => [capability.id, capability.specs])); - const plan = (0, pre_branch_sdd_1.parseSddPlan)(analysisValue, owners); + let plan; + try { + plan = (0, pre_branch_sdd_1.parseSddPlan)(analysisValue, owners); + } + catch (error) { + if (!(error instanceof pre_branch_sdd_1.SddOwnershipFailure)) + throw error; + await this.writeAnalysisStatus(context, allComments, error.reason); + throw new application_error_1.ApplicationError('provider.contract-invalid', `${error.message} Clarify the catalog owner/path in the same issue and rerun the original workflow. No automatic retry was attempted.`); + } if (card?.record.branchName && (plan.action !== 'update' || plan.path !== card.record.plan.path || plan.capabilityId !== card.record.plan.capabilityId)) { throw new Error('An existing linked branch can only revise its owning SDD on the same path.'); } + await this.writeAnalysisStatus(context, allComments); const round = publicationRetry ? card.record.round : card?.record.phase === 'awaiting-answer' && card.record.issueDigest === digest && !staleAwaiting ? card.record.round + (plan.questions.length > 0 ? 1 : 0) : 1; @@ -58856,9 +59151,19 @@ class PreBranchSddGateUseCase { const currentSdd = plan.action === 'update' ? await this.workspace.readSdd(snapshot.baseSha, plan.path) : undefined; if (plan.action === 'update' && !currentSdd) throw new Error('The catalogued SDD owner is missing from the selected base.'); + const ownerDocuments = []; + for (const path of snapshot.capabilities.find(capability => capability.id === plan.capabilityId)?.specs ?? []) { + const markdown = path === plan.path && currentSdd ? currentSdd : await this.workspace.readSdd(snapshot.baseSha, path); + if (!markdown) + throw new Error('A catalogued owning SDD is unavailable at the selected immutable base.'); + ownerDocuments.push({ path, markdown }); + } + const reservedCases = JSON.stringify((0, sdd_draft_consistency_1.reservedSddCaseIds)(ownerDocuments)); + if (reservedCases.length > 30000) + throw new Error('The owning SDD case inventory exceeds the bounded drafting context; maintainer review is required.'); const newCapability = plan.action === 'new' ? parseNewCapability(analysisValue.newCapability, plan) : undefined; let prepared; - await (0, pre_branch_sdd_draft_workflow_1.draftSddMarkdown)(this.agent, context.agentConfiguration, plan, buildDraftPrompt(context, snapshot, plan, answers, currentSdd), async (markdown) => { + await (0, pre_branch_sdd_draft_workflow_1.draftSddMarkdown)(this.agent, context.agentConfiguration, plan, `${buildDraftPrompt(context, snapshot, plan, answers, currentSdd)}\n\nCase IDs reserved across every owning SDD at ${snapshot.baseSha}:\n${reservedCases}`, async (markdown) => { prepared = await this.workspace.validateDraft(snapshot, plan, markdown, newCapability); }); if (!prepared) @@ -58948,6 +59253,20 @@ class PreBranchSddGateUseCase { else await this.comments.updateComment(issueNumber, cardId, body); } + async writeAnalysisStatus(context, comments, reason) { + const marker = (0, sdd_analysis_status_policy_1.sddAnalysisStatusMarker)(context.issueNumber); + const prior = comments.filter(comment => comment.user?.login?.toLowerCase() === context.tokenUser.toLowerCase() + && comment.body?.includes(marker)).sort((a, b) => b.id - a.id)[0]; + if (!reason && !prior) + return; + const body = (0, sdd_analysis_status_policy_1.renderSddAnalysisStatus)(context.issueNumber, context.issueLocale, reason); + if (prior) { + if (prior.body !== body) + await this.comments.updateComment(context.issueNumber, prior.id, body); + } + else + await this.comments.addComment(context.issueNumber, body); + } async assertFresh(context, expectedBaseSha, sourceBranch) { const [liveBody, liveTitle, snapshot] = await Promise.all([ this.descriptions.getDescription(context.issueNumber), @@ -59708,7 +60027,7 @@ function partitionFailureCategory(error) { return error instanceof Error ? error.name : 'unknown'; } function suppressDismissedFindings(execution, context, prepared) { - const activeFindings = (prepared.activeFindings ?? prepared.toPublish).filter((finding) => { + const activeFindings = (0, finding_1.retainExistingFindingIds)(prepared.activeFindings ?? prepared.toPublish, context.existingByFindingId).filter((finding) => { const existing = (0, finding_1.findExistingFindingInfo)(context.existingByFindingId, finding); return existing?.issue?.resolution !== 'dismissed' && existing?.pullRequest?.resolution !== 'dismissed'; }); @@ -59728,6 +60047,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.applyDetectedFindings = applyDetectedFindings; const mark_findings_resolved_use_case_1 = __nccwpck_require__(96963); const publish_findings_use_case_1 = __nccwpck_require__(88442); +const bugbot_mutation_error_1 = __nccwpck_require__(82937); const pull_request_review_errors_1 = __nccwpck_require__(46445); async function applyDetectedFindings(operation, context, prepared, publicationPorts, resolutionPorts, catalog) { try { @@ -59743,7 +60063,7 @@ async function applyDetectedFindings(operation, context, prepared, publicationPo }); } catch (error) { - const publicationError = error instanceof pull_request_review_errors_1.PullRequestReviewOperationError + const publicationError = error instanceof bugbot_mutation_error_1.BugbotMutationError || error instanceof pull_request_review_errors_1.PullRequestReviewOperationError ? error : new Error("Unable to publish findings."); return [publicationError]; @@ -60294,6 +60614,7 @@ function buildPreviousFindingsContext(previousFindings) { `; const suffix = ` **Your task 2:** For each finding above, analyze the current code and decide: +- Trace the original failure precondition through current callers, validation helpers and effective configuration, including modules outside the original anchor. A retained finding is not proof that its old explanation is still true. Reuse its exact id if reporting the same defect again; do not create a second report for it. - If the problem **still exists** (same code or same issue present): do **not** include it in \`resolved_findings\`. - If the problem **no longer applies** (e.g. that code was removed or refactored away): include \`{ "id": "", "resolution": "obsolete" }\` in \`resolved_findings\`. - If the problem **has been fixed** (code was changed and the issue is resolved): include \`{ "id": "", "resolution": "fixed" }\` in \`resolved_findings\`. @@ -60413,6 +60734,10 @@ function buildReviewConversationContext(issueComments, commentsByPullRequest, bo omitted, truncated: chronological.filter((entry) => entry.truncated).length, retained: chronological.length, + ...(chronological.some(entry => entry.truncated) ? { + truncatedItemIds: chronological.filter(entry => entry.truncated) + .map(entry => entry.providerId).filter(id => /^(?:issue:[0-9]+|review:[A-Za-z0-9_=-]+)$/.test(id) && id.length <= 160), + } : {}), }; } function appendConversationEntry(entries, author, kind, body, createdAt, providerId) { @@ -61904,6 +62229,7 @@ async function loadBugbotContext(request, ports, resolvedPreflight) { itemsFetched: conversationContext.retained + conversationContext.omitted, omittedItems: conversationContext.omitted, truncatedItems: conversationContext.truncated, + ...(conversationContext.truncatedItemIds ? { truncatedItemIds: conversationContext.truncatedItemIds } : {}), limitReached: conversationContext.omitted > 0 || conversationContext.truncated > 0, }, { @@ -62105,11 +62431,11 @@ Object.defineProperty(exports, "markFindingsResolved", ({ enumerable: true, get: Object.defineProperty(exports, "__esModule", ({ value: true })); exports.markFindingsResolved = markFindingsResolved; -const pull_request_review_errors_1 = __nccwpck_require__(46445); const logging_ports_1 = __nccwpck_require__(6152); const resolve_issue_finding_1 = __nccwpck_require__(35300); const resolve_pull_request_finding_1 = __nccwpck_require__(64567); const review_state_1 = __nccwpck_require__(79200); +const bugbot_mutation_error_1 = __nccwpck_require__(82937); const application_error_1 = __nccwpck_require__(75999); async function markFindingsResolved(param) { const errors = []; @@ -62137,8 +62463,8 @@ async function repairExistingPullRequestFinding(ports, operation, findingId, des try { await ports.pullRequestComments.unresolvePullRequestReviewThread(destination.pullRequestNumber, destination.commentIdentity); } - catch { - addResolutionError(errors, 'pull request'); + catch (cause) { + addResolutionError(errors, 'pull request', findingId, cause); } } } @@ -62152,7 +62478,7 @@ async function resolveIssueIfNeeded(param, findingId, destination, errors) { return; const comment = param.context.issueComments.find(item => item.id === destination.commentId); if (comment?.body == null) { - addResolutionError(errors, 'issue'); + addResolutionError(errors, 'issue', findingId); return; } try { @@ -62163,8 +62489,8 @@ async function resolveIssueIfNeeded(param, findingId, destination, errors) { resolution: param.resolvedFindingResolutions?.get(findingId), }, param.catalog); } - catch { - addResolutionError(errors, 'issue'); + catch (cause) { + addResolutionError(errors, 'issue', findingId, cause); } } async function tryResolvePullRequestFinding(ports, findingId, destination, errors, resolution, catalog) { @@ -62176,17 +62502,14 @@ async function tryResolvePullRequestFinding(ports, findingId, destination, error resolution, }, catalog); } - catch { - addResolutionError(errors, 'pull request'); + catch (cause) { + addResolutionError(errors, 'pull request', findingId, cause); } } -function addResolutionError(errors, destination) { - const cause = destination === 'pull request' - ? new pull_request_review_errors_1.PullRequestReviewOperationError('mark-resolved') - : new Error('Unable to mark an issue finding as resolved.'); - const semanticError = new application_error_1.ApplicationError('provider.unavailable', destination === 'pull request' - ? 'Unable to mark a pull request finding as resolved.' - : 'Unable to mark an issue finding as resolved.', { cause }); +function addResolutionError(errors, destination, findingId, cause) { + const semanticError = destination === 'pull request' + ? (0, bugbot_mutation_error_1.bugbotMutationError)(cause, 'resolution', [findingId], 'mark-resolved') + : new application_error_1.ApplicationError('provider.unavailable', 'Unable to mark an issue finding as resolved.'); (0, logging_ports_1.logError)(semanticError); errors.push(semanticError); } @@ -62439,6 +62762,7 @@ function isRecord(value) { */ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.publishFindings = publishFindings; +const bugbot_mutation_error_1 = __nccwpck_require__(82937); const finding_1 = __nccwpck_require__(31011); const publish_issue_finding_comment_1 = __nccwpck_require__(84950); const publish_pr_review_comments_1 = __nccwpck_require__(50352); @@ -62457,12 +62781,17 @@ async function publishFindings(param) { catalog, }) : undefined; - for (const finding of findings) { + for (const finding of (0, finding_1.retainExistingFindingIds)(findings, existingByFindingId)) { if (operation.target.issueNumber > 0 && !reviewPublisher) { await (0, publish_issue_finding_comment_1.publishIssueFindingComment)(ports.issueComments, operation.target.issueNumber, finding, (0, finding_1.findExistingFindingInfo)(existingByFindingId, finding), commitSha, catalog); } if (reviewPublisher) { - await reviewPublisher.publish(finding, (0, finding_1.findExistingFindingInfo)(existingByFindingId, finding)); + try { + await reviewPublisher.publish(finding, (0, finding_1.findExistingFindingInfo)(existingByFindingId, finding)); + } + catch (cause) { + throw (0, bugbot_mutation_error_1.bugbotMutationError)(cause, 'publication', [finding.id], 'publish-comments'); + } } } await reviewPublisher?.flush(overflowCount, overflowTitles); @@ -62534,6 +62863,7 @@ ${catalog.message('bugbot.overflow.body', { count: `**${overflowCount}**` }, ove Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestReviewCommentPublisher = void 0; +const bugbot_mutation_error_1 = __nccwpck_require__(82937); const bugbot_finding_marker_policy_1 = __nccwpck_require__(98024); const path_validation_1 = __nccwpck_require__(70124); const logging_ports_1 = __nccwpck_require__(6152); @@ -62605,11 +62935,16 @@ class PullRequestReviewCommentPublisher { if (this.findingsToCreate.length === 0 && overflowCount === 0) return; const { repository, operation, openPrNumber, prContext } = this.options; - await repository.createReviewWithComments(openPrNumber, prContext.prHeadSha, buildReviewSummary(this.findingsToCreate, this.commentsToCreate.length, this.unanchoredBodies, overflowCount, overflowTitles, operation.analysis.reviewConfiguration.traceRules - ? this.options.ruleSources ?? [] - : [], operation.analysis.reviewConfiguration.traceRules - ? this.options.omittedRuleCount ?? 0 - : 0, prContext.prHeadSha, this.catalog), this.commentsToCreate); + try { + await repository.createReviewWithComments(openPrNumber, prContext.prHeadSha, buildReviewSummary(this.findingsToCreate, this.commentsToCreate.length, this.unanchoredBodies, overflowCount, overflowTitles, operation.analysis.reviewConfiguration.traceRules + ? this.options.ruleSources ?? [] + : [], operation.analysis.reviewConfiguration.traceRules + ? this.options.omittedRuleCount ?? 0 + : 0, prContext.prHeadSha, this.catalog), this.commentsToCreate); + } + catch (cause) { + throw (0, bugbot_mutation_error_1.bugbotMutationError)(cause, 'publication', this.findingsToCreate.map(finding => finding.id), 'publish-comments', this.findingsToCreate.length + overflowCount); + } } get catalog() { return this.options.catalog ?? (0, bugbot_message_catalog_1.resolveStaticBugbotCatalog)(this.options.operation.locale.pullRequest); @@ -62765,6 +63100,8 @@ async function queryBugbotPartitionFindings(repository, configuration, prompt, t Object.defineProperty(exports, "__esModule", ({ value: true })); exports.reconcileBugbotReviewState = reconcileBugbotReviewState; +const bugbot_mutation_error_1 = __nccwpck_require__(82937); +const finding_1 = __nccwpck_require__(31011); const review_projection_1 = __nccwpck_require__(80859); const bugbot_reconciliation_policy_1 = __nccwpck_require__(78128); const bugbot_provider_projection_policy_1 = __nccwpck_require__(85821); @@ -62795,11 +63132,12 @@ async function reconcileBugbotReviewState(input) { }; } const snapshot = snapshotResult.snapshot; + const activeFindings = (0, finding_1.retainExistingFindingIds)(input.activeFindings, input.loadedContext.existingByFindingId); + const expectedPublishedFindings = (0, finding_1.retainExistingFindingIds)(input.expectedPublishedFindings ?? input.activeFindings, input.loadedContext.existingByFindingId); const diagnostics = [ - ...(input.mutationErrors ?? []).map((error) => ({ - code: 'operation-failed', - operatorMessage: toSafeOperationMessage(error), - })), + ...(input.mutationErrors ?? []).map((error) => error instanceof bugbot_mutation_error_1.BugbotMutationError + ? { code: 'finding-mutation-failed', mutation: error.diagnostic } + : { code: 'operation-failed', operatorMessage: toSafeOperationMessage(error) }), ...(!input.target.trustedAuthorLogin?.trim() ? [{ code: 'identity-unavailable' }] : []), @@ -62808,7 +63146,7 @@ async function reconcileBugbotReviewState(input) { const providerProjection = (0, bugbot_provider_projection_policy_1.projectBugbotProviderEvidence)({ snapshot, trustedAuthorLogin: input.target.trustedAuthorLogin, - activeFindings: input.activeFindings, + activeFindings, existingByFindingId: input.loadedContext.existingByFindingId, }); const plan = (0, bugbot_reconciliation_policy_1.buildBugbotReconciliationPlan)({ @@ -62818,8 +63156,8 @@ async function reconcileBugbotReviewState(input) { id, (0, bugbot_finding_marker_policy_1.extractTitleFromBody)(fullBody) || id, ])), - activeFindings: input.activeFindings, - expectedPublishedFindings: input.expectedPublishedFindings ?? input.activeFindings, + activeFindings, + expectedPublishedFindings, diagnostics, coverage: input.loadedContext.coverage, }); @@ -63323,14 +63661,16 @@ function toPresentationFailure(diagnostic) { const message = (0, bugbot_message_catalog_1.bugbotDiagnosticOperatorMessage)(diagnostic); return { diagnostic, - error: diagnostic.code === 'review-updates-pending' - ? new application_error_1.ApplicationError('workflow.presentation-pending', message, { - recovery: { - id: 'bugbot-review-blocks-pending', - variables: { pendingCount: diagnostic.count }, - }, - }) - : new Error(message), + error: diagnostic.code === 'finding-mutation-failed' + ? new application_error_1.ApplicationError(diagnostic.mutation.errorCode, message) + : diagnostic.code === 'review-updates-pending' + ? new application_error_1.ApplicationError('workflow.presentation-pending', message, { + recovery: { + id: 'bugbot-review-blocks-pending', + variables: { pendingCount: diagnostic.count }, + }, + }) + : new Error(message), }; } function report(projection, reviewUpdates, pendingReviewUpdates, statusCardOperation, errors) { @@ -63443,6 +63783,7 @@ exports.runVerifyCommands = runVerifyCommands; const logging_ports_1 = __nccwpck_require__(6152); const verify_command_policy_1 = __nccwpck_require__(96031); const verification_runtime_policy_1 = __nccwpck_require__(89347); +const verification_setup_policy_1 = __nccwpck_require__(65326); async function runVerifyCommands(commands, execute) { for (const command of commands) { const result = await executeVerifyCommand(command, execute); @@ -63462,7 +63803,7 @@ async function executeVerifyCommand(command, execute) { : { success: false, failedCommand: formatCommandForDiagnostics(parsed) }; } catch (error) { - if (error instanceof verification_runtime_policy_1.VerificationPrerequisiteError) { + if (error instanceof verification_runtime_policy_1.VerificationPrerequisiteError || error instanceof verification_setup_policy_1.VerificationSetupError) { return { success: false, failedCommand: formatCommandForDiagnostics(parsed), error: `${error.message} Verification command: ${formatCommandForDiagnostics(parsed)}.` }; } @@ -68785,9 +69126,16 @@ exports.APPLICATION_ERROR_RECOVERY_IDS = Object.freeze([ 'branch-sync-resolution-invalid', 'sdd-draft-size-exceeded', 'sdd-draft-format-invalid', + 'sdd-draft-case-identity-invalid', + 'sdd-draft-case-budget-invalid', + 'sdd-draft-requirement-mapping-invalid', + 'sdd-draft-repository-path-invalid', 'workspace-changes-rejected', 'closed-issue-reconciliation-failed', 'approval-evidence-read-failed', + 'stored-configuration-schema-missing', + 'stored-configuration-schema-unsupported', + 'stored-configuration-invalid', ]); const PRESERVED_STATE = 'Existing persisted state and completed external effects were preserved.'; const UNCHANGED_STATE = 'No new state or external effect was created.'; @@ -68979,6 +69327,9 @@ class ApplicationError extends Error { exports.ApplicationError = ApplicationError; _ApplicationError_cause = new WeakMap(); const RECOVERY_VARIABLE_KEYS = Object.freeze({ + 'stored-configuration-schema-missing': Object.freeze(['issueNumber', 'expectedVersion']), + 'stored-configuration-schema-unsupported': Object.freeze(['issueNumber', 'expectedVersion', 'actualVersion']), + 'stored-configuration-invalid': Object.freeze(['issueNumber', 'expectedVersion']), 'closed-issue-reconciliation-failed': Object.freeze(['resultId', 'phase', 'state', 'reason', 'changed', 'remaining']), 'approval-evidence-read-failed': Object.freeze(['operation', 'reason', 'permission']), 'pull-request-link-restored': Object.freeze([]), @@ -68993,6 +69344,10 @@ const RECOVERY_VARIABLE_KEYS = Object.freeze({ 'branch-sync-resolution-invalid': Object.freeze(['validationCode', 'command']), 'sdd-draft-size-exceeded': Object.freeze([]), 'sdd-draft-format-invalid': Object.freeze([]), + 'sdd-draft-case-identity-invalid': Object.freeze([]), + 'sdd-draft-case-budget-invalid': Object.freeze([]), + 'sdd-draft-requirement-mapping-invalid': Object.freeze([]), + 'sdd-draft-repository-path-invalid': Object.freeze([]), 'workspace-changes-rejected': Object.freeze([]), }); function normalizeApplicationErrorRecovery(recovery) { @@ -69008,6 +69363,13 @@ function normalizeApplicationErrorRecovery(recovery) { || actualKeys.some((key, index) => key !== expectedKeys[index])) { throw new TypeError(`Application error recovery variables are invalid for ${recovery.id}.`); } + if (recovery.id.startsWith('stored-configuration-') + && (![variables.issueNumber, variables.expectedVersion].every(value => typeof value === 'number' && Number.isSafeInteger(value) && value > 0) + || (recovery.id === 'stored-configuration-schema-unsupported' + && !(typeof variables.actualVersion === 'number' + && Number.isSafeInteger(variables.actualVersion) && variables.actualVersion >= 0)))) { + throw new TypeError('Stored configuration diagnostic is invalid.'); + } if (recovery.id === 'managed-branch-enrichment-failed' && (typeof variables.branchName !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9._/-]{0,254}$/u.test(variables.branchName))) { @@ -69389,6 +69751,7 @@ class Execution { this.currentIssueWorkflowAdmission = components.issueWorkflowAdmission; this.currentConfiguration.issueWorkflowProfileDigest = components.issueWorkflowProfileDigest; this.preBranchSdd = components.preBranchSdd ?? false; + this.verificationSetup = components.verificationSetup ?? false; } } exports.Execution = Execution; @@ -74451,6 +74814,7 @@ function combineOrganizationAccess(secrets, variables) { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.isGithubAlreadyExists = exports.isGithubPermissionDenied = exports.isGithubRateLimited = exports.isGithubNotFound = exports.getGithubErrorStatus = void 0; +exports.githubReadErrorCode = githubReadErrorCode; const getGithubErrorStatus = (error) => { if (typeof error !== "object" || error === null) return undefined; @@ -74460,6 +74824,23 @@ const getGithubErrorStatus = (error) => { exports.getGithubErrorStatus = getGithubErrorStatus; const isGithubNotFound = (error) => (0, exports.getGithubErrorStatus)(error) === 404; exports.isGithubNotFound = isGithubNotFound; +/** Maps failed metadata reads without copying untrusted provider text. */ +function githubReadErrorCode(error) { + const status = (0, exports.getGithubErrorStatus)(error); + if (status === 401) + return 'authorization.credential-invalid'; + if ((0, exports.isGithubRateLimited)(error)) + return 'provider.rate-limited'; + if (status === 403) + return 'authorization.denied'; + if (status === 404) + return 'provider.not-found'; + if (status === 409 || status === 412) + return 'provider.conflict'; + if (status === 400 || status === 422) + return 'provider.contract-invalid'; + return 'provider.unavailable'; +} const isGithubRateLimited = (error) => { const status = (0, exports.getGithubErrorStatus)(error); if (status === 429) @@ -75170,8 +75551,9 @@ class IssueContentRepository { return issue.body ?? ''; } catch (error) { - (0, logger_1.logError)((0, application_error_1.toApplicationError)(error, 'provider.unavailable', `Unable to read issue #${issueNumber} description.`)); - throw error; + const semanticError = (0, application_error_1.toApplicationError)(error, (0, github_error_policy_1.githubReadErrorCode)(error), 'Unable to read the issue or pull-request description.'); + (0, logger_1.logError)(semanticError); + throw semanticError; } }; this.getIssueDescription = async (owner, repository, issueNumber, token) => { @@ -77533,8 +77915,8 @@ function collectDiagnostic(diagnostics, cause) { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestChangesRepository = void 0; +const pull_request_review_error_metadata_1 = __nccwpck_require__(54354); const logger_1 = __nccwpck_require__(91151); -const pull_request_review_errors_1 = __nccwpck_require__(46445); const github_pagination_policy_1 = __nccwpck_require__(44812); const application_error_1 = __nccwpck_require__(75999); class PullRequestChangesRepository { @@ -77547,7 +77929,7 @@ class PullRequestChangesRepository { } catch (error) { (0, logger_1.logError)((0, application_error_1.toApplicationError)(error, 'provider.unavailable', 'Unable to read the pull request review diff.')); - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'list-files'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'list-files'); } }; this.getBoundedBugbotReviewDiffSnapshot = async (owner, repository, pullNumber, token) => { @@ -77589,7 +77971,7 @@ class PullRequestChangesRepository { } catch (error) { (0, logger_1.logError)((0, application_error_1.toApplicationError)(error, 'provider.unavailable', 'Unable to read the pull request review diff.')); - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'list-files'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'list-files'); } }; /** Head commit SHA of the PR (for creating review). */ @@ -77608,7 +77990,7 @@ class PullRequestChangesRepository { } catch (error) { (0, logger_1.logError)((0, application_error_1.toApplicationError)(error, 'provider.unavailable', 'Unable to read the pull request head SHA.')); - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "get-head-sha"); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "get-head-sha"); } }; } @@ -77951,6 +78333,7 @@ function toBugbotPullRequestIdentity(value) { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestReviewCommentCommandRepository = void 0; +const pull_request_review_error_metadata_1 = __nccwpck_require__(54354); const pull_request_review_errors_1 = __nccwpck_require__(46445); const github_pagination_policy_1 = __nccwpck_require__(44812); class PullRequestReviewCommentCommandRepository { @@ -78019,7 +78402,7 @@ class PullRequestReviewCommentCommandRepository { const context = comments.length > 0 ? { failedCount: comments.length, totalCount: comments.length } : undefined; - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "publish-comments", context); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "publish-comments", context); } } async updatePullRequestReview(owner, repository, pullRequestNumber, reviewIdentity, body, token) { @@ -78040,7 +78423,7 @@ class PullRequestReviewCommentCommandRepository { throw new pull_request_review_errors_1.PullRequestReviewOperationError('update-review'); } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'update-review'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'update-review'); } } async updatePullRequestReviewComment(_owner, _repository, commentIdentity, body, token) { @@ -78059,7 +78442,7 @@ class PullRequestReviewCommentCommandRepository { } } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "update-comment"); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "update-comment"); } } } @@ -78075,7 +78458,7 @@ exports.PullRequestReviewCommentCommandRepository = PullRequestReviewCommentComm Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestReviewCommentQueryRepository = void 0; -const pull_request_review_errors_1 = __nccwpck_require__(46445); +const pull_request_review_error_metadata_1 = __nccwpck_require__(54354); const github_pagination_policy_1 = __nccwpck_require__(44812); function toReviewComment(comment) { if (typeof comment.node_id !== "string" || comment.node_id.length === 0) { @@ -78131,7 +78514,7 @@ class PullRequestReviewCommentQueryRepository { return comments; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "list-comments"); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "list-comments"); } } async listBugbotPullRequestReviewCommentsBounded(owner, repository, pullRequestNumber, token) { @@ -78174,7 +78557,7 @@ class PullRequestReviewCommentQueryRepository { }; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "list-comments"); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "list-comments"); } } async listPullRequestReviews(owner, repository, pullRequestNumber, token) { @@ -78188,7 +78571,7 @@ class PullRequestReviewCommentQueryRepository { return reviews; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'list-reviews'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'list-reviews'); } } async getPullRequestReviewCommentBody(owner, repository, _pullRequestNumber, commentId, token) { @@ -78202,13 +78585,37 @@ class PullRequestReviewCommentQueryRepository { return data.body ?? null; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "get-comment"); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "get-comment"); } } } exports.PullRequestReviewCommentQueryRepository = PullRequestReviewCommentQueryRepository; +/***/ }), + +/***/ 54354: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toPullRequestReviewOperationError = toPullRequestReviewOperationError; +const pull_request_review_errors_1 = __nccwpck_require__(46445); +/** Only safe HTTP metadata crosses the provider boundary; provider prose never does. */ +function toPullRequestReviewOperationError(error, operation, context) { + if (!error || typeof error !== 'object') + return (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, operation, context); + const record = error; + return (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, operation, { + ...context, + ...(typeof record.status === 'number' ? { providerStatus: record.status } : {}), + ...(typeof record.response?.headers?.['x-github-request-id'] === 'string' + ? { providerReference: record.response.headers['x-github-request-id'] } : {}), + }); +} + + /***/ }), /***/ 2307: @@ -78319,6 +78726,7 @@ function nextConnectionCursor(pageInfo, seenCursors) { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestReviewThreadRepository = void 0; +const pull_request_review_error_metadata_1 = __nccwpck_require__(54354); const logger_1 = __nccwpck_require__(91151); const pull_request_review_errors_1 = __nccwpck_require__(46445); const pull_request_review_thread_locator_1 = __nccwpck_require__(2307); @@ -78366,7 +78774,7 @@ class PullRequestReviewThreadRepository { return states; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'list-threads'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'list-threads'); } }; this.listBugbotPullRequestReviewThreadStatesBounded = async (owner, repository, pullNumber, token) => { @@ -78435,7 +78843,7 @@ class PullRequestReviewThreadRepository { }; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'list-threads'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'list-threads'); } }; this.resolvePullRequestReviewThread = async (owner, repository, pullNumber, commentIdentity, token) => { @@ -78459,7 +78867,7 @@ class PullRequestReviewThreadRepository { (0, logger_1.logDebugInfo)('Resolved pull request review thread.'); } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'resolve-thread'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'resolve-thread'); } }; this.unresolvePullRequestReviewThread = async (owner, repository, pullNumber, commentIdentity, token) => { @@ -78483,7 +78891,7 @@ class PullRequestReviewThreadRepository { (0, logger_1.logDebugInfo)('Reopened pull request review thread.'); } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, 'unresolve-thread'); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, 'unresolve-thread'); } }; } @@ -78500,7 +78908,7 @@ exports.PullRequestReviewThreadRepository = PullRequestReviewThreadRepository; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestReviewerRepository = void 0; -const pull_request_review_errors_1 = __nccwpck_require__(46445); +const pull_request_review_error_metadata_1 = __nccwpck_require__(54354); const github_pagination_policy_1 = __nccwpck_require__(44812); const COMPLETED_REVIEW_STATES = new Set([ "APPROVED", @@ -78533,7 +78941,7 @@ class PullRequestReviewerRepository { return [...reviewers.values()]; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "list-reviewers"); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "list-reviewers"); } } async addReviewersToPullRequest(owner, repository, pullRequestNumber, reviewers, token) { @@ -78558,7 +78966,7 @@ class PullRequestReviewerRepository { return [...confirmed.values()]; } catch (error) { - throw (0, pull_request_review_errors_1.toPullRequestReviewOperationError)(error, "request-reviewers"); + throw (0, pull_request_review_error_metadata_1.toPullRequestReviewOperationError)(error, "request-reviewers"); } } async listRequestedReviewers(client, parameters) { @@ -79976,10 +80384,15 @@ function matchesConstrainedHead(target, candidate) { /***/ }), /***/ 31011: -/***/ ((__unused_webpack_module, exports) => { +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isExistingFindingFullyResolved = isExistingFindingFullyResolved; +exports.findExistingFindingInfo = findExistingFindingInfo; +exports.findExistingFindingMatch = findExistingFindingMatch; +exports.retainExistingFindingIds = retainExistingFindingIds; /** * Provider-neutral Bugbot finding and durable identity contracts. * @@ -79987,9 +80400,7 @@ function matchesConstrainedHead(target, candidate) { * them in the domain prevents policies from depending on a particular use-case * folder and gives every adapter one stable semantic vocabulary. */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.isExistingFindingFullyResolved = isExistingFindingFullyResolved; -exports.findExistingFindingInfo = findExistingFindingInfo; +const finding_identity_1 = __nccwpck_require__(91853); function isExistingFindingFullyResolved(finding) { const destinations = [finding.issue, finding.pullRequest].filter((destination) => destination != null); return (destinations.length > 0 && @@ -79997,21 +80408,62 @@ function isExistingFindingFullyResolved(finding) { finding.pullRequest?.verificationRequired !== true); } function findExistingFindingInfo(existingByFindingId, finding) { + return findExistingFindingMatch(existingByFindingId, finding)?.info; +} +/** A match carries its durable key so updating a comment cannot re-key it. */ +function findExistingFindingMatch(existingByFindingId, finding) { const direct = existingByFindingId[finding.id]; if (direct && identitiesAreCompatible(direct, finding)) - return direct; - const candidates = Object.values(existingByFindingId); + return { id: finding.id, info: direct }; + const candidates = Object.entries(existingByFindingId); if (finding.fingerprint) { - const locationMatch = candidates.find((candidate) => candidate.issue?.fingerprint === finding.fingerprint + const locationMatches = candidates.filter(([, candidate]) => candidate.issue?.fingerprint === finding.fingerprint || candidate.pullRequest?.fingerprint === finding.fingerprint); - if (locationMatch) - return locationMatch; + if (locationMatches.length > 0) + return uniqueFindingMatch(locationMatches); } if (!finding.semanticFingerprint) return undefined; - const semanticMatches = candidates.filter((candidate) => candidate.issue?.semanticFingerprint === finding.semanticFingerprint + const semanticMatches = candidates.filter(([, candidate]) => candidate.issue?.semanticFingerprint === finding.semanticFingerprint || candidate.pullRequest?.semanticFingerprint === finding.semanticFingerprint); - return semanticMatches.length === 1 ? semanticMatches[0] : undefined; + return uniqueFindingMatch(semanticMatches); +} +/** + * Preserve trusted IDs across title/location changes, before limits, publication + * and final projection. Multiple reports of one uniquely matched durable finding + * share one record; unmatched or ambiguous reports remain independent evidence. + */ +function retainExistingFindingIds(findings, existingByFindingId) { + const retained = new Set(); + const durableIds = new Set(Object.keys(existingByFindingId)); + // Reserve the whole input up front so a generated ID cannot take another + // report's ID, including one that occurs later in the response. + const reservedIds = new Set([...durableIds, ...findings.map((finding) => finding.id)]); + const emittedIds = new Set(); + return findings.flatMap((finding) => { + const match = findExistingFindingMatch(existingByFindingId, finding); + if (!match) { + let id = finding.id; + if (durableIds.has(id) || emittedIds.has(id)) { + const base = `candidate-${(0, finding_identity_1.buildFindingFingerprint)(finding)}`; + id = base; + let suffix = 0; + while (reservedIds.has(id)) + id = `${base}-${++suffix}`; + reservedIds.add(id); + } + emittedIds.add(id); + return [id === finding.id ? finding : { ...finding, id }]; + } + if (retained.has(match.id)) + return []; + retained.add(match.id); + emittedIds.add(match.id); + return [finding.id === match.id ? finding : { ...finding, id: match.id }]; + }); +} +function uniqueFindingMatch(matches) { + return matches.length === 1 ? { id: matches[0][0], info: matches[0][1] } : undefined; } function identitiesAreCompatible(existing, finding) { const existingFingerprints = [ @@ -80553,6 +81005,63 @@ function isCopilotCommentRequest(commentBody, botLogin) { } +/***/ }), + +/***/ 33430: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.COPILOT_COMMENT_REMOTE_WORKFLOW = exports.COPILOT_COMMENT_SELF_WORKFLOW = exports.COPILOT_COMMENT_RUNTIME = void 0; +exports.isCopilotCommentWorkflow = isCopilotCommentWorkflow; +exports.isCopilotCommentRunner = isCopilotCommentRunner; +exports.copilotCommentRunner = copilotCommentRunner; +/** The comment coordinator is a versioned Copilot workflow, not an arbitrary reusable job. */ +exports.COPILOT_COMMENT_RUNTIME = 'copilot_comment_runtime.yml'; +exports.COPILOT_COMMENT_SELF_WORKFLOW = `$/.github/workflows/${exports.COPILOT_COMMENT_RUNTIME}`; +exports.COPILOT_COMMENT_REMOTE_WORKFLOW = `vypdev/copilot/.github/workflows/${exports.COPILOT_COMMENT_RUNTIME}@v3`; +function isCopilotCommentWorkflow(value) { + return typeof value === 'string' && (value === exports.COPILOT_COMMENT_SELF_WORKFLOW + || /^vypdev\/copilot\/\.github\/workflows\/copilot_comment_runtime\.yml@(?:v3(?:\.[0-9]+\.[0-9]+)?|[a-f0-9]{40})$/u.test(value)); +} +const literal = (value) => typeof value === 'string' && value.length > 0 && value.length <= 100 + && value === value.trim() && !/[\p{Cc}\p{Cf}${}<>]/u.test(value); +const labels = (value) => literal(value) || Array.isArray(value) && value.length > 0 && value.length <= 10 + && value.every(literal) && new Set(value.map(label => label.toLowerCase())).size === value.length; +/** Runner routing is literal data; expressions need their original full workflow reviewed. */ +function isCopilotCommentRunner(value) { + if (labels(value)) + return true; + if (!value || typeof value !== 'object' || Array.isArray(value)) + return false; + const route = value; + const keys = Object.keys(route); + return keys.length > 0 && (route.group !== undefined || route.labels !== undefined) + && keys.every(key => key === 'group' || key === 'labels') + && (route.group === undefined || literal(route.group)) + && (route.labels === undefined || labels(route.labels)); +} +function copilotCommentRunner(job) { + if (!job || !isCopilotCommentWorkflow(job.uses)) + return job?.['runs-on']; + const inputs = job.with; + if (typeof inputs?.['runs-on'] !== 'string') + throw new Error('Comment workflow runner JSON is unavailable; review the workflow separately.'); + try { + if (inputs['runs-on'].length > 16000) + throw new Error('Runner JSON exceeds its bound.'); + const route = JSON.parse(inputs['runs-on']); + if (!isCopilotCommentRunner(route)) + throw new Error('Unsupported execution route.'); + return route; + } + catch { + throw new Error('Comment workflow runner JSON is invalid; review the workflow separately.'); + } +} + + /***/ }), /***/ 72418: @@ -82357,7 +82866,7 @@ function parsePositiveSafeInteger(value) { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.SDD_REQUIRED_HEADINGS = exports.SddOwnerFormatFailure = exports.SddDraftFormatFailure = exports.SDD_MAX_UPDATE_CHARACTERS = exports.SDD_MAX_DRAFT_CHARACTERS = exports.SDD_MIN_DRAFT_CHARACTERS = exports.SDD_GATE_MARKER = void 0; +exports.SDD_REQUIRED_HEADINGS = exports.SddOwnerFormatFailure = exports.SddDraftFormatFailure = exports.SddOwnershipFailure = exports.SDD_MAX_UPDATE_CHARACTERS = exports.SDD_MAX_DRAFT_CHARACTERS = exports.SDD_MIN_DRAFT_CHARACTERS = exports.SDD_GATE_MARKER = void 0; exports.retainSddAnswers = retainSddAnswers; exports.normalizeSddIssueTitle = normalizeSddIssueTitle; exports.isSafeSddPath = isSafeSddPath; @@ -82368,6 +82877,7 @@ exports.isSddAnswerComment = isSddAnswerComment; exports.parseSddAnswer = parseSddAnswer; exports.validateSddMarkdown = validateSddMarkdown; exports.composeSddUpdate = composeSddUpdate; +exports.recoverSddUpdate = recoverSddUpdate; exports.SDD_GATE_MARKER = 'copilot:sdd-gate:v1'; exports.SDD_MIN_DRAFT_CHARACTERS = 1800; exports.SDD_MAX_DRAFT_CHARACTERS = 70000; @@ -82395,6 +82905,15 @@ function normalizeSddIssueTitle(title) { function isSafeSddPath(path) { return SDD_PATH.test(path) && !['specs/CATALOG.md', 'specs/_template.md'].includes(path); } +/** Closed diagnostics contain no model-selected identifiers or provider text. */ +class SddOwnershipFailure extends Error { + constructor(reason) { + super(`SDD ownership analysis rejected (${reason}).`); + this.reason = reason; + this.name = 'SddOwnershipFailure'; + } +} +exports.SddOwnershipFailure = SddOwnershipFailure; /** The agent may propose ownership but cannot invent a catalogued owner or arbitrary path. */ function parseSddPlan(value, catalog) { if (!isRecord(value)) @@ -82412,14 +82931,16 @@ function parseSddPlan(value, catalog) { const ownerPaths = catalog.get(capabilityId); const registered = [...catalog.values()].some(paths => paths.includes(path)); if (action === 'update' && (!ownerPaths?.includes(path) || !registered)) { - throw new Error('The requested SDD update is not owned by the selected catalog capability.'); - } - if (action === 'companion' && (!ownerPaths || registered)) { - throw new Error('A companion SDD requires an existing owner and a new path.'); - } - if (action === 'new' && (ownerPaths || registered)) { - throw new Error('A new SDD requires an unregistered capability and path.'); - } + throw new SddOwnershipFailure('update-owner-mismatch'); + } + if (action === 'companion' && !ownerPaths) + throw new SddOwnershipFailure('companion-owner-unknown'); + if (action === 'companion' && registered) + throw new SddOwnershipFailure('companion-path-registered'); + if (action === 'new' && ownerPaths) + throw new SddOwnershipFailure('new-owner-registered'); + if (action === 'new' && registered) + throw new SddOwnershipFailure('new-path-registered'); if (!Array.isArray(value.questions) || value.questions.length > 8) { throw new Error('The SDD analysis must contain at most eight blocking questions.'); } @@ -82660,8 +83181,24 @@ function composeSddUpdate(existing, change) { validateSddMarkdown(change); if (change.length > exports.SDD_MAX_UPDATE_CHARACTERS) throw new Error('An SDD update appendix exceeds 18000 characters; use a proportional change or a companion SDD.'); + const appendix = shiftSddHeadings(change, 1); + const merged = `${existing.trimEnd()}\n\n${appendix.trim()}\n`; + validateSddMarkdown(merged); + return merged; +} +/** Recovery validates the original candidate, not a second copy of its retained baseline. */ +function recoverSddUpdate(existing, published) { + const prefix = `${existing.trimEnd()}\n\n`; + if (!published.startsWith(prefix)) + return undefined; + // Composition normalizes outer whitespace and adds a publication newline. + // Reconstruct an equivalent candidate inside the original size bounds. + const change = shiftSddHeadings(published.slice(prefix.length), -1).trim().padEnd(exports.SDD_MIN_DRAFT_CHARACTERS, '\n'); + return composeSddUpdate(existing, change) === published ? change : undefined; +} +function shiftSddHeadings(source, direction) { let fence; - const appendix = change.split('\n').map(line => { + return source.split('\n').map(line => { const boundary = line.match(/^\s*(`{3,}|~{3,})/); if (boundary) { if (!fence) @@ -82670,11 +83207,11 @@ function composeSddUpdate(existing, change) { fence = undefined; return line; } - return !fence && /^#{1,5} /.test(line) ? `#${line}` : line; + if (fence) + return line; + return direction === 1 ? (/^#{1,5} /.test(line) ? `#${line}` : line) + : (/^#{2,6} /.test(line) ? line.slice(1) : line); }).join('\n'); - const merged = `${existing.trimEnd()}\n\n${appendix.trim()}\n`; - validateSddMarkdown(merged); - return merged; } function serializeSddGateValue(value) { // Human answer text must never terminate its hidden state comment. @@ -83271,6 +83808,254 @@ function replyRequestBodyDigest(body) { } +/***/ }), + +/***/ 27910: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.SDD_CONSISTENCY_PROMPT = void 0; +exports.reservedSddCaseIds = reservedSddCaseIds; +exports.validateSddDraftConsistency = validateSddDraftConsistency; +const pre_branch_sdd_1 = __nccwpck_require__(34730); +const CASE = /\b(?:[A-Za-z][A-Za-z0-9]*-)+C\d+\b/gu; +const CASE_ID = /^(?:[A-Za-z][A-Za-z0-9]*-)+C\d+$/u; +const REQUIREMENT_ID = /^[A-Za-z][A-Za-z0-9]*(?:-[A-Za-z0-9]+)+$/u; +/** Generated candidates use visible tables; retained legacy owners are never reformatted. */ +exports.SDD_CONSISTENCY_PROMPT = `Consistency contract for the proposed draft/appendix (not the retained owner): +In section 4 include one table: Requirement | Behavior. Give every goal a stable requirement ID. +In section 14 include one budget table: Area | Minimum distinct cases | Behaviors/risks covered; positive integers and one Total. +Also in section 14 include one inventory table: Case ID | Area | Requirements | Scenario. +Each row is one distinct executable case with a fully qualified ID such as capability-change-C01, one exact budget area, comma-separated requirement IDs and an observable scenario. Never use shorthand C01, ranges or redefine an ID found in any owning SDD. Reference retained baseline cases in prose using their full IDs; count only the new inventory. +In section 17 include one table: Requirement | Cases. List comma-separated full case IDs for every requirement. Its links must exactly match the case inventory in both directions, with no undefined or generic documentation checks. +In section 15 include one table: Path | Change. Change is update, reference or create. Include the selected SDD path itself with update for an existing SDD or create for a new/companion SDD. Use existing immutable-base files for update/reference. Only explicitly proposed new files may use create; never mark a missing current document as an existing artifact. Cite repository files as full repository-relative paths in backticks, or relative Markdown file links. Put every planned new file in this table. These tables are publication consistency checks, not runtime/security acceptance.`; +function fail(reason) { + // Closed diagnostics: rejected Markdown and repository text never become repair instructions. + throw new pre_branch_sdd_1.SddDraftFormatFailure(reason, `The SDD draft violates its ${reason} consistency contract.`); +} +/** Excludes examples and hidden records from the contract. */ +function visible(source) { + let fence; + let comment = false; + return source.replace(/\r\n/gu, '\n').split('\n').map(line => { + const boundary = /^\s*(`{3,}|~{3,})/u.exec(line); + if (fence) { + // Comment syntax inside code is literal; only the original line can close it. + if (boundary && boundary[1][0] === fence[0] && boundary[1].length >= fence.length + && /^ {0,3}(?:`+|~+)[ \t]*$/u.test(line)) + fence = undefined; + return ''; + } + if (!comment && boundary) { + fence = boundary[1]; + return ''; + } + let result = ''; + let offset = 0; + while (offset < line.length) { + const marker = comment ? '-->' : ''; +/** Owned delimiters begin a line; ordinary mentions are not state. Complete legacy fenced records remain readable. */ +function readConfigurationBlock(description) { + if (description === undefined) + return { kind: 'absent' }; + let fence; + let fencedMarker = false; + let fencedStart; + let nestedFencedStart = false; + let start; + let contentStart = 0; + let block; + let offset = 0; + for (const line of description.match(/[^\n]*(?:\n|$)/gu) ?? []) { + const text = line.replace(/\r?\n$/u, ''); + const starts = /^ {0,3}[ \t]*$/u.test(text); + const boundary = /^ {0,3}(`{3,}|~{3,})(.*)$/u.exec(text); + if (fence) { + fencedMarker || (fencedMarker = starts || ends); + if (starts) { + if (fencedStart !== undefined) + nestedFencedStart = true; + else + fencedStart = offset + text.indexOf(exports.CONFIGURATION_START); + } + const end = text.indexOf(exports.CONFIGURATION_END); + if (fencedStart !== undefined && end >= 0 && !text.slice(end + exports.CONFIGURATION_END.length).trim()) { + if (block || nestedFencedStart) + return { kind: 'invalid' }; + block = { kind: 'present', start: fencedStart, end: offset + end + exports.CONFIGURATION_END.length, + content: description.slice(fencedStart + exports.CONFIGURATION_START.length, offset + end) }; + fencedStart = undefined; + } + if (boundary && boundary[1][0] === fence[0] && boundary[1].length >= fence.length && !boundary[2].trim()) { + fence = undefined; + fencedMarker = false; + fencedStart = undefined; + nestedFencedStart = false; + } + } + else if (start !== undefined || starts) { + if (starts) { + if (start !== undefined || block) + return { kind: 'invalid' }; + start = offset + text.indexOf(exports.CONFIGURATION_START); + contentStart = start + exports.CONFIGURATION_START.length; + } + const end = text.indexOf(exports.CONFIGURATION_END); + if (end >= 0 && !text.slice(end + exports.CONFIGURATION_END.length).trim()) { + block = { kind: 'present', start: start, end: offset + end + exports.CONFIGURATION_END.length, + content: description.slice(contentStart, offset + end) }; + start = undefined; + } + } + else if (ends) + return { kind: 'invalid' }; + else if (boundary && (boundary[1][0] !== '`' || !boundary[2].includes('`'))) + fence = boundary[1]; + offset += line.length; + } + // A legacy block behind an unclosed fence is ambiguous: never silently discard its state. + if (start !== undefined || fence && fencedMarker) + return { kind: 'invalid' }; + return block ?? { kind: 'absent', ...(fence ? { closingFence: fence } : {}) }; +} +function writeConfigurationBlock(description, content) { + const block = readConfigurationBlock(description); + if (block.kind === 'invalid') + return undefined; + const replacement = `${exports.CONFIGURATION_START}\n${content}\n${exports.CONFIGURATION_END}`; + if (block.kind === 'present') + return description.slice(0, block.start) + replacement + description.slice(block.end); + // Closing an otherwise empty dangling example preserves its rendered text and keeps new state outside it. + return `${description}\n\n${block.closingFence ? `${block.closingFence}\n\n` : ''}${replacement}`; +} + + /***/ }), /***/ 58043: @@ -89121,11 +91228,13 @@ function getBranchSyncConflictsPrompt(params) { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.BUGBOT_FINDING_GROUNDING_INSTRUCTION = void 0; exports.getBugbotPrompt = getBugbotPrompt; /** * Prompt for Bugbot detection (detect potential problems on push). */ const fill_1 = __nccwpck_require__(2559); +exports.BUGBOT_FINDING_GROUNDING_INSTRUCTION = 'Before returning a finding, try to disprove it against the exact reviewed source. Read effective repository configuration and inherited library/protocol defaults before inferring behavior from a missing command flag. Trace short-circuit guards, validation helpers and the actual caller/render path before claiming that an unsafe branch is reachable or that separate call sites coexist. Recompute arithmetic and check cited line numbers against the current file/diff. If your evidence refutes the alleged defect, withdraw the finding entirely; do not publish a contradictory or self-refuting report. These checks apply equally to low/info severity. Report a confirmed failure when those protections are absent; do not assume they exist.'; const TEMPLATE = `You are analyzing the latest code changes for potential bugs and issues. Write every human-readable finding title, description, evidence, and suggestion in {{targetLocale}}. Preserve identifiers, code, symbols, paths, refs, commands, and URLs verbatim. Echo \`outputLocale\` exactly as \`{{targetLocale}}\`. @@ -89161,6 +91270,8 @@ For every finding: - include the nearest stable \`symbol\` and a minimal exact \`codeSnippet\` when available so the finding can survive rebases, line movement, and file renames. - when a fix is a safe replacement of exactly the reported line range, include only the replacement text in \`suggestedCode\`; otherwise omit it. +${exports.BUGBOT_FINDING_GROUNDING_INSTRUCTION} + Return every finding field required by the response schema. Use null for file, line, endLine, severity, confidence, category, evidence, suggestion, symbol, codeSnippet, or suggestedCode when that value does not safely apply. Only include files outside the ignore list. {{previousBlock}} @@ -90638,11 +92749,13 @@ const setup_approval_workflow_1 = __nccwpck_require__(9512); const setup_workflow_upgrade_1 = __nccwpck_require__(85493); const setup_installation_review_1 = __nccwpck_require__(23799); const repository_agent_guidance_policy_1 = __nccwpck_require__(67402); +const setup_verification_action_1 = __nccwpck_require__(12471); /** * Ensure .github, .github/workflows and .github/ISSUE_TEMPLATE exist; create them if missing. * @param cwd - Directory (repo root) */ function ensureGitHubDirs(cwd) { + (0, setup_verification_action_1.inspectSetupVerificationActionPath)(cwd); const githubDir = path.join(cwd, '.github'); const workflowsDir = path.join(cwd, '.github', 'workflows'); const issueTemplateDir = path.join(cwd, '.github', 'ISSUE_TEMPLATE'); @@ -90675,6 +92788,7 @@ function copySetupFiles(cwd, setupDirOverride, features, options = {}) { const installationReview = options.setupConfiguration && (0, setup_installation_review_1.inspectSetupInstallation)(cwd, options.setupConfiguration, setupDir); if (installationReview?.blockers.length) throw new Error(installationReview.blockers.join(' ')); + const verificationAction = (0, setup_verification_action_1.createSetupVerificationAction)(cwd, options.verificationActionState); const preserveSourceGuidance = installationReview?.assets.some(asset => asset.path === repository_agent_guidance_policy_1.REPOSITORY_AGENT_GUIDE_PATH && asset.status === 'source-only'); const sourceInstallation = installationReview?.assets.some(asset => asset.path.startsWith('.github/workflows/') && asset.status === 'source-only'); const snapshotContent = options.setupConfiguration && (0, setup_installation_review_1.renderSetupRunnerSnapshot)(options.setupConfiguration); @@ -90729,7 +92843,7 @@ function copySetupFiles(cwd, setupDirOverride, features, options = {}) { snapshot.copied++; } } - return [retired, workflows, approvalWorkflow, issueTemplates, pullRequestTemplate, guidance, snapshot].reduce((total, current) => ({ + return [verificationAction, retired, workflows, approvalWorkflow, issueTemplates, pullRequestTemplate, guidance, snapshot].reduce((total, current) => ({ copied: total.copied + current.copied, skipped: total.skipped + current.skipped, }), { copied: 0, skipped: 0 }); @@ -90943,6 +93057,9 @@ const setup_workflow_upgrade_1 = __nccwpck_require__(85493); const setup_approval_workflow_1 = __nccwpck_require__(9512); const sensitive_text_1 = __nccwpck_require__(47122); const repository_agent_guidance_policy_1 = __nccwpck_require__(67402); +const setup_verification_action_1 = __nccwpck_require__(33156); +const setup_verification_action_2 = __nccwpck_require__(12471); +const copilot_comment_workflow_1 = __nccwpck_require__(33430); exports.SETUP_RUNNER_SNAPSHOT = '.copilot/runner-profile.json'; const object = (value) => value !== null && typeof value === 'object' && !Array.isArray(value) ? value : undefined; @@ -90984,6 +93101,22 @@ function inspectSetupInstallation(root, configuration, setup = (0, node_path_1.j const jobs = []; const changes = []; const blockers = []; + let action; + try { + action = (0, setup_verification_action_2.inspectSetupVerificationActionPath)(root); + } + catch (error) { + action = 'blocked'; + blockers.push(error instanceof Error ? error.message : 'Verification setup path could not be inspected.'); + } + const verificationSetup = { action, enabled: configuration.repository.verificationSetup ?? false, + mainBranch: configuration.repository.mainBranch }; + assets.push({ path: setup_verification_action_1.SETUP_VERIFICATION_ACTION_PATH, enabled: verificationSetup.enabled, + status: action === 'create' ? 'missing' : action === 'preserve' ? 'customized' : 'incompatible' }); + if (action === 'blocked') + return { assets, jobs, changes, blockers, verificationSetup }; + if (action === 'create') + changes.push({ path: setup_verification_action_1.SETUP_VERIFICATION_ACTION_PATH, before: null, after: (0, setup_verification_action_2.readSetupVerificationActionStarter)() }); const addJobs = (file, content, retained) => { const documents = (0, js_yaml_1.loadAll)(content); if (documents.length !== 1) @@ -90992,7 +93125,7 @@ function inspectSetupInstallation(root, configuration, setup = (0, node_path_1.j if (!parsedJobs) throw new Error('Workflow jobs are unavailable for review.'); for (const [job, raw] of Object.entries(parsedJobs)) { - const runsOn = object(raw)?.['runs-on']; + const runsOn = (0, copilot_comment_workflow_1.copilotCommentRunner)(object(raw)); if (runsOn === undefined) continue; // reusable workflow calls have no runner jobs.push({ file, job, role: (0, setup_runner_policy_1.setupRunnerRole)(file, job) ?? 'validation', @@ -91080,7 +93213,7 @@ function inspectSetupInstallation(root, configuration, setup = (0, node_path_1.j before: before === undefined ? null : (0, sensitive_text_1.redactSensitiveText)(before), after: (0, sensitive_text_1.redactSensitiveText)(after) }); if (after !== undefined && before !== undefined && !compatibleSetupRunnerSnapshot(before)) blockers.push('Runner snapshot is incompatible. Retain it or restore a supported version before replacing routing.'); - return { assets, jobs, changes, blockers }; + return { assets, jobs, changes, blockers, verificationSetup }; } @@ -91099,6 +93232,7 @@ const js_yaml_1 = __nccwpck_require__(783); const node_util_1 = __nccwpck_require__(47261); const setup_runner_policy_1 = __nccwpck_require__(91027); const action_types_1 = __nccwpck_require__(19625); +const copilot_comment_workflow_1 = __nccwpck_require__(33430); const object = (value) => value !== null && typeof value === 'object' && !Array.isArray(value) ? value : undefined; const document = (value) => { try { @@ -91120,6 +93254,8 @@ const runner = (value) => labels(value) || !!object(value) && (object(value).labels === undefined || labels(object(value).labels)); const copilotCommands = new Set(Object.values(action_types_1.ACTIONS)); const callsRootAction = (jobs) => !!jobs && Object.values(jobs).some(job => { + if (object(job)?.uses === copilot_comment_workflow_1.COPILOT_COMMENT_SELF_WORKFLOW) + return true; const steps = object(job)?.steps; return Array.isArray(steps) && steps.some(step => { const invocation = object(step); @@ -91182,6 +93318,32 @@ function renderSetupWorkflowUpgrade(template, existing, selection) { const templateJobs = object(document(template)?.jobs); if (!previousJobs || !templateJobs) throw new Error('Workflow jobs cannot be inspected; review the workflow separately.'); + if (Object.values(templateJobs).some(job => (0, copilot_comment_workflow_1.isCopilotCommentWorkflow)(object(job)?.uses))) { + const parsed = document(template); + const jobs = object(parsed.jobs); + let changed = false; + for (const [name, value] of Object.entries(jobs)) { + const job = object(value); + if (!(0, copilot_comment_workflow_1.isCopilotCommentWorkflow)(job.uses)) + throw new Error('Mixed comment workflow jobs require separate workflow review before setup.'); + const previousJob = object(previousJobs[name]); + if (Array.isArray(previousJob?.steps) && previousJob.steps.some(raw => { + const uses = object(raw)?.uses; + return typeof uses !== 'string' || !(uses.startsWith('actions/checkout@') + || /^vypdev\/copilot@[^\s]+$/u.test(uses) || uses === './.git/copilot-verification-setup'); + })) + throw new Error('Custom comment job steps require migration to the reviewed repository verification setup action before switching to the reusable workflow. Review the workflow separately.'); + const retained = (0, setup_runner_policy_1.selectedSetupRunsOn)(selection?.runners, selection && (0, setup_runner_policy_1.setupRunnerRole)(selection.file, name)) + ?? (0, copilot_comment_workflow_1.copilotCommentRunner)(previousJob) ?? (0, copilot_comment_workflow_1.copilotCommentRunner)(job); + if (!runner(retained)) + throw new Error('Existing runner selection is invalid; review the workflow separately.'); + if (JSON.stringify(retained).includes('${{') && existing !== template) + throw new Error('Dynamic runner selection requires separate workflow review before setup.'); + changed || (changed = !(0, node_util_1.isDeepStrictEqual)(retained, (0, copilot_comment_workflow_1.copilotCommentRunner)(job))); + job.with = { ...object(job.with), 'runs-on': JSON.stringify(retained) }; + } + return changed ? (0, js_yaml_1.dump)(parsed, { noRefs: true, lineWidth: -1 }) : template; + } const lines = template.split('\n'); let job = ''; let insideJobs = false; @@ -91557,6 +93719,14 @@ module.exports = require("node:stream"); /***/ }), +/***/ 76915: +/***/ ((module) => { + +"use strict"; +module.exports = require("node:string_decoder"); + +/***/ }), + /***/ 31764: /***/ ((module) => { diff --git a/build/web/assets/index-CsboG2sG.js b/build/web/assets/index-CNXf8Vmj.js similarity index 60% rename from build/web/assets/index-CsboG2sG.js rename to build/web/assets/index-CNXf8Vmj.js index edfe3da26..aeed8db3d 100644 --- a/build/web/assets/index-CsboG2sG.js +++ b/build/web/assets/index-CNXf8Vmj.js @@ -1,3 +1,3 @@ (function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})(),typeof window<`u`&&((window.__svelte??={}).v??=new Set).add(`5`);var e=!1;function t(){e=!0}t();var n={},r=Symbol(`uninitialized`),i=`http://www.w3.org/1999/xhtml`,a=Array.isArray,o=Array.prototype.indexOf,s=Array.prototype.includes,c=Array.from,l=Object.defineProperty,u=Object.getOwnPropertyDescriptor,d=Object.getOwnPropertyDescriptors,f=Object.prototype,p=Array.prototype,m=Object.getPrototypeOf,h=Object.isExtensible,g=()=>{};function _(e){return e()}function v(e){for(var t=0;t{e=n,t=r}),resolve:e,reject:t}}function b(e,t){if(Array.isArray(e))return e;if(t===void 0||!(Symbol.iterator in e))return Array.from(e);let n=[];for(let r of e)if(n.push(r),n.length===t)break;return n}var x=1024,S=2048,C=4096,w=8192,ee=16384,te=32768,ne=1<<25,re=65536,ie=1<<19,ae=1<<20,oe=1<<25,se=1<<21,ce=1<<22,le=1<<23,ue=Symbol(`$state`),de=Symbol(`component`),fe=Symbol(`legacy props`),pe=Symbol(``),me=Symbol(`attributes`),he=Symbol(`class`),ge=Symbol(`style`),_e=Symbol(`text`),ve=Symbol(`form reset`),ye=new class extends Error{name=`StaleReactionError`;message="The reaction that called `getAbortSignal()` was re-run or destroyed"},be=!!globalThis.document?.contentType&&globalThis.document.contentType.includes(`xml`);function xe(){console.warn(`https://svelte.dev/e/derived_inert`)}function Se(e){console.warn(`https://svelte.dev/e/hydration_mismatch`)}function Ce(){console.warn(`https://svelte.dev/e/select_multiple_invalid_value`)}function we(){console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`)}var T=!1;function Te(e){T=e}var E;function Ee(e){if(e===null)throw Se(),n;return E=e}function De(){return Ee(cn(E))}function D(e){if(T){if(cn(E)!==null)throw Se(),n;E=e}}function Oe(e=1){if(T){for(var t=e,n=E;t--;)n=cn(n);E=n}}function ke(e=!0){for(var t=0,n=E;;){if(n.nodeType===8){var r=n.data;if(r===`]`){if(t===0)return n;--t}else(r===`[`||r===`[!`||r[0]===`[`&&!isNaN(Number(r.slice(1))))&&(t+=1)}var i=cn(n);e&&n.remove(),n=i}}function Ae(e){if(!e||e.nodeType!==8)throw Se(),n;return e.data}function je(e){return e===this.v}function Me(e,t){return e==e?e!==t||typeof e==`object`&&!!e||typeof e==`function`:t==t}function Ne(e){return!Me(e,this.v)}function Pe(e){throw Error(`https://svelte.dev/e/lifecycle_outside_component`)}function Fe(){throw Error(`https://svelte.dev/e/async_derived_orphan`)}function Ie(e,t,n){throw Error(`https://svelte.dev/e/each_key_duplicate`)}function Le(e){throw Error(`https://svelte.dev/e/effect_in_teardown`)}function Re(){throw Error(`https://svelte.dev/e/effect_in_unowned_derived`)}function ze(e){throw Error(`https://svelte.dev/e/effect_orphan`)}function Be(){throw Error(`https://svelte.dev/e/effect_update_depth_exceeded`)}function Ve(e){throw Error(`https://svelte.dev/e/props_invalid_value`)}function He(){throw Error(`https://svelte.dev/e/state_descriptors_fixed`)}function Ue(){throw Error(`https://svelte.dev/e/state_prototype_fixed`)}function We(){throw Error(`https://svelte.dev/e/state_unsafe_mutation`)}function Ge(){throw Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`)}var Ke=null;function qe(e){Ke=e}function O(t,n=!1,r){Ke={p:Ke,i:!1,c:null,e:null,s:t,x:null,r:Yn,l:e&&!n?{s:null,u:null,$:[]}:null}}function k(e){var t=Ke,n=t.e;if(n!==null){t.e=null;for(var r of n)xn(r)}return e!==void 0&&(t.x=e),t.i=!0,Ke=t.p,Je(e)}function Je(e={}){return l(e,de,{value:!0}),e}function Ye(){return!e||Ke!==null&&Ke.l===null}var Xe=[];function Ze(){var e=Xe;Xe=[],v(e)}function Qe(e){if(Xe.length===0&&!Et){var t=Xe;queueMicrotask(()=>{t===Xe&&Ze()})}Xe.push(e)}function $e(){for(;Xe.length>0;)Ze()}var et=~(S|C|x);function tt(e,t){e.f=e.f&et|t}function nt(e){e.f&512||e.deps===null?tt(e,x):tt(e,C)}function rt(e,t,n){e.f&2048?t.add(e):e.f&4096&&n.add(e),tt(e,x)}function it(e){T&&sn(e)!==null&&ln(e)}var at=!1;function ot(){at||(at=!0,document.addEventListener(`reset`,e=>{Promise.resolve().then(()=>{if(!e.defaultPrevented)for(let t of e.target.elements)t[ve]?.()})},{capture:!0}))}function st(e){var t=Kn,n=Yn;Jn(null),Xn(null);try{return e()}finally{Jn(t),Xn(n)}}function ct(e,t,n,r=n){e.addEventListener(t,()=>st(n));let i=e[ve];e[ve]=i?()=>{i(),r(!0)}:()=>r(!0),ot()}function lt(e,t,n,r){let i=Ye()?pt:A;var a=e.filter(e=>!e.settled),o=t.map(i);if(n.length===0&&a.length===0){r(o);return}var s=Yn,c=ut(),l=a.length===1?a[0].promise:a.length>1?Promise.all(a.map(e=>e.promise)):null;function u(e){if(!(s.f&16384)){c();try{r([...o,...e])}catch(e){mn(e,s)}dt()}}var d=ft();if(n.length===0){l.then(()=>u([])).finally(d);return}function f(){Promise.all(n.map(e=>ht(e))).then(u).catch(e=>mn(e,s)).finally(d)}l?l.then(()=>{c(),f(),dt()}):f()}function ut(){var e=Yn,t=Kn,n=Ke,r=j;return function(i=!0){Xn(e),Jn(t),qe(n),i&&!(e.f&16384)&&(r?.activate(),r?.apply())}}function dt(e=!0){Xn(null),Jn(null),qe(null),e&&j?.deactivate()}function ft(){var e=Yn,t=e.b,n=j,r=!!t?.is_rendered();return t?.update_pending_count(1,n),n.increment(r,e),()=>{t?.update_pending_count(-1,n),n.decrement(r,e)}}function pt(e){var t=2|S;return Yn!==null&&(Yn.f|=ie),{ctx:Ke,deps:null,effects:null,equals:je,f:t,fn:e,reactions:null,rv:0,v:r,wv:0,parent:Yn,ac:null}}var mt=Symbol(`obsolete`);function ht(e,t,n){let i=Yn;i===null&&Fe();var a=void 0,o=Ut(r),s=!Kn,c=new Set;return Dn(()=>{var t=Yn,n=y();a=n.promise;try{Promise.resolve(e()).then(n.resolve,e=>{e!==ye&&n.reject(e)}).finally(dt)}catch(e){n.reject(e),dt()}var r=j;if(s){if(t.f&32768)var l=ft();if(i.b?.is_rendered())r.async_deriveds.get(t)?.reject(mt);else for(let e of c.values())e.reject(mt);c.add(n),r.async_deriveds.set(t,n)}let u=(e,t=void 0)=>{l?.(),c.delete(n),t!==mt&&(r.activate(),t?(o.f|=le,qt(o,t)):(o.f&8388608&&(o.f^=le),qt(o,e)),r.deactivate())};n.promise.then(u,e=>u(null,e||`unknown`))}),yn(()=>{for(let e of c)e.reject(mt)}),new Promise(e=>{function t(n){function r(){n===a?e(o):t(a)}n.then(r,r)}t(a)})}function gt(e){let t=pt(e);return Qn(t),t}function A(e){let t=pt(e);return t.equals=Ne,t}function _t(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n{t.ac.abort(ye),t.ac=null}),t.fn!==null&&(t.teardown=g),pr(t,0),Mn(t))}function xt(e){if(e.effects!==null)for(let t of e.effects)t.teardown&&t.fn!==null&&mr(t)}var St=null,j=null,Ct=null,wt=null,Tt=null,Et=!1,Dt=!1,Ot=null,kt=null,At=0,jt=1,Mt=class e{id=jt++;#e=!1;linked=!0;#t=null;#n=null;async_deriveds=new Map;current=new Map;previous=new Map;#r=new Set;#i=new Set;#a=0;#o=new Map;#s=null;#c=[];#l=[];#u=new Set;#d=new Set;#f=new Map;#p=new Set;is_fork=!1;#m=!1;constructor(){St===null?St=this:(St.#n=this,this.#t=St),St=this}#h(){if(this.is_fork)return!0;for(let n of this.#o.keys()){for(var e=n,t=!1;e.parent!==null;){if(this.#f.has(e)){t=!0;break}e=e.parent}if(!t)return!0}return!1}skip_effect(e){this.#f.has(e)||this.#f.set(e,{d:[],m:[]}),this.#p.delete(e)}unskip_effect(e,t=e=>this.schedule(e)){var n=this.#f.get(e);if(n){this.#f.delete(e);for(var r of n.d)tt(r,S),t(r);for(r of n.m)tt(r,C),t(r)}this.#p.add(e)}#g(){var e=[];for(let i of this.#c)if(!(i.f&16384||!(i.f&6144))){for(var t=i,n=!1;t.parent!==null;){t=t.parent;var r=t.f;if(r&96){if(!(r&1024)){n=!0;break}t.f^=x}}n||e.push(t)}return this.#c=[],e}#_(){this.#e=!0;for(let e of this.#u)this.#d.delete(e),tt(e,S),this.schedule(e);for(let e of this.#d)tt(e,C),this.schedule(e);this.apply();for(var t=Ot=[],n=[],r=kt=[];this.#c.length>0;){At++>1e3&&(this.#S(),Pt());for(let e of this.#g())try{this.#v(e,t,n)}catch(t){throw zt(e),this.#h()||this.discard(),t}}if(j=null,r.length>0){var i=e.ensure();for(let e of r)i.schedule(e)}if(Ot=null,kt=null,this.#h()){this.#x(n),this.#x(t);for(let[e,t]of this.#f)Rt(e,t);r.length>0&&j.#_();return}let a=this.#y();if(a){this.#x(n),this.#x(t),a.#b(this);return}this.#u.clear(),this.#d.clear();for(let e of this.#r)e(this);this.#r.clear(),Ct=this,It(n),It(t),Ct=null,this.#s?.resolve();var o=j;if(this.#a===0&&(this.#c.length===0||o!==null)&&this.#S(),this.#c.length>0){if(o!==null){for(let e of this.#c)o.#c.push(e);this.#c=[]}else o=this}o!==null&&(Vt.clear(),o.#_())}#v(e,t,n){e.f^=x;for(var r=e.first;r!==null;){var i=r.f,a=!!(i&96);if(!(a&&i&1024||i&8192||this.#f.has(r))&&r.fn!==null){a?r.f^=x:i&4?t.push(r):cr(r)&&(i&16&&this.#d.add(r),mr(r));var o=r.first;if(o!==null){r=o;continue}}for(;r!==null;){var s=r.next;if(s!==null){r=s;break}r=r.parent}}}#y(){for(var e=this.#t;e!==null;){if(!e.is_fork){for(let[t,[,n]]of this.current)if(e.current.has(t)&&!n)return e}e=e.#t}return null}#b(e){for(let[t,n]of e.current)!this.previous.has(t)&&e.previous.has(t)&&this.previous.set(t,e.previous.get(t)),this.current.set(t,n);for(let[t,n]of e.async_deriveds){let e=this.async_deriveds.get(t);e&&n.promise.then(e.resolve).catch(e.reject)}e.async_deriveds.clear(),this.transfer_effects(e.#u,e.#d);let t=e=>{var n=e.reactions;if(n!==null&&!(e.f&2&&!(e.f&6144)))for(let e of n){var r=e.f;if(r&2)t(e);else{var i=e;r&4194320&&!this.async_deriveds.has(i)&&(this.#d.delete(i),tt(i,S),this.schedule(i))}}};for(let e of this.current.keys())t(e);this.oncommit(()=>e.discard()),e.#S(),j=this,this.#_()}#x(e){for(var t=0;t{this.#m=!1,this.linked&&this.flush()}))}transfer_effects(e,t){for(let t of e)this.#u.add(t);for(let e of t)this.#d.add(e);e.clear(),t.clear()}oncommit(e){this.#r.add(e)}ondiscard(e){this.#i.add(e)}settled(){return(this.#s??=y()).promise}static ensure(){if(j===null){let t=j=new e;!Dt&&!Et&&Qe(()=>{t.#e||t.flush()})}return j}apply(){wt=null}schedule(e){if(Tt=e,e.b?.is_pending&&e.f&16777228&&!(e.f&32768)){e.b.defer_effect(e);return}this.#c.push(e)}#S(){if(this.linked){var e=this.#t,t=this.#n;e===null||(e.#n=t),t===null?St=e:t.#t=e,this.linked=!1}}};function Nt(e){var t=Et;Et=!0;try{var n;for(e&&(j!==null&&!j.is_fork&&j.flush(),n=e());;){if($e(),j===null)return n;j.flush()}}finally{Et=t}}function Pt(){try{Be()}catch(e){mn(e,Tt)}}var Ft=null;function It(e){var t=e.length;if(t!==0){for(var n=0;n0)){Vt.clear();for(let e of Ft){if(e.f&24576)continue;let t=[e],n=e.parent;for(;n!==null;)Ft.has(n)&&(Ft.delete(n),t.push(n)),n=n.parent;for(let e=t.length-1;e>=0;e--){let n=t[e];n.f&24576||mr(n)}}Ft.clear()}}Ft=null}}function Lt(e){j.schedule(e)}function Rt(e,t){if(!(e.f&32&&e.f&1024)){e.f&2048?t.d.push(e):e.f&4096&&t.m.push(e),tt(e,x);for(var n=e.first;n!==null;)Rt(n,t),n=n.next}}function zt(e){tt(e,x);for(var t=e.first;t!==null;)zt(t),t=t.next}var Bt=new Set,Vt=new Map,Ht=!1;function Ut(e,t){return{f:0,v:e,reactions:null,equals:je,rv:0,wv:0}}function Wt(e,t){let n=Ut(e,t);return Qn(n),n}function M(t,n=!1,r=!0){let i=Ut(t);return n||(i.equals=Ne),e&&r&&Ke!==null&&Ke.l!==null&&(Ke.l.s??=[]).push(i),i}function N(e,t,n=!1){return Kn!==null&&(!qn||Kn.f&131072)&&Ye()&&Kn.f&4325394&&(Zn===null||!Zn.has(e))&&We(),qt(e,n?Zt(t):t,kt)}var Gt=null,Kt=0;function qt(e,t,n=null){if(!e.equals(t)){Wn?Vt.set(e,t):Vt.has(e)||Vt.set(e,e.v);var r=Mt.ensure();if(r.capture(e,t),e.f&2){let t=e;e.f&2048&&vt(t),wt===null&&nt(t)}e.wv=sr(),Gt=null,Kt=0,Xt(e,S,n),Gt=null,Ye()&&Yn!==null&&Yn.f&1024&&!(Yn.f&96)&&(tr===null?nr([e]):tr.push(e)),!r.is_fork&&Bt.size>0&&!Ht&&Jt()}return t}function Jt(){Ht=!1;for(let e of Bt){e.f&1024&&tt(e,C);let t;try{t=cr(e)}catch{t=!0}t&&mr(e)}Bt.clear()}function Yt(e){N(e,e.v+1)}function Xt(e,t,n){var r=e.reactions;if(r!==null){var i=Ye(),a=r.length;if(Kt+=a,Kt>1e5&&Gt===null&&(Gt=new Set),Gt!==null){if(Gt.has(e))return;Gt.add(e)}for(var o=0;o{if(ar===c)return e();var t=Kn,n=ar;Jn(null),or(c);var r=e();return Jn(t),or(n),r};return i&&n.set(`length`,Wt(e.length,s)),new Proxy(e,{defineProperty(e,t,r){(!(`value`in r)||r.configurable===!1||r.enumerable===!1||r.writable===!1)&&He();var i=n.get(t);return i===void 0?l(()=>{var e=Wt(r.value,s);return n.set(t,e),e}):N(i,r.value,!0),!0},deleteProperty(e,t){var i=n.get(t);if(i===void 0){if(t in e){let e=l(()=>Wt(r,s));n.set(t,e),Yt(o)}}else N(i,r),Yt(o);return!0},get(t,i,a){if(i===ue)return e;var o=n.get(i),c=i in t;if(o===void 0&&(!c||u(t,i)?.writable)&&(o=l(()=>Wt(Zt(c?t[i]:r),s)),n.set(i,o)),o!==void 0){var d=z(o);return d===r?void 0:d}return Reflect.get(t,i,a)},getOwnPropertyDescriptor(e,t){this.has?.(e,t);var i=Reflect.getOwnPropertyDescriptor(e,t),a=n.get(t);if(a!==void 0){var o=z(a);if(o===r)return;if(i&&`value`in i)i.value=o;else return{enumerable:!0,configurable:!0,value:o,writable:!0}}return i},has(e,t){if(t===ue)return!0;var i=n.get(t),a=i!==void 0&&i.v!==r||Reflect.has(e,t);return(i!==void 0||Yn!==null&&(!a||u(e,t)?.writable))&&(i===void 0&&(i=l(()=>Wt(a?Zt(e[t]):r,s)),n.set(t,i)),z(i)===r)?!1:a},set(e,t,a,c){var d=n.get(t),f=t in e;if(i&&t===`length`)for(var p=a;pWt(r,s)),n.set(p+``,m)):N(m,r)}if(d===void 0)(!f||u(e,t)?.writable)&&(d=l(()=>Wt(void 0,s)),N(d,Zt(a)),n.set(t,d));else{f=d.v!==r;var h=l(()=>Zt(a));N(d,h)}var g=Reflect.getOwnPropertyDescriptor(e,t);if(g?.set&&g.set.call(c,a),!f){if(i&&typeof t==`string`){var _=n.get(`length`),v=Number(t);Number.isInteger(v)&&v>=_.v&&N(_,v+1)}Yt(o)}return!0},ownKeys(e){z(o);var t=Reflect.ownKeys(e).filter(e=>{var t=n.get(e);return t===void 0||t.v!==r});for(var[i,a]of n)a.v!==r&&!(i in e)&&t.push(i);return t},setPrototypeOf(){Ue()}})}function Qt(e){try{if(typeof e==`object`&&e&&ue in e)return e[ue]}catch{}return e}function $t(e,t){return Object.is(Qt(e),Qt(t))}var en,tn,nn,rn;function an(){if(en===void 0){en=window,tn=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;nn=u(t,`firstChild`).get,rn=u(t,`nextSibling`).get,h(e)&&(e[he]=void 0,e[me]=null,e[ge]=void 0,e.__e=void 0),h(n)&&(n[_e]=void 0)}}function on(e=``){return document.createTextNode(e)}function sn(e){return nn.call(e)}function cn(e){return rn.call(e)}function P(e,t){if(!T)return sn(e);var n=sn(E);if(n===null)n=E.appendChild(on());else if(t&&n.nodeType!==3){var r=on();return n?.before(r),Ee(r),r}return t&&fn(n),Ee(n),n}function F(e,t=!1){if(!T){var n=sn(e);return n instanceof Comment&&n.data===``?cn(n):n}if(t){if(E?.nodeType!==3){var r=on();return E?.before(r),Ee(r),r}fn(E)}return E}function I(e,t=!1){if(!T)return sn(e);var n=P(e,t);return D(e),n}function L(e,t=1,n=!1){let r=T?E:e;for(var i;t--;)i=r,r=cn(r);if(!T)return r;if(n){if(r?.nodeType!==3){var a=on();return r===null?i?.after(a):r.before(a),Ee(a),a}fn(r)}return Ee(r),r}function ln(e){e.textContent=``}function un(){return!1}function dn(e,t,n){return t==null||t===`http://www.w3.org/1999/xhtml`?n?document.createElement(e,{is:n}):document.createElement(e):n?document.createElementNS(t,e,{is:n}):document.createElementNS(t,e)}function fn(e){if(e.nodeValue.length<65536)return;let t=e.nextSibling;for(;t!==null&&t.nodeType===3;)t.remove(),e.nodeValue+=t.nodeValue,t=e.nextSibling}function pn(e){var t=Yn;if(t===null)return Kn.f|=le,e;if(!(t.f&32768)&&!(t.f&4))throw e;mn(e,t)}function mn(e,t){if(!(t!==null&&t.f&16384)){for(;t!==null;){if(t.f&128&&!(t.f&33570816)){if(!(t.f&32768))throw e;try{t.b.error(e);return}catch(t){e=t}}t=t.parent}throw e}}function hn(e){Yn===null&&(Kn===null&&ze(e),Re()),Wn&&Le(e)}function gn(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function _n(e,t){var n=Yn;n!==null&&n.f&8192&&(e|=w);var r={ctx:Ke,deps:null,nodes:null,f:e|S|512,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null};j?.register_created_effect(r);var i=r;if(e&4)Ot===null?Mt.ensure().schedule(r):Ot.push(r);else if(t!==null){try{mr(r)}catch(e){throw Pn(r),e}i.deps===null&&i.teardown===null&&i.nodes===null&&i.first===i.last&&!(i.f&524288)&&(i=i.first,e&16&&e&65536&&i!==null&&(i.f|=re))}if(i!==null&&(i.parent=n,n!==null&&gn(i,n),Kn!==null&&Kn.f&2&&!(e&64))){var a=Kn;(a.effects??=[]).push(i)}return r}function vn(){return Kn!==null&&!qn}function yn(e){let t=_n(8,null);return tt(t,x),t.teardown=e,t}function bn(e){hn(`$effect`);var t=Yn.f;if(!Kn&&t&32&&Ke!==null&&!Ke.i){var n=Ke;(n.e??=[]).push(e)}else return xn(e)}function xn(e){return _n(4|ae,e)}function Sn(e){return hn(`$effect.pre`),_n(8|ae,e)}function Cn(e){Mt.ensure();let t=_n(64|ie,e);return(e={})=>new Promise(n=>{e.outro?Ln(t,()=>{Pn(t),n(void 0)}):(Pn(t),n(void 0))})}function wn(e){return _n(4,e)}function Tn(e,t){var n=Ke,r={effect:null,ran:!1,deps:e};n.l.$.push(r),r.effect=On(()=>{if(e(),!r.ran){r.ran=!0;var n=Yn;try{Xn(n.parent),B(t)}finally{Xn(n)}}})}function En(){var e=Ke;On(()=>{for(var t of e.l.$){t.deps();var n=t.effect;n.f&1024&&n.deps!==null&&tt(n,C),cr(n)&&mr(n),t.ran=!1}})}function Dn(e){return _n(ce|ie,e)}function On(e,t=0){return _n(8|t,e)}function R(e,t=[],n=[],r=[]){lt(r,t,n,t=>{_n(8,()=>{e(...t.map(z))})})}function kn(e,t=0){return _n(16|t,e)}function An(e){return _n(32|ie,e)}function jn(e){var t=e.teardown;if(t!==null){let n=Wn,r=Kn;Gn(!0),Jn(null);try{t.call(null)}catch(t){mn(t,e.parent)}finally{Gn(n),Jn(r)}}}function Mn(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){let e=n.ac;e!==null&&st(()=>{e.abort(ye)});var r=n.next;n.f&64?n.parent=null:Pn(n,t),n=r}}function Nn(e){for(var t=e.first;t!==null;){var n=t.next;t.f&32||Pn(t),t=n}}function Pn(e,t=!0){var n=!1;(t||e.f&262144)&&e.nodes!==null&&e.nodes.end!==null&&(Fn(e.nodes.start,e.nodes.end),n=!0),e.f|=ne,Mn(e,t&&!n),pr(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)e.stop();jn(e),e.f^=ne,e.f|=ee;var i=e.parent;i!==null&&i.first!==null&&In(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=e.b=null}function Fn(e,t){for(;e!==null;){var n=e===t?null:cn(e);e.remove(),e=n}}function In(e){var t=e.parent,n=e.prev,r=e.next;n!==null&&(n.next=r),r!==null&&(r.prev=n),t!==null&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function Ln(e,t,n=!0){var r=[];e.f|=256,Rn(e,r,!0);var i=()=>{n&&Pn(e),t&&t()},a=r.length;if(a>0){var o=()=>--a||i();for(var s of r)s.out(o)}else i()}function Rn(e,t,n){if(!(e.f&8192)){e.f^=w;var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)(e.is_global||n)&&t.push(e);for(var i=e.first;i!==null;){var a=i.next;if(!(i.f&64)){var o=!!(i.f&65536)||!!(i.f&32)&&!!(e.f&16);Rn(i,t,o?n:!1)}i=a}}}function zn(e){e.f&=-257,Bn(e,!0)}function Bn(e,t){if(!(e.f&256)&&e.f&8192){e.f^=w,e.f&1024||(tt(e,S),Mt.ensure().schedule(e));for(var n=e.first;n!==null;){var r=n.next,i=!!(n.f&65536)||!!(n.f&32);Bn(n,i?t:!1),n=r}var a=e.nodes&&e.nodes.t;if(a!==null)for(let e of a)(e.is_global||t)&&e.in()}}function Vn(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var i=n===r?null:cn(n);t.append(n),n=i}}var Hn=null,Un=!1,Wn=!1;function Gn(e){Wn=e}var Kn=null,qn=!1;function Jn(e){Kn=e}var Yn=null;function Xn(e){Yn=e}var Zn=null;function Qn(e){Kn!==null&&(Kn.f&2097152||Kn.f&2)&&(Zn??=new Set).add(e)}var $n=null,er=0,tr=null;function nr(e){tr=e}var rr=1,ir=0,ar=ir;function or(e){ar=e}function sr(){return++rr}function cr(e){var t=e.f;if(t&2048)return!0;if(t&4096){for(var n=e.deps,r=n.length,i=0;ie.wv)return!0}t&512&&wt===null&&tt(e,x)}return!1}function lr(e,t,n=!0){var r=e.reactions;if(r!==null&&!(Zn!==null&&Zn.has(e)))for(var i=0;i{e.ac.abort(ye)}),e.ac=null);try{e.f|=se;var u=e.fn,d=u();e.f|=te;var f=dr(e);if(Ye()&&tr!==null&&!qn&&f!==null&&!(e.f&6146))for(var p=0;p0)for(t.length=er+$n.length,r=0;r<$n.length;r++)t[er+r]=$n[r];else e.deps=t=$n;if(vn()&&e.f&512)for(r=er;r{c.ac.abort(ye),c.ac=null,tt(c,S)}),bt(c),pr(c,0)}}function pr(e,t){var n=e.deps;if(n!==null)for(var r=t;rn?.call(this,e))}return e.startsWith(`pointer`)||e.startsWith(`touch`)||e===`wheel`?(i.__removed=!1,Qe(()=>{i.__removed||t.addEventListener(e,i,r)})):t.addEventListener(e,i,r),i}function Cr(e,t,n,r,i){var a={capture:r,passive:i},o=Sr(e,t,n,a);(t===document.body||t===window||t===document||t instanceof HTMLMediaElement)&&yn(()=>{o.__removed=!0,t.removeEventListener(e,o,a)})}function wr(e,t,n){(t[yr]??={})[e]=n}function Tr(e){for(var t=0;t{Dr=!1,Er=null}));var o=0,s=Er===e&&e[yr];if(s){var c=i.indexOf(s);if(c!==-1&&(t===document||t===window)){e[yr]=t;return}var u=i.indexOf(t);if(u===-1)return;c<=u&&(o=c)}if(a=i[o]||e.target,a!==t){l(e,`currentTarget`,{configurable:!0,get(){return a||n}});var d=Kn,f=Yn;Jn(null),Xn(null);try{for(var p,m=[];a!==null&&a!==t;){try{var h=a[yr]?.[r];h!=null&&(!a.disabled||e.target===a)&&h.call(a,e)}catch(e){p?m.push(e):p=e}if(e.cancelBubble)break;o++,a=o{throw e});throw p}}finally{e[yr]=t,delete e.currentTarget,Jn(d),Xn(f)}}}var kr=globalThis?.window?.trustedTypes&&globalThis.window.trustedTypes.createPolicy(`svelte-trusted-html`,{createHTML:e=>e});function Ar(e){return kr?.createHTML(e)??e}function jr(e){var t=dn(`template`);return t.innerHTML=Ar(e.replaceAll(``,``)),t.content}function Mr(e,t){var n=Yn;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function H(e,t){var n=!!(t&1),r=!!(t&2),i,a=!e.startsWith(``);return()=>{if(T)return Mr(E,null),E;i===void 0&&(i=jr(a?e:``+e),n||(i=sn(i)));var t=r||tn?document.importNode(i,!0):i.cloneNode(!0);if(n){var o=sn(t),s=t.lastChild;Mr(o,s)}else Mr(t,t);return t}}function Nr(e=``){if(!T){var t=on(e+``);return Mr(t,t),t}var n=E;return n.nodeType===3?fn(n):(n.before(n=on()),Ee(n)),Mr(n,n),n}function Pr(){if(T)return Mr(E,null),E;var e=document.createDocumentFragment(),t=document.createComment(``),n=on();return e.append(t,n),Mr(t,n),e}function U(e,t){if(T){var n=Yn;(!(n.f&32768)||n.nodes.end===null)&&(n.nodes.end=E),De();return}e!==null&&e.before(t)}[...`allowfullscreen.async.autofocus.autoplay.checked.controls.default.disabled.formnovalidate.indeterminate.inert.ismap.loop.multiple.muted.nomodule.novalidate.open.playsinline.readonly.required.reversed.seamless.selected.webkitdirectory.defer.disablepictureinpicture.disableremoteplayback`.split(`.`)];var Fr=[`touchstart`,`touchmove`];function Ir(e){return Fr.includes(e)}function Lr(e){let t=0,n=Ut(0),r;return()=>{vn()&&(z(n),On(()=>(t===0&&(r=B(()=>e(()=>Yt(n)))),t+=1,()=>{Qe(()=>{--t,t===0&&(r?.(),r=void 0,Yt(n))})})))}}var Rr=re|ie;function zr(e,t,n,r){new Br(e,t,n,r)}var Br=class{parent;is_pending=!1;transform_error;#e;#t=T?E:null;#n;#r;#i;#a=null;#o=null;#s=null;#c=null;#l=0;#u=0;#d=!1;#f=new Set;#p=new Set;#m=null;#h=Lr(()=>(this.#m=Ut(this.#l),()=>{this.#m=null}));constructor(e,t,n,r){this.#e=e,this.#n=t,this.#r=e=>{var t=Yn;t.b=this,t.f|=128,n(e)},this.parent=Yn.b,this.transform_error=r??this.parent?.transform_error??(e=>e),this.#i=kn(()=>{if(T){let e=this.#t;De();let t=e.data===`[!`;if(e.data.startsWith(`[?`)){let t=JSON.parse(e.data.slice(2));this.#_(t)}else t?this.#y():this.#g()}else this.#b()},Rr),T&&(this.#e=E)}#g(){try{this.#a=An(()=>this.#r(this.#e))}catch(e){this.error(e)}}#_(e){let t=this.#n.failed,{reset:n,invoke_onerror:r}=this.#v(e);Qe(r),t&&(this.#s=An(()=>{t(this.#e,()=>e,()=>n)}))}#v(e){var t=!1,n=!1;let r=()=>{if(t){we();return}t=!0,n&&Ge(),this.#s!==null&&Ln(this.#s,()=>{this.#s=null}),this.#S(()=>{this.#b()})};return{reset:r,invoke_onerror:()=>{try{n=!0,this.#n.onerror?.(e,r),n=!1}catch(e){mn(e,this.#i&&this.#i.parent)}}}}#y(){let e=this.#n.pending;e&&(this.is_pending=!0,this.#o=An(()=>e(this.#e)),Qe(()=>{var e=this.#c=document.createDocumentFragment(),t=on(),n=!1;if(e.append(t),this.#a=this.#S(()=>{try{return An(()=>this.#r(t))}catch(e){try{this.error(e),n=!0}catch(e){mn(e,this.#i.parent)}return null}}),this.#a===null){this.#c=null,n&&this.#x(j);return}this.#u===0&&(this.#e.before(e),this.#c=null,Ln(this.#o,()=>{this.#o=null}),this.#x(j))}))}#b(){try{if(this.is_pending=this.has_pending_snippet(),this.#u=0,this.#l=0,this.#a=An(()=>{this.#r(this.#e)}),this.#u>0){var e=this.#c=document.createDocumentFragment();Vn(this.#a,e);let t=this.#n.pending;this.#o=An(()=>t(this.#e))}else this.#x(j)}catch(e){this.error(e)}}#x(e){this.is_pending=!1,e.transfer_effects(this.#f,this.#p)}defer_effect(e){rt(e,this.#f,this.#p)}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!this.#n.pending}#S(e){var t=Yn,n=Kn,r=Ke;Xn(this.#i),Jn(this.#i),qe(this.#i.ctx);try{return Mt.ensure(),e()}finally{Xn(t),Jn(n),qe(r)}}#C(e,t){if(!this.has_pending_snippet()){this.parent&&this.parent.#C(e,t);return}this.#u+=e,this.#u===0&&(this.#x(t),this.#o&&Ln(this.#o,()=>{this.#o=null}),this.#c&&=(this.#e.before(this.#c),null))}update_pending_count(e,t){this.#C(e,t),this.#l+=e,!(!this.#m||this.#d)&&(this.#d=!0,Qe(()=>{this.#d=!1,this.#m&&qt(this.#m,this.#l)}))}get_effect_pending(){return this.#h(),z(this.#m)}error(e){if(!this.#n.onerror&&!this.#n.failed)throw e;j?.is_fork?(this.#a&&j.skip_effect(this.#a),this.#o&&j.skip_effect(this.#o),this.#s&&j.skip_effect(this.#s),j.oncommit(()=>{this.#w(e)})):this.#w(e)}#w(e){this.#a&&=(Pn(this.#a),null),this.#o&&=(Pn(this.#o),null),this.#s&&=(Pn(this.#s),null),T&&(Ee(this.#t),Oe(),Ee(ke()));let t=this.#n.failed,n=e=>{let{reset:n,invoke_onerror:r}=this.#v(e);r(),t&&(this.#s=this.#S(()=>{try{return An(()=>{var r=Yn;r.b=this,r.f|=128,t(this.#e,()=>e,()=>n)})}catch(e){return mn(e,this.#i.parent),null}}))};Qe(()=>{var t;try{t=this.transform_error(e)}catch(e){mn(e,this.#i&&this.#i.parent);return}typeof t==`object`&&t&&typeof t.then==`function`?t.then(n,e=>mn(e,this.#i&&this.#i.parent)):n(t)})}};function W(e,t){var n=t==null?``:typeof t==`object`?`${t}`:t;n!==(e[_e]??=e.nodeValue)&&(e[_e]=n,e.nodeValue=`${n}`)}function Vr(e,t){return Ur(e,t)}var Hr=new Map;function Ur(e,{target:t,anchor:r,props:i={},events:a,context:o,intro:s=!0,transformError:l}){an();var u=void 0,d=Cn(()=>{var s=r??t.appendChild(on());zr(s,{pending:()=>{}},t=>{O({});var r=Ke;if(o&&(r.c=o),a&&(i.$$events=a),T&&Mr(t,null),u=e(t,i)||Je(),T&&(Yn.nodes.end=E,E===null||E.nodeType!==8||E.data!==`]`))throw Se(),n;k()},l);var d=new Set,f=e=>{for(var n=0;n{for(var e of d)for(let r of[t,document]){var n=Hr.get(r),i=n.get(e);--i==0?(r.removeEventListener(e,Or),n.delete(e),n.size===0&&Hr.delete(r)):n.set(e,i)}xr.delete(f),s!==r&&s.parentNode?.removeChild(s)}});return Wr.set(u,d),u}var Wr=new WeakMap,Gr=class{anchor;#e=new Map;#t=new Map;#n=new Map;#r=new Set;#i=!0;constructor(e,t=!0){this.anchor=e,this.#i=t}#a=e=>{if(this.#e.has(e)){var t=this.#e.get(e),n=this.#t.get(t);if(n)zn(n),this.#r.delete(t);else{var r=this.#n.get(t);r&&(zn(r.effect),this.#t.set(t,r.effect),this.#n.delete(t),r.fragment.lastChild.remove(),this.anchor.before(r.fragment),n=r.effect)}for(let[t,n]of this.#e){if(this.#e.delete(t),t===e)break;let r=this.#n.get(n);r&&(Pn(r.effect),this.#n.delete(n))}for(let[e,r]of this.#t){if(e===t||this.#r.has(e))continue;let i=()=>{if(Array.from(this.#e.values()).includes(e)){var t=document.createDocumentFragment();Vn(r,t),t.append(on()),this.#n.set(e,{effect:r,fragment:t})}else Pn(r);this.#r.delete(e),this.#t.delete(e)};this.#i||!n?(this.#r.add(e),Ln(r,i,!1)):i()}}};#o=e=>{this.#e.delete(e);let t=Array.from(this.#e.values());for(let[e,n]of this.#n)t.includes(e)||(Pn(n.effect),this.#n.delete(e))};ensure(e,t){var n=j,r=un();if(t&&!this.#t.has(e)&&!this.#n.has(e)){if(r){var i=document.createDocumentFragment(),a=on();i.append(a),this.#n.set(e,{effect:An(()=>t(a)),fragment:i})}else this.#t.set(e,An(()=>t(this.anchor)))}if(this.#e.set(n,e),r){for(let[t,r]of this.#t)t===e?n.unskip_effect(r):n.skip_effect(r);for(let[t,r]of this.#n)t===e?n.unskip_effect(r.effect):n.skip_effect(r.effect);n.oncommit(this.#a),n.ondiscard(this.#o)}else T&&(this.anchor=E),this.#a(n)}};function Kr(t){Ke===null&&Pe(`onMount`),e&&Ke.l!==null?qr(Ke).m.push(t):bn(()=>{let e=B(t);if(typeof e==`function`)return e})}function qr(e){var t=e.l;return t.u??={a:[],b:[],m:[]}}function G(e,t,n=!1){var r;T&&(r=E,De());var i=new Gr(e),a=n?re:0;function o(e,t){if(T){var n=Ae(r);if(e!==parseInt(n.substring(1))){var a=ke();Ee(a),i.anchor=a,Te(!1),i.ensure(e,t),Te(!0);return}}i.ensure(e,t)}kn(()=>{var e=!1;t((t,n=0)=>{e=!0,o(n,t)}),e||o(-1,null)},a)}var Jr=Symbol(`NaN`);function Yr(e,t,n){T&&De();var r=new Gr(e),i=!Ye();kn(()=>{var e=t();e!==e&&(e=Jr),i&&typeof e==`object`&&e&&(e={}),r.ensure(e,n)})}function K(e,t){return t}function Xr(e,t,n){for(var r=[],i=t.length,a,o=t.length,s=0;s{if(a){if(a.pending.delete(n),a.done.add(n),a.pending.size===0){var t=e.outrogroups;Zr(e,c(a.done)),t.delete(a),t.size===0&&(e.outrogroups=null)}}else--o},!1)}if(o===0){var l=r.length===0&&n!==null&&e.pending.size===0;if(l){var u=n,d=u.parentNode;ln(d),d.append(u),e.items.clear()}Zr(e,t,!l)}else a={pending:new Set(t),done:new Set},(e.outrogroups??=new Set).add(a)}function Zr(e,t,n=!0){var r;if(e.pending.size>0){r=new Set;for(let t of e.pending.values())for(let n of t)r.add(e.items.get(n).e)}for(var i=0;i{var e=n();return a(e)?e:e==null?[]:c(e)}),p,m=new Map,h=!0;function g(e){v.effect.f&16384||(v.pending.delete(e),v.fallback=d,ei(v,p,s,t,r),d!==null&&(p.length===0?d.f&33554432?(d.f^=oe,ni(d,null,s)):zn(d):Ln(d,()=>{d=null})))}function _(e){v.pending.delete(e)}var v={effect:kn(()=>{p=z(f);var e=p.length;let a=!1;T&&Ae(s)===`[!`!=(e===0)&&(s=ke(),Ee(s),Te(!1),a=!0);for(var c=new Set,u=j,v=un(),y=0;yo(s)):(d=An(()=>o(Qr??=on())),d.f|=oe)),e>c.size&&Ie(``,``,``),T&&e>0&&Ee(ke()),!h){if(m.set(u,c),v){for(let[e,t]of l)c.has(e)||u.skip_effect(t.e);u.oncommit(g),u.ondiscard(_)}else g(u)}a&&Te(!0),z(f)}),flags:t,items:l,pending:m,outrogroups:null,fallback:d};h=!1,T&&(s=E)}function $r(e){for(;e!==null&&!(e.f&32);)e=e.next;return e}function ei(e,t,n,r,i){var a=!!(r&8),o=t.length,s=e.items,l=$r(e.effect.first),u,d=null,f,p=[],m=[],h,g,_,v;if(a)for(v=0;v0){var te=r&4&&o===0?n:null;if(a){for(v=0;v{if(f!==void 0)for(_ of f)_.nodes?.a?.apply()})}function ti(e,t,n,r,i,a,o,s){var c=o&1?o&16?Ut(n):M(n,!1,!1):null,l=o&2?Ut(i):null;return{v:c,i:l,e:An(()=>(a(t,c??n,l??i,s),()=>{e.delete(r)}))}}function ni(e,t,n){if(e.nodes)for(var r=e.nodes.start,i=e.nodes.end,a=t&&!(t.f&33554432)?t.nodes.start:n;r!==null;){var o=cn(r);if(a.before(r),r===i)return;r=o}}function ri(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function ii(e,t,n){wn(()=>{var r=B(()=>t(e,n?.())||{});if(n&&r?.update){var i=!1,a={};On(()=>{var e=n();V(e),i&&Me(a,e)&&(a=e,r.update(e))}),i=!0}if(r?.destroy)return()=>r.destroy()})}function ai(e){var t,n,r=``;if(typeof e==`string`||typeof e==`number`)r+=e;else if(typeof e==`object`){if(Array.isArray(e)){var i=e.length;for(t=0;t=0;){var s=o+a;(o===0||ci.includes(r[o-1]))&&(s===r.length||ci.includes(r[s]))?r=(o===0?``:r.substring(0,o))+r.substring(s+1):o=s}}return r===``?null:r}function ui(e,t,n,r,i,a){var o=e[he];if(T||o!==n||o===void 0){var s=li(n,r,a);(!T||s!==e.getAttribute(`class`))&&(s==null?e.removeAttribute(`class`):t?e.className=s:e.setAttribute(`class`,s)),e[he]=n}else if(a&&i!==a)for(var c in a){var l=!!a[c];(i==null||l!==!!i[c])&&e.classList.toggle(c,l)}return a}function di(e,t){t?e.hasAttribute(`selected`)||e.setAttribute(`selected`,``):e.removeAttribute(`selected`)}function fi(e,t){var n=e.__defaultValue,r=e.multiple,i=r?n??[]:null;if(!r||a(i)){var o=e.selectedIndex,s=t&&r?new Set(e.selectedOptions):null;for(var c of e.options){var l=gi(c);di(c,r?i.includes(l):$t(l,n))}if(t){if(s!==null)for(c of e.options){var u=s.has(c);c.selected!==u&&(c.selected=u)}else e.selectedIndex!==o&&(e.selectedIndex=o)}}}function pi(e,t,n=!1){if(e.multiple){if(t==null)return;if(!a(t))return Ce();for(var r of e.options)r.selected=t.includes(gi(r));return}for(r of e.options)if($t(gi(r),t)){r.selected=!0;return}(!n||t!==void 0)&&(e.selectedIndex=-1)}function mi(e){var t=new MutationObserver(t=>{t.every(_i)||(`__defaultValue`in e&&fi(e,!1),`__value`in e&&pi(e,e.__value))});t.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[`value`]}),yn(()=>{t.disconnect()})}function hi(e,t,n=t){var r=new WeakSet,i=!0;ct(e,`change`,t=>{var i=t?`[selected]`:`:checked`,a;if(e.multiple)a=[].map.call(e.querySelectorAll(i),gi);else{var o=e.querySelector(i)??e.querySelector(`option:not([disabled])`);a=o&&gi(o)}n(a),e.__value=a,j!==null&&r.add(j)}),wn(()=>{var a=t();if(e===document.activeElement){var o=j;if(r.has(o))return}if(pi(e,a,i),i&&a===void 0){var s=e.querySelector(`:checked`);s!==null&&(a=gi(s),n(a))}e.__value=a,i=!1})}function gi(e){return`__value`in e?e.__value:e.value}function _i(e){if(e.target.closest(`selectedcontent`)!==null)return!0;if(e.type===`childList`){var t=[...e.addedNodes,...e.removedNodes];return t.length>0&&t.every(e=>e.nodeName===`SELECTEDCONTENT`)}return!1}var vi=Symbol(`is custom element`),yi=Symbol(`is html`),bi=be?`link`:`LINK`;function xi(e){if(T){var t=!1,n=()=>{if(!t){if(t=!0,e.hasAttribute(`value`)){var n=e.value;J(e,`value`,null),e.value=n}if(e.hasAttribute(`checked`)){var r=e.checked;J(e,`checked`,null),e.checked=r}}};e[ve]=n,Qe(n),ot()}}function Si(e,t){var n=Ci(e);n.checked!==(n.checked=t??void 0)&&(e.checked=t)}function J(e,t,n,r){var i=Ci(e);T&&(i[t]=e.getAttribute(t),t===`src`||t===`srcset`||t===`href`&&e.nodeName===bi)||i[t]!==(i[t]=n)&&(t===`loading`&&(e[pe]=n),n==null?e.removeAttribute(t):typeof n!=`string`&&Ti(e).has(t)?e[t]=n:e.setAttribute(t,n))}function Ci(e){return e[me]??={[vi]:e.nodeName.includes(`-`),[yi]:e.namespaceURI===i}}var wi=new Map;function Ti(e){var t=e.getAttribute(`is`)||e.nodeName,n=wi.get(t);if(n)return n;wi.set(t,n=new Set);for(var r,i=e,a=Element.prototype;a!==i;){for(var o in r=d(i),r)r[o].set&&o!==`innerHTML`&&o!==`textContent`&&o!==`innerText`&&n.add(o);i=m(i)}return n}function Ei(e,t,n=t){var r=new WeakSet;ct(e,`input`,async i=>{var a=i?e.defaultValue:e.value;if(a=Di(e)?Oi(a):a,n(a),j!==null&&r.add(j),await hr(),a!==(a=t())){var o=e.selectionStart,s=e.selectionEnd,c=e.value.length;if(e.value=a??``,s!==null){var l=e.value.length;o===s&&s===c&&l>c?(e.selectionStart=l,e.selectionEnd=l):(e.selectionStart=o,e.selectionEnd=Math.min(s,l))}}}),(T&&e.defaultValue!==e.value||B(t)==null&&e.value)&&(n(Di(e)?Oi(e.value):e.value),j!==null&&r.add(j)),On(()=>{var n=t();if(e===document.activeElement){var i=j;if(r.has(i))return}Di(e)&&n===Oi(e.value)||(e.type!==`date`||n||e.value)&&n!==e.value&&(e.value=n??``)})}function Di(e){var t=e.type;return t===`number`||t===`range`}function Oi(e){return e===``?null:+e}function ki(e,t){return e===t||e?.[ue]===t}function Ai(e=Je(),t,n,r){var i=Ke.r,a=Yn;return wn(()=>{var o,s;return On(()=>{o=s,s=r?.()||[],B(()=>{ki(n(...s),e)||(t(e,...s),o&&ki(n(...o),e)&&t(null,...o))})}),()=>{let r=a;for(;r!==i&&r.parent!==null&&r.parent.f&33554432;)r=r.parent;let o=()=>{s&&ki(n(...s),e)&&t(null,...s)},c=r.teardown;r.teardown=()=>{o(),c?.()}}}),e}function ji(e=!1){let t=Ke,n=t.l.u;if(!n)return;let r=()=>V(t.s);if(e){let e=0,n={},i=pt(()=>{let r=!1,i=t.s;for(let e in i)i[e]!==n[e]&&(n[e]=i[e],r=!0);return r&&e++,e});r=()=>z(i)}n.b.length&&Sn(()=>{Mi(t,r),v(n.b)}),bn(()=>{let e=B(()=>n.m.map(_));return()=>{for(let t of e)typeof t==`function`&&t()}}),n.a.length&&bn(()=>{Mi(t,r),v(n.a)})}function Mi(e,t){if(e.l.s)for(let t of e.l.s)z(t);t()}function Ni(e,t,n){if(e==null)return t(void 0),n&&n(void 0),g;let r=B(()=>e.subscribe(t,n));return r.unsubscribe?()=>r.unsubscribe():r}var Pi=[];function Fi(e,t=g){let n=null,r=new Set;function i(t){if(Me(e,t)&&(e=t,n)){let t=!Pi.length;for(let t of r)t[1](),Pi.push(t,e);if(t){for(let e=0;e{r.delete(c),r.size===0&&n&&(n(),n=null)}}return{set:i,update:a,subscribe:o}}function Ii(e){let t;return Ni(e,e=>t=e)(),t}var Li=!1,Ri=Symbol(`unmounted`);function Y(e,t,n){let r=n[t]??={store:null,source:M(void 0),unsubscribe:g};if(r.store!==e&&!(Ri in n)){if(r.unsubscribe(),r.store=e??null,e==null)r.source.v=void 0,r.unsubscribe=g;else{var i=!0;r.unsubscribe=Ni(e,e=>{i?r.source.v=e:N(r.source,e)}),i=!1}}return e&&Ri in n?Ii(e):z(r.source)}function zi(){let e={};function t(){yn(()=>{for(var t in e)e[t].unsubscribe();l(e,Ri,{enumerable:!1,value:!0})})}return[e,t]}function Bi(e){var t=Li;try{return Li=!1,[e(),Li]}finally{Li=t}}function X(t,n,r,i){var a=!e||!!(r&2),o=!!(r&8),s=!!(r&16),c=i,l=!0,d=void 0,f=()=>s&&a?(d??=pt(i),z(d)):(l&&(l=!1,c=s?B(i):i),c);let p;if(o){var m=ue in t||fe in t;p=u(t,n)?.set??(m&&n in t?e=>t[n]=e:void 0)}var h,g=!1;o?[h,g]=Bi(()=>t[n]):h=t[n],h===void 0&&i!==void 0&&(h=f(),p&&(a&&Ve(n),p(h)));var _=a?()=>{var e=t[n];return e===void 0?f():(l=!0,e)}:()=>{var e=t[n];return e!==void 0&&(c=void 0),e===void 0?c:e};if(a&&!(r&4))return _;if(p){var v=t.$$legacy;return(function(e,t){return arguments.length>0?((!a||!t||v||g)&&p(t?_():e),e):_()})}var y=!1,b=(r&1?pt:A)(()=>(y=!1,_()));o&&z(b);var x=Yn;return(function(e,t){if(arguments.length>0){let n=t?z(b):a&&o?Zt(e):e;return N(b,n),y=!0,c!==void 0&&(c=n),e}return Wn&&y||x.f&16384?b.v:z(b)})}async function Vi(e,t,n){let r=await fetch(e,{method:`POST`,cache:`no-store`,headers:{"Content-Type":`application/json`,"X-Setup-Session-Key":n.sessionKey,...n.capability?{"X-Setup-Capability":n.capability}:{}},body:JSON.stringify(t)}),i=await r.json();if(!r.ok)throw Error(String(i.error??`The request was rejected.`));return i}function Hi(e){let t=Fi({paired:!!e,controller:!1,busy:!1,error:``}),n=e,r,i={paired:!!e,controller:!1,busy:!1,error:``},a=!1;function o(e){i={...i,...e},t.set(i)}async function s(e=!1){if(!(a||!n||i.closed)){a=!0;try{let t=await fetch(`/api/state`,{cache:`no-store`,headers:{"X-Setup-Session-Key":n}});if(!t.ok)throw Error(`The local setup session is unavailable.`);let r=await t.json();i.closed||o({view:r,...e?{}:{error:``}})}catch{i.closed||o({view:void 0,error:`Connection lost. The CLI may have stopped. Check the terminal before trying again.`})}finally{a=!1}}}let c=()=>s(!0);async function l(){if(n&&!i.closed)try{let e=await fetch(`/api/bootstrap`,{cache:`no-store`,headers:{"X-Setup-Session-Key":n}});if(!e.ok)throw Error(`Could not join this local session.`);let t=await e.json();r=t.capability,o({controller:t.controller,error:``}),await s()}catch{n=void 0,r=void 0,o({view:void 0,paired:!1,controller:!1,error:`Could not connect to the local setup session. Check the terminal and pair again.`})}}async function u(e){if(!(i.busy||i.paired)){o({busy:!0,error:``});try{let t=await fetch(`/api/pair`,{method:`POST`,cache:`no-store`,headers:{"Content-Type":`application/json`},body:JSON.stringify({code:e.trim().toLowerCase()})}),r=await t.json();if(!t.ok)throw Error(String(r.error??`Pairing was rejected.`));if(typeof r.sessionKey!=`string`||!/^[a-f0-9]{64}$/.test(r.sessionKey))throw Error(`Invalid local pairing response.`);n=r.sessionKey,o({paired:!0,error:``}),await l()}catch(e){o({error:e instanceof Error?e.message:`Could not pair this browser.`})}finally{o({busy:!1})}}}let d=(e,t,i=!0)=>Vi(e,t,{sessionKey:n,capability:i?r:void 0});async function f(e,t){let n=e instanceof Error?e.message:t;o({error:n}),/read-only|Control moved/.test(n)?await l():await s(!0)}async function p(e,t){if(!i.busy&&i.controller&&i.view?.promptRevision===e){o({busy:!0,error:``});try{await d(`/api/answer`,{revision:e,value:t}),await s()}catch(e){await f(e,`Could not submit this answer.`)}finally{o({busy:!1})}}}async function m(e){if(!i.busy&&i.controller&&i.view?.promptRevision===e){o({busy:!0,error:``});try{await d(`/api/retry-discovery`,{revision:e}),await s()}catch(e){await f(e,`Could not retry discovery.`)}finally{o({busy:!1})}}}async function h(e){if(!i.busy&&i.controller&&i.view?.promptRevision===e){o({busy:!0,error:``});try{await d(`/api/back`,{revision:e}),await s()}catch(e){await f(e,`Could not return to the previous question.`)}finally{o({busy:!1})}}}async function g(){if(i.controller&&!i.busy){o({busy:!0,error:``});try{await d(`/api/cancel`,{}),await s()}catch(e){let t=e instanceof Error?e.message:`Cancellation failed.`;o({error:t}),/read-only|Control moved/.test(t)&&await l()}finally{o({busy:!1})}}}async function _(e){if(!(i.busy||i.closed||!i.paired||i.controller)){o({busy:!0,error:``});try{let t=await d(`/api/takeover`,{code:e.trim().toLowerCase()},!1);r=String(t.capability),o({controller:!0,error:``}),await s()}catch(e){o({error:e instanceof Error?e.message:`Takeover failed.`}),await s(!0)}finally{o({busy:!1})}}}async function v(){if(!i.busy&&!i.closed&&i.controller&&i.view?.outcome){o({busy:!0,error:``});try{if((await d(`/api/close`,{})).closed!==!0)throw Error(`Could not close the local session. Check the terminal before trying again.`);n=void 0,r=void 0,o({closed:!0,controller:!1,error:``})}catch{o({error:`Could not close the local session. Check the terminal before trying again.`})}finally{o({busy:!1})}}}async function y(){if(!(i.busy||i.closed||!i.controller||i.view?.outcome!==`complete`)){o({busy:!0,error:``,view:{...i.view,doctor:{status:`running`}}});try{await d(`/api/doctor`,{})}catch(e){o({error:e instanceof Error?e.message:`Read-only verification failed.`})}finally{await s(!0),o({busy:!1})}}}return{subscribe:t.subscribe,pair:u,connect:l,refresh:s,poll:c,submit:p,retryDiscovery:m,back:h,cancel:g,takeOver:_,close:v,runDoctor:y}}var Ui={setupHelp:`Setup help`,setupTutorial:`Setup tutorial`,firstWorkflowGuide:`First issue-to-PR workflow`,setupRecovery:`Troubleshooting`,setupHelpHint:`Documentation opens in a new tab. Your setup answers stay here.`,setupNextWorkflow:`Install the reviewed files, then verify the Action in GitHub. A metadata check alone does not prove runtime success.`,batchNextActions:`Next steps`,batchStatusReady:`Ready for review`,batchStatusBlocked:`Needs action`,batchStatusApplying:`Applying reviewed plan`,batchStatusPartial:`Partially applied; inspect before retry`,batchStatusWaiting:`PR created · waiting for human merge`,batchStatusPending:`Configuration applied · verification pending`,batchStatusUnchanged:`Already matches · unchanged`,batchStatusCancelled:`Pending work stopped; completed effects retained`,batchConfigurationPreview:`Configuration preview. This adds the configuration to your batch review. No permission probe or installation runs before you approve the complete batch.`,batchUseConfiguration:`Use this configuration`,planReuseBody:`Approve the listed temporary permission checks, then apply the reviewed setup. Existing Secret values are retained and will not be requested or replaced. Runtime capability verification can remain pending.`,organizationReuseTitle:`Reusing existing configuration`,organizationReuseBody:`{imported} compatible settings imported. Retain {shared} organization Variables and {overrides} repository overrides; write {writes} repository Variables. Shared values and existing Secret values stay unchanged.`,batchBranchReview:`Installation branch and reviewed base`,batchFocusTitle:`Selected repositories`,batchFocusBody:`{count} explicitly selected repositories in this organization. Review each target independently.`,batchReviewTitle:`Review setup plans`,batchProgressTitle:`Applying repository plans`,batchResultTitle:`Repository setup results`,batchProgressBody:`Applying the approved plans sequentially. Stop pauses pending work after the current request; completed changes and PRs remain.`,batchReviewBody:`Approve only the ready plans below. Setup proceeds sequentially, adds reviewed access without replacing shared values, and creates a PR for each changed repository. It does not merge, tag, release or deploy.`,batchResultBody:`A setup PR still needs human review and merge. Credential and runtime capability verification can remain pending. Completed PRs and access changes are kept if another target stops.`,batchStopping:`Stopping pending work after the current request. Completed changes will be retained.`,batchReasonDrift:`The reviewed base or ownership changed. Inspect the repository and review a fresh plan.`,batchReasonProvider:`GitHub did not confirm the last step. Retry inspects existing effects before continuing.`,batchCleanupPending:`Permission-check cleanup could not be confirmed. Pending work is stopped. Inspect GitHub history and the local recovery journal; resolve cleanup before starting a fresh setup. This operation cannot resume writes.`,batchReasonCancelled:`Pending work stopped. Completed changes were retained.`,batchReasonPreflight:`Review repository access, required bindings and target-specific settings before continuing.`,batchOpenPull:`Open setup PR`,batchFilesCount:`{count} changed files`,batchVariablesCount:`{count} repository Variable changes`,batchGrantsCount:`{count} additive repository access grants`,batchRetainedSecrets:`Existing Secret bindings retained`,batchResourcesExplanation:`Labels and enabled Issue Types are ensured separately for this target. Existing shared Secret values and other repositories’ access stay unchanged.`,batchReviewFiles:`Inspect proposed files`,batchDeleteFile:`This setup-managed file will be removed from the installation tree; inspect its retained backup.`,batchRepositoryOverrides:`Review repository Variable names`,batchReviewedAccess:`Review additive access`,batchApplyPlans:`Apply ready plans`,batchLeavePreview:`Leave without applying`,batchStopPending:`Stop pending work`,batchStopConfirm:`Stop pending setup work after the current request? Completed PRs, access and other changes will be kept.`,batchRetryPending:`Inspect and retry unfinished work`,batchFinish:`Finish this operation`,batchCleanup:`Delete temporary setup PATs in GitHub after this operation. Keep the bot PAT while repositories still consume its Secret.`,batchTechnical:`Operation details`,batchLookupUnavailable:`GitHub could not confirm that repository. Check its exact name and PAT access.`,batchSelectionInvalid:`Review the selection: choose 1–25 available repositories from this organization.`,batchAccessUnavailable:`Access is unconfirmed. Review the temporary PAT or remove this repository from the selection.`,batchSelectionBody:`Choose 1–25 repositories in {organization}. Only the repositories you select will be configured.`,batchDiscoveryUnavailable:`GitHub could not list repositories. The current repository remains available; find another by its exact name or review PAT access.`,batchDiscoveryTruncated:`This view reached its 1,000-repository limit. Search an exact repository name to add a missing target.`,batchFilter:`Filter visible repositories`,batchSelectedCount:`{count} selected · maximum 25`,batchRepositories:`Repositories`,batchPrivate:`Private`,batchPublic:`Public`,batchCurrent:`Current repository`,batchArchived:`Archived`,batchDisabled:`Disabled`,batchReadOnly:`Write access unavailable`,batchNoMatches:`No visible repositories match this filter.`,batchPrevious:`Previous`,batchNext:`Next`,batchMissingRepository:`Cannot find a repository?`,batchAccessExplanation:`Discovery shows only repositories this PAT can see. An exact-name lookup does not grant access or select the repository automatically. If you replace the temporary PAT, limit it to the repositories you intend to configure.`,batchExactName:`Exact repository name in this organization`,batchFindRepository:`Find repository`,batchChangeAccess:`Change temporary PAT access`,batchReviewSelection:`Review selected repositories`,patStorageRetain:`Keep the existing PAT Secret binding in {destination}. Its value is not requested, copied or replaced. A missing binding requires separate provisioning. Runtime identity and capability verification remain pending.`,patStorageTitle:`Bot PAT storage`,patRepositoryReplace:`Secret PAT already exists in repository {destination}. It will be replaced even when other existing Secrets are preserved.`,patOrganizationReplace:`Secret PAT already exists in organization {destination}. It will be replaced even when other existing Secrets are preserved.`,patRepositoryCreate:`The bot PAT will be stored as Secret PAT in repository {destination}.`,patOrganizationCreate:`The bot PAT will be stored as Secret PAT in organization {destination}.`,patReplacementChecks:`The supplied bot PAT must pass identity, repository access and required permission checks before this Secret is written.`,patOrganizationImpact:`Replacing this organization Secret can affect other repositories that use it. Checks for this repository do not verify their requirements.`,repositorySecretSettings:`Open repository Actions Secrets`,botAccountWarning:`You must open this link with the selected bot account: @{account}.`,botAccountHelp:`Check the GitHub account before generating the PAT. Use a private window or switch accounts if your browser is signed in as the setup operator.`,botGithubForm:`Create bot PAT as @{account}`,language:`Language`,english:`English`,spanish:`Español`,setup:`SETUP`,connecting:`Connecting…`,localSession:`LOCAL SESSION`,progress:`Setup progress`,studio:`SETUP STUDIO`,journey:`YOUR SETUP JOURNEY`,repository:`Repository`,choices:`Setup choices`,setupPat:`Setup PAT`,plan:`Plan`,botPat:`Bot PAT & credentials`,apply:`Apply`,localDesign:`Local by design`,localDesignBody:`This page runs on your computer. GitHub creates both PATs in its own browser tabs.`,preparing:`Preparing your setup…`,completeTitle:`Setup complete.`,previewTitle:`Preview complete.`,cancelledTitle:`Setup cancelled.`,blockedTitle:`Setup needs attention.`,gettingReady:`GETTING READY`,activeLede:`One decision at a time. Your choices shape the permissions, plan and credentials needed for this repository.`,resultLede:`Review the result and next action below. The terminal has additional technical detail.`,readOnly:`Read-only tab`,readOnlyBody:`Another tab controls this session. You can review progress here or explicitly take over.`,takeOver:`Take control in this tab`,attention:`Needs attention`,checked:`Checked`,pleaseNote:`Please note`,progressUpdate:`Progress update`,reviewPass:`Reviewing saved choices — pass {pass}. This is the same setup run, not a restart.`,cancelSetup:`Cancel setup`,cancelConfirm:`Cancel this local setup session? PATs already created in GitHub will still exist.`,footerLocal:`LOCALHOST ONLY`,footerCloud:`NO CLOUD SETUP ACCOUNT`,footerGithub:`GITHUB OWNS PAT ISSUANCE`,currentDecision:`CURRENT DECISION`,session:`SESSION`,continue:`Continue`,previousQuestion:`Previous question`,questionProgress:`Question {current} of {total} in this group · {overall} of {all} overall`,yes:`Yes`,no:`No`,permissionPreview:`PERMISSION PREVIEW`,changeAnswersTitle:`Change your answers`,changeAnswersHelp:`Return to a section without losing other answers. The plan and required PAT grants will be checked again.`,changeSection:`Change {section}`,editCapabilities:`Capabilities`,editRuntimes:`Agent runtimes`,editModels:`Agent models`,editRoleModels:`Per-role models`,editRepository:`Repository behavior`,editDeployment:`Release and hotfix`,editBugbot:`Bugbot`,editApproval:`PR approval`,editProjects:`Projects`,editProvisioning:`Provisioning`,editStorage:`Secrets and Variables`,suggested:`Suggested answer: {answer}. You can review choices again before creating your setup PAT.`,none:`none`,sourceGithub:`Observed from authenticated GitHub repository metadata.`,sourceConfig:`Provided by your configuration; GitHub has not replaced it.`,sourceDefault:`Product default; not verified against this repository.`,sourceLocal:`Observed in this local checkout; confirm this branch exists on GitHub before applying.`,whyMatters:`Why this matters`,whenApplies:`When it applies`,whereConfigured:`Where it is configured`,howToChoose:`How to choose`,whyRecommendation:`Why this matters`,example:`Example`,effect:`What changes`,verify:`How to check`,learnMore:`Read documentation about this setting`,resultApplied:`Your configuration was applied`,resultNoChanges:`No changes were made`,resultStopped:`No setup changes started`,resultPartial:`Check partial changes before retrying`,resultCompleteBody:`The temporary setup PAT is not revoked automatically. Delete it in GitHub after confirming your setup. Keep the bot PAT until you rotate the installed Secret.`,resultPartialBody:`A bot Secret write or another change may have succeeded. Inspect GitHub and run copilot doctor --read-only before replacing or deleting its PAT.`,resultNoChangesBody:`Copilot did not begin applying setup changes. Temporary permission checks may have run; GitHub can retain Actions, Issue or PR history after cleanup. PATs you created still exist until you delete them in GitHub.`,whatHappened:`What happened`,alreadyChanged:`Already changed`,noChanges:`No repository or GitHub setup changes were started in this session.`,nextAction:`Next action`,reasonPermissions:`The setup PAT lacked or could not confirm required permissions.`,nextPermissions:`Check the displayed grants, correct the PAT in GitHub, then start a fresh setup run.`,reasonWorkflowPermissions:`The bot PAT did not complete every required permission check. Check the failed grant and any preparation or cleanup prerequisite below.`,permissionReportTitle:`PAT permission evidence`,permissionReportLead:`Any required grants that could not be confirmed are listed below. Unverifiable does not mean missing.`,updatedSetupPatTitle:`Correct the setup PAT`,updatedSetupPatBody:`This GitHub link includes the required permissions for this setup run. Select this repository before creating the PAT. Close this local session, then start a fresh setup run with the corrected PAT.`,updatedSetupPatGrants:`Additional permissions discovered after inspection`,updatedSetupPatLink:`Create corrected setup PAT`,permissionProbeCleanupPending:`A temporary permission-test resource may still exist. Setup has stopped; do not assume cleanup succeeded.`,permissionProbeCleanupAction:`Retry with a PAT that can remove this resource. The local recovery journal is checked before any new permission tests.`,permissionSecretCollision:`GitHub reported that a Secret at the random test name was updated. A concurrent Secret value may have changed. Setup stopped without deleting it.`,permissionSecretCollisionAction:`Inspect the GitHub Secret audit trail and restore any affected value before retrying. This collision cannot be repaired from the local recovery journal.`,permissionIdentity:`GitHub identity and repository access`,permissionIdentityValid:`Verified`,permissionIdentityInvalid:`Rejected`,permissionIdentityUnknown:`Could not be confirmed`,permissionGrantNotChecked:`Not checked`,permissionReportNoFailedGrant:`No required grant failed this check. Review the intended PAT account and the terminal error before retrying.`,reasonStorage:`The selected GitHub Actions storage could not be used safely.`,nextStorage:`Inspect the Variables/Secrets scope and existing resources, then retry.`,reasonConfiguration:`The chosen configuration could not be validated.`,nextConfiguration:`Review the terminal validation details, correct the choices, and retry.`,reasonExpired:`The local setup session expired.`,nextExpired:`Start a new setup session; the old approval cannot be replayed.`,reasonCancelled:`This setup was cancelled.`,nextCancelled:`Start a new run if you still want to configure this repository.`,reasonUnknown:`Setup stopped. The browser could not determine the exact cause. Review the resource receipt when available and inspect the terminal.`,nextUnknown:`Check the final terminal error before retrying; do not assume a PAT was revoked.`,reasonProvider:`GitHub or another provider did not complete the requested operation.`,nextProvider:`Use the diagnostic reference to inspect the terminal result, check provider availability and access, then retry only after reviewing possible partial changes.`,reasonRateLimit:`GitHub temporarily limited the requests needed for setup.`,nextRateLimit:`Wait for the limit to reset. Inspect any completed changes before starting another setup run.`,diagnosticReference:`Diagnostic reference`,resourceReceipt:`Setup operation receipt`,effectCompleted:`Reported completed`,effectSkipped:`Reported skipped`,effectInspect:`Outcome needs inspection`,effectNotStarted:`Not started`,effectInProgress:`In progress; outcome not yet confirmed`,scopeLocal:`Local checkout`,scopeMixed:`Repository and organization`,receiptFiles:`Setup files`,receiptSecrets:`GitHub Actions Secrets`,receiptLabels:`Issue labels`,receiptIssueTypes:`Issue types`,receiptVariables:`GitHub Actions Variables`,receiptInitialTag:`Initial version tag`,inspectPartial:`Some setup changes may already be active. Inspect GitHub and the terminal result before retrying.`,patSettings:`Open GitHub PAT settings ↗`,closeSession:`Close local session`,sessionClosed:`Local session closed`,sessionClosedBody:`The local server accepted the close request. This page has stopped contacting it and retains the result. Closing the session does not revoke any PAT created in GitHub.`,doctorHelp:`After success, you can verify installed resources here without dispatching Actions. Or run copilot doctor --read-only from the repository root with the temporary setup PAT and the same non-secret --config file, if used.`,doctorRun:`Verify installed setup (read-only)`,doctorRunning:`Checking installed resources without dispatching Actions…`,doctorPassed:`Read-only verification found no failing checks.`,doctorWarnings:`Read-only verification needs attention.`,doctorFailed:`Read-only verification did not finish. Check the terminal or run the command below.`,doctorCounts:`{pass} passed · {warn} warnings · {fail} failed · {skipped} skipped.`,doctorSecretLimit:`Secret values cannot be verified in this mode.`,botRenewal:`The bot PAT stays in the selected GitHub Actions Secret for future runs. Its actual expiry is not verified here; record it in GitHub and rotate the Secret before expiry.`,working:`Working on the next step`,workingBody:`The local process is checking your answers and preparing the next decision. Keep this page open.`,repoFocus:`Repository in focus`,repoFocusBody:`This setup configures the repository below. Organization Secrets and Variables may be shared with other repositories.`,access:`access`,readOnlyCheck:`Capability check`,provisionalGrants:`Provisional least-privilege grants`,conditionalGrants:`Conditional grants depend on the choices and GitHub facts. A final audit runs before setup changes.`,permissionEvidenceVerified:`A GitHub read confirmed this access.`,permissionEvidenceVerifiedWrite:`A temporary resource was created, read, and removed.`,permissionEvidencePrivateProject:`A non-public organization Project confirmed Projects read access.`,permissionEvidenceMissing:`GitHub rejected the required access. Check the PAT settings.`,permissionEvidenceWrite:`The temporary write check did not finish successfully. Review the failed phase and retry.`,permissionEvidencePublic:`The read succeeded, but this public resource does not independently prove the PAT grant.`,permissionEvidencePublicProjects:`The Projects read succeeded, including an empty result. Private Project access is checked when a Project is selected.`,permissionEvidenceUnknownRead:`The read check was inconclusive. Review the terminal detail and retry if needed.`,permissionUnknown:`This permission needs review. Check its exact grant and technical explanation in the terminal before continuing.`,permissionsFollow:`Permissions follow your choices`,permissionsFollowBody:`We’ll show the exact grants before you create each PAT. Nothing is created just by opening this page.`,files:`Files`,workflows:`Workflows`,variables:`Variables`,secretNames:`Secret names`,planBody:`Review exactly what this run may change. Approval first runs temporary PAT write checks, then collects the bot PAT and other credentials. GitHub may retain workflow runs, Issue or PR history, or notifications from those checks.`,planPermissionProbeTitle:`Temporary permission checks after approval`,planPermissionProbeBody:`Each listed permission creates, reads and removes its own temporary resource. The Issues check creates a visible Issue; if GitHub denies deletion, setup closes it, reports its number and stops. Actions, Issues and Pull requests may leave history or notifications.`,planActionsProbePrerequisites:`The Actions check needs Contents Write to create its isolated branch. If the exact packaged health workflow is unavailable on the default branch, it also needs Workflows Write to prepare a disabled-job override. For the bot check, the setup PAT prepares and cleans the fixture; the bot PAT dispatches and reads its run. A blocked prerequisite does not prove Actions is missing.`,planSecretProbeLimit:`GitHub only offers an upsert for Secrets. The check uses a private random name and confirms it is absent first, but GitHub cannot guarantee atomic create-only behavior. If it reports an update, setup stops and asks you to inspect the Secret audit trail.`,planChoices:`Your key decisions`,planEnabledCapabilities:`Enabled capabilities`,planBranchRoles:`Production / development branch`,planApprovalMode:`Pull-request approval`,planVariableScope:`Variables scope`,planSecretScope:`Secrets scope`,planInitialTag:`Create initial tag`,planAgentRouting:`Agent and model for each task`,planIssueWorkflows:`Issue workflows`,planTrustedChecks:`Trusted CI producers`,planCoverage:`Coverage evidence`,planProjectStatuses:`Project Status transitions`,planIssueResources:`Issue labels and issue types`,planIssueResourcesValue:`Checked or provisioned during Apply`,planProducerAttested:`CI identity and enforcing step verified by you`,planCoverageThreshold:`Minimum changed-line coverage`,planCoverageReporter:`Artifact-publishing workflow`,planReporterAttested:`Coverage reporter verified by you`,planAdvancedDefaults:`The plan also includes defaults for settings you did not change. Use Change below to inspect any section before approving.`,planUnknownWarning:`An additional plan warning could not be displayed here. Read the terminal warning before approving.`,planBasicDefaultsIntro:`Basic setup retained these advanced defaults. Open a section below to review or change them:`,scopeRepository:`Repository`,scopeOrganization:`Organization`,scopeDisabled:`Not provisioned`,approvalOff:`Off`,approvalRecommend:`Recommendation only`,approvalGuarded:`Guarded approval`,beforeContinue:`Before you continue`,stopHere:`Stop here`,approvePlan:`Approve this plan`,githubLink:`Open GitHub link ↗`,githubForm:`Open the official GitHub PAT form`,githubFormHelp:`Check the signed-in account, select Only select repositories, then select this repository. GitHub handles 2FA and creates the PAT.`,pasteHere:`Paste the value here`,yourAnswer:`Your answer`,hiddenAfter:`Hidden after submission`,typeAnswer:`Type your answer`,secretHelp:`Sent only to this local process. It will not be shown again or saved in browser storage.`,pairTitle:`Pair this browser`,pairLabel:`Pairing code from terminal`,pairPlaceholder:`16 hexadecimal characters`,pairBody:`Find the 16-character pairing code in the terminal that started copilot setup --web. Enter it here to view or control this setup. The code is never placed in the browser URL or stored after this page closes.`,pairHelp:`Keep the code private. After refreshing this page, enter it again to reconnect.`,pairButton:`Connect to local setup`,privateSession:`PRIVATE LOCAL SESSION`,theme:`Color theme`,themeAuto:`Auto`,themeSystem:`Follow system theme`,themeLight:`Light theme`,themeDark:`Dark theme`,selectOne:`Select one`,ciRun:`Open CI run on GitHub ↗`,manualCheck:`Check not listed? Enter exact name|App ID|workflow, separated by semicolons.`,checksObserved:`Recent CI jobs were found. Open each run and verify the exact job, App and enforcing coverage step before trusting it.`,checksNoRecent:`No recent pull-request workflow runs were found. Run your normal CI on a real pull request, or enter an exact producer manually.`,checksNoVerifiable:`Recent runs exist, but no job could be linked to an exact Check Run and App identity. Inspect GitHub or enter an exact producer manually.`,checksDenied:`GitHub did not allow CI discovery. Give the setup PAT Actions: read and Checks: read, or enter an exact producer manually.`,checksUnavailable:`GitHub CI discovery could not complete. This is not evidence that the repository has no checks. Retry setup or enter an exact producer manually.`,projectsObserved:`These existing Projects belong to the repository owner. Select only Projects this automation should update.`,projectsEmpty:`This bounded GitHub query returned no open, accessible organization Projects; it does not prove none exist. Check access or enter a verified Project number.`,projectsDenied:`GitHub did not allow Project discovery. Check organization Projects: read on the setup PAT, or enter Project numbers manually.`,projectsUnavailable:`GitHub Project discovery could not complete. This is not evidence that no Projects exist. Enter a verified Project number manually or retry.`,projectsUnsupported:`GitHub does not support listing personal Projects with a fine-grained PAT through this endpoint. Enter an existing Project number from its URL.`,discoveryTruncated:`Only a bounded sample of accessible Projects or recent checks was inspected. Use manual entry for an item not shown.`,checksDiscoveryScope:`Search scope: select up to 20 PR runs from the latest 1,000 workflow runs (up to 10 pages) within 90 days; at most 15 runs and 100 checks per commit are inspected.`,projectsDiscoveryScope:`Search scope: at most 30 open, accessible organization Projects from two pages; up to 100 fields are inspected per Project. Closed Projects are excluded.`,retryDiscovery:`Retry GitHub discovery`,retryRemaining:`{count} read-only retries left. Your answers stay here.`,retryExhausted:`No discovery retries remain. Inspect GitHub and use the manual option if the item is missing.`,observationTimeUnknown:`observation time unavailable`,branchRequirementUnknown:`Required by branch rule: not checked`,branchRequirementObserved:`Required on {branch} by an active ruleset for this exact check and App.`,ciRule:`Open required-check ruleset ↗`,projectSharedStatus:`All selected Projects must share each chosen Status value. This setup cannot assign a different Status vocabulary per Project.`,fixedWorkflowEnabled:`Your configuration fixes features.{kind}=true. Keep {kind} selected; edit --config or flags to change this.`,fixedWorkflowDisabled:`Your configuration fixes features.{kind}=false. Leave {kind} unselected; edit --config or flags to change this.`,fixedIssuesRequired:`Your configuration explicitly enables release or hotfix automation. Keep Issues enabled, or change --config or flags first.`,projectSelectionNotObserved:`Previously selected Project numbers are retained, but no longer appear in this GitHub result. Verify each in GitHub or remove it.`,removeSelection:`Remove selection`,projectTransitionIssueCreated:`New issue`,projectTransitionPullRequestCreated:`New pull request`,projectTransitionIssueInProgress:`Issue in progress`,projectTransitionPullRequestInProgress:`Pull request in progress`,projectUrl:`Open Project on GitHub ↗`,projectManual:`Project not listed? Enter its positive number or exact GitHub URL. PVT_ IDs are not accepted.`,projectStatusUnavailable:`Status options could not be verified for every selected Project. Enter the exact existing Status value after checking each Project in GitHub.`,projectStatusIncompatible:`Selected Projects have no shared Status values. Choose compatible Projects before continuing.`,producerName:`Check/job name`,producerAppId:`Source GitHub App ID`,producerWorkflow:`Workflow name`,producerAdd:`Add exact check`,producerRemove:`Remove check`,producerManualHelp:`Use the exact identity shown on GitHub. Adding it does not attest that it enforces coverage.`,producerManualInvalid:`Enter a check name, positive numeric App ID and workflow name. Do not use | or ; in names. Commas are allowed.`,translationPreviewTitle:`Translation review in progress`,translationPreviewBody:`First-party setup questions are translated. Some dynamic GitHub or provider diagnostics may still appear in English while localization review finishes. Changing language does not change your answers.`,unknownLocalError:`An unexpected local setup error occurred. Check the terminal for details, then refresh or restart setup.`},Wi={setupHelp:`Ayuda de configuración`,setupTutorial:`Tutorial de configuración`,firstWorkflowGuide:`Primer flujo de issue a PR`,setupRecovery:`Resolver problemas`,setupHelpHint:`La documentación se abre en otra pestaña. Tus respuestas se conservan aquí.`,setupNextWorkflow:`Instala los archivos revisados y comprueba la Action en GitHub. Una inspección de metadatos no demuestra que funcione en ejecución.`,batchNextActions:`Siguientes pasos`,batchStatusReady:`Listo para revisar`,batchStatusBlocked:`Requiere una acción`,batchStatusApplying:`Aplicando el plan revisado`,batchStatusPartial:`Aplicado parcialmente; revisa antes de reintentar`,batchStatusWaiting:`PR creada · pendiente de merge por un mantenedor`,batchStatusPending:`Configuración aplicada · verificación pendiente`,batchStatusUnchanged:`Ya coincide · sin cambios`,batchStatusCancelled:`Trabajo pendiente detenido; se conservan los cambios completados`,batchConfigurationPreview:`Vista previa de la configuración. Se añadirá a la revisión del lote. Las pruebas de permisos y la instalación esperan a que apruebes el lote completo.`,batchUseConfiguration:`Usar esta configuración`,planReuseBody:`Aprueba las pruebas temporales de permisos indicadas y después se aplicará el setup revisado. Los valores de los Secrets existentes se conservan y no se solicitan ni se sustituyen. La verificación de permisos en ejecución puede quedar pendiente.`,organizationReuseTitle:`Reutilización de la configuración existente`,organizationReuseBody:`{imported} ajustes compatibles importados. Se conservan {shared} Variables de organización y {overrides} del repositorio; se escriben {writes} Variables en el repositorio. Los valores compartidos y los Secrets existentes se conservan.`,batchBranchReview:`Rama de instalación y base revisada`,batchFocusTitle:`Repositorios seleccionados`,batchFocusBody:`{count} repositorios seleccionados explícitamente en esta organización. Revisa cada destino por separado.`,batchReviewTitle:`Revisa los planes de setup`,batchProgressTitle:`Aplicando los planes por repositorio`,batchResultTitle:`Resultados del setup por repositorio`,batchProgressBody:`Se aplican los planes aprobados por orden. Detener pausa el trabajo pendiente después de la petición actual; los cambios y las PRs completadas se conservan.`,batchReviewBody:`Aprueba solo los planes listos que aparecen abajo. El setup avanza por orden, añade el acceso revisado sin sustituir valores compartidos y crea una PR por cada repositorio con cambios. No hace merge, crea tags, publica versiones ni despliega.`,batchResultBody:`Una PR de setup todavía necesita revisión y merge por un mantenedor. La verificación de credenciales y permisos en ejecución puede quedar pendiente. Las PRs y los accesos completados se conservan si otro destino se detiene.`,batchStopping:`Deteniendo el trabajo pendiente tras la petición actual. Los cambios completados se conservarán.`,batchReasonDrift:`La base revisada o su titularidad han cambiado. Inspecciona el repositorio y revisa un plan nuevo.`,batchReasonProvider:`GitHub no ha confirmado el último paso. El reintento inspecciona lo existente antes de continuar.`,batchCleanupPending:`No se pudo confirmar la limpieza de la comprobación de permisos. El trabajo pendiente está detenido. Revisa el historial de GitHub y el registro local de recuperación; resuelve la limpieza antes de iniciar un setup nuevo. Esta operación no puede reanudar escrituras.`,batchReasonCancelled:`El trabajo pendiente se detuvo. Se conservaron los cambios completados.`,batchReasonPreflight:`Revisa el acceso, los secretos requeridos y los ajustes específicos del repositorio antes de continuar.`,batchOpenPull:`Abrir PR de setup`,batchFilesCount:`{count} archivos con cambios`,batchVariablesCount:`{count} cambios en Variables del repositorio`,batchGrantsCount:`{count} accesos que se añadirán para este repositorio`,batchRetainedSecrets:`Secrets existentes que se conservan`,batchResourcesExplanation:`Los labels y los Issue Types habilitados se preparan por separado para este destino. Se conservan los valores de los Secrets compartidos y el acceso de los demás repositorios.`,batchReviewFiles:`Inspeccionar archivos propuestos`,batchDeleteFile:`Este archivo gestionado por el setup se retirará del árbol de instalación; inspecciona la copia conservada.`,batchRepositoryOverrides:`Revisar nombres de Variables del repositorio`,batchReviewedAccess:`Revisar accesos que se añadirán`,batchApplyPlans:`Aplicar planes listos`,batchLeavePreview:`Salir sin aplicar`,batchStopPending:`Detener trabajo pendiente`,batchStopConfirm:`¿Detener el trabajo pendiente tras la petición actual? Se conservarán las PRs, los accesos y los cambios completados.`,batchRetryPending:`Inspeccionar y reintentar lo pendiente`,batchFinish:`Finalizar esta operación`,batchCleanup:`Elimina los PATs temporales de setup en GitHub al terminar. Conserva el PAT del bot mientras los repositorios consuman su Secret.`,batchTechnical:`Detalles de la operación`,batchLookupUnavailable:`GitHub no ha podido confirmar ese repositorio. Revisa el nombre exacto y el acceso del PAT.`,batchSelectionInvalid:`Revisa la selección: elige entre 1 y 25 repositorios disponibles de esta organización.`,batchAccessUnavailable:`El acceso no está confirmado. Revisa el PAT temporal o quita este repositorio de la selección.`,batchSelectionBody:`Elige entre 1 y 25 repositorios de {organization}. Solo se configurarán los que selecciones.`,batchDiscoveryUnavailable:`GitHub no ha podido listar los repositorios. Puedes seleccionar el actual, buscar otro por su nombre exacto o revisar el acceso del PAT.`,batchDiscoveryTruncated:`Esta vista ha alcanzado el límite de 1.000 repositorios. Busca por nombre exacto para añadir uno que falte.`,batchFilter:`Filtrar repositorios visibles`,batchSelectedCount:`{count} seleccionados · máximo 25`,batchRepositories:`Repositorios`,batchPrivate:`Privado`,batchPublic:`Público`,batchCurrent:`Repositorio actual`,batchArchived:`Archivado`,batchDisabled:`Deshabilitado`,batchReadOnly:`Sin acceso de escritura`,batchNoMatches:`Ningún repositorio visible coincide con el filtro.`,batchPrevious:`Anterior`,batchNext:`Siguiente`,batchMissingRepository:`¿No encuentras un repositorio?`,batchAccessExplanation:`La lista solo muestra los repositorios visibles para este PAT. Buscar por nombre exacto no concede acceso ni selecciona el repositorio automáticamente. Si sustituyes el PAT temporal, limítalo a los repositorios que quieras configurar.`,batchExactName:`Nombre exacto del repositorio en esta organización`,batchFindRepository:`Buscar repositorio`,batchChangeAccess:`Cambiar acceso del PAT temporal`,batchReviewSelection:`Revisar repositorios seleccionados`,patStorageRetain:`Se conserva el Secret PAT existente en {destination}. No se pide, copia ni sustituye su valor. Si falta, debe crearse por separado. La verificación de la identidad y los permisos en ejecución queda pendiente.`,patStorageTitle:`Almacenamiento del PAT del bot`,patRepositoryReplace:`El Secret PAT ya existe en el repositorio {destination}. Se sustituirá aunque hayas elegido preservar los demás Secrets existentes.`,patOrganizationReplace:`El Secret PAT ya existe en la organización {destination}. Se sustituirá aunque hayas elegido preservar los demás Secrets existentes.`,patRepositoryCreate:`El PAT del bot se guardará como Secret PAT en el repositorio {destination}.`,patOrganizationCreate:`El PAT del bot se guardará como Secret PAT en la organización {destination}.`,patReplacementChecks:`El PAT del bot que introduzcas debe superar las comprobaciones de identidad, acceso al repositorio y permisos necesarios antes de escribir este Secret.`,patOrganizationImpact:`Sustituir este Secret de organización puede afectar a otros repositorios que lo utilizan. Las comprobaciones para este repositorio no verifican los requisitos de los demás.`,repositorySecretSettings:`Abrir los Secrets de Actions del repositorio`,botAccountWarning:`Debes abrir este enlace con la cuenta de bot seleccionada: @{account}.`,botAccountHelp:`Comprueba la cuenta de GitHub antes de generar el PAT. Usa una ventana privada o cambia de cuenta si el navegador tiene la sesión del operador del setup.`,botGithubForm:`Crear PAT del bot como @{account}`,language:`Idioma`,english:`English`,spanish:`Español`,setup:`CONFIGURACIÓN`,connecting:`Conectando…`,localSession:`SESIÓN LOCAL`,progress:`Progreso de la configuración`,studio:`ASISTENTE DE CONFIGURACIÓN`,journey:`TU RECORRIDO`,repository:`Repositorio`,choices:`Opciones de configuración`,setupPat:`PAT de configuración`,plan:`Plan`,botPat:`PAT del bot y credenciales`,apply:`Aplicar`,localDesign:`Local por diseño`,localDesignBody:`Esta página se ejecuta en tu ordenador. GitHub crea ambos PAT en sus propias pestañas.`,preparing:`Preparando la configuración…`,completeTitle:`Configuración completada.`,previewTitle:`Vista previa completada.`,cancelledTitle:`Configuración cancelada.`,blockedTitle:`La configuración necesita atención.`,gettingReady:`PREPARANDO`,activeLede:`Una decisión cada vez. Tus elecciones determinan los permisos, el plan y las credenciales que necesita este repositorio.`,resultLede:`Revisa abajo el resultado y el siguiente paso. La terminal contiene más detalles técnicos.`,readOnly:`Pestaña de solo lectura`,readOnlyBody:`Otra pestaña controla esta sesión. Puedes ver el progreso aquí o tomar el control explícitamente.`,takeOver:`Tomar el control en esta pestaña`,attention:`Necesita atención`,checked:`Comprobado`,pleaseNote:`Ten en cuenta`,progressUpdate:`Actualización de progreso`,reviewPass:`Revisando las opciones guardadas — pasada {pass}. Es la misma ejecución, no un reinicio.`,cancelSetup:`Cancelar configuración`,cancelConfirm:`¿Cancelar esta sesión local? Los PAT ya creados en GitHub seguirán existiendo.`,footerLocal:`SOLO LOCALHOST`,footerCloud:`SIN CUENTA DE CONFIGURACIÓN EN LA NUBE`,footerGithub:`GITHUB EMITE LOS PAT`,currentDecision:`DECISIÓN ACTUAL`,session:`SESIÓN`,continue:`Continuar`,previousQuestion:`Pregunta anterior`,questionProgress:`Pregunta {current} de {total} en este grupo · {overall} de {all} en total`,yes:`Sí`,no:`No`,permissionPreview:`VISTA PREVIA DE PERMISOS`,changeAnswersTitle:`Cambiar respuestas`,changeAnswersHelp:`Vuelve a una sección sin perder las demás respuestas. Se comprobarán de nuevo el plan y los permisos necesarios del PAT.`,changeSection:`Cambiar {section}`,editCapabilities:`Funciones`,editRuntimes:`Agentes`,editModels:`Modelos de agentes`,editRoleModels:`Modelos por tarea`,editRepository:`Comportamiento del repositorio`,editDeployment:`Releases y hotfixes`,editBugbot:`Bugbot`,editApproval:`Aprobación de PR`,editProjects:`Projects`,editProvisioning:`Aprovisionamiento`,editStorage:`Secrets y Variables`,suggested:`Respuesta sugerida: {answer}. Podrás revisar las opciones antes de crear el PAT de configuración.`,none:`ninguna`,sourceGithub:`Consultado en los metadatos autenticados de este repositorio en GitHub.`,sourceConfig:`Valor de tu configuración; GitHub no lo ha sustituido.`,sourceDefault:`Valor predeterminado del producto; no verificado en este repositorio.`,sourceLocal:`Observado en este checkout local; confirma que la rama existe en GitHub antes de aplicar cambios.`,whyMatters:`Por qué importa`,whenApplies:`Cuándo se aplica`,whereConfigured:`Dónde se configura`,howToChoose:`Cómo elegir`,whyRecommendation:`Por qué importa`,example:`Ejemplo`,effect:`Qué cambia`,verify:`Cómo comprobarlo`,learnMore:`Leer documentación de esta opción`,resultApplied:`Tu configuración se ha aplicado`,resultNoChanges:`No se hicieron cambios`,resultStopped:`No se empezó a aplicar la configuración`,resultPartial:`Revisa los cambios parciales antes de reintentar`,resultCompleteBody:`El PAT temporal de configuración no se revoca automáticamente. Elimínalo en GitHub tras comprobar el resultado. Conserva el PAT del bot hasta que rotes el Secret instalado.`,resultPartialBody:`Puede haberse escrito el Secret del bot u otro recurso. Revisa GitHub y ejecuta copilot doctor --read-only antes de reemplazar o eliminar ese PAT.`,resultNoChangesBody:`Copilot no empezó a aplicar cambios de configuración. Puede haber ejecutado pruebas temporales de permisos; GitHub puede conservar historial de Actions, Issues o PR después de limpiarlas. Los PAT creados siguen allí hasta que los elimines.`,whatHappened:`Qué ha pasado`,alreadyChanged:`Qué ha cambiado`,noChanges:`No se iniciaron cambios de configuración en el repositorio ni en GitHub durante esta sesión.`,nextAction:`Siguiente paso`,reasonPermissions:`Faltan permisos del PAT de configuración o no pudieron confirmarse.`,nextPermissions:`Comprueba los permisos mostrados, corrige el PAT en GitHub e inicia una nueva sesión.`,reasonWorkflowPermissions:`El PAT del bot no completó todas las comprobaciones de permisos. Revisa el permiso fallido y los requisitos de preparación o limpieza indicados abajo.`,permissionReportTitle:`Comprobación de permisos del PAT`,permissionReportLead:`Se muestran los permisos obligatorios que no pudieron confirmarse. «No verificable» no significa «ausente».`,updatedSetupPatTitle:`Corrige el PAT de configuración`,updatedSetupPatBody:`Este enlace de GitHub incluye los permisos necesarios para esta configuración. Selecciona este repositorio antes de crear el PAT. Cierra esta sesión local e inicia una nueva configuración con el PAT corregido.`,updatedSetupPatGrants:`Permisos adicionales detectados tras la inspección`,updatedSetupPatLink:`Crear PAT de configuración corregido`,permissionProbeCleanupPending:`Puede quedar un recurso temporal de comprobación de permisos. El setup se ha detenido; no supongas que se eliminó.`,permissionProbeCleanupAction:`Reintenta con un PAT capaz de eliminarlo. Se revisa el registro local de recuperación antes de nuevas pruebas.`,permissionSecretCollision:`GitHub indicó que se actualizó un Secret con el nombre aleatorio de prueba. Es posible que haya cambiado un valor creado a la vez. El setup se detuvo sin eliminarlo.`,permissionSecretCollisionAction:`Revisa el historial de Secrets de GitHub y restaura cualquier valor afectado antes de reintentar. El registro local de recuperación no puede reparar esta colisión.`,permissionIdentity:`Identidad de GitHub y acceso al repositorio`,permissionIdentityValid:`Verificados`,permissionIdentityInvalid:`Rechazados`,permissionIdentityUnknown:`No se pudieron confirmar`,permissionGrantNotChecked:`Sin comprobar`,permissionReportNoFailedGrant:`La comprobación no detectó un permiso obligatorio fallido. Revisa la cuenta prevista para el PAT y el error de la terminal antes de reintentarlo.`,reasonStorage:`No se pudo usar de forma segura el almacenamiento elegido de GitHub Actions.`,nextStorage:`Revisa el ámbito de Variables/Secrets y los recursos existentes; después, reinténtalo.`,reasonConfiguration:`No se pudo validar la configuración elegida.`,nextConfiguration:`Revisa el detalle de validación en la terminal, corrige las opciones y reinténtalo.`,reasonExpired:`La sesión local caducó.`,nextExpired:`Inicia una sesión nueva; la aprobación anterior no puede reutilizarse.`,reasonCancelled:`La sesión se canceló.`,nextCancelled:`Inicia una nueva ejecución si todavía quieres configurar este repositorio.`,reasonUnknown:`La configuración se detuvo. El navegador no pudo determinar la causa exacta. Revisa el recibo de recursos, si está disponible, y consulta la terminal.`,nextUnknown:`Consulta el último error de la terminal antes de reintentar; no supongas que se revocó ningún PAT.`,reasonProvider:`GitHub u otro proveedor no completó la operación solicitada.`,nextProvider:`Usa la referencia de diagnóstico para consultar la terminal, comprueba la disponibilidad y el acceso al proveedor y revisa posibles cambios parciales antes de reintentar.`,reasonRateLimit:`GitHub ha limitado temporalmente las solicitudes necesarias para la configuración.`,nextRateLimit:`Espera a que se restablezca el límite. Inspecciona los cambios completados antes de iniciar otra configuración.`,diagnosticReference:`Referencia de diagnóstico`,resourceReceipt:`Registro de operaciones de configuración`,effectCompleted:`Marcada como completada`,effectSkipped:`Marcada como omitida`,effectInspect:`Resultado pendiente de inspección`,effectNotStarted:`No iniciada`,effectInProgress:`En curso; resultado aún sin confirmar`,scopeLocal:`Checkout local`,scopeMixed:`Repositorio y organización`,receiptFiles:`Archivos de configuración`,receiptSecrets:`Secrets de GitHub Actions`,receiptLabels:`Etiquetas de issues`,receiptIssueTypes:`Tipos de issue`,receiptVariables:`Variables de GitHub Actions`,receiptInitialTag:`Etiqueta de versión inicial`,inspectPartial:`Algunos cambios podrían estar activos. Revisa GitHub y el resultado de la terminal antes de reintentar.`,patSettings:`Abrir ajustes de PAT en GitHub ↗`,closeSession:`Cerrar sesión local`,sessionClosed:`Sesión local cerrada`,sessionClosedBody:`El servidor local aceptó la solicitud de cierre. Esta página deja de consultarlo y conserva el resultado. Cerrar la sesión no revoca ningún PAT creado en GitHub.`,doctorHelp:`Tras completar el setup, puedes comprobar aquí los recursos instalados sin lanzar Actions. También puedes ejecutar copilot doctor --read-only desde la raíz del repositorio con el PAT temporal y el mismo archivo --config no secreto, si lo usaste.`,doctorRun:`Comprobar instalación (solo lectura)`,doctorRunning:`Comprobando los recursos instalados sin lanzar Actions…`,doctorPassed:`La comprobación de solo lectura no encontró fallos.`,doctorWarnings:`La comprobación de solo lectura requiere atención.`,doctorFailed:`La comprobación de solo lectura no terminó. Revisa la terminal o ejecuta el comando indicado abajo.`,doctorCounts:`{pass} correctas · {warn} avisos · {fail} fallos · {skipped} omitidas.`,doctorSecretLimit:`Este modo no puede verificar los valores de Secrets.`,botRenewal:`El PAT del bot permanece en el Secret de GitHub Actions seleccionado para futuras ejecuciones. Su fecha real de caducidad no se verifica aquí; anótala en GitHub y rota el Secret antes de que venza.`,working:`Preparando el siguiente paso`,workingBody:`El proceso local comprueba tus respuestas y prepara la siguiente decisión. Mantén esta página abierta.`,repoFocus:`Repositorio seleccionado`,repoFocusBody:`Este setup configura el repositorio indicado. Los Secrets y Variables de organización pueden compartirse con otros repositorios.`,access:`acceso`,readOnlyCheck:`Comprobación de capacidades`,provisionalGrants:`Permisos provisionales de mínimo privilegio`,conditionalGrants:`Los permisos condicionales dependen de tus elecciones y de GitHub. Se hará una auditoría final antes de cualquier cambio.`,permissionEvidenceVerified:`Una lectura de GitHub confirmó este acceso.`,permissionEvidenceVerifiedWrite:`Se creó, leyó y eliminó un recurso temporal.`,permissionEvidencePrivateProject:`Un Project no público de la organización confirmó el acceso de lectura a Projects.`,permissionEvidenceMissing:`GitHub rechazó el acceso necesario. Comprueba los ajustes del PAT.`,permissionEvidenceWrite:`La comprobación temporal de escritura no terminó correctamente. Revisa la fase fallida y vuelve a intentarlo.`,permissionEvidencePublic:`La lectura funcionó, pero este recurso público no demuestra por sí solo el permiso del PAT.`,permissionEvidencePublicProjects:`La lectura de Projects funcionó, incluso si devolvió una lista vacía. El acceso a Projects privados se comprueba al seleccionarlos.`,permissionEvidenceUnknownRead:`La consulta de lectura no fue concluyente. Revisa el detalle en la terminal y reintenta si hace falta.`,permissionUnknown:`Este permiso requiere revisión. Comprueba en la terminal el permiso exacto y su explicación técnica antes de continuar.`,permissionsFollow:`Los permisos dependen de tus elecciones`,permissionsFollowBody:`Mostraremos los permisos exactos antes de crear cada PAT. Abrir esta página no crea nada.`,files:`Archivos`,workflows:`Workflows`,variables:`Variables`,secretNames:`Nombres de Secrets`,planBody:`Revisa exactamente lo que podría cambiar. Al aprobar, se prueban los permisos de escritura del PAT con recursos temporales; después se pedirán el PAT del bot y otras credenciales. GitHub puede conservar ejecuciones, historial de Issues o PR y notificaciones de esas pruebas.`,planPermissionProbeTitle:`Pruebas temporales de permisos tras aprobar`,planPermissionProbeBody:`Cada permiso indicado crea, lee y elimina su propio recurso temporal. La prueba de Issues crea un Issue visible; si GitHub impide borrarlo, el setup lo cierra, informa de su número y se detiene. Actions, Issues y Pull requests pueden dejar historial o notificaciones.`,planActionsProbePrerequisites:`La prueba de Actions necesita Contents Write para crear su rama aislada. Si el workflow de salud empaquetado exacto no está disponible en la rama predeterminada, también necesita Workflows Write para preparar una versión con los jobs desactivados. Al comprobar el bot, el PAT de setup prepara y limpia el recurso; el PAT del bot lanza y lee su ejecución. Un requisito bloqueado no demuestra que falte Actions.`,planSecretProbeLimit:`GitHub solo permite crear o actualizar Secrets con la misma operación. La prueba usa un nombre aleatorio privado y comprueba antes que no exista, pero GitHub no garantiza una creación atómica. Si informa de una actualización, el setup se detiene y te pide revisar el historial del Secret.`,planChoices:`Tus decisiones principales`,planEnabledCapabilities:`Funciones activadas`,planBranchRoles:`Rama de producción / desarrollo`,planApprovalMode:`Aprobación de pull requests`,planVariableScope:`Ámbito de Variables`,planSecretScope:`Ámbito de Secrets`,planInitialTag:`Crear etiqueta inicial`,planAgentRouting:`Agente y modelo por tarea`,planIssueWorkflows:`Flujos de issues`,planTrustedChecks:`Productores de CI fiables`,planCoverage:`Prueba de cobertura`,planProjectStatuses:`Transiciones de Status en Projects`,planIssueResources:`Etiquetas y tipos de issue`,planIssueResourcesValue:`Se comprobarán o crearán al aplicar`,planProducerAttested:`Identidad de CI y paso obligatorio comprobados por ti`,planCoverageThreshold:`Cobertura mínima de líneas modificadas`,planCoverageReporter:`Workflow que publica el artefacto`,planReporterAttested:`Generador de cobertura comprobado por ti`,planAdvancedDefaults:`El plan también incluye valores predeterminados de ajustes que no cambiaste. Usa Cambiar más abajo para revisar cualquier sección antes de aprobar.`,planUnknownWarning:`Hay un aviso adicional del plan que no se puede mostrar aquí. Léelo en la terminal antes de aprobar.`,planBasicDefaultsIntro:`El modo básico conservó estos ajustes avanzados. Abre una sección más abajo para revisarlos o cambiarlos:`,scopeRepository:`Repositorio`,scopeOrganization:`Organización`,scopeDisabled:`Sin aprovisionar`,approvalOff:`Desactivada`,approvalRecommend:`Solo recomendaciones`,approvalGuarded:`Aprobación protegida`,beforeContinue:`Antes de continuar`,stopHere:`Detener aquí`,approvePlan:`Aprobar este plan`,githubLink:`Abrir enlace de GitHub ↗`,githubForm:`Abrir el formulario oficial de PAT de GitHub`,githubFormHelp:`Comprueba la cuenta activa, elige Only select repositories y selecciona este repositorio. GitHub gestiona el 2FA y crea el PAT.`,pasteHere:`Pega aquí el valor`,yourAnswer:`Tu respuesta`,hiddenAfter:`Oculto tras enviarlo`,typeAnswer:`Escribe tu respuesta`,secretHelp:`Se envía solo a este proceso local. No volverá a mostrarse ni se guardará en el almacenamiento del navegador.`,pairTitle:`Vincula este navegador`,pairLabel:`Código de vinculación de la terminal`,pairPlaceholder:`16 caracteres hexadecimales`,pairBody:`Busca el código de 16 caracteres en la terminal donde ejecutaste copilot setup --web. Introdúcelo para ver o controlar la sesión. No aparece en la URL ni se almacena al cerrar la página.`,pairHelp:`Mantén el código en privado. Tras actualizar la página, introdúcelo de nuevo para reconectar.`,pairButton:`Conectar a la configuración local`,privateSession:`SESIÓN LOCAL PRIVADA`,theme:`Tema de color`,themeAuto:`Sistema`,themeSystem:`Seguir tema del sistema`,themeLight:`Tema claro`,themeDark:`Tema oscuro`,selectOne:`Selecciona una opción`,ciRun:`Abrir ejecución de CI en GitHub ↗`,manualCheck:`¿No aparece el check? Introduce nombre|ID de App|workflow exactos, separados por punto y coma.`,checksObserved:`Se encontraron jobs recientes de CI. Abre cada ejecución y comprueba el job, la App y el paso obligatorio de cobertura antes de confiar en él.`,checksNoRecent:`No hay ejecuciones recientes de workflows de pull request. Ejecuta tu CI habitual en un PR real o introduce manualmente un productor exacto.`,checksNoVerifiable:`Hay ejecuciones recientes, pero ningún job pudo vincularse a un Check Run y una App concretos. Revisa GitHub o introduce el productor manualmente.`,checksDenied:`GitHub no permitió consultar los checks. Concede Actions: read y Checks: read al PAT de configuración, o introduce el productor manualmente.`,checksUnavailable:`No se pudo completar la consulta de CI. Esto no significa que el repositorio no tenga checks. Reintenta o introduce el productor manualmente.`,projectsObserved:`Estos Projects existentes pertenecen al dueño del repositorio. Selecciona solo los que deba actualizar la automatización.`,projectsEmpty:`Esta consulta limitada no devolvió Projects abiertos y accesibles; eso no demuestra que no existan. Comprueba el acceso o introduce un número verificado.`,projectsDenied:`GitHub no permitió consultar Projects. Comprueba Projects: read de la organización en el PAT o introduce los números manualmente.`,projectsUnavailable:`No se pudo consultar Projects. Eso no demuestra que no existan. Introduce un número verificado o reintenta.`,projectsUnsupported:`GitHub no permite listar Projects personales con un PAT de permisos precisos mediante esta API. Introduce el número de la URL de un Project existente.`,discoveryTruncated:`Solo se inspeccionó una muestra limitada de Projects accesibles o checks recientes. Usa la entrada manual si falta uno.`,checksDiscoveryScope:`Alcance: hasta 20 ejecuciones de PR entre las últimas 1.000 ejecuciones de workflows (hasta 10 páginas) de los últimos 90 días; se inspeccionan como máximo 15 ejecuciones y 100 checks por commit.`,projectsDiscoveryScope:`Alcance: hasta 30 Projects abiertos y accesibles de la organización en dos páginas; se inspeccionan hasta 100 campos por Project. Se excluyen los Projects cerrados.`,retryDiscovery:`Reintentar búsqueda en GitHub`,retryRemaining:`Quedan {count} reintentos de solo lectura. Tus respuestas se conservan.`,retryExhausted:`No quedan reintentos. Consulta GitHub e introduce manualmente lo que falte.`,observationTimeUnknown:`fecha de observación no disponible`,branchRequirementUnknown:`Obligatorio según la regla de rama: no comprobado`,branchRequirementObserved:`Obligatorio en {branch} por un ruleset activo para este check y esta App exactos.`,ciRule:`Abrir ruleset del check obligatorio ↗`,projectSharedStatus:`Todos los Projects elegidos deben compartir cada valor Status. Este setup no asigna valores diferentes por Project.`,fixedWorkflowEnabled:`Tu configuración fija features.{kind}=true. Mantén {kind} seleccionado; cambia --config o los flags si quieres modificarlo.`,fixedWorkflowDisabled:`Tu configuración fija features.{kind}=false. Deja {kind} sin seleccionar; cambia --config o los flags si quieres modificarlo.`,fixedIssuesRequired:`Tu configuración activa expresamente release o hotfix. Mantén Issues activado o cambia antes --config o los flags.`,projectSelectionNotObserved:`Se conservan los números de Project elegidos antes, aunque ya no figuren en esta consulta. Compruébalos en GitHub o quítalos.`,removeSelection:`Quitar selección`,projectTransitionIssueCreated:`Issue nuevo`,projectTransitionPullRequestCreated:`Pull request nuevo`,projectTransitionIssueInProgress:`Issue en curso`,projectTransitionPullRequestInProgress:`Pull request en curso`,projectUrl:`Abrir Project en GitHub ↗`,projectManual:`¿Falta un Project? Introduce su número positivo o URL exacta de GitHub. No se aceptan IDs PVT_.`,projectStatusUnavailable:`No se pudieron verificar las opciones Status de todos los Projects elegidos. Comprueba cada Project en GitHub e introduce el valor exacto.`,projectStatusIncompatible:`Los Projects elegidos no comparten valores Status. Elige Projects compatibles antes de continuar.`,producerName:`Nombre del check/job`,producerAppId:`ID de la App de GitHub`,producerWorkflow:`Nombre del workflow`,producerAdd:`Añadir check exacto`,producerRemove:`Quitar check`,producerManualHelp:`Usa la identidad exacta de GitHub. Añadirla no acredita que exija la cobertura.`,producerManualInvalid:`Indica nombre, ID numérico positivo de App y workflow. No uses | ni ; en los nombres. Se permiten comas.`,translationPreviewTitle:`Revisión de la traducción en curso`,translationPreviewBody:`Las preguntas propias de la configuración ya están traducidas. Algunos diagnósticos dinámicos de GitHub o del proveedor aún pueden aparecer en inglés mientras termina la revisión. Cambiar de idioma no modifica tus respuestas.`,unknownLocalError:`Se ha producido un error inesperado en la configuración local. Consulta la terminal y actualiza la página o reinicia la configuración.`},Gi={setupHelp:`Aide à la configuration`,setupTutorial:`Tutoriel de configuration`,firstWorkflowGuide:`Premier parcours issue vers PR`,setupRecovery:`Dépannage`,setupHelpHint:`La documentation s’ouvre dans un nouvel onglet. Vos réponses restent ici.`,setupNextWorkflow:`Installez les fichiers vérifiés, puis testez l’Action dans GitHub. Une vérification des métadonnées ne prouve pas son fonctionnement.`,batchNextActions:`Prochaines étapes`,batchStatusReady:`Prêt à examiner`,batchStatusBlocked:`Action requise`,batchStatusApplying:`Application du plan validé`,batchStatusPartial:`Partiellement appliqué ; vérifier avant de réessayer`,batchStatusWaiting:`PR créée · en attente de fusion par un mainteneur`,batchStatusPending:`Configuration appliquée · vérification en attente`,batchStatusUnchanged:`Déjà conforme · inchangé`,batchStatusCancelled:`Travail en attente arrêté ; effets réalisés conservés`,batchConfigurationPreview:`Aperçu de la configuration, ajouté à la revue du lot. Les tests de permissions et l’installation attendent votre approbation du lot complet.`,batchUseConfiguration:`Utiliser cette configuration`,planReuseBody:`Approuvez les tests temporaires de permissions indiqués, puis la configuration revue sera appliquée. Les valeurs des Secrets existants sont conservées, sans être demandées ni remplacées. La vérification des capacités d’exécution peut rester en attente.`,organizationReuseTitle:`Réutilisation de la configuration existante`,organizationReuseBody:`{imported} paramètres compatibles importés. Conservation de {shared} Variables d’organisation et de {overrides} surcharges du dépôt ; écriture de {writes} Variables du dépôt. Les valeurs partagées et les Secrets existants restent inchangés.`,batchBranchReview:`Branche d’installation et base revue`,batchFocusTitle:`Dépôts sélectionnés`,batchFocusBody:`{count} dépôts sélectionnés explicitement dans cette organisation. Vérifiez chaque cible séparément.`,batchReviewTitle:`Examinez les plans de configuration`,batchProgressTitle:`Application des plans par dépôt`,batchResultTitle:`Résultats de configuration par dépôt`,batchProgressBody:`Application séquentielle des plans approuvés. Arrêter suspend le travail restant après la requête en cours ; les modifications et PR terminées sont conservées.`,batchReviewBody:`Approuvez uniquement les plans prêts ci-dessous. La configuration avance dans l’ordre, ajoute les accès validés sans remplacer les valeurs partagées et crée une PR par dépôt modifié. Elle ne fusionne pas, ne crée pas de tag, ne publie pas et ne déploie pas.`,batchResultBody:`Une PR de configuration nécessite encore une revue et une fusion par un mainteneur. La vérification des identifiants et capacités à l’exécution peut rester en attente. Les PR et accès réalisés sont conservés si un autre dépôt s’arrête.`,batchStopping:`Arrêt du travail en attente après la requête actuelle. Les changements réalisés seront conservés.`,batchReasonDrift:`La base validée ou sa propriété a changé. Inspectez le dépôt et examinez un nouveau plan.`,batchReasonProvider:`GitHub n’a pas confirmé la dernière étape. Une nouvelle tentative inspecte les effets existants avant de continuer.`,batchCleanupPending:`Le nettoyage du contrôle des permissions n’a pas pu être confirmé. Le travail restant est arrêté. Vérifiez l’historique GitHub et le journal local de récupération ; résolvez le nettoyage avant de démarrer une nouvelle configuration. Cette opération ne peut pas reprendre les écritures.`,batchReasonCancelled:`Le travail en attente s’est arrêté. Les changements réalisés ont été conservés.`,batchReasonPreflight:`Vérifiez l’accès, les identifiants requis et les réglages propres au dépôt avant de continuer.`,batchOpenPull:`Ouvrir la PR de configuration`,batchFilesCount:`{count} fichiers modifiés`,batchVariablesCount:`{count} changements de Variables du dépôt`,batchGrantsCount:`{count} ajouts d’accès pour ce dépôt`,batchRetainedSecrets:`Secrets existants conservés`,batchResourcesExplanation:`Les labels et Issue Types activés sont préparés séparément pour ce dépôt. Les valeurs des Secrets partagés et les accès des autres dépôts sont conservés.`,batchReviewFiles:`Inspecter les fichiers proposés`,batchDeleteFile:`Ce fichier géré par la configuration sera retiré de l’arbre d’installation ; inspectez sa sauvegarde conservée.`,batchRepositoryOverrides:`Examiner les noms des Variables du dépôt`,batchReviewedAccess:`Examiner les ajouts d’accès`,batchApplyPlans:`Appliquer les plans prêts`,batchLeavePreview:`Quitter sans appliquer`,batchStopPending:`Arrêter le travail en attente`,batchStopConfirm:`Arrêter le travail en attente après la requête actuelle ? Les PR, accès et changements réalisés seront conservés.`,batchRetryPending:`Inspecter et réessayer le travail inachevé`,batchFinish:`Terminer cette opération`,batchCleanup:`Supprimez les PAT temporaires de configuration dans GitHub après cette opération. Conservez le PAT du bot tant que les dépôts utilisent son Secret.`,batchTechnical:`Détails de l’opération`,batchLookupUnavailable:`GitHub n’a pas pu confirmer ce dépôt. Vérifiez son nom exact et l’accès du PAT.`,batchSelectionInvalid:`Vérifiez la sélection : choisissez 1 à 25 dépôts disponibles de cette organisation.`,batchAccessUnavailable:`L’accès n’est pas confirmé. Vérifiez le PAT temporaire ou retirez ce dépôt de la sélection.`,batchSelectionBody:`Choisissez 1 à 25 dépôts de {organization}. Seuls les dépôts sélectionnés seront configurés.`,batchDiscoveryUnavailable:`GitHub n’a pas pu lister les dépôts. Le dépôt actuel reste disponible ; cherchez un autre par son nom exact ou vérifiez l’accès du PAT.`,batchDiscoveryTruncated:`Cette vue a atteint la limite de 1 000 dépôts. Recherchez un nom exact pour ajouter un dépôt absent.`,batchFilter:`Filtrer les dépôts visibles`,batchSelectedCount:`{count} sélectionnés · maximum 25`,batchRepositories:`Dépôts`,batchPrivate:`Privé`,batchPublic:`Public`,batchCurrent:`Dépôt actuel`,batchArchived:`Archivé`,batchDisabled:`Désactivé`,batchReadOnly:`Accès en écriture indisponible`,batchNoMatches:`Aucun dépôt visible ne correspond au filtre.`,batchPrevious:`Précédent`,batchNext:`Suivant`,batchMissingRepository:`Un dépôt manque ?`,batchAccessExplanation:`La liste montre uniquement les dépôts visibles avec ce PAT. Une recherche par nom exact n’accorde aucun accès et ne sélectionne pas automatiquement le dépôt. Si vous remplacez le PAT temporaire, limitez-le aux dépôts à configurer.`,batchExactName:`Nom exact du dépôt dans cette organisation`,batchFindRepository:`Trouver le dépôt`,batchChangeAccess:`Changer l’accès du PAT temporaire`,batchReviewSelection:`Examiner les dépôts sélectionnés`,patStorageRetain:`Conservez le Secret PAT existant dans {destination}. Sa valeur n’est ni demandée, ni copiée, ni remplacée. S’il manque, créez-le séparément. La vérification de l’identité et des autorisations à l’exécution reste en attente.`,patStorageTitle:`Stockage du PAT du bot`,patRepositoryReplace:`Le Secret PAT existe déjà dans le dépôt {destination}. Il sera remplacé même si vous avez choisi de conserver les autres Secrets existants.`,patOrganizationReplace:`Le Secret PAT existe déjà dans l’organisation {destination}. Il sera remplacé même si vous avez choisi de conserver les autres Secrets existants.`,patRepositoryCreate:`Le PAT du bot sera enregistré comme Secret PAT dans le dépôt {destination}.`,patOrganizationCreate:`Le PAT du bot sera enregistré comme Secret PAT dans l’organisation {destination}.`,patReplacementChecks:`Le PAT du bot fourni doit réussir les vérifications d’identité, d’accès au dépôt et des autorisations requises avant l’écriture de ce Secret.`,patOrganizationImpact:`Remplacer ce Secret d’organisation peut affecter les autres dépôts qui l’utilisent. Les vérifications pour ce dépôt ne valident pas leurs exigences.`,repositorySecretSettings:`Ouvrir les Secrets Actions du dépôt`,botAccountWarning:`Vous devez ouvrir ce lien avec le compte bot sélectionné : @{account}.`,botAccountHelp:`Vérifiez le compte GitHub avant de générer le PAT. Utilisez une fenêtre privée ou changez de compte si le navigateur utilise le compte de l’opérateur de configuration.`,botGithubForm:`Créer le PAT du bot en tant que @{account}`,language:`Langue`,english:`Anglais`,spanish:`Espagnol`,setup:`CONFIGURATION`,connecting:`Connexion…`,localSession:`SESSION LOCALE`,progress:`Progression`,studio:`ASSISTANT DE CONFIGURATION`,journey:`VOTRE PARCOURS`,repository:`Dépôt`,choices:`Choix`,setupPat:`PAT de configuration`,plan:`Plan`,botPat:`PAT du bot et identifiants`,apply:`Appliquer`,localDesign:`Local par conception`,localDesignBody:`Cette page fonctionne sur votre ordinateur. GitHub crée les deux PAT dans ses propres onglets.`,preparing:`Préparation…`,completeTitle:`Configuration terminée.`,previewTitle:`Aperçu terminé.`,cancelledTitle:`Configuration annulée.`,blockedTitle:`Une intervention est nécessaire.`,gettingReady:`PRÉPARATION`,activeLede:`Une décision à la fois. Vos choix déterminent les droits, le plan et les identifiants nécessaires.`,resultLede:`Consultez le résultat et la prochaine étape ci-dessous. Le terminal fournit les détails techniques.`,readOnly:`Onglet en lecture seule`,readOnlyBody:`Un autre onglet contrôle cette session. Vous pouvez suivre la progression ou prendre le contrôle.`,takeOver:`Prendre le contrôle`,attention:`Action nécessaire`,checked:`Vérifié`,pleaseNote:`À noter`,progressUpdate:`Mise à jour`,reviewPass:`Révision des choix enregistrés — passage {pass}. C’est la même session, pas un redémarrage.`,cancelSetup:`Annuler`,cancelConfirm:`Annuler cette session locale ? Les PAT créés sur GitHub continueront d’exister.`,footerLocal:`LOCALHOST UNIQUEMENT`,footerCloud:`AUCUN COMPTE CLOUD`,footerGithub:`GITHUB ÉMET LES PAT`,currentDecision:`DÉCISION ACTUELLE`,session:`SESSION`,continue:`Continuer`,previousQuestion:`Question précédente`,questionProgress:`Question {current} sur {total} dans ce groupe · {overall} sur {all} au total`,yes:`Oui`,no:`Non`,permissionPreview:`APERÇU DES DROITS`,changeAnswersTitle:`Modifier vos réponses`,changeAnswersHelp:`Revenez à une section sans perdre les autres réponses. Le plan et les droits PAT requis seront vérifiés à nouveau.`,changeSection:`Modifier {section}`,editCapabilities:`Fonctionnalités`,editRuntimes:`Agents`,editModels:`Modèles des agents`,editRoleModels:`Modèles par tâche`,editRepository:`Comportement du dépôt`,editDeployment:`Releases et correctifs`,editBugbot:`Bugbot`,editApproval:`Approbation des PR`,editProjects:`Projects`,editProvisioning:`Provisionnement`,editStorage:`Secrets et Variables`,suggested:`Réponse suggérée : {answer}. Vous pourrez revoir vos choix avant de créer le PAT.`,none:`aucune`,sourceGithub:`Observé dans les métadonnées authentifiées de ce dépôt GitHub.`,sourceConfig:`Fourni par votre configuration ; GitHub ne l’a pas remplacé.`,sourceDefault:`Valeur par défaut du produit ; non vérifiée dans ce dépôt.`,sourceLocal:`Observé dans ce dossier local ; vérifiez que cette branche existe sur GitHub avant d’appliquer les changements.`,whyMatters:`Pourquoi c’est important`,whenApplies:`Quand cela s’applique`,whereConfigured:`Où se fait le réglage`,howToChoose:`Comment choisir`,whyRecommendation:`Pourquoi c’est important`,example:`Exemple`,effect:`Ce qui change`,verify:`Comment vérifier`,learnMore:`Lire la documentation de ce réglage`,resultApplied:`Configuration appliquée`,resultNoChanges:`Aucun changement effectué`,resultStopped:`Aucun changement commencé`,resultPartial:`Vérifiez les changements partiels`,resultCompleteBody:`Le PAT temporaire n’est pas révoqué automatiquement. Supprimez-le sur GitHub après vérification. Gardez le PAT du bot jusqu’à rotation du Secret.`,resultPartialBody:`Un Secret ou une autre ressource a peut-être été modifié. Vérifiez GitHub et exécutez copilot doctor --read-only avant de remplacer ou supprimer un PAT.`,resultNoChangesBody:`Copilot n’a pas commencé à appliquer la configuration. Des tests temporaires de permissions ont pu s’exécuter ; GitHub peut conserver l’historique Actions, Issues ou PR après leur nettoyage. Les PAT créés restent actifs jusqu’à leur suppression.`,whatHappened:`Ce qui s’est passé`,alreadyChanged:`Déjà modifié`,noChanges:`Aucun changement du dépôt ou de GitHub n’a commencé pendant cette session.`,nextAction:`Prochaine étape`,reasonPermissions:`Les droits nécessaires du PAT de configuration manquent ou n’ont pas pu être confirmés.`,nextPermissions:`Vérifiez les droits affichés, corrigez le PAT sur GitHub, puis recommencez.`,reasonWorkflowPermissions:`Le PAT du bot n’a pas terminé toutes les vérifications de droits. Consultez le droit concerné et les prérequis de préparation ou de nettoyage ci-dessous.`,permissionReportTitle:`Vérification des droits du PAT`,permissionReportLead:`Les droits requis qui n’ont pas pu être confirmés sont indiqués ci-dessous. « Non vérifiable » ne signifie pas « absent ».`,updatedSetupPatTitle:`Corrigez le PAT de configuration`,updatedSetupPatBody:`Ce lien GitHub inclut les droits requis pour cette configuration. Sélectionnez ce dépôt avant de créer le PAT. Fermez cette session locale, puis recommencez la configuration avec le PAT corrigé.`,updatedSetupPatGrants:`Droits supplémentaires détectés après inspection`,updatedSetupPatLink:`Créer un PAT de configuration corrigé`,permissionProbeCleanupPending:`Une ressource temporaire de vérification peut encore exister. La configuration est arrêtée ; ne supposez pas que le nettoyage a réussi.`,permissionProbeCleanupAction:`Réessayez avec un PAT capable de la supprimer. Le journal local de récupération est consulté avant tout nouveau test.`,permissionSecretCollision:`GitHub a indiqué qu’un Secret portant le nom de test aléatoire a été mis à jour. Une valeur créée simultanément peut avoir changé. La configuration s’est arrêtée sans le supprimer.`,permissionSecretCollisionAction:`Consultez l’historique des Secrets GitHub et restaurez toute valeur concernée avant de réessayer. Le journal local ne peut pas corriger cette collision.`,permissionIdentity:`Identité GitHub et accès au dépôt`,permissionIdentityValid:`Vérifiés`,permissionIdentityInvalid:`Refusés`,permissionIdentityUnknown:`Non confirmés`,permissionGrantNotChecked:`Non vérifié`,permissionReportNoFailedGrant:`Cette vérification n’a trouvé aucun droit requis en échec. Vérifiez le compte prévu pour le PAT et l’erreur du terminal avant de réessayer.`,reasonStorage:`Le stockage GitHub Actions choisi ne peut pas être utilisé en sécurité.`,nextStorage:`Vérifiez la portée des Variables/Secrets et les ressources existantes, puis réessayez.`,reasonConfiguration:`La configuration choisie n’a pas pu être validée.`,nextConfiguration:`Lisez les détails du terminal, corrigez les choix et réessayez.`,reasonExpired:`La session locale a expiré.`,nextExpired:`Démarrez une nouvelle session ; l’ancienne approbation ne peut pas être réutilisée.`,reasonCancelled:`La configuration a été annulée.`,nextCancelled:`Démarrez une nouvelle session si vous souhaitez encore configurer ce dépôt.`,reasonUnknown:`La configuration s’est arrêtée. Le navigateur n’a pas pu déterminer la cause exacte. Consultez le reçu des ressources, s’il est disponible, et le terminal.`,nextUnknown:`Consultez la dernière erreur du terminal avant de réessayer. Ne supposez pas qu’un PAT a été révoqué.`,reasonProvider:`GitHub ou un autre fournisseur n’a pas terminé l’opération demandée.`,nextProvider:`Utilisez la référence de diagnostic pour consulter le terminal, vérifiez la disponibilité et les accès, puis examinez tout changement partiel avant de réessayer.`,reasonRateLimit:`GitHub a temporairement limité les requêtes nécessaires à la configuration.`,nextRateLimit:`Attendez la réinitialisation de la limite. Examinez les changements effectués avant de recommencer.`,diagnosticReference:`Référence de diagnostic`,resourceReceipt:`Reçu des opérations de configuration`,effectCompleted:`Signalée comme terminée`,effectSkipped:`Signalée comme ignorée`,effectInspect:`Résultat à vérifier`,effectNotStarted:`Non commencée`,effectInProgress:`En cours ; résultat non encore confirmé`,scopeLocal:`Dossier local`,scopeMixed:`Dépôt et organisation`,receiptFiles:`Fichiers de configuration`,receiptSecrets:`Secrets GitHub Actions`,receiptLabels:`Étiquettes des tickets`,receiptIssueTypes:`Types de ticket`,receiptVariables:`Variables GitHub Actions`,receiptInitialTag:`Première étiquette de version`,inspectPartial:`Des changements peuvent déjà être actifs. Vérifiez GitHub et le terminal avant de réessayer.`,patSettings:`Ouvrir les paramètres PAT GitHub ↗`,closeSession:`Fermer la session locale`,sessionClosed:`Session locale fermée`,sessionClosedBody:`Le serveur local a accepté la demande de fermeture. Cette page ne le contacte plus et conserve le résultat. Fermer la session ne révoque aucun PAT créé dans GitHub.`,doctorHelp:`Après la configuration, vérifiez ici les ressources installées sans déclencher d’Actions. Vous pouvez aussi exécuter copilot doctor --read-only à la racine du dépôt avec le PAT temporaire et le même fichier --config non secret, le cas échéant.`,doctorRun:`Vérifier l’installation (lecture seule)`,doctorRunning:`Vérification des ressources installées sans déclencher d’Actions…`,doctorPassed:`La vérification en lecture seule n’a trouvé aucun échec.`,doctorWarnings:`La vérification en lecture seule demande une attention particulière.`,doctorFailed:`La vérification en lecture seule ne s’est pas terminée. Consultez le terminal ou exécutez la commande ci-dessous.`,doctorCounts:`{pass} réussis · {warn} avertissements · {fail} échecs · {skipped} ignorés.`,doctorSecretLimit:`Ce mode ne peut pas vérifier les valeurs des Secrets.`,botRenewal:`Le PAT du bot reste dans le secret GitHub Actions choisi pour les futures exécutions. Sa date d’expiration réelle n’est pas vérifiée ici ; notez-la sur GitHub et remplacez le secret avant cette date.`,working:`Préparation de l’étape suivante`,workingBody:`Le processus local vérifie vos réponses. Gardez cette page ouverte.`,repoFocus:`Dépôt concerné`,repoFocusBody:`Cette configuration concerne le dépôt indiqué. Les Secrets et Variables d’organisation peuvent être partagés avec d’autres dépôts.`,access:`accès`,readOnlyCheck:`Vérification des capacités`,provisionalGrants:`Droits provisoires minimaux`,conditionalGrants:`Les droits conditionnels dépendent de vos choix et de GitHub. Un contrôle final précède toute modification.`,permissionEvidenceVerified:`Une lecture GitHub a confirmé cet accès.`,permissionEvidenceVerifiedWrite:`Une ressource temporaire a été créée, lue et supprimée.`,permissionEvidencePrivateProject:`Un Project non public de l’organisation a confirmé l’accès Projects en lecture.`,permissionEvidenceMissing:`GitHub a refusé l’accès requis. Vérifiez les paramètres du PAT.`,permissionEvidenceWrite:`La vérification temporaire en écriture n’a pas abouti. Examinez l’étape échouée puis réessayez.`,permissionEvidencePublic:`La lecture a réussi, mais cette ressource publique ne prouve pas à elle seule le droit du PAT.`,permissionEvidencePublicProjects:`La lecture des Projects a réussi, même avec une liste vide. L’accès aux Projects privés est vérifié lors de leur sélection.`,permissionEvidenceUnknownRead:`Le contrôle en lecture n’est pas concluant. Consultez le détail dans le terminal et réessayez si nécessaire.`,permissionUnknown:`Ce droit exige une vérification. Consultez le droit exact et son explication technique dans le terminal avant de continuer.`,permissionsFollow:`Les droits suivent vos choix`,permissionsFollowBody:`Les droits exacts sont affichés avant chaque PAT. Ouvrir cette page ne crée rien.`,files:`Fichiers`,workflows:`Workflows`,variables:`Variables`,secretNames:`Noms des Secrets`,planBody:`Vérifiez précisément ce qui pourrait changer. Après approbation, des ressources temporaires testent les droits d’écriture du PAT, puis le PAT du bot et les autres identifiants sont demandés. GitHub peut conserver des exécutions, l’historique des Issues ou PR et des notifications.`,planPermissionProbeTitle:`Tests temporaires des permissions après approbation`,planPermissionProbeBody:`Chaque permission indiquée crée, lit puis supprime sa propre ressource temporaire. Le test Issues crée une Issue visible ; si GitHub refuse sa suppression, la configuration la ferme, indique son numéro et s’arrête. Actions, Issues et Pull requests peuvent laisser un historique ou des notifications.`,planActionsProbePrerequisites:`Le test Actions nécessite Contents Write pour créer sa branche isolée. Si le workflow de santé empaqueté exact est indisponible sur la branche par défaut, il nécessite aussi Workflows Write pour préparer une version dont les jobs sont désactivés. Pour le bot, le PAT de configuration prépare et nettoie la ressource ; le PAT du bot déclenche et lit son exécution. Un prérequis bloqué ne prouve pas qu’Actions manque.`,planSecretProbeLimit:`GitHub ne propose qu’une opération de création ou mise à jour pour les Secrets. Le contrôle utilise un nom aléatoire privé et vérifie d’abord son absence, mais GitHub ne garantit pas une création atomique. S’il signale une mise à jour, la configuration s’arrête et vous demande de consulter l’historique du Secret.`,planChoices:`Vos décisions principales`,planEnabledCapabilities:`Fonctionnalités activées`,planBranchRoles:`Branche de production / développement`,planApprovalMode:`Approbation des pull requests`,planVariableScope:`Portée des variables`,planSecretScope:`Portée des secrets`,planInitialTag:`Créer la première étiquette`,planAgentRouting:`Agent et modèle par tâche`,planIssueWorkflows:`Workflows de tickets`,planTrustedChecks:`Producteurs CI de confiance`,planCoverage:`Preuve de couverture`,planProjectStatuses:`Transitions Status des Projects`,planIssueResources:`Étiquettes et types de ticket`,planIssueResourcesValue:`Vérifiés ou créés lors de l’application`,planProducerAttested:`Identité CI et étape obligatoire vérifiées par vous`,planCoverageThreshold:`Couverture minimale des lignes modifiées`,planCoverageReporter:`Workflow publiant l’artefact`,planReporterAttested:`Producteur du rapport de couverture vérifié par vous`,planAdvancedDefaults:`Le plan comprend aussi les valeurs par défaut des réglages non modifiés. Utilisez Modifier ci-dessous pour examiner une section avant de valider.`,planUnknownWarning:`Un avertissement supplémentaire du plan ne peut pas être affiché ici. Lisez-le dans le terminal avant de valider.`,planBasicDefaultsIntro:`Le parcours de base a conservé ces réglages avancés. Ouvrez une section ci-dessous pour les vérifier ou les modifier :`,scopeRepository:`Dépôt`,scopeOrganization:`Organisation`,scopeDisabled:`Non provisionné`,approvalOff:`Désactivée`,approvalRecommend:`Recommandation uniquement`,approvalGuarded:`Approbation protégée`,beforeContinue:`Avant de continuer`,stopHere:`Arrêter ici`,approvePlan:`Approuver ce plan`,githubLink:`Ouvrir le lien GitHub ↗`,githubForm:`Ouvrir le formulaire PAT officiel de GitHub`,githubFormHelp:`Vérifiez le compte connecté, choisissez Only select repositories et ce dépôt. GitHub gère la 2FA et crée le PAT.`,pasteHere:`Collez la valeur ici`,yourAnswer:`Votre réponse`,hiddenAfter:`Masquée après envoi`,typeAnswer:`Saisissez votre réponse`,secretHelp:`Envoyé uniquement au processus local. Ni réaffiché ni enregistré dans le navigateur.`,pairTitle:`Associer ce navigateur`,pairLabel:`Code du terminal`,pairPlaceholder:`16 caractères hexadécimaux`,pairBody:`Trouvez le code à 16 caractères dans le terminal qui a lancé copilot setup --web. Il ne figure pas dans l’URL et n’est pas conservé après fermeture.`,pairHelp:`Gardez ce code secret. Après actualisation, saisissez-le de nouveau.`,pairButton:`Se connecter à la configuration locale`,privateSession:`SESSION LOCALE PRIVÉE`,theme:`Thème`,themeAuto:`Auto`,themeSystem:`Suivre le système`,themeLight:`Thème clair`,themeDark:`Thème sombre`,selectOne:`Choisissez une option`,ciRun:`Voir l’exécution CI sur GitHub ↗`,manualCheck:`Check absent ? Saisissez nom|ID App|workflow exacts, séparés par des points-virgules.`,checksObserved:`Des jobs CI récents ont été trouvés. Ouvrez chaque exécution et vérifiez le job, l’App et l’étape obligatoire de couverture avant de lui faire confiance.`,checksNoRecent:`Aucune exécution récente de workflow de pull request. Lancez le CI habituel sur une vraie PR ou saisissez un producteur exact.`,checksNoVerifiable:`Des exécutions récentes existent, mais aucun job ne correspond à une identité exacte de Check Run et d’App. Vérifiez GitHub ou saisissez-la.`,checksDenied:`GitHub a refusé la découverte CI. Accordez Actions: read et Checks: read au PAT de configuration, ou saisissez un producteur exact.`,checksUnavailable:`La découverte CI a échoué. Cela ne prouve pas l’absence de checks. Réessayez ou saisissez un producteur exact.`,projectsObserved:`Ces Projects existants appartiennent au propriétaire du dépôt. Ne choisissez que ceux que l’automatisation doit modifier.`,projectsEmpty:`Cette requête GitHub limitée n’a renvoyé aucun Project ouvert et accessible ; elle ne prouve pas leur absence. Vérifiez l’accès ou saisissez un numéro vérifié.`,projectsDenied:`GitHub a refusé la découverte des Projects. Vérifiez Projects: read au niveau organisation sur le PAT, ou saisissez les numéros.`,projectsUnavailable:`La découverte des Projects a échoué. Cela ne prouve pas leur absence. Saisissez un numéro vérifié ou réessayez.`,projectsUnsupported:`Cette API GitHub ne liste pas les Projects personnels avec un PAT à permissions fines. Saisissez le numéro figurant dans l’URL.`,discoveryTruncated:`Seul un échantillon limité de Projects accessibles ou checks récents a été inspecté. Saisissez manuellement un élément absent.`,checksDiscoveryScope:`Périmètre : jusqu’à 20 exécutions de PR parmi les 1 000 dernières exécutions de workflows (jusqu’à 10 pages) des 90 derniers jours ; au plus 15 exécutions et 100 checks par commit sont inspectés.`,projectsDiscoveryScope:`Périmètre : au plus 30 Projects ouverts et accessibles de l’organisation sur deux pages ; jusqu’à 100 champs sont inspectés par Project. Les Projects fermés sont exclus.`,retryDiscovery:`Relancer la recherche GitHub`,retryRemaining:`Il reste {count} essais en lecture seule. Vos réponses sont conservées.`,retryExhausted:`Plus aucun essai disponible. Vérifiez GitHub et saisissez manuellement tout élément manquant.`,observationTimeUnknown:`date d’observation indisponible`,branchRequirementUnknown:`Exigé par la règle de branche : non vérifié`,branchRequirementObserved:`Exigé sur {branch} par un ruleset actif pour ce contrôle et cette application précis.`,ciRule:`Ouvrir le ruleset du contrôle obligatoire ↗`,projectSharedStatus:`Tous les Projects choisis doivent partager chaque valeur Status. Cette configuration ne définit pas de valeurs différentes par Project.`,fixedWorkflowEnabled:`Votre configuration fixe features.{kind}=true. Gardez {kind} sélectionné ; modifiez --config ou les options pour changer ce choix.`,fixedWorkflowDisabled:`Votre configuration fixe features.{kind}=false. Ne sélectionnez pas {kind} ; modifiez --config ou les options pour changer ce choix.`,fixedIssuesRequired:`Votre configuration active explicitement release ou hotfix. Gardez Issues activé ou modifiez d’abord --config ou les options.`,projectSelectionNotObserved:`Les numéros de Projects choisis auparavant sont conservés, mais n’apparaissent plus dans ce résultat GitHub. Vérifiez-les sur GitHub ou retirez-les.`,removeSelection:`Retirer la sélection`,projectTransitionIssueCreated:`Nouveau ticket`,projectTransitionPullRequestCreated:`Nouvelle pull request`,projectTransitionIssueInProgress:`Ticket en cours`,projectTransitionPullRequestInProgress:`Pull request en cours`,projectUrl:`Ouvrir le Project sur GitHub ↗`,projectManual:`Project absent ? Saisissez son numéro positif ou son URL GitHub exacte. Les ID PVT_ sont refusés.`,projectStatusUnavailable:`Les options Status n’ont pas pu être vérifiées pour tous les Projects. Vérifiez-les sur GitHub et saisissez la valeur exacte.`,projectStatusIncompatible:`Les Projects choisis ne partagent aucun Status. Choisissez des Projects compatibles avant de continuer.`,producerName:`Nom du check/job`,producerAppId:`ID de l’App GitHub source`,producerWorkflow:`Nom du workflow`,producerAdd:`Ajouter le check exact`,producerRemove:`Retirer le check`,producerManualHelp:`Utilisez l’identité exacte affichée sur GitHub. L’ajouter ne prouve pas que la couverture est imposée.`,producerManualInvalid:`Indiquez le nom, un ID numérique positif d’App et le workflow. N’utilisez ni | ni ; dans les noms. Les virgules sont autorisées.`,translationPreviewTitle:`Révision de la traduction en cours`,translationPreviewBody:`Les questions propres à la configuration sont traduites. Certains diagnostics dynamiques de GitHub ou du fournisseur peuvent encore apparaître en anglais pendant la révision. Changer de langue ne modifie pas vos réponses.`,unknownLocalError:`Une erreur inattendue est survenue pendant la configuration locale. Consultez le terminal, puis actualisez la page ou relancez la configuration.`},Ki={setupHelp:`Ajuda de configuração`,setupTutorial:`Tutorial de configuração`,firstWorkflowGuide:`Primeiro fluxo de issue para PR`,setupRecovery:`Resolver problemas`,setupHelpHint:`A documentação abre num novo separador. As suas respostas ficam aqui.`,setupNextWorkflow:`Instale os ficheiros revistos e verifique a Action no GitHub. Uma inspeção de metadados não comprova o funcionamento em execução.`,batchNextActions:`Próximos passos`,batchStatusReady:`Pronto para revisão`,batchStatusBlocked:`Requer uma ação`,batchStatusApplying:`A aplicar o plano revisto`,batchStatusPartial:`Aplicado parcialmente; reveja antes de tentar novamente`,batchStatusWaiting:`PR criada · aguarda integração por um responsável`,batchStatusPending:`Configuração aplicada · verificação pendente`,batchStatusUnchanged:`Já corresponde · sem alterações`,batchStatusCancelled:`Trabalho pendente interrompido; alterações concluídas mantidas`,batchConfigurationPreview:`Prévia da configuração, adicionada à revisão do lote. Os testes de permissões e a instalação aguardam a aprovação do lote completo.`,batchUseConfiguration:`Usar esta configuração`,planReuseBody:`Aprove os testes temporários de permissões indicados; em seguida, aplica-se o setup revisto. Os valores dos Secrets existentes são preservados, sem serem pedidos ou substituídos. A verificação de permissões em execução pode ficar pendente.`,organizationReuseTitle:`Reutilizar a configuração existente`,organizationReuseBody:`{imported} definições compatíveis importadas. Preservam-se {shared} Variables da organização e {overrides} substituições do repositório; escrevem-se {writes} Variables no repositório. Os valores partilhados e os Secrets existentes são preservados.`,batchBranchReview:`Ramo de instalação e base revista`,batchFocusTitle:`Repositórios selecionados`,batchFocusBody:`{count} repositórios selecionados explicitamente nesta organização. Reveja cada destino separadamente.`,batchReviewTitle:`Reveja os planos de configuração`,batchProgressTitle:`A aplicar os planos por repositório`,batchResultTitle:`Resultados da configuração por repositório`,batchProgressBody:`Aplicam-se os planos aprovados por ordem. Parar suspende o trabalho pendente após o pedido atual; as alterações e PRs concluídas são preservadas.`,batchReviewBody:`Aprove apenas os planos prontos abaixo. A configuração avança por ordem, adiciona o acesso revisto sem substituir valores partilhados e cria uma PR por repositório alterado. Não integra, cria tags, publica versões nem implementa.`,batchResultBody:`Uma PR de configuração ainda precisa de revisão e integração por um responsável. A verificação de credenciais e permissões em execução pode ficar pendente. As PRs e os acessos concluídos mantêm-se se outro destino parar.`,batchStopping:`A interromper o trabalho pendente após o pedido atual. As alterações concluídas serão mantidas.`,batchReasonDrift:`A base revista ou a sua titularidade mudou. Inspecione o repositório e reveja um novo plano.`,batchReasonProvider:`O GitHub não confirmou o último passo. Uma nova tentativa inspeciona os efeitos existentes antes de continuar.`,batchCleanupPending:`Não foi possível confirmar a limpeza da verificação de permissões. O trabalho pendente foi interrompido. Verifique o histórico do GitHub e o registro local de recuperação; resolva a limpeza antes de iniciar uma nova configuração. Esta operação não pode retomar gravações.`,batchReasonCancelled:`O trabalho pendente parou. As alterações concluídas foram mantidas.`,batchReasonPreflight:`Reveja o acesso, as credenciais necessárias e os ajustes específicos do repositório antes de continuar.`,batchOpenPull:`Abrir PR de configuração`,batchFilesCount:`{count} ficheiros alterados`,batchVariablesCount:`{count} alterações de Variables do repositório`,batchGrantsCount:`{count} acessos a adicionar para este repositório`,batchRetainedSecrets:`Secrets existentes mantidos`,batchResourcesExplanation:`Os labels e Issue Types ativados são preparados separadamente para este destino. Os valores dos Secrets partilhados e os acessos dos outros repositórios são mantidos.`,batchReviewFiles:`Inspecionar ficheiros propostos`,batchDeleteFile:`Este ficheiro gerido pela configuração será removido da árvore de instalação; inspecione a cópia mantida.`,batchRepositoryOverrides:`Rever os nomes das Variables do repositório`,batchReviewedAccess:`Rever os acessos a adicionar`,batchApplyPlans:`Aplicar planos prontos`,batchLeavePreview:`Sair sem aplicar`,batchStopPending:`Interromper trabalho pendente`,batchStopConfirm:`Interromper o trabalho pendente após o pedido atual? As PRs, os acessos e as alterações concluídas serão mantidos.`,batchRetryPending:`Inspecionar e repetir o trabalho pendente`,batchFinish:`Concluir esta operação`,batchCleanup:`Elimine os PATs temporários de configuração no GitHub após esta operação. Mantenha o PAT do bot enquanto os repositórios consumirem o seu Secret.`,batchTechnical:`Detalhes da operação`,batchLookupUnavailable:`O GitHub não conseguiu confirmar esse repositório. Verifique o nome exato e o acesso do PAT.`,batchSelectionInvalid:`Reveja a seleção: escolha entre 1 e 25 repositórios disponíveis desta organização.`,batchAccessUnavailable:`O acesso não está confirmado. Reveja o PAT temporário ou remova este repositório da seleção.`,batchSelectionBody:`Escolha entre 1 e 25 repositórios de {organization}. Apenas os selecionados serão configurados.`,batchDiscoveryUnavailable:`O GitHub não conseguiu listar os repositórios. O atual continua disponível; procure outro pelo nome exato ou reveja o acesso do PAT.`,batchDiscoveryTruncated:`Esta vista atingiu o limite de 1.000 repositórios. Procure pelo nome exato para adicionar um destino em falta.`,batchFilter:`Filtrar repositórios visíveis`,batchSelectedCount:`{count} selecionados · máximo 25`,batchRepositories:`Repositórios`,batchPrivate:`Privado`,batchPublic:`Público`,batchCurrent:`Repositório atual`,batchArchived:`Arquivado`,batchDisabled:`Desativado`,batchReadOnly:`Sem acesso de escrita`,batchNoMatches:`Nenhum repositório visível corresponde ao filtro.`,batchPrevious:`Anterior`,batchNext:`Seguinte`,batchMissingRepository:`Não encontra um repositório?`,batchAccessExplanation:`A lista mostra apenas os repositórios visíveis para este PAT. A pesquisa por nome exato não concede acesso nem seleciona o repositório automaticamente. Se substituir o PAT temporário, limite-o aos repositórios que pretende configurar.`,batchExactName:`Nome exato do repositório nesta organização`,batchFindRepository:`Procurar repositório`,batchChangeAccess:`Alterar o acesso do PAT temporário`,batchReviewSelection:`Rever repositórios selecionados`,patStorageRetain:`Mantém-se o Secret PAT existente em {destination}. O seu valor não é pedido, copiado nem substituído. Se faltar, deve ser criado em separado. A verificação da identidade e das permissões em execução fica pendente.`,patStorageTitle:`Armazenamento do PAT do bot`,patRepositoryReplace:`O Secret PAT já existe no repositório {destination}. Será substituído mesmo que tenha escolhido preservar os outros Secrets existentes.`,patOrganizationReplace:`O Secret PAT já existe na organização {destination}. Será substituído mesmo que tenha escolhido preservar os outros Secrets existentes.`,patRepositoryCreate:`O PAT do bot será guardado como Secret PAT no repositório {destination}.`,patOrganizationCreate:`O PAT do bot será guardado como Secret PAT na organização {destination}.`,patReplacementChecks:`O PAT do bot fornecido tem de passar as verificações de identidade, acesso ao repositório e permissões necessárias antes de escrever este Secret.`,patOrganizationImpact:`Substituir este Secret da organização pode afetar outros repositórios que o utilizam. As verificações deste repositório não validam os requisitos dos restantes.`,repositorySecretSettings:`Abrir os Secrets Actions do repositório`,botAccountWarning:`Deve abrir este link com a conta de bot selecionada: @{account}.`,botAccountHelp:`Confirme a conta do GitHub antes de gerar o PAT. Use uma janela privada ou mude de conta se o navegador tiver a sessão do operador da configuração.`,botGithubForm:`Criar PAT do bot como @{account}`,language:`Idioma`,english:`Inglês`,spanish:`Espanhol`,setup:`CONFIGURAÇÃO`,connecting:`A ligar…`,localSession:`SESSÃO LOCAL`,progress:`Progresso`,studio:`ASSISTENTE DE CONFIGURAÇÃO`,journey:`O SEU PERCURSO`,repository:`Repositório`,choices:`Opções`,setupPat:`PAT de configuração`,plan:`Plano`,botPat:`PAT do bot e credenciais`,apply:`Aplicar`,localDesign:`Local por conceção`,localDesignBody:`Esta página funciona no seu computador. O GitHub cria ambos os PAT nos seus próprios separadores.`,preparing:`A preparar a configuração…`,completeTitle:`Configuração concluída.`,previewTitle:`Pré-visualização concluída.`,cancelledTitle:`Configuração cancelada.`,blockedTitle:`A configuração requer atenção.`,gettingReady:`A PREPARAR`,activeLede:`Uma decisão de cada vez. As suas escolhas determinam permissões, plano e credenciais.`,resultLede:`Consulte abaixo o resultado e o próximo passo. O terminal contém mais detalhes técnicos.`,readOnly:`Separador só de leitura`,readOnlyBody:`Outro separador controla esta sessão. Pode acompanhar o progresso ou assumir o controlo.`,takeOver:`Assumir o controlo`,attention:`Requer atenção`,checked:`Verificado`,pleaseNote:`Atenção`,progressUpdate:`Atualização de progresso`,reviewPass:`A rever as escolhas guardadas — passagem {pass}. É a mesma execução, não um reinício.`,cancelSetup:`Cancelar configuração`,cancelConfirm:`Cancelar esta sessão local? Os PAT já criados no GitHub continuarão a existir.`,footerLocal:`APENAS LOCALHOST`,footerCloud:`SEM CONTA DE CONFIGURAÇÃO NA NUVEM`,footerGithub:`O GITHUB EMITE OS PAT`,currentDecision:`DECISÃO ATUAL`,session:`SESSÃO`,continue:`Continuar`,previousQuestion:`Pergunta anterior`,questionProgress:`Pergunta {current} de {total} neste grupo · {overall} de {all} no total`,yes:`Sim`,no:`Não`,permissionPreview:`PRÉ-VISUALIZAÇÃO DAS PERMISSÕES`,changeAnswersTitle:`Alterar respostas`,changeAnswersHelp:`Volte a uma secção sem perder as outras respostas. O plano e as permissões PAT necessárias serão verificados de novo.`,changeSection:`Alterar {section}`,editCapabilities:`Funcionalidades`,editRuntimes:`Agentes`,editModels:`Modelos dos agentes`,editRoleModels:`Modelos por tarefa`,editRepository:`Comportamento do repositório`,editDeployment:`Releases e correções`,editBugbot:`Bugbot`,editApproval:`Aprovação de PR`,editProjects:`Projects`,editProvisioning:`Provisionamento`,editStorage:`Secrets e Variables`,suggested:`Resposta sugerida: {answer}. Pode rever as opções antes de criar o PAT.`,none:`nenhuma`,sourceGithub:`Observado nos metadados autenticados deste repositório no GitHub.`,sourceConfig:`Fornecido pela sua configuração; o GitHub não o substituiu.`,sourceDefault:`Valor predefinido do produto; não verificado neste repositório.`,sourceLocal:`Observado neste checkout local; confirme que o ramo existe no GitHub antes de aplicar alterações.`,whyMatters:`Porque importa`,whenApplies:`Quando se aplica`,whereConfigured:`Onde se configura`,howToChoose:`Como escolher`,whyRecommendation:`Porque importa`,example:`Exemplo`,effect:`O que muda`,verify:`Como verificar`,learnMore:`Ler a documentação desta opção`,resultApplied:`A configuração foi aplicada`,resultNoChanges:`Nenhuma alteração efetuada`,resultStopped:`Nenhuma alteração iniciada`,resultPartial:`Verifique as alterações parciais`,resultCompleteBody:`O PAT temporário não é revogado automaticamente. Elimine-o no GitHub após verificar. Guarde o PAT do bot até rodar o Secret.`,resultPartialBody:`Um Secret ou outro recurso pode ter sido alterado. Verifique o GitHub e execute copilot doctor --read-only antes de substituir ou eliminar o PAT.`,resultNoChangesBody:`O Copilot não começou a aplicar alterações. Podem ter ocorrido testes temporários de permissões; o GitHub pode conservar o histórico de Actions, Issues ou PR após a limpeza. Os PAT criados permanecem até serem eliminados.`,whatHappened:`O que aconteceu`,alreadyChanged:`O que mudou`,noChanges:`Não foram iniciadas alterações no repositório nem no GitHub nesta sessão.`,nextAction:`Próximo passo`,reasonPermissions:`Faltam permissões do PAT de configuração ou não foi possível confirmá-las.`,nextPermissions:`Verifique as permissões, corrija o PAT no GitHub e inicie uma nova sessão.`,reasonWorkflowPermissions:`O PAT do bot não concluiu todas as verificações de permissões. Verifique a permissão que falhou e os requisitos de preparação ou limpeza abaixo.`,permissionReportTitle:`Verificação das permissões do PAT`,permissionReportLead:`As permissões obrigatórias que não puderam ser confirmadas aparecem abaixo. «Não verificável» não significa «ausente».`,updatedSetupPatTitle:`Corrija o PAT de configuração`,updatedSetupPatBody:`Esta ligação do GitHub inclui as permissões necessárias para esta configuração. Selecione este repositório antes de criar o PAT. Feche esta sessão local e inicie uma nova configuração com o PAT corrigido.`,updatedSetupPatGrants:`Permissões adicionais detetadas após a inspeção`,updatedSetupPatLink:`Criar PAT de configuração corrigido`,permissionProbeCleanupPending:`Pode ainda existir um recurso temporário de verificação de permissões. O setup parou; não presuma que foi removido.`,permissionProbeCleanupAction:`Tente novamente com um PAT que o possa remover. O registo local de recuperação é verificado antes de novos testes.`,permissionSecretCollision:`O GitHub indicou que um Secret com o nome aleatório de teste foi atualizado. Um valor criado em simultâneo pode ter mudado. A configuração parou sem o eliminar.`,permissionSecretCollisionAction:`Consulte o histórico de Secrets do GitHub e reponha qualquer valor afetado antes de tentar novamente. O registo local não pode corrigir esta colisão.`,permissionIdentity:`Identidade GitHub e acesso ao repositório`,permissionIdentityValid:`Verificados`,permissionIdentityInvalid:`Recusados`,permissionIdentityUnknown:`Não confirmados`,permissionGrantNotChecked:`Não verificada`,permissionReportNoFailedGrant:`Esta verificação não encontrou uma permissão obrigatória em falta. Confirme a conta prevista para o PAT e o erro no terminal antes de tentar novamente.`,reasonStorage:`O armazenamento GitHub Actions escolhido não pôde ser usado com segurança.`,nextStorage:`Verifique o âmbito das Variables/Secrets e os recursos existentes; depois tente novamente.`,reasonConfiguration:`Não foi possível validar a configuração escolhida.`,nextConfiguration:`Leia os detalhes no terminal, corrija as opções e tente novamente.`,reasonExpired:`A sessão local expirou.`,nextExpired:`Inicie uma nova sessão; a aprovação anterior não pode ser reutilizada.`,reasonCancelled:`A configuração foi cancelada.`,nextCancelled:`Inicie outra execução se ainda quiser configurar o repositório.`,reasonUnknown:`A configuração parou. O navegador não conseguiu determinar a causa exata. Consulte o recibo de recursos, se estiver disponível, e o terminal.`,nextUnknown:`Leia o último erro no terminal antes de tentar novamente. Não presuma que um PAT foi revogado.`,reasonProvider:`O GitHub ou outro fornecedor não concluiu a operação solicitada.`,nextProvider:`Use a referência de diagnóstico para consultar o terminal, verifique a disponibilidade e o acesso e reveja possíveis alterações parciais antes de tentar novamente.`,reasonRateLimit:`O GitHub limitou temporariamente os pedidos necessários para a configuração.`,nextRateLimit:`Aguarde a reposição do limite. Inspecione as alterações concluídas antes de iniciar outra configuração.`,diagnosticReference:`Referência de diagnóstico`,resourceReceipt:`Registo das operações de configuração`,effectCompleted:`Indicada como concluída`,effectSkipped:`Indicada como ignorada`,effectInspect:`Resultado por inspecionar`,effectNotStarted:`Não iniciada`,effectInProgress:`Em curso; resultado ainda por confirmar`,scopeLocal:`Checkout local`,scopeMixed:`Repositório e organização`,receiptFiles:`Ficheiros de configuração`,receiptSecrets:`Secrets do GitHub Actions`,receiptLabels:`Etiquetas das questões`,receiptIssueTypes:`Tipos de questão`,receiptVariables:`Variables do GitHub Actions`,receiptInitialTag:`Etiqueta de versão inicial`,inspectPartial:`Algumas alterações podem estar ativas. Verifique o GitHub e o terminal antes de tentar novamente.`,patSettings:`Abrir definições de PAT no GitHub ↗`,closeSession:`Fechar sessão local`,sessionClosed:`Sessão local encerrada`,sessionClosedBody:`O servidor local aceitou o pedido de encerramento. Esta página deixa de o contactar e preserva o resultado. Encerrar a sessão não revoga nenhum PAT criado no GitHub.`,doctorHelp:`Depois de concluir a configuração, pode verificar aqui os recursos instalados sem iniciar Actions. Também pode executar copilot doctor --read-only na raiz do repositório com o PAT temporário e o mesmo ficheiro --config não secreto, caso o tenha usado.`,doctorRun:`Verificar instalação (só de leitura)`,doctorRunning:`A verificar os recursos instalados sem iniciar Actions…`,doctorPassed:`A verificação só de leitura não encontrou falhas.`,doctorWarnings:`A verificação só de leitura requer atenção.`,doctorFailed:`A verificação só de leitura não terminou. Consulte o terminal ou execute o comando abaixo.`,doctorCounts:`{pass} aprovados · {warn} avisos · {fail} falhas · {skipped} ignorados.`,doctorSecretLimit:`Este modo não consegue verificar os valores dos Secrets.`,botRenewal:`O PAT do bot permanece no Secret do GitHub Actions escolhido para execuções futuras. A data de validade real não é verificada aqui; registe-a no GitHub e substitua o Secret antes de expirar.`,working:`A preparar o próximo passo`,workingBody:`O processo local está a verificar as respostas. Mantenha esta página aberta.`,repoFocus:`Repositório em foco`,repoFocusBody:`Esta configuração destina-se ao repositório indicado. Secrets e Variables da organização podem ser partilhados com outros repositórios.`,access:`acesso`,readOnlyCheck:`Verificação de capacidades`,provisionalGrants:`Permissões provisórias mínimas`,conditionalGrants:`As permissões condicionais dependem das escolhas e do GitHub. Haverá uma auditoria final antes das alterações.`,permissionEvidenceVerified:`Uma leitura no GitHub confirmou este acesso.`,permissionEvidenceVerifiedWrite:`Foi criado, lido e removido um recurso temporário.`,permissionEvidencePrivateProject:`Um Project não público da organização confirmou o acesso de leitura a Projects.`,permissionEvidenceMissing:`O GitHub recusou o acesso necessário. Verifique as definições do PAT.`,permissionEvidenceWrite:`A verificação temporária de escrita não terminou com sucesso. Reveja a etapa que falhou e tente novamente.`,permissionEvidencePublic:`A leitura foi bem-sucedida, mas este recurso público não comprova por si só a permissão do PAT.`,permissionEvidencePublicProjects:`A leitura dos Projects foi bem-sucedida, mesmo com uma lista vazia. O acesso a Projects privados é verificado quando são selecionados.`,permissionEvidenceUnknownRead:`A consulta de leitura foi inconclusiva. Consulte o detalhe no terminal e tente de novo se necessário.`,permissionUnknown:`Esta permissão exige revisão. Consulte a permissão exata e a explicação técnica no terminal antes de continuar.`,permissionsFollow:`As permissões seguem as suas escolhas`,permissionsFollowBody:`Mostramos as permissões exatas antes de criar cada PAT. Abrir esta página não cria nada.`,files:`Ficheiros`,workflows:`Workflows`,variables:`Variables`,secretNames:`Nomes dos Secrets`,planBody:`Reveja exatamente o que pode mudar. Após a aprovação, recursos temporários testam as permissões de escrita do PAT; depois são pedidos o PAT do bot e outras credenciais. O GitHub pode conservar execuções, histórico de Issues ou PR e notificações.`,planPermissionProbeTitle:`Testes temporários de permissões após aprovação`,planPermissionProbeBody:`Cada permissão indicada cria, lê e remove o seu recurso temporário. O teste de Issues cria uma Issue visível; se o GitHub impedir a eliminação, a configuração fecha-a, indica o número e para. Actions, Issues e Pull requests podem deixar histórico ou notificações.`,planActionsProbePrerequisites:`O teste de Actions precisa de Contents Write para criar a branch isolada. Se o workflow de saúde empacotado exato não estiver disponível na branch predefinida, também precisa de Workflows Write para preparar uma versão com os jobs desativados. Para verificar o bot, o PAT de configuração prepara e limpa o recurso; o PAT do bot inicia e lê a execução. Um pré-requisito bloqueado não prova que falte Actions.`,planSecretProbeLimit:`O GitHub só oferece uma operação de criação ou atualização para Secrets. A verificação usa um nome aleatório privado e confirma primeiro que não existe, mas o GitHub não garante uma criação atómica. Se indicar uma atualização, a configuração para e pede a revisão do histórico do Secret.`,planChoices:`As suas decisões principais`,planEnabledCapabilities:`Funcionalidades ativadas`,planBranchRoles:`Ramo de produção / desenvolvimento`,planApprovalMode:`Aprovação de pull requests`,planVariableScope:`Âmbito das Variables`,planSecretScope:`Âmbito dos Secrets`,planInitialTag:`Criar etiqueta inicial`,planAgentRouting:`Agente e modelo por tarefa`,planIssueWorkflows:`Fluxos de questões`,planTrustedChecks:`Produtores CI de confiança`,planCoverage:`Evidência de cobertura`,planProjectStatuses:`Transições Status dos Projects`,planIssueResources:`Etiquetas e tipos de questão`,planIssueResourcesValue:`Verificados ou criados ao aplicar`,planProducerAttested:`Identidade CI e passo obrigatório verificados por si`,planCoverageThreshold:`Cobertura mínima das linhas alteradas`,planCoverageReporter:`Workflow que publica o artefacto`,planReporterAttested:`Produtor do relatório de cobertura verificado por si`,planAdvancedDefaults:`O plano também inclui valores predefinidos para definições que não alterou. Use Alterar abaixo para rever qualquer secção antes de aprovar.`,planUnknownWarning:`Um aviso adicional do plano não pode ser apresentado aqui. Leia-o no terminal antes de aprovar.`,planBasicDefaultsIntro:`O percurso básico manteve estas definições avançadas. Abra uma secção abaixo para as rever ou alterar:`,scopeRepository:`Repositório`,scopeOrganization:`Organização`,scopeDisabled:`Sem aprovisionamento`,approvalOff:`Desativada`,approvalRecommend:`Apenas recomendações`,approvalGuarded:`Aprovação protegida`,beforeContinue:`Antes de continuar`,stopHere:`Parar aqui`,approvePlan:`Aprovar este plano`,githubLink:`Abrir ligação do GitHub ↗`,githubForm:`Abrir formulário oficial de PAT no GitHub`,githubFormHelp:`Confirme a conta ligada, escolha Only select repositories e este repositório. O GitHub gere 2FA e cria o PAT.`,pasteHere:`Cole o valor aqui`,yourAnswer:`A sua resposta`,hiddenAfter:`Oculto após envio`,typeAnswer:`Escreva a sua resposta`,secretHelp:`Enviado apenas ao processo local. Não será mostrado de novo nem guardado no navegador.`,pairTitle:`Emparelhar este navegador`,pairLabel:`Código do terminal`,pairPlaceholder:`16 caracteres hexadecimais`,pairBody:`Encontre o código de 16 caracteres no terminal onde iniciou copilot setup --web. Não aparece no URL nem fica guardado após fechar a página.`,pairHelp:`Mantenha o código privado. Após atualizar a página, introduza-o novamente.`,pairButton:`Ligar à configuração local`,privateSession:`SESSÃO LOCAL PRIVADA`,theme:`Tema`,themeAuto:`Automático`,themeSystem:`Seguir sistema`,themeLight:`Tema claro`,themeDark:`Tema escuro`,selectOne:`Selecione uma opção`,ciRun:`Abrir execução de CI no GitHub ↗`,manualCheck:`Check não listado? Indique nome|ID da App|workflow exatos, separados por ponto e vírgula.`,checksObserved:`Foram encontrados jobs recentes de CI. Abra cada execução e confirme o job, a App e o passo obrigatório de cobertura antes de confiar nele.`,checksNoRecent:`Não há execuções recentes de workflows de pull request. Execute o CI habitual numa PR real ou introduza um produtor exato.`,checksNoVerifiable:`Há execuções recentes, mas nenhum job foi ligado a um Check Run e App exatos. Consulte o GitHub ou introduza o produtor manualmente.`,checksDenied:`O GitHub recusou a consulta do CI. Conceda Actions: read e Checks: read ao PAT de configuração ou introduza um produtor exato.`,checksUnavailable:`A consulta do CI falhou. Isto não prova que o repositório não tenha checks. Tente novamente ou introduza um produtor exato.`,projectsObserved:`Estes Projects existentes pertencem ao proprietário do repositório. Selecione só os que a automatização deve atualizar.`,projectsEmpty:`Esta consulta limitada ao GitHub não devolveu Projects abertos e acessíveis; isso não prova que não existam. Verifique o acesso ou introduza um número confirmado.`,projectsDenied:`O GitHub recusou a consulta de Projects. Verifique Projects: read da organização no PAT ou introduza os números.`,projectsUnavailable:`Não foi possível consultar Projects. Isto não prova que não existam. Introduza um número verificado ou tente novamente.`,projectsUnsupported:`Esta API do GitHub não lista Projects pessoais com um PAT de permissões precisas. Introduza o número do URL de um Project existente.`,discoveryTruncated:`Só foi inspecionada uma amostra limitada de Projects acessíveis ou checks recentes. Introduza manualmente um elemento em falta.`,checksDiscoveryScope:`Âmbito: até 20 execuções de PR entre as últimas 1.000 execuções de workflows (até 10 páginas) dos últimos 90 dias; são inspecionadas no máximo 15 execuções e 100 checks por commit.`,projectsDiscoveryScope:`Âmbito: no máximo 30 Projects abertos e acessíveis da organização em duas páginas; são inspecionados até 100 campos por Project. Os Projects fechados são excluídos.`,retryDiscovery:`Repetir pesquisa no GitHub`,retryRemaining:`Restam {count} tentativas só de leitura. As suas respostas são mantidas.`,retryExhausted:`Não restam tentativas. Verifique o GitHub e introduza manualmente os itens em falta.`,observationTimeUnknown:`data de observação indisponível`,branchRequirementUnknown:`Exigido pela regra do ramo: não verificado`,branchRequirementObserved:`Exigido em {branch} por um ruleset ativo para esta verificação e esta App específicas.`,ciRule:`Abrir ruleset da verificação obrigatória ↗`,projectSharedStatus:`Todos os Projects escolhidos devem partilhar cada valor Status. Esta configuração não atribui valores diferentes por Project.`,fixedWorkflowEnabled:`A sua configuração fixa features.{kind}=true. Mantenha {kind} selecionado; altere --config ou as opções para mudar esta escolha.`,fixedWorkflowDisabled:`A sua configuração fixa features.{kind}=false. Não selecione {kind}; altere --config ou as opções para mudar esta escolha.`,fixedIssuesRequired:`A sua configuração ativa explicitamente release ou hotfix. Mantenha Issues ativo ou altere primeiro --config ou as opções.`,projectSelectionNotObserved:`Os números de Projects escolhidos anteriormente são mantidos, mas já não aparecem neste resultado do GitHub. Confirme-os no GitHub ou remova-os.`,removeSelection:`Remover seleção`,projectTransitionIssueCreated:`Nova questão`,projectTransitionPullRequestCreated:`Novo pull request`,projectTransitionIssueInProgress:`Questão em curso`,projectTransitionPullRequestInProgress:`Pull request em curso`,projectUrl:`Abrir Project no GitHub ↗`,projectManual:`Project em falta? Introduza o número positivo ou o URL exato do GitHub. IDs PVT_ não são aceites.`,projectStatusUnavailable:`Não foi possível verificar as opções Status de todos os Projects. Consulte cada um no GitHub e introduza o valor exato.`,projectStatusIncompatible:`Os Projects escolhidos não partilham valores Status. Selecione Projects compatíveis antes de continuar.`,producerName:`Nome do check/job`,producerAppId:`ID da App GitHub de origem`,producerWorkflow:`Nome do workflow`,producerAdd:`Adicionar check exato`,producerRemove:`Remover check`,producerManualHelp:`Use a identidade exata apresentada no GitHub. Adicioná-la não prova que exige cobertura.`,producerManualInvalid:`Indique nome, ID numérico positivo da App e workflow. Não use | ou ; nos nomes. São permitidas vírgulas.`,translationPreviewTitle:`Revisão da tradução em curso`,translationPreviewBody:`As perguntas próprias da configuração já estão traduzidas. Alguns diagnósticos dinâmicos do GitHub ou do fornecedor ainda podem aparecer em inglês durante a revisão. Mudar de idioma não altera as suas respostas.`,unknownLocalError:`Ocorreu um erro inesperado na configuração local. Consulte o terminal e atualize a página ou reinicie a configuração.`},qi=[`en`,`es`,`fr`,`pt`],Ji={en:`English`,es:`Español`,fr:`Français`,pt:`Português`},Yi={en:Ui,es:Wi,fr:Gi,pt:Ki};function Z(e,t,n={}){return(Yi[t]??Yi.en)[e].replace(/\{(\w+)\}/gu,(e,t)=>n[t]??``)}var Xi={Repository:`repository`,"Setup choices":`choices`,"Setup PAT":`setupPat`,Plan:`plan`,"Bot PAT & credentials":`botPat`,Apply:`apply`,Preparation:`gettingReady`};function Zi(e,t){return Z(Qi(e),t)}function Qi(e){return Xi[e??``]??`gettingReady`}var Q=Fi(`en`),$i={en:{checking:`Checking permission for this adjustment. The temporary Variable will be removed before the reviewed setting is written.`,finish:`Finish`,finished:`Configuration updated`,inspectionFinished:`Configuration inspection finished`,inspectionStopped:`Configuration inspection stopped`,inspectAdjustment:`Check this adjustment before retrying`,finishedBody:`Your adjustments were verified by reading GitHub again. Delete the temporary setup PAT when you finish.`,inspectionBody:`No adjustment was applied. Your configuration is preserved. Any PAT created on GitHub remains until you delete it.`,title:`Your Copilot configuration`,unconfigured:`Copilot is not configured in this checkout`,detected:`Configuration detected in this checkout`,incomplete:`Some configuration could not be inspected`,intro:`Review what this checkout configures, make a small adjustment, or run the complete assistant again.`,startHelp:`Start the guided assistant to choose workflows, agents and GitHub settings for this repository. You will review the plan before any setup changes are applied.`,local:`Local files are shown below. Connect to GitHub to read the current repository and organization settings. No changes happen when you open this panel.`,limits:`This panel describes the current checkout. It does not certify the default branch, runner authentication, branch rules, or environment-specific overrides.`,connect:`Read configuration from GitHub`,refresh:`Refresh configuration`,wizard:`Run the complete assistant`,start:`Start setup`,close:`Close local session`,unknown:`Not verified`,repository:`Repository`,organization:`Organization`,workflow:`Workflow value`,source:`Where this value comes from`,quick:`Quick adjustments`,quickHelp:`Only independent settings can be changed here. Use the complete assistant for workflows, agents, Projects, permissions or credentials.`,edit:`Change`,details:`All workflow settings`,credentials:`Credentials`,secretHelp:`Secret names only. GitHub cannot return their values, owners or permissions; presence is not proof of validity.`,variables:`GitHub settings used by these workflows`,shadowed:`Overridden by the repository value`,empty:`No entries detected`,githubIncomplete:`Some GitHub inventories are unavailable. Unknown values stay unknown; quick changes are disabled until both Variable scopes can be read.`,current:`Current value`,next:`New value`,review:`Review this adjustment`,back:`Back to configuration`,preview:`Review change`,apply:`Apply this adjustment`,effect:`Only this setting is written. Workflows and Secrets are preserved. Before writing, Copilot tests Variables Write using one temporary Variable and removes it.`,orgImpact:`This changes a shared organization setting and can affect every repository with access to it. Its visibility and repository access are preserved.`,repoImpact:`This changes the setting for this repository only.`,connected:`GitHub configuration read. Review the current values below.`,invalid:`Choose a supported value. Nothing was changed.`,unchanged:`That value is already in effect. Nothing was changed.`,stale:`The configuration changed while you reviewed it. Review the refreshed value and try again; nothing was written.`,blocked:`Access could not be confirmed. You can reconnect with a corrected setup PAT; your configuration is preserved.`,updated:`Adjustment applied and read back from GitHub. You can make another adjustment or close the session.`,partial:`The write could not be confirmed. Inspect GitHub before retrying; the previous value was not restored automatically.`},es:{checking:`Comprobando el permiso para este ajuste. La Variable temporal se eliminará antes de escribir el parámetro aprobado.`,finish:`Terminar`,finished:`Configuración actualizada`,inspectionFinished:`Inspección de configuración finalizada`,inspectionStopped:`Inspección de configuración interrumpida`,inspectAdjustment:`Revisa este ajuste antes de reintentar`,finishedBody:`Los ajustes se confirmaron mediante una nueva lectura de GitHub. Elimina el PAT temporal de setup cuando termines.`,inspectionBody:`No se ha aplicado ningún ajuste. Tu configuración se conserva. Los PAT creados en GitHub existen hasta que los elimines.`,title:`Tu configuración de Copilot`,unconfigured:`Copilot no está configurado en este checkout`,detected:`Configuración detectada en este checkout`,incomplete:`No se pudo inspeccionar parte de la configuración`,intro:`Revisa la configuración de este checkout, haz un ajuste puntual o vuelve a ejecutar el asistente completo.`,startHelp:`Inicia el asistente guiado para elegir workflows, agentes y parámetros de GitHub para este repositorio. Revisarás el plan antes de aplicar cambios de configuración.`,local:`Estos son los archivos locales. Conecta con GitHub para leer los valores actuales del repositorio y la organización. Abrir el panel no realiza cambios.`,limits:`El panel describe este checkout. No certifica la rama por defecto, la autenticación del runner, las reglas de ramas ni las excepciones de entornos.`,connect:`Leer configuración de GitHub`,refresh:`Actualizar información`,wizard:`Ejecutar el asistente completo`,start:`Iniciar configuración`,close:`Cerrar sesión local`,unknown:`Sin verificar`,repository:`Repositorio`,organization:`Organización`,workflow:`Valor del workflow`,source:`Procedencia del valor`,quick:`Ajustes rápidos`,quickHelp:`Aquí puedes cambiar parámetros independientes. Para workflows, agentes, Projects, permisos o credenciales, usa el asistente completo.`,edit:`Cambiar`,details:`Todos los parámetros de los workflows`,credentials:`Credenciales`,secretHelp:`Solo se muestran nombres. GitHub no devuelve valores, propietarios ni permisos de los Secrets; su presencia no demuestra su validez.`,variables:`Parámetros de GitHub usados por estos workflows`,shadowed:`El valor del repositorio tiene prioridad`,empty:`No se han detectado entradas`,githubIncomplete:`Parte de la información de GitHub no está disponible. Los valores desconocidos siguen sin verificar; los ajustes requieren leer ambos scopes de Variables.`,current:`Valor actual`,next:`Nuevo valor`,review:`Revisar este ajuste`,back:`Volver a la configuración`,preview:`Revisar cambio`,apply:`Aplicar este ajuste`,effect:`Solo se escribe este parámetro. Se conservan workflows y Secrets. Antes de escribir, Copilot prueba Variables Write con una Variable temporal y la elimina.`,orgImpact:`Cambiarás un parámetro compartido de la organización: puede afectar a todos los repositorios con acceso. Se conservarán su visibilidad y sus accesos.`,repoImpact:`El cambio afecta únicamente a este repositorio.`,connected:`Configuración de GitHub leída. Revisa los valores actuales.`,invalid:`Elige un valor permitido. No se ha cambiado nada.`,unchanged:`Ese valor ya está en uso. No se ha cambiado nada.`,stale:`La configuración cambió durante la revisión. Revisa el valor actualizado y vuelve a intentarlo; no se ha escrito nada.`,blocked:`No se pudo confirmar el acceso. Puedes conectar con un PAT de setup corregido; tu configuración se conserva.`,updated:`Ajuste aplicado y confirmado mediante una nueva lectura de GitHub. Puedes hacer otro ajuste o cerrar la sesión.`,partial:`No se pudo confirmar la escritura. Revisa GitHub antes de reintentar; el valor anterior no se restauró automáticamente.`},fr:{checking:`Vérification de la permission pour cet ajustement. La Variable temporaire sera supprimée avant l’écriture du paramètre approuvé.`,finish:`Terminer`,finished:`Configuration mise à jour`,inspectionFinished:`Inspection de la configuration terminée`,inspectionStopped:`Inspection de la configuration interrompue`,inspectAdjustment:`Vérifiez cet ajustement avant de réessayer`,finishedBody:`Les ajustements ont été confirmés par une nouvelle lecture de GitHub. Supprimez le PAT temporaire à la fin.`,inspectionBody:`Aucun ajustement appliqué. La configuration est conservée. Tout PAT créé sur GitHub existe jusqu’à sa suppression.`,title:`Votre configuration Copilot`,unconfigured:`Copilot n’est pas configuré dans ce checkout`,detected:`Configuration détectée dans ce checkout`,incomplete:`Une partie de la configuration n’a pas pu être inspectée`,intro:`Consultez la configuration, ajustez un paramètre ou relancez l’assistant complet.`,local:`Voici les fichiers locaux. Connectez GitHub pour lire les valeurs actuelles du dépôt et de l’organisation. Ouvrir ce panneau ne modifie rien.`,startHelp:`Lancez l’assistant guidé pour choisir les workflows, agents et paramètres GitHub de ce dépôt. Vous examinerez le plan avant toute modification de configuration.`,limits:`Ce panneau décrit le checkout actuel. Il ne certifie pas la branche par défaut, l’authentification du runner, les règles de branches ni les exceptions des environnements.`,connect:`Lire la configuration GitHub`,refresh:`Actualiser`,wizard:`Relancer l’assistant complet`,start:`Configurer Copilot`,close:`Fermer la session locale`,unknown:`Non vérifié`,repository:`Dépôt`,organization:`Organisation`,workflow:`Valeur du workflow`,source:`Origine de cette valeur`,quick:`Ajustements rapides`,quickHelp:`Seuls les paramètres indépendants sont modifiables ici. Utilisez l’assistant complet pour les workflows, agents, Projects, permissions ou identifiants.`,edit:`Modifier`,details:`Tous les paramètres des workflows`,credentials:`Identifiants`,secretHelp:`Noms des Secrets uniquement. GitHub ne retourne ni valeurs, ni propriétaires, ni permissions ; leur présence ne prouve pas leur validité.`,variables:`Paramètres GitHub utilisés par ces workflows`,shadowed:`Remplacé par la valeur du dépôt`,empty:`Aucune entrée détectée`,githubIncomplete:`Certaines données GitHub sont indisponibles. Les valeurs inconnues restent non vérifiées ; les deux scopes de Variables doivent être lisibles.`,current:`Valeur actuelle`,next:`Nouvelle valeur`,review:`Vérifier cet ajustement`,back:`Retour à la configuration`,preview:`Vérifier le changement`,apply:`Appliquer cet ajustement`,effect:`Seul ce paramètre est écrit. Workflows et Secrets sont conservés. Copilot teste Variables Write avec une Variable temporaire, puis la supprime.`,orgImpact:`Ce paramètre partagé peut affecter tous les dépôts autorisés. Sa visibilité et ses accès restent identiques.`,repoImpact:`Ce changement affecte seulement ce dépôt.`,connected:`Configuration GitHub lue. Consultez les valeurs actuelles.`,invalid:`Choisissez une valeur autorisée. Aucun changement.`,unchanged:`Cette valeur est déjà appliquée. Aucun changement.`,stale:`La configuration a changé pendant votre examen. Vérifiez la nouvelle valeur et réessayez ; aucune écriture.`,blocked:`L’accès n’a pas été confirmé. Reconnectez un PAT de configuration corrigé ; la configuration est conservée.`,updated:`Ajustement appliqué et relu depuis GitHub. Vous pouvez continuer ou fermer la session.`,partial:`L’écriture n’a pas été confirmée. Vérifiez GitHub avant de réessayer ; la valeur précédente n’a pas été restaurée automatiquement.`},pt:{checking:`A verificar a permissão para este ajuste. A Variable temporária será eliminada antes de escrever o parâmetro aprovado.`,finish:`Terminar`,finished:`Configuração atualizada`,inspectionFinished:`Inspeção da configuração concluída`,inspectionStopped:`Inspeção da configuração interrompida`,inspectAdjustment:`Verifique este ajuste antes de tentar novamente`,finishedBody:`Os ajustes foram confirmados por uma nova leitura do GitHub. Elimine o PAT temporário de setup ao terminar.`,inspectionBody:`Nenhum ajuste aplicado. A configuração é preservada. Os PAT criados no GitHub existem até os eliminar.`,title:`A sua configuração Copilot`,unconfigured:`Copilot não está configurado neste checkout`,detected:`Configuração detetada neste checkout`,incomplete:`Parte da configuração não pôde ser inspecionada`,intro:`Veja a configuração, ajuste um parâmetro ou execute o assistente completo novamente.`,local:`Estes são os ficheiros locais. Ligue ao GitHub para ler os valores atuais do repositório e da organização. Abrir este painel não altera nada.`,startHelp:`Inicie o assistente guiado para escolher workflows, agentes e parâmetros GitHub para este repositório. Irá rever o plano antes de aplicar alterações de configuração.`,limits:`Este painel descreve o checkout atual. Não certifica o branch predefinido, a autenticação do runner, as regras de branches nem exceções dos ambientes.`,connect:`Ler configuração do GitHub`,refresh:`Atualizar informação`,wizard:`Executar o assistente completo`,start:`Configurar Copilot`,close:`Fechar sessão local`,unknown:`Não verificado`,repository:`Repositório`,organization:`Organização`,workflow:`Valor do workflow`,source:`Origem do valor`,quick:`Ajustes rápidos`,quickHelp:`Aqui pode alterar parâmetros independentes. Use o assistente completo para workflows, agentes, Projects, permissões ou credenciais.`,edit:`Alterar`,details:`Todos os parâmetros dos workflows`,credentials:`Credenciais`,secretHelp:`Apenas nomes dos Secrets. GitHub não devolve valores, contas ou permissões; a presença não comprova a validade.`,variables:`Parâmetros GitHub usados por estes workflows`,shadowed:`Substituído pelo valor do repositório`,empty:`Nenhuma entrada detetada`,githubIncomplete:`Alguns dados GitHub estão indisponíveis. Os valores desconhecidos continuam não verificados; os dois scopes de Variables devem poder ser lidos.`,current:`Valor atual`,next:`Novo valor`,review:`Rever este ajuste`,back:`Voltar à configuração`,preview:`Rever alteração`,apply:`Aplicar este ajuste`,effect:`Só este parâmetro é escrito. Workflows e Secrets são preservados. Copilot testa Variables Write com uma Variable temporária e depois elimina-a.`,orgImpact:`Este parâmetro partilhado pode afetar todos os repositórios autorizados. A visibilidade e os acessos são preservados.`,repoImpact:`Esta alteração afeta apenas este repositório.`,connected:`Configuração GitHub lida. Reveja os valores atuais.`,invalid:`Escolha um valor permitido. Nada foi alterado.`,unchanged:`Este valor já está aplicado. Nada foi alterado.`,stale:`A configuração mudou durante a revisão. Reveja o valor atualizado e tente novamente; nada foi escrito.`,blocked:`O acesso não foi confirmado. Ligue um PAT de setup corrigido; a configuração é preservada.`,updated:`Ajuste aplicado e confirmado por uma nova leitura do GitHub. Pode continuar ou fechar a sessão.`,partial:`A escrita não foi confirmada. Verifique GitHub antes de tentar novamente; o valor anterior não foi restaurado automaticamente.`}},ea={assignees:[`Issue assignees`,`Responsables de issues`,`Responsables des issues`,`Responsáveis pelas issues`],reviewers:[`PR reviewers`,`Revisores de PRs`,`Relecteurs des PRs`,`Revisores de PRs`],inactivity:[`Close waiting issues after (hours)`,`Cerrar issues en espera tras (horas)`,`Fermer les issues en attente après (heures)`,`Fechar issues em espera após (horas)`],reopen:[`Reopen issues after a push`,`Reabrir issues tras un push`,`Rouvrir les issues après un push`,`Reabrir issues após um push`],description:[`PR description updates`,`Actualizaciones de la descripción de PRs`,`Mise à jour des descriptions de PRs`,`Atualizações da descrição de PRs`],members:[`Limit AI interactions to members`,`Limitar interacciones de IA a miembros`,`Limiter l’IA aux membres`,`Limitar interações de IA a membros`],reasoning:[`Include AI reasoning`,`Incluir razonamiento de IA`,`Inclure le raisonnement de l’IA`,`Incluir raciocínio da IA`],severity:[`Minimum finding severity`,`Severidad mínima de findings`,`Gravité minimale des findings`,`Gravidade mínima dos findings`],commentLimit:[`Maximum review comments`,`Máximo de comentarios por revisión`,`Maximum de commentaires par analyse`,`Máximo de comentários por revisão`],dryRun:[`Preview findings without publishing`,`Analizar findings sin publicarlos`,`Analyser sans publier les findings`,`Analisar findings sem publicar`],effort:[`Review depth`,`Profundidad de revisión`,`Profondeur de l’analyse`,`Profundidade da revisão`],drafts:[`Review draft PRs`,`Revisar PRs en borrador`,`Analyser les PRs en brouillon`,`Rever PRs em rascunho`],suggestions:[`Publish suggested code changes`,`Publicar cambios de código sugeridos`,`Publier des suggestions de code`,`Publicar sugestões de código`],telemetry:[`Include review metrics`,`Incluir métricas de revisión`,`Inclure les métriques d’analyse`,`Incluir métricas de revisão`]},ta=e=>$i[e],na=(e,t)=>ea[e]?.[[`en`,`es`,`fr`,`pt`].indexOf(t)]??e,ra={true:[`On`,`Activado`,`Activé`,`Ativado`],false:[`Off`,`Desactivado`,`Désactivé`,`Desativado`],replace:[`Replace the description`,`Sustituir la descripción`,`Remplacer la description`,`Substituir a descrição`],append:[`Add to the description`,`Añadir a la descripción`,`Compléter la description`,`Acrescentar à descrição`],preserve:[`Keep the description`,`Conservar la descripción`,`Conserver la description`,`Preservar a descrição`],disabled:[`Disabled`,`Desactivado`,`Désactivé`,`Desativado`],info:[`Informational`,`Informativo`,`Information`,`Informativo`],low:[`Low`,`Bajo`,`Faible`,`Baixo`],medium:[`Medium`,`Medio`,`Moyen`,`Médio`],high:[`High`,`Alto`,`Élevé`,`Alto`],smart:[`Automatic`,`Automático`,`Automatique`,`Automático`],default:[`Standard`,`Estándar`,`Standard`,`Padrão`]},ia=(e,t)=>ra[e]?.[[`en`,`es`,`fr`,`pt`].indexOf(t)]??e,aa=H(`

`,1),oa=H(`
  • `),sa=H(`
      `,1),ca=H(``);function la(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`management`,8,!1),s=X(t,`journey`,8),c=[`repository`,`choices`,`setupPat`,`plan`,`botPat`,`apply`];Tn(()=>(V(s()),Qi),()=>{N(a,s()?.complete?.map(Qi)??[])}),En(),ji();var l=ca(),u=P(l),d=L(P(u)),f=I(L(P(d)),!0);D(d),D(u);var p=L(u,2),m=e=>{var t=aa(),r=F(t),i=I(r,!0),a=I(L(r,2),!0);R((e,t)=>{W(i,e),W(a,t)},[()=>(V(ta),n(),B(()=>ta(n()).title)),()=>(V(ta),n(),B(()=>ta(n()).quickHelp))]),U(e,t)},h=e=>{var t=sa(),r=F(t),i=I(r,!0),o=L(r,2);q(o,5,()=>c,K,(e,t,r)=>{var i=oa();let o;var c=P(i),l=I(c,!0),u=I(L(c,2),!0);D(i),R((e,t,n,r,a)=>{J(i,`aria-current`,e),o=ui(i,1,``,null,o,{current:t,completed:n}),W(l,r),W(u,a)},[()=>(V(s()),z(a),z(t),B(()=>s()?.position===r+1&&!z(a).includes(z(t))?`step`:void 0)),()=>s()?.position===r+1&&!z(a).includes(z(t)),()=>z(a).includes(z(t)),()=>(z(a),z(t),B(()=>z(a).includes(z(t))?`✓`:String(r+1).padStart(2,`0`))),()=>(V(Z),z(t),n(),B(()=>Z(z(t),n())))]),U(e,i)}),D(o),R(e=>W(i,e),[()=>(V(Z),n(),B(()=>Z(`journey`,n())))]),U(e,t)};G(p,e=>{o()?e(m):e(h,-1)});var g=L(p,2),_=L(P(g)),v=P(_),y=I(v,!0),b=I(L(v),!0);D(_),D(g),D(l),R((e,t,n,r)=>{J(l,`aria-label`,e),W(f,t),W(y,n),W(b,r)},[()=>(V(Z),n(),B(()=>Z(`progress`,n()))),()=>(V(Z),n(),B(()=>Z(`studio`,n()))),()=>(V(Z),n(),B(()=>Z(`localDesign`,n()))),()=>(V(Z),n(),B(()=>Z(`localDesignBody`,n())))]),U(e,l),k(),i()}var ua=H(`
      `);function da(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(`system`);Tn(()=>z(a),()=>{document.documentElement.dataset.theme=z(a)}),En(),ji();var o=ua(),s=P(o);let c;var l=I(s,!0),u=L(s,2);let d;var f=L(u,2);let p;D(o),R((e,t,n,r,i,m,h,g)=>{J(o,`aria-label`,e),J(s,`aria-pressed`,z(a)===`system`),J(s,`aria-label`,t),J(s,`title`,n),c=ui(s,1,``,null,c,{active:z(a)===`system`}),W(l,r),J(u,`aria-pressed`,z(a)===`light`),J(u,`aria-label`,i),J(u,`title`,m),d=ui(u,1,``,null,d,{active:z(a)===`light`}),J(f,`aria-pressed`,z(a)===`dark`),J(f,`aria-label`,h),J(f,`title`,g),p=ui(f,1,``,null,p,{active:z(a)===`dark`})},[()=>(V(Z),n(),B(()=>Z(`theme`,n()))),()=>(V(Z),n(),B(()=>Z(`themeSystem`,n()))),()=>(V(Z),n(),B(()=>Z(`themeSystem`,n()))),()=>(V(Z),n(),B(()=>Z(`themeAuto`,n()))),()=>(V(Z),n(),B(()=>Z(`themeLight`,n()))),()=>(V(Z),n(),B(()=>Z(`themeLight`,n()))),()=>(V(Z),n(),B(()=>Z(`themeDark`,n()))),()=>(V(Z),n(),B(()=>Z(`themeDark`,n())))]),wr(`click`,s,()=>N(a,`system`)),wr(`click`,u,()=>N(a,`light`)),wr(`click`,f,()=>N(a,`dark`)),U(e,o),k(),i()}Tr([`click`]);var fa=H(``),pa=H(` `,1);function ma(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi();function a(e){let t=e.currentTarget.value;qi.includes(t)&&Q.set(t)}ji();var o=pa(),s=F(o),c=P(s),l=L(c);q(l,5,()=>qi,K,(e,t)=>{var n=fa(),r=I(n,!0),i={};R(()=>{W(r,Ji[z(t)]),i!==(i=z(t))&&(n.value=(n.__value=i)??``)}),U(e,n)}),D(l);var u;mi(l),D(s);var d=I(L(s,2),!0);R((e,t)=>{W(c,`${e??``} `),J(l,`aria-label`,t),u!==(u=n())&&(l.value=(l.__value=u)??``,pi(l,u)),W(d,Ji[n()])},[()=>Z(`language`,n()),()=>Z(`language`,n())]),wr(`change`,l,a),U(e,o),k(),i()}Tr([`change`]);var ha=H(``),ga=H(`
      `);function _a(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`repository`,8),o=X(t,`closed`,8,!1);ji();var s=ga(),c=P(s),l=P(c),u=I(l,!0),d=L(l,2),f=I(P(d),!0);D(d),D(c);var p=L(c,2),m=P(p),h=P(m),g=e=>{U(e,ha())};G(h,e=>{o()||e(g)});var _=L(h);D(m);var v=L(m);ma(v,{}),da(L(v),{}),D(p),D(s),R((e,t,n)=>{W(u,e),W(f,t),W(_,` ${n??``}`)},[()=>(V(Z),n(),B(()=>Z(`setup`,n()))),()=>(V(a()),V(Z),n(),B(()=>a()??Z(`connecting`,n()))),()=>(V(Z),V(o()),n(),B(()=>Z(o()?`sessionClosed`:`localSession`,n())))]),U(e,s),k(),i()}var va={"setup.scope":{title:`Choose setup scope`,description:`This repository keeps the local preview and Apply flow. Several repositories lets you explicitly select 1–25 targets in the same organization and create reviewed setup PRs. Batch setup does not merge, create tags, release or deploy.`,choices:[`This repository`,`Several repositories in this organization`]},"setup.batchSource":{title:`Where should configuration come from?`,description:`Reuse compatible organization settings to skip completed questions, or customize repository settings. Batch setup keeps existing Secret bindings in both paths. Provision missing credentials separately, then inspect again; shared values are never replaced.`,choices:[`Reuse organization configuration`,`Customize settings; keep existing Secrets`]},"batch.token":{title:`Temporary PAT for selected repositories`,description:`Create a temporary setup PAT limited to these repositories: {repositories}. The GitHub link proposes grants; select only the intended repositories yourself. Leave blank to keep the current PAT. The final plan rechecks exact permissions. Delete temporary setup PATs afterwards.`},"setup.source":{title:`Where should configuration come from?`,description:`Reuse compatible organization Variables and existing Secret bindings, keeping repository overrides. Only missing, invalid or repository-specific settings are asked again. Shared values are preserved; reviewed differences become repository overrides. Choose Customize to provision or replace credentials.`,choices:[`Reuse organization configuration`,`Customize configuration`]},"setup.reusePatReview":{title:`Review organization reuse access`,description:`These provisional grants inspect existing organization configuration and allow repository setup. Shared Secret values are never requested or replaced. The final plan rechecks exact permissions; authentication evidence can remain pending. Select only the intended repositories in GitHub and delete the temporary PAT afterwards.`,choices:[`Continue to GitHub`,`Enter a PAT manually`]},"botPat.scopeConflict":{title:`Resolve the bot PAT scope conflict`,description:`Repository Secret PAT in {repository} overrides the selected organization PAT. Delete the repository Secret in GitHub, then ask Copilot to check again, or change the PAT scope to this repository. Your setup answers are retained. Copilot will not delete any Secret.`,choices:[`I have deleted the repository PAT — check again`,`Store PAT in the repository instead`,`Stop setup`]},"botPat.scopeConflictUnavailable":{title:`Resolve the bot PAT scope conflict`,description:`GitHub could not confirm whether the repository PAT was removed. The conflict remains unresolved. Your setup answers are retained. Check access and try again, change the PAT scope to this repository, or stop setup.`,choices:[`I have deleted the repository PAT — check again`,`Store PAT in the repository instead`,`Stop setup`]},"repository.confirm":{title:`Confirm this repository`,description:`This checkout points to {repository} on branch {branch}. Confirm the target before configuring PAT access or files.`,choices:[`Yes, this is my repository`,`Stop and choose another checkout`]},"setup.depth":{title:`Choose how much detail to review`,description:`Basic still asks about permissions, security, branch roles, Projects, approval and storage. Selected advanced agent, branch-prefix and Bugbot settings keep their defaults; inspect and edit them in the final plan. Custom asks every applicable question. Neither path applies changes now.`,choices:[`Basic guided setup (recommended)`,`Customize every setting`]},"setup.environmentPat":{title:`An environment setup PAT is available`,description:`The value stays in the CLI process. Continuing starts identity checks and isolated temporary create/read/delete tests before planning. Installation requires final approval. Exiting Copilot cannot unset your parent shell variable.`,choices:[`Use the environment PAT`,`Create or enter a different PAT`]},"plan.review":{title:`Review your setup plan`,description:`Inspect the affected files, workflows, Variables and Secret names before approving. No setup changes start by opening this plan.`},"workflow.update":{title:`Update existing workflows?`,description:`These existing workflow files differ from the setup plan: {files}. Keeping them may leave some new settings inactive.`,choices:[`Keep existing`,`Update setup-managed workflows`]},"setupPat.method":{title:`How will you provide your setup PAT?`,description:`This temporary PAT authorizes this one setup run. GitHub creates it under your operator account; Copilot cannot revoke it for you.`,choices:[`Guided GitHub link`,`Manual PAT`]},"setupPat.ownerKind":{title:`Who owns this repository on GitHub?`,description:`The owner determines which organization permissions may be needed. Check the repository header on GitHub if unsure.`,choices:[`Organization`,`Personal account`,`Not sure`]},"setupPat.review":{title:`Review provisional setup PAT permissions`,description:`These grants follow your choices. When managing Secrets, the link prefills Actions, Contents and Workflows write for possible health checks. Those checks run only if the approved plan requires them. GitHub inspection may reveal other requirements.`,choices:[`Continue to GitHub`,`Review setup choices again`,`View full permission table`,`Enter a PAT manually`]},"setupPat.entry":{title:`Temporary setup PAT`,description:`Open GitHub as your operator account, complete 2FA, choose “Only select repositories”, select this repository and copy the generated PAT here. This PAT is for this run only; delete it on GitHub afterwards.`},"setupPat.confirmAccount":{title:`GitHub authenticated the setup PAT as @{account}`,description:`Is this the operator account that should configure this repository? A wrong account must stop before any setup change.`,choices:[`Yes, continue`,`No, stop`]},"setupPat.confirmUnverifiedAccess":{title:`Check the PAT grants marked Unverifiable`,description:`Verified rows already passed. Compare each required Unverifiable row with the scope and access level in your GitHub PAT settings. Read-only checks cannot prove Write; Unverifiable does not mean missing. Check Projects: read only if that row is Unverifiable. Continue only after checking every such grant.`,choices:[`No, stop`,`Yes, I checked them`]},"botPat.method":{title:`How will you provide the bot PAT?`,description:`The bot PAT is separate from the setup PAT. It belongs to the account that will run future GitHub Actions and is stored as a Secret after approval.`,choices:[`Guided GitHub link`,`Manual PAT`]},"botPat.login":{title:`Expected GitHub bot login`,description:`Enter the bot account login without @. Copilot resolves its numeric GitHub ID and compares it with the PAT owner.`},"botPat.entry.guided":{title:`{name} — bot account PAT`,description:`Open GitHub as @{account} (account ID {accountId}), not as the setup operator. Select only this repository, review all grants and paste the PAT here. Suggested expiry: 90 days. An existing Secret value cannot be read back.`},"botPat.entry.manual":{title:`{name} — bot account PAT`,description:`Use the bot account, select only the intended repository and review all grants before pasting its PAT. Suggested expiry: 90 days. An existing Secret value cannot be read back.`},"botPat.identityMismatch":{title:`This PAT belongs to a different GitHub account`,description:`The PAT belongs to @{actual}; the selected bot is @{expected}. No bot Secret was written. Your answers and approved plan are retained. Delete the unused PAT in GitHub, switch to @{expected}, then choose whether to enter another PAT or stop setup.`,choices:[`Enter another bot PAT`,`Stop setup`]},"credential.apiKey":{title:`{name} — {provider} API key`,description:`Paste the API key for {provider}. It is sent only to this local setup process and, if approved, installed as a GitHub Actions Secret. Existing Secret values cannot be read back.`},"credential.existing":{title:`Existing {name}: {status}`,description:`GitHub cannot reveal the current Secret value. Keep it only if you deliberately accept that its health cannot be verified here; replace or skip it otherwise.`,choices:[`Keep existing`,`Replace it`,`Skip this credential`]},"apply.confirm":{title:`Apply this setup now?`,description:`This is the final approval. Local files and selected GitHub resources may change. A partial result may require inspection before retrying.`,choices:[`Apply setup`,`Stop without applying`]},"management.token":{title:`Temporary setup PAT`,description:`Read configuration from GitHub with a setup PAT. Read access is enough for inspection; changes require Variables Write and a separate approval. Secrets are shown by name only. Leave blank to return to the panel.`},"management.tokenWrite":{title:`Setup PAT for this adjustment`,description:`Use Variables Write in the reviewed scope. After approval, verification creates and removes one temporary Variable. Leave blank to return to the panel.`}},ya={"setup.scope":{title:`Elige el alcance del setup`,description:`Este repositorio conserva la vista previa y la aplicación local. Varios repositorios permite seleccionar entre 1 y 25 destinos de la misma organización y crear PRs de setup para revisarlas. El lote no hace merge, crea tags, publica versiones ni despliega.`,choices:[`Este repositorio`,`Varios repositorios de esta organización`]},"setup.batchSource":{title:`¿De dónde debe venir la configuración?`,description:`Reutiliza los ajustes compatibles de la organización para saltar preguntas ya resueltas, o personaliza los ajustes del repositorio. En ambos casos, el lote conserva los Secrets existentes. Crea por separado las credenciales que falten y vuelve a inspeccionar; los valores compartidos no se sustituyen.`,choices:[`Reutilizar configuración de la organización`,`Personalizar ajustes; conservar Secrets`]},"batch.token":{title:`PAT temporal para los repositorios seleccionados`,description:`Crea un PAT temporal de setup limitado a estos repositorios: {repositories}. El enlace propone permisos; selecciona tú solo los repositorios previstos en GitHub. Déjalo vacío para conservar el PAT actual. El plan final vuelve a comprobar los permisos exactos. Elimina después los PATs temporales de setup.`},"setup.source":{title:`¿De dónde debe venir la configuración?`,description:`Reutiliza las Variables compatibles y los Secrets existentes de la organización, conservando los ajustes del repositorio. Solo se preguntan los ajustes que falten, sean inválidos o dependan del repositorio. Los valores compartidos se conservan; las diferencias revisadas se guardan en el repositorio. Elige Personalizar para crear o sustituir credenciales.`,choices:[`Reutilizar configuración de la organización`,`Personalizar configuración`]},"setup.reusePatReview":{title:`Revisa el acceso para reutilizar configuración`,description:`Estos permisos provisionales permiten inspeccionar la configuración existente y configurar el repositorio. No se piden ni sustituyen los valores de los Secrets compartidos. El plan final comprueba los permisos exactos; la verificación de las credenciales puede quedar pendiente. Selecciona solo los repositorios previstos en GitHub y elimina después el PAT temporal.`,choices:[`Continuar a GitHub`,`Introducir un PAT manualmente`]},"botPat.scopeConflict":{title:`Resuelve el conflicto de scope del PAT del bot`,description:`El Secret PAT del repositorio {repository} tiene prioridad sobre el PAT de organización seleccionado. Elimina el Secret del repositorio en GitHub y pide a Copilot que lo compruebe de nuevo, o cambia el scope del PAT a este repositorio. Tus respuestas se conservan. Copilot no eliminará ningún Secret.`,choices:[`Ya he eliminado el PAT del repositorio — comprobar de nuevo`,`Guardar PAT en el repositorio`,`Detener setup`]},"botPat.scopeConflictUnavailable":{title:`Resuelve el conflicto de scope del PAT del bot`,description:`GitHub no ha permitido confirmar si se eliminó el PAT del repositorio. El conflicto sigue sin resolverse. Tus respuestas se conservan. Comprueba el acceso y vuelve a intentarlo, cambia el scope del PAT a este repositorio o detén el setup.`,choices:[`Ya he eliminado el PAT del repositorio — comprobar de nuevo`,`Guardar PAT en el repositorio`,`Detener setup`]},"botPat.identityMismatch":{title:`Este PAT pertenece a otra cuenta de GitHub`,description:`El PAT pertenece a @{actual}; el bot seleccionado es @{expected}. No se ha escrito el Secret del bot. Conservamos tus respuestas y el plan aprobado. Elimina el PAT sin usar en GitHub, cambia a @{expected} y elige si quieres introducir otro PAT o detener el setup.`,choices:[`Introducir otro PAT del bot`,`Detener setup`]},"repository.confirm":{title:`Confirma el repositorio`,description:`Este checkout apunta a {repository} en la rama {branch}. Comprueba el destino antes de configurar permisos del PAT o archivos.`,choices:[`Sí, es mi repositorio`,`Detener y elegir otro checkout`]},"setup.depth":{title:`Elige cuánto detalle quieres revisar`,description:`El modo básico sigue preguntando por permisos, seguridad, ramas, Projects, aprobación y almacenamiento. Algunos ajustes avanzados de agentes, prefijos de rama y Bugbot conservan sus valores predeterminados; podrás revisarlos y editarlos en el plan final. El modo personalizado pregunta por todos los ajustes aplicables. Ninguno aplica cambios todavía.`,choices:[`Configuración básica guiada (recomendada)`,`Personalizar todos los ajustes`]},"setup.environmentPat":{title:`Hay un PAT de configuración en el entorno`,description:`El valor permanece en el proceso CLI. Al continuar se comprueba la identidad y se crean, leen y eliminan recursos temporales antes de preparar el plan. La instalación requiere aprobación final. Cerrar Copilot no elimina la variable de la terminal original.`,choices:[`Usar el PAT del entorno`,`Crear o introducir otro PAT`]},"plan.review":{title:`Revisa el plan de configuración`,description:`Comprueba los archivos, workflows, Variables y nombres de Secrets antes de aprobar. Abrir el plan no inicia ningún cambio.`},"workflow.update":{title:`¿Actualizar los workflows existentes?`,description:`Estos archivos difieren del plan: {files}. Si los conservas, algunos ajustes nuevos podrían no activarse.`,choices:[`Conservar los existentes`,`Actualizar los workflows gestionados`]},"setupPat.method":{title:`¿Cómo proporcionarás el PAT de configuración?`,description:`Este PAT temporal autoriza una sola ejecución. GitHub lo crea con tu cuenta de operador; Copilot no puede revocarlo por ti.`,choices:[`Enlace guiado de GitHub`,`Introducir PAT manualmente`]},"setupPat.ownerKind":{title:`¿Quién es propietario de este repositorio en GitHub?`,description:`El propietario determina qué permisos de organización pueden hacer falta. Consulta la cabecera del repositorio en GitHub si dudas.`,choices:[`Organización`,`Cuenta personal`,`No lo sé`]},"setupPat.review":{title:`Revisa los permisos provisionales del PAT de configuración`,description:`Estos permisos dependen de tus elecciones. Si gestionas Secrets, el enlace preselecciona Actions, Contents y Workflows en escritura para posibles comprobaciones de credenciales. Esas comprobaciones solo se ejecutan si el plan aprobado las necesita. La inspección de GitHub puede revelar otros requisitos.`,choices:[`Continuar en GitHub`,`Revisar de nuevo las opciones`,`Ver la tabla completa de permisos`,`Introducir un PAT manualmente`]},"setupPat.entry":{title:`PAT temporal de configuración`,description:`Abre GitHub con tu cuenta de operador, completa el 2FA, elige «Only select repositories», selecciona este repositorio y pega aquí el PAT generado. Es solo para esta ejecución; elimínalo en GitHub después.`},"setupPat.confirmAccount":{title:`GitHub autenticó el PAT de configuración como @{account}`,description:`¿Es la cuenta de operador que debe configurar este repositorio? Una cuenta incorrecta debe detener el proceso antes de cualquier cambio.`,choices:[`Sí, continuar`,`No, detener`]},"setupPat.confirmUnverifiedAccess":{title:`Comprueba los permisos del PAT marcados como No verificable`,description:`Los permisos Verificados ya pasaron la comprobación. Compara cada permiso obligatorio No verificable con su ámbito y nivel de acceso en los ajustes del PAT en GitHub. Una consulta de solo lectura no demuestra Escritura; No verificable no significa ausente. Comprueba Projects: lectura solo si esa fila aparece como No verificable. Continúa únicamente tras comprobar todos esos permisos.`,choices:[`No, detener`,`Sí, los he comprobado`]},"botPat.method":{title:`¿Cómo proporcionarás el PAT del bot?`,description:`Es distinto del PAT de configuración. Pertenece a la cuenta que ejecutará las futuras GitHub Actions y se instalará como Secret tras la aprobación.`,choices:[`Enlace guiado de GitHub`,`Introducir PAT manualmente`]},"botPat.login":{title:`Usuario previsto del bot en GitHub`,description:`Introduce el nombre de usuario del bot sin @. Copilot consultará su ID numérico de GitHub y lo comparará con el propietario del PAT.`},"botPat.entry.guided":{title:`{name} — PAT de la cuenta bot`,description:`Abre GitHub como @{account} (ID {accountId}), no como operador de setup. Selecciona solo este repositorio, revisa todos los permisos y pega aquí el PAT. Caducidad sugerida: 90 días. El valor de un Secret existente no puede leerse.`},"botPat.entry.manual":{title:`{name} — PAT de la cuenta bot`,description:`Usa la cuenta bot, selecciona solo el repositorio previsto y revisa todos los permisos antes de pegar el PAT. Caducidad sugerida: 90 días. El valor de un Secret existente no puede leerse.`},"credential.apiKey":{title:`{name} — clave API de {provider}`,description:`Pega la clave API de {provider}. Solo se envía a este proceso local y, si apruebas el plan, se instala como Secret de GitHub Actions. Los valores existentes no pueden leerse.`},"credential.existing":{title:`{name} existente: {status}`,description:`GitHub no muestra el valor actual del Secret. Consérvalo solo si aceptas expresamente que aquí no se puede comprobar su estado; de lo contrario, sustitúyelo u omítelo.`,choices:[`Conservar`,`Sustituir`,`Omitir esta credencial`]},"apply.confirm":{title:`¿Aplicar la configuración ahora?`,description:`Esta es la aprobación final. Pueden cambiar archivos locales y recursos de GitHub seleccionados. Si el resultado es parcial, revísalo antes de reintentar.`,choices:[`Aplicar configuración`,`Detener sin aplicar`]},"management.token":{title:`PAT temporal de setup`,description:`Lee la configuración de GitHub con un PAT de setup. Leer basta para inspeccionar; los cambios requieren Variables Write y aprobación independiente. Solo se muestran nombres de Secrets. Deja el campo vacío para volver al panel.`},"management.tokenWrite":{title:`PAT de setup para este ajuste`,description:`Usa Variables Write en el ámbito revisado. Tras aprobar, la verificación crea y elimina una Variable temporal. Deja el campo vacío para volver al panel.`}},ba={"setup.scope":{title:`Choisissez la portée de la configuration`,description:`Ce dépôt conserve l’aperçu et l’application locale. Plusieurs dépôts permet de sélectionner explicitement 1 à 25 destinations de la même organisation et de créer des PR à examiner. Le lot ne fusionne pas, ne crée pas de tag, ne publie pas et ne déploie pas.`,choices:[`Ce dépôt`,`Plusieurs dépôts de cette organisation`]},"setup.batchSource":{title:`D’où doit venir la configuration ?`,description:`Réutilisez les réglages compatibles de l’organisation pour passer les questions déjà résolues, ou personnalisez les réglages du dépôt. Dans les deux cas, le lot conserve les Secrets existants. Créez séparément les identifiants manquants puis inspectez à nouveau ; les valeurs partagées ne sont jamais remplacées.`,choices:[`Réutiliser la configuration de l’organisation`,`Personnaliser les réglages ; conserver les Secrets`]},"batch.token":{title:`PAT temporaire pour les dépôts sélectionnés`,description:`Créez un PAT temporaire limité à ces dépôts : {repositories}. Le lien propose des autorisations ; sélectionnez vous-même uniquement les dépôts prévus dans GitHub. Laissez vide pour conserver le PAT actuel. Le plan final vérifie à nouveau les autorisations exactes. Supprimez ensuite les PAT temporaires de configuration.`},"setup.source":{title:`D’où doit venir la configuration ?`,description:`Réutilisez les Variables compatibles et les Secrets existants de l’organisation en conservant les réglages du dépôt. Seuls les réglages manquants, invalides ou propres au dépôt seront demandés. Les valeurs partagées sont conservées ; les différences validées sont enregistrées dans le dépôt. Choisissez Personnaliser pour créer ou remplacer des identifiants.`,choices:[`Réutiliser la configuration de l’organisation`,`Personnaliser la configuration`]},"setup.reusePatReview":{title:`Vérifiez l’accès pour réutiliser la configuration`,description:`Ces autorisations provisoires permettent de lire la configuration existante et de configurer le dépôt. Les valeurs des Secrets partagés ne sont jamais demandées ni remplacées. Le plan final vérifie les autorisations exactes ; la vérification des identifiants peut rester en attente. Sélectionnez uniquement les dépôts prévus dans GitHub puis supprimez le PAT temporaire.`,choices:[`Continuer vers GitHub`,`Saisir un PAT manuellement`]},"botPat.scopeConflict":{title:`Résoudre le conflit de périmètre du PAT du bot`,description:`Le Secret PAT du dépôt {repository} est prioritaire sur le PAT d’organisation sélectionné. Supprimez le Secret du dépôt dans GitHub, puis demandez à Copilot de vérifier à nouveau, ou choisissez le périmètre du dépôt pour le PAT. Vos réponses sont conservées. Copilot ne supprimera aucun Secret.`,choices:[`J’ai supprimé le PAT du dépôt — vérifier à nouveau`,`Enregistrer le PAT dans le dépôt`,`Arrêter la configuration`]},"botPat.scopeConflictUnavailable":{title:`Résoudre le conflit de périmètre du PAT du bot`,description:`GitHub n’a pas permis de confirmer la suppression du PAT du dépôt. Le conflit reste non résolu. Vos réponses sont conservées. Vérifiez l’accès et réessayez, choisissez le périmètre du dépôt pour le PAT ou arrêtez la configuration.`,choices:[`J’ai supprimé le PAT du dépôt — vérifier à nouveau`,`Enregistrer le PAT dans le dépôt`,`Arrêter la configuration`]},"botPat.identityMismatch":{title:`Ce PAT appartient à un autre compte GitHub`,description:`Le PAT appartient à @{actual} ; le bot sélectionné est @{expected}. Aucun Secret du bot n’a été écrit. Vos réponses et le plan approuvé sont conservés. Supprimez le PAT inutilisé dans GitHub, passez à @{expected}, puis choisissez de saisir un autre PAT ou d’arrêter la configuration.`,choices:[`Saisir un autre PAT du bot`,`Arrêter la configuration`]},"repository.confirm":{title:`Confirmez ce dépôt`,description:`Ce dossier pointe vers {repository}, branche {branch}. Vérifiez la cible avant de configurer les accès PAT ou les fichiers.`,choices:[`Oui, c’est mon dépôt`,`Arrêter et choisir un autre dossier`]},"setup.depth":{title:`Choisissez le niveau de détail`,description:`Le parcours de base demande toujours les autorisations, la sécurité, les branches, Projects, l’approbation et le stockage. Certains réglages avancés des agents, préfixes de branche et Bugbot conservent leurs valeurs par défaut ; vous pourrez les examiner et les modifier dans le plan final. Le parcours personnalisé pose toutes les questions applicables. Aucun changement n’est appliqué à ce stade.`,choices:[`Configuration de base guidée (recommandée)`,`Personnaliser tous les réglages`]},"setup.environmentPat":{title:`Un PAT de configuration est disponible dans l’environnement`,description:`La valeur reste dans le processus CLI. Continuer lance la vérification de l’identité puis des tests temporaires isolés de création, lecture et suppression avant le plan. L’installation exige une approbation finale. Quitter Copilot ne supprime pas la variable du shell parent.`,choices:[`Utiliser le PAT de l’environnement`,`Créer ou saisir un autre PAT`]},"plan.review":{title:`Examinez le plan de configuration`,description:`Vérifiez les fichiers, workflows, Variables et noms de Secrets avant d’approuver. Ouvrir le plan ne lance aucun changement.`},"workflow.update":{title:`Mettre à jour les workflows existants ?`,description:`Ces fichiers diffèrent du plan : {files}. Les conserver peut laisser certains nouveaux réglages inactifs.`,choices:[`Conserver les fichiers existants`,`Mettre à jour les workflows gérés`]},"setupPat.method":{title:`Comment fournirez-vous le PAT de configuration ?`,description:`Ce PAT temporaire autorise une seule exécution. GitHub le crée avec votre compte opérateur ; Copilot ne peut pas le révoquer à votre place.`,choices:[`Lien GitHub guidé`,`Saisir un PAT manuellement`]},"setupPat.ownerKind":{title:`À qui appartient ce dépôt sur GitHub ?`,description:`Le propriétaire détermine les éventuelles autorisations d’organisation. Consultez l’en-tête du dépôt sur GitHub en cas de doute.`,choices:[`Organisation`,`Compte personnel`,`Je ne sais pas`]},"setupPat.review":{title:`Examinez les autorisations provisoires du PAT de configuration`,description:`Ces droits suivent vos choix. Si vous gérez des Secrets, le lien présélectionne Actions, Contents et Workflows en écriture pour les éventuelles vérifications des identifiants. Ces vérifications ne démarrent que si le plan approuvé les exige. L’inspection de GitHub peut révéler d’autres besoins.`,choices:[`Continuer sur GitHub`,`Revoir les choix de configuration`,`Voir toutes les autorisations`,`Saisir un PAT manuellement`]},"setupPat.entry":{title:`PAT temporaire de configuration`,description:`Ouvrez GitHub avec votre compte opérateur, effectuez la 2FA, choisissez « Only select repositories », sélectionnez ce dépôt puis collez ici le PAT généré. Il ne sert qu’à cette exécution ; supprimez-le sur GitHub ensuite.`},"setupPat.confirmAccount":{title:`GitHub a authentifié le PAT de configuration comme @{account}`,description:`Est-ce bien le compte opérateur autorisé à configurer ce dépôt ? Un autre compte doit arrêter le processus avant tout changement.`,choices:[`Oui, continuer`,`Non, arrêter`]},"setupPat.confirmUnverifiedAccess":{title:`Vérifiez les droits du PAT marqués Non vérifiable`,description:`Les lignes Vérifiées ont déjà passé le contrôle. Comparez chaque droit requis Non vérifiable avec sa portée et son niveau d’accès dans les paramètres du PAT GitHub. Une lecture seule ne prouve pas le niveau Écriture ; Non vérifiable ne signifie pas absent. Vérifiez Projects : lecture seulement si cette ligne est Non vérifiable. Continuez uniquement après avoir vérifié tous ces droits.`,choices:[`Non, arrêter`,`Oui, je les ai vérifiés`]},"botPat.method":{title:`Comment fournirez-vous le PAT du bot ?`,description:`Il est distinct du PAT de configuration. Il appartient au compte qui exécutera les futures GitHub Actions et sera installé comme Secret après approbation.`,choices:[`Lien GitHub guidé`,`Saisir un PAT manuellement`]},"botPat.login":{title:`Identifiant GitHub attendu pour le bot`,description:`Saisissez l’identifiant du bot sans @. Copilot récupère son ID numérique GitHub et le compare au propriétaire du PAT.`},"botPat.entry.guided":{title:`{name} — PAT du compte bot`,description:`Ouvrez GitHub en tant que @{account} (ID {accountId}), pas en tant qu’opérateur. Sélectionnez uniquement ce dépôt, vérifiez tous les droits et collez le PAT ici. Expiration suggérée : 90 jours. La valeur d’un Secret existant ne peut pas être relue.`},"botPat.entry.manual":{title:`{name} — PAT du compte bot`,description:`Utilisez le compte bot, sélectionnez uniquement le dépôt voulu et vérifiez tous les droits avant de coller le PAT. Expiration suggérée : 90 jours. La valeur d’un Secret existant ne peut pas être relue.`},"credential.apiKey":{title:`{name} — clé API de {provider}`,description:`Collez la clé API de {provider}. Elle est envoyée uniquement au processus local puis, si vous approuvez le plan, installée comme Secret GitHub Actions. Les valeurs existantes ne peuvent pas être relues.`},"credential.existing":{title:`{name} existant : {status}`,description:`GitHub ne révèle pas la valeur actuelle du Secret. Ne la conservez que si vous acceptez explicitement de ne pas pouvoir vérifier son état ici ; sinon, remplacez-la ou ignorez-la.`,choices:[`Conserver`,`Remplacer`,`Ignorer cet identifiant`]},"apply.confirm":{title:`Appliquer la configuration maintenant ?`,description:`C’est l’approbation finale. Des fichiers locaux et ressources GitHub choisis peuvent changer. Un résultat partiel doit être inspecté avant une nouvelle tentative.`,choices:[`Appliquer la configuration`,`Arrêter sans appliquer`]},"management.token":{title:`PAT temporaire de configuration`,description:`Lisez la configuration GitHub avec un PAT. La lecture suffit pour inspecter ; les changements nécessitent Variables Write et une approbation distincte. Noms des Secrets uniquement. Laissez vide pour revenir au panneau.`},"management.tokenWrite":{title:`PAT de configuration pour cet ajustement`,description:`Utilisez Variables Write dans le scope examiné. Après approbation, la vérification crée et supprime une Variable temporaire. Laissez vide pour revenir au panneau.`}},xa={"setup.scope":{title:`Escolha o âmbito da configuração`,description:`Este repositório mantém a pré-visualização e a aplicação local. Vários repositórios permite selecionar explicitamente entre 1 e 25 destinos da mesma organização e criar PRs para revisão. O lote não integra, cria tags, publica versões nem implementa.`,choices:[`Este repositório`,`Vários repositórios desta organização`]},"setup.batchSource":{title:`De onde deve vir a configuração?`,description:`Reutilize os ajustes compatíveis da organização para saltar perguntas já resolvidas, ou personalize os ajustes do repositório. Em ambos os casos, o lote mantém os Secrets existentes. Crie separadamente as credenciais em falta e volte a inspecionar; os valores partilhados nunca são substituídos.`,choices:[`Reutilizar a configuração da organização`,`Personalizar ajustes; manter os Secrets`]},"batch.token":{title:`PAT temporário para os repositórios selecionados`,description:`Crie um PAT temporário limitado a estes repositórios: {repositories}. O link propõe permissões; selecione pessoalmente apenas os repositórios previstos no GitHub. Deixe vazio para manter o PAT atual. O plano final volta a verificar as permissões exatas. Elimine depois os PATs temporários de configuração.`},"setup.source":{title:`De onde deve vir a configuração?`,description:`Reutilize as Variables compatíveis e os Secrets existentes da organização, mantendo os ajustes do repositório. Só serão pedidos os ajustes em falta, inválidos ou específicos do repositório. Os valores partilhados são mantidos; as diferenças revistas ficam no repositório. Escolha Personalizar para criar ou substituir credenciais.`,choices:[`Reutilizar a configuração da organização`,`Personalizar a configuração`]},"setup.reusePatReview":{title:`Reveja o acesso para reutilizar a configuração`,description:`Estas permissões provisórias permitem consultar a configuração existente e configurar o repositório. Os valores dos Secrets partilhados nunca são pedidos nem substituídos. O plano final verifica as permissões exatas; a verificação das credenciais pode ficar pendente. Selecione apenas os repositórios previstos no GitHub e elimine depois o PAT temporário.`,choices:[`Continuar para o GitHub`,`Introduzir um PAT manualmente`]},"botPat.scopeConflict":{title:`Resolver o conflito de âmbito do PAT do bot`,description:`O Secret PAT do repositório {repository} tem prioridade sobre o PAT da organização selecionado. Elimine o Secret do repositório no GitHub e peça ao Copilot para verificar novamente, ou altere o âmbito do PAT para este repositório. As suas respostas são preservadas. O Copilot não eliminará nenhum Secret.`,choices:[`Já eliminei o PAT do repositório — verificar novamente`,`Guardar o PAT no repositório`,`Parar a configuração`]},"botPat.scopeConflictUnavailable":{title:`Resolver o conflito de âmbito do PAT do bot`,description:`O GitHub não permitiu confirmar se o PAT do repositório foi eliminado. O conflito continua por resolver. As suas respostas são preservadas. Verifique o acesso e tente novamente, altere o âmbito do PAT para este repositório ou pare a configuração.`,choices:[`Já eliminei o PAT do repositório — verificar novamente`,`Guardar o PAT no repositório`,`Parar a configuração`]},"botPat.identityMismatch":{title:`Este PAT pertence a outra conta do GitHub`,description:`O PAT pertence a @{actual}; o bot selecionado é @{expected}. Nenhum Secret do bot foi gravado. As suas respostas e o plano aprovado são mantidos. Elimine o PAT não utilizado no GitHub, mude para @{expected} e escolha entre introduzir outro PAT ou parar a configuração.`,choices:[`Introduzir outro PAT do bot`,`Parar a configuração`]},"repository.confirm":{title:`Confirme este repositório`,description:`Esta pasta aponta para {repository}, no ramo {branch}. Confirme o destino antes de configurar acessos PAT ou ficheiros.`,choices:[`Sim, é o meu repositório`,`Parar e escolher outra pasta`]},"setup.depth":{title:`Escolha o nível de detalhe`,description:`O percurso básico continua a perguntar sobre permissões, segurança, ramos, Projects, aprovação e armazenamento. Algumas definições avançadas de agentes, prefixos de ramos e Bugbot mantêm os valores predefinidos; poderá revê-las e editá-las no plano final. O percurso personalizado pergunta por todas as definições aplicáveis. Nenhum dos percursos aplica alterações nesta fase.`,choices:[`Configuração básica guiada (recomendada)`,`Personalizar todas as definições`]},"setup.environmentPat":{title:`Existe um PAT de configuração no ambiente`,description:`O valor permanece no processo CLI. Continuar inicia a verificação de identidade e testes temporários isolados de criação, leitura e eliminação antes do plano. A instalação exige aprovação final. Sair do Copilot não remove a variável da shell original.`,choices:[`Usar o PAT do ambiente`,`Criar ou introduzir outro PAT`]},"plan.review":{title:`Reveja o plano de configuração`,description:`Confirme ficheiros, fluxos, Variables e nomes de Secrets antes de aprovar. Abrir o plano não inicia alterações.`,choices:void 0},"workflow.update":{title:`Atualizar os fluxos existentes?`,description:`Estes ficheiros diferem do plano: {files}. Conservá-los pode deixar algumas definições novas inativas.`,choices:[`Conservar os existentes`,`Atualizar os fluxos geridos`]},"setupPat.method":{title:`Como irá fornecer o PAT de configuração?`,description:`Este PAT temporário autoriza uma única execução. O GitHub cria-o na sua conta de operador; o Copilot não pode revogá-lo por si.`,choices:[`Ligação guiada do GitHub`,`Introduzir PAT manualmente`]},"setupPat.ownerKind":{title:`Quem é o proprietário deste repositório no GitHub?`,description:`O proprietário determina as permissões de organização necessárias. Consulte o cabeçalho do repositório no GitHub se tiver dúvidas.`,choices:[`Organização`,`Conta pessoal`,`Não tenho a certeza`]},"setupPat.review":{title:`Reveja as permissões provisórias do PAT de configuração`,description:`Estas permissões seguem as suas escolhas. Ao gerir Secrets, a ligação pré-seleciona Actions, Contents e Workflows em escrita para possíveis verificações de credenciais. Estas verificações só decorrem se o plano aprovado as exigir. A inspeção do GitHub pode revelar outros requisitos.`,choices:[`Continuar no GitHub`,`Rever as escolhas`,`Ver a tabela completa de permissões`,`Introduzir um PAT manualmente`]},"setupPat.entry":{title:`PAT temporário de configuração`,description:`Abra o GitHub com a sua conta de operador, conclua a 2FA, escolha «Only select repositories», selecione este repositório e cole aqui o PAT gerado. É apenas para esta execução; elimine-o no GitHub depois.`},"setupPat.confirmAccount":{title:`O GitHub autenticou o PAT de configuração como @{account}`,description:`É esta a conta de operador que deve configurar o repositório? Uma conta errada tem de parar o processo antes de qualquer alteração.`,choices:[`Sim, continuar`,`Não, parar`]},"setupPat.confirmUnverifiedAccess":{title:`Verifique as permissões do PAT marcadas Não verificável`,description:`As linhas Verificadas já passaram na verificação. Compare cada permissão necessária Não verificável com o âmbito e o nível de acesso nas definições do PAT no GitHub. Uma consulta só de leitura não prova Escrita; Não verificável não significa ausente. Verifique Projects: leitura apenas se essa linha estiver Não verificável. Continue só depois de verificar todas essas permissões.`,choices:[`Não, parar`,`Sim, já as verifiquei`]},"botPat.method":{title:`Como irá fornecer o PAT do bot?`,description:`É diferente do PAT de configuração. Pertence à conta que executará as futuras GitHub Actions e será instalado como Secret após aprovação.`,choices:[`Ligação guiada do GitHub`,`Introduzir PAT manualmente`]},"botPat.login":{title:`Utilizador GitHub esperado para o bot`,description:`Introduza o nome de utilizador do bot sem @. O Copilot consulta o ID numérico do GitHub e compara-o com o proprietário do PAT.`},"botPat.entry.guided":{title:`{name} — PAT da conta bot`,description:`Abra o GitHub como @{account} (ID {accountId}), não como operador. Selecione apenas este repositório, reveja todas as permissões e cole aqui o PAT. Validade sugerida: 90 dias. Não é possível voltar a ler o valor de um Secret existente.`},"botPat.entry.manual":{title:`{name} — PAT da conta bot`,description:`Use a conta bot, selecione apenas o repositório pretendido e reveja todas as permissões antes de colar o PAT. Validade sugerida: 90 dias. Não é possível voltar a ler o valor de um Secret existente.`},"credential.apiKey":{title:`{name} — chave API de {provider}`,description:`Cole a chave API de {provider}. Só é enviada para este processo local e, se aprovar o plano, instalada como Secret do GitHub Actions. Os valores existentes não podem voltar a ser lidos.`},"credential.existing":{title:`{name} existente: {status}`,description:`O GitHub não revela o valor atual do Secret. Conserve-o apenas se aceitar expressamente que aqui não se pode verificar o seu estado; caso contrário, substitua-o ou ignore-o.`,choices:[`Conservar`,`Substituir`,`Ignorar esta credencial`]},"apply.confirm":{title:`Aplicar a configuração agora?`,description:`Esta é a aprovação final. Ficheiros locais e recursos GitHub selecionados podem mudar. Um resultado parcial exige inspeção antes de tentar novamente.`,choices:[`Aplicar configuração`,`Parar sem aplicar`]},"management.token":{title:`PAT temporário de setup`,description:`Leia a configuração GitHub com um PAT. A leitura basta para inspecionar; alterações exigem Variables Write e aprovação separada. Apenas nomes dos Secrets. Deixe vazio para voltar ao painel.`},"management.tokenWrite":{title:`PAT de setup para este ajuste`,description:`Use Variables Write no scope revisto. Após aprovação, a verificação cria e elimina uma Variable temporária. Deixe vazio para voltar ao painel.`}},Sa={"session.controlMoved":`Control moved to this tab. The previous tab is now read-only.`,"session.cancelled":`Cancellation requested. Temporary permission checks already started will finish cleanup before the process exits. PATs created on GitHub remain until you delete them there.`,"plan.ready":`Plan ready: {files} files, {variables} Variables and {secrets} Secret names. Review it before continuing.`,"permission.preview":`Permission preview: issue workflows {issues}; PR approval {approval}; Secrets {secrets}; Variables {variables}; Projects {projects}. Review the exact grants before creating the setup PAT.`,"setupPat.corrected.bootstrap":`The setup PAT could not access the repository. Installation has not started. Resolve failed permission tests and any pending cleanup before retrying. Required grants: {grants}. Create a corrected PAT using the updated GitHub link.`,"setupPat.corrected.final":`Required setup PAT permissions changed after inspection. Installation has not started. Resolve failed permission tests and any pending cleanup before retrying. New grants: {grants}. Create a corrected PAT using the updated GitHub link.`,"setupPat.cleanup":`Delete the temporary setup PAT in GitHub Settings after this run. Closing Copilot does not revoke it.`,"botPat.separation":`The bot PAT is separate from your setup PAT. These credentials become GitHub Actions Secrets: {names}. Existing Secret values cannot be read back. Re-enter an existing bot PAT so its grants can be checked. No credential-health workflow runs before Apply.`,"credential.checks":`Credential checks finished for {count} items. Each result is shown below. The terminal has technical details; an existing Secret value cannot be read back.`,"credential.status.valid":`Valid`,"credential.status.invalid":`Invalid`,"credential.status.missing":`Missing`,"credential.status.unverifiable":`Cannot be verified without a new value`,"credential.status.not_required":`Not required`,"validation.producers":`Select 1–8 observed checks or enter exact name|App ID|workflow tuples.`,"validation.duplicateNames":`Two trusted producers use the same check name. Coverage stores only the name: choose one producer or rename the CI jobs.`,"validation.projectStatusVerified":`Open every selected Project in GitHub and confirm that all four exact Status values exist. Answer Yes after checking, or No to choose Projects again.`,"validation.projectStatusRedo":`Status values were not confirmed. Choose compatible Projects, then review their Status options again.`,"validation.number":`Enter a non-negative whole number.`,"validation.boolean":`Enter yes or no.`,"validation.choice":`Select one of the listed options.`,"validation.unknownResource":`Unknown inherited resource names: {names}. Choose only names shown in the inherited list.`,"validation.unknownWorkflow":`Unknown issue workflows: {names}. Choose only the listed workflow types.`,"validation.firstQuestion":`This is the first question in this pass. Review it or cancel setup.`,"validation.duplicateProducer":`This trusted check was selected twice. Remove the duplicate selection.`,"validation.savedStatus":`The saved Status value is not available in every selected Project. Choose a listed option.`,"validation.projectIncompatible":`The selected Projects have no common Status option. Choose compatible Projects or configure them separately.`,"validation.projectLimit":`Choose at most 10 Projects; separate their numbers or URLs with commas.`,"validation.projectOwnerNeeded":`A Project URL needs a known repository owner; enter its positive number instead.`,"validation.projectOwnerMismatch":`Use a GitHub Project URL belonging to {owner}, without query parameters.`,"validation.projectUrl":`Enter a valid GitHub Project URL or positive Project number.`,"validation.projectNumber":`Enter the positive Project number from its GitHub URL, not a PVT_ GraphQL ID.`,"validation.projectNumberRange":`Project numbers must be positive integers at most 2147483647.`,"validation.projectDuplicate":`Project {number} was selected more than once.`,"validation.fixedIssues":`Your configuration explicitly enables release or hotfix automation. Keep Issues enabled or edit that configuration first.`,"validation.fixedWorkflowEnabled":`Your configuration enables {kind}. Keep that workflow selected or edit the configuration first.`,"validation.fixedWorkflowDisabled":`Your configuration disables {kind}. Deselect that workflow or edit the configuration first.`,"validation.unknown":`This answer could not be accepted. Review the question and its help; the terminal has the technical detail.`},Ca={"session.controlMoved":`El control ha pasado a esta pestaña. La anterior ahora es de solo lectura.`,"session.cancelled":`Cancelación solicitada. Las pruebas temporales ya iniciadas terminarán su limpieza antes de que salga el proceso. Los PAT creados en GitHub seguirán allí hasta que los elimines.`,"plan.ready":`Plan listo: {files} archivos, {variables} Variables y {secrets} nombres de Secrets. Revísalo antes de continuar.`,"permission.preview":`Vista previa de permisos: flujos de incidencias {issues}; aprobación de PR {approval}; Secrets {secrets}; Variables {variables}; Projects {projects}. Revisa los permisos exactos antes de crear el PAT de configuración.`,"setupPat.corrected.bootstrap":`El PAT de configuración no pudo acceder al repositorio. La instalación no ha empezado. Resuelve las pruebas fallidas y cualquier limpieza pendiente antes de reintentar. Permisos necesarios: {grants}. Crea un PAT corregido desde el enlace actualizado de GitHub.`,"setupPat.corrected.final":`Los permisos necesarios del PAT cambiaron tras la inspección. La instalación no ha empezado. Resuelve las pruebas fallidas y cualquier limpieza pendiente antes de reintentar. Permisos nuevos: {grants}. Crea un PAT corregido desde el enlace actualizado.`,"setupPat.cleanup":`Elimina el PAT temporal de configuración en los ajustes de GitHub después de esta ejecución. Cerrar Copilot no lo revoca.`,"botPat.separation":`El PAT del bot es distinto del de configuración. Estas credenciales se instalarán como Secrets de GitHub Actions: {names}. Los valores existentes no pueden leerse. Vuelve a introducir un PAT del bot para comprobar sus permisos. Antes de Aplicar no se ejecuta ningún workflow de comprobación.`,"credential.checks":`Se han comprobado {count} credenciales. Abajo aparece el resultado de cada una. La terminal contiene los detalles técnicos; el valor de un Secret existente no puede leerse.`,"credential.status.valid":`Válida`,"credential.status.invalid":`No válida`,"credential.status.missing":`Falta`,"credential.status.unverifiable":`No verificable sin un valor nuevo`,"credential.status.not_required":`No necesaria`,"validation.producers":`Selecciona entre 1 y 8 checks observados o introduce las tuplas exactas nombre|ID de App|workflow.`,"validation.duplicateNames":`Dos productores fiables tienen el mismo nombre de check. La cobertura solo guarda el nombre: elige uno o cambia el nombre de los jobs de CI.`,"validation.projectStatusVerified":`Abre cada Project elegido en GitHub y confirma los cuatro valores Status exactos. Responde Sí tras comprobarlo, o No para elegir Projects de nuevo.`,"validation.projectStatusRedo":`No se confirmaron los valores Status. Elige Projects compatibles y vuelve a revisar sus opciones Status.`,"validation.number":`Introduce un número entero no negativo.`,"validation.boolean":`Elige Sí o No.`,"validation.choice":`Elige una de las opciones mostradas.`,"validation.unknownResource":`Nombres de recursos heredados desconocidos: {names}. Elige solo nombres de la lista heredada.`,"validation.unknownWorkflow":`Flujos de issues desconocidos: {names}. Elige solo los tipos indicados.`,"validation.firstQuestion":`Esta es la primera pregunta de esta pasada. Revísala o cancela la configuración.`,"validation.duplicateProducer":`Has seleccionado dos veces el mismo check fiable. Quita la selección duplicada.`,"validation.savedStatus":`El valor Status guardado no existe en todos los Projects seleccionados. Elige una opción de la lista.`,"validation.projectIncompatible":`Los Projects elegidos no comparten ningún valor Status. Elige Projects compatibles o configúralos por separado.`,"validation.projectLimit":`Elige como máximo 10 Projects; separa sus números o URL con comas.`,"validation.projectOwnerNeeded":`Para usar la URL de un Project hay que conocer el propietario del repositorio; introduce su número positivo.`,"validation.projectOwnerMismatch":`Usa la URL de un Project de GitHub que pertenezca a {owner}, sin parámetros.`,"validation.projectUrl":`Introduce una URL válida de un Project de GitHub o su número positivo.`,"validation.projectNumber":`Introduce el número positivo del Project que aparece en su URL, no un ID GraphQL PVT_.`,"validation.projectNumberRange":`El número del Project debe ser un entero positivo no mayor de 2147483647.`,"validation.projectDuplicate":`Has seleccionado el Project {number} más de una vez.`,"validation.fixedIssues":`Tu configuración activa expresamente release o hotfix. Mantén Issues activado o cambia antes la configuración.`,"validation.fixedWorkflowEnabled":`Tu configuración activa {kind}. Mantén ese flujo seleccionado o cambia antes la configuración.`,"validation.fixedWorkflowDisabled":`Tu configuración desactiva {kind}. Desmarca ese flujo o cambia antes la configuración.`,"validation.unknown":`No se pudo aceptar esta respuesta. Revisa la pregunta y su ayuda; la terminal contiene el detalle técnico.`},wa={"session.controlMoved":`Le contrôle est passé à cet onglet. L’onglet précédent est maintenant en lecture seule.`,"session.cancelled":`Annulation demandée. Les tests temporaires déjà lancés termineront leur nettoyage avant la fin du processus. Les PAT créés sur GitHub restent actifs jusqu’à leur suppression.`,"plan.ready":`Plan prêt : {files} fichiers, {variables} Variables et {secrets} noms de Secrets. Examinez-le avant de continuer.`,"permission.preview":`Aperçu des droits : flux de tickets {issues} ; approbation des PR {approval} ; Secrets {secrets} ; Variables {variables} ; Projects {projects}. Vérifiez les droits exacts avant de créer le PAT de configuration.`,"setupPat.corrected.bootstrap":`Le PAT de configuration n’a pas pu accéder au dépôt. L’installation n’a pas commencé. Résolvez les tests échoués et tout nettoyage incomplet avant de réessayer. Droits requis : {grants}. Créez un PAT corrigé avec le lien GitHub mis à jour.`,"setupPat.corrected.final":`Les droits requis du PAT ont changé après inspection. L’installation n’a pas commencé. Résolvez les tests échoués et tout nettoyage incomplet avant de réessayer. Nouveaux droits : {grants}. Créez un PAT corrigé avec le lien mis à jour.`,"setupPat.cleanup":`Supprimez le PAT temporaire de configuration dans les paramètres GitHub après cette exécution. Fermer Copilot ne le révoque pas.`,"botPat.separation":`Le PAT du bot est distinct du PAT de configuration. Ces identifiants deviendront des Secrets GitHub Actions : {names}. Les valeurs existantes ne peuvent pas être relues. Saisissez à nouveau un PAT du bot pour vérifier ses droits. Aucun workflow de vérification ne démarre avant Appliquer.`,"credential.checks":`Vérification terminée pour {count} identifiants. Le résultat de chacun figure ci-dessous. Le terminal contient les détails techniques ; la valeur d’un Secret existant ne peut pas être relue.`,"credential.status.valid":`Valide`,"credential.status.invalid":`Invalide`,"credential.status.missing":`Manquant`,"credential.status.unverifiable":`Invérifiable sans nouvelle valeur`,"credential.status.not_required":`Non requis`,"validation.producers":`Choisissez 1 à 8 vérifications observées ou saisissez les triplets exacts nom|ID d’App|workflow.`,"validation.duplicateNames":`Deux producteurs fiables portent le même nom de vérification. La couverture ne stocke que ce nom : choisissez-en un ou renommez les jobs CI.`,"validation.projectStatusVerified":`Ouvrez chaque Project choisi sur GitHub et confirmez les quatre valeurs Status exactes. Répondez Oui après vérification, ou Non pour choisir à nouveau les Projects.`,"validation.projectStatusRedo":`Les valeurs Status n’ont pas été confirmées. Choisissez des Projects compatibles, puis revérifiez leurs options Status.`,"validation.number":`Saisissez un entier positif ou nul.`,"validation.boolean":`Choisissez Oui ou Non.`,"validation.choice":`Choisissez une des options affichées.`,"validation.unknownResource":`Noms de ressources héritées inconnus : {names}. Choisissez seulement les noms de la liste héritée.`,"validation.unknownWorkflow":`Workflows de ticket inconnus : {names}. Choisissez seulement les types proposés.`,"validation.firstQuestion":`C’est la première question de cette passe. Vérifiez-la ou annulez la configuration.`,"validation.duplicateProducer":`Cette vérification fiable a été choisie deux fois. Retirez le doublon.`,"validation.savedStatus":`La valeur Status enregistrée n’existe pas dans tous les Projects choisis. Sélectionnez une option proposée.`,"validation.projectIncompatible":`Les Projects choisis ne partagent aucune valeur Status. Choisissez des Projects compatibles ou configurez-les séparément.`,"validation.projectLimit":`Choisissez au plus 10 Projects ; séparez leurs numéros ou URL par des virgules.`,"validation.projectOwnerNeeded":`Une URL de Project exige de connaître le propriétaire du dépôt ; saisissez plutôt son numéro positif.`,"validation.projectOwnerMismatch":`Utilisez une URL de Project GitHub appartenant à {owner}, sans paramètres.`,"validation.projectUrl":`Saisissez une URL valide de Project GitHub ou son numéro positif.`,"validation.projectNumber":`Saisissez le numéro positif figurant dans l’URL du Project, pas un ID GraphQL PVT_.`,"validation.projectNumberRange":`Le numéro du Project doit être un entier positif inférieur ou égal à 2147483647.`,"validation.projectDuplicate":`Le Project {number} a été choisi plusieurs fois.`,"validation.fixedIssues":`Votre configuration active explicitement release ou hotfix. Gardez Issues activé ou modifiez d’abord la configuration.`,"validation.fixedWorkflowEnabled":`Votre configuration active {kind}. Gardez ce flux sélectionné ou modifiez d’abord la configuration.`,"validation.fixedWorkflowDisabled":`Votre configuration désactive {kind}. Désélectionnez ce flux ou modifiez d’abord la configuration.`,"validation.unknown":`Cette réponse n’a pas été acceptée. Vérifiez la question et son aide ; le terminal contient le détail technique.`},Ta={"session.controlMoved":`O controlo passou para este separador. O separador anterior é agora apenas de leitura.`,"session.cancelled":`Cancelamento solicitado. Os testes temporários já iniciados concluirão a limpeza antes de o processo terminar. Os PAT criados no GitHub permanecem até serem eliminados.`,"plan.ready":`Plano pronto: {files} ficheiros, {variables} Variables e {secrets} nomes de Secrets. Reveja-o antes de continuar.`,"permission.preview":`Pré-visualização das permissões: fluxos de issues {issues}; aprovação de PR {approval}; Secrets {secrets}; Variables {variables}; Projects {projects}. Reveja as permissões exatas antes de criar o PAT de configuração.`,"setupPat.corrected.bootstrap":`O PAT de configuração não conseguiu aceder ao repositório. A instalação não começou. Resolva os testes falhados e qualquer limpeza pendente antes de repetir. Permissões necessárias: {grants}. Crie um PAT corrigido com a ligação GitHub atualizada.`,"setupPat.corrected.final":`As permissões necessárias do PAT mudaram após inspeção. A instalação não começou. Resolva os testes falhados e qualquer limpeza pendente antes de repetir. Novas permissões: {grants}. Crie um PAT corrigido com a ligação atualizada.`,"setupPat.cleanup":`Elimine o PAT temporário de configuração nas definições do GitHub após esta execução. Fechar o Copilot não o revoga.`,"botPat.separation":`O PAT do bot é distinto do PAT de configuração. Estas credenciais serão Secrets do GitHub Actions: {names}. Os valores existentes não podem voltar a ser lidos. Reintroduza um PAT do bot para verificar as permissões. Nenhum fluxo de verificação é executado antes de Aplicar.`,"credential.checks":`Verificação concluída para {count} credenciais. O resultado de cada uma aparece abaixo. O terminal contém os detalhes técnicos; o valor de um Secret existente não pode voltar a ser lido.`,"credential.status.valid":`Válida`,"credential.status.invalid":`Inválida`,"credential.status.missing":`Em falta`,"credential.status.unverifiable":`Não verificável sem um novo valor`,"credential.status.not_required":`Não necessária`,"validation.producers":`Selecione 1 a 8 verificações observadas ou introduza os triplos exatos nome|ID da App|workflow.`,"validation.duplicateNames":`Dois produtores fiáveis têm o mesmo nome de check. A cobertura guarda apenas o nome: escolha um ou altere o nome dos jobs de CI.`,"validation.projectStatusVerified":`Abra cada Project escolhido no GitHub e confirme os quatro valores Status exatos. Responda Sim após verificar, ou Não para voltar a escolher Projects.`,"validation.projectStatusRedo":`Os valores Status não foram confirmados. Escolha Projects compatíveis e volte a verificar as opções Status.`,"validation.number":`Introduza um número inteiro não negativo.`,"validation.boolean":`Escolha Sim ou Não.`,"validation.choice":`Escolha uma das opções apresentadas.`,"validation.unknownResource":`Nomes de recursos herdados desconhecidos: {names}. Escolha apenas nomes da lista herdada.`,"validation.unknownWorkflow":`Fluxos de questões desconhecidos: {names}. Escolha apenas os tipos indicados.`,"validation.firstQuestion":`Esta é a primeira pergunta desta ronda. Reveja-a ou cancele a configuração.`,"validation.duplicateProducer":`Esta verificação de confiança foi selecionada duas vezes. Remova a seleção duplicada.`,"validation.savedStatus":`O valor Status guardado não existe em todos os Projects escolhidos. Selecione uma opção da lista.`,"validation.projectIncompatible":`Os Projects escolhidos não partilham qualquer valor Status. Escolha Projects compatíveis ou configure-os separadamente.`,"validation.projectLimit":`Escolha no máximo 10 Projects; separe os números ou URL por vírgulas.`,"validation.projectOwnerNeeded":`Uma URL de Project exige que se conheça o proprietário do repositório; introduza antes o número positivo.`,"validation.projectOwnerMismatch":`Use uma URL de Project do GitHub pertencente a {owner}, sem parâmetros.`,"validation.projectUrl":`Introduza uma URL válida de Project do GitHub ou o respetivo número positivo.`,"validation.projectNumber":`Introduza o número positivo apresentado na URL do Project, não um ID GraphQL PVT_.`,"validation.projectNumberRange":`O número do Project tem de ser um inteiro positivo até 2147483647.`,"validation.projectDuplicate":`O Project {number} foi selecionado mais do que uma vez.`,"validation.fixedIssues":`A sua configuração ativa explicitamente release ou hotfix. Mantenha Issues ativo ou altere primeiro a configuração.`,"validation.fixedWorkflowEnabled":`A sua configuração ativa {kind}. Mantenha esse fluxo selecionado ou altere primeiro a configuração.`,"validation.fixedWorkflowDisabled":`A sua configuração desativa {kind}. Desmarque esse fluxo ou altere primeiro a configuração.`,"validation.unknown":`Esta resposta não foi aceite. Reveja a pergunta e a ajuda; o terminal contém o detalhe técnico.`},Ea={en:{title:`Runners and installation parity`,help:`Access and capacity are observations. Verify runner authentication separately. Busy/offline waits for capacity; unknown access needs administrator verification. The chosen route never changes automatically.`,assets:`Asset inventory`,changes:`Complete changes (recognized credential formats masked)`,redactionNotice:`Masking covers recognized credential formats. Other hardcoded values can remain visible in these local workflow files; inspect them before sharing the review.`,before:`Before`,after:`After`,absent:`Absent`,disabled:`Disabled`,retained:`Retained`,blockers:`Needs attention`,registry:`Profile registry`,inventory:`Runner discovery`,profiles:`Reusable profiles`,observed:`Observed groups and labels`,limited:`Showing the first 10 runners. Manual entry remains available.`,available:`Available`,incomplete:`Incomplete`,missing:`Missing`,invalid:`Invalid: repair the registry or enter a manual profile`,unavailable:`Unavailable`,confirmed:`Repository access confirmed`,unknown:`Access unverified`,ready:`Available capacity observed`,hosted:`GitHub-hosted`,"pending-capacity":`Capacity pending: busy or offline`,"access-unknown":`Access unverified`,shared:`Shared/generated`,"source-only":`Source extension: retained`,customized:`Customized: review`,incompatible:`Incompatible generator: inspect before replacing`,agent:`Agent jobs`,"credential-health":`Credential verification`,validation:`Ordinary validation`,observer:`Trusted approval observer`,publication:`Publication`,isolated:`Isolated merge-group check`,retain:`Keep installed routing (recommended)`,"organization-profile":`Reuse an existing shared profile`,"manual-self-hosted":`Choose an existing self-hosted runner`,"validation-agent":`Use the selected agent runner`,"validation-hosted":`Use GitHub-hosted runners (recommended)`},es:{title:`Runners y paridad de la instalación`,help:`Acceso y capacidad son observaciones. Verifica la autenticación del runner por separado. Ocupado/desconectado espera capacidad; acceso desconocido requiere verificación del administrador. La ruta elegida nunca cambia automáticamente.`,assets:`Inventario de archivos`,changes:`Cambios completos (formatos de credenciales reconocidos ocultos)`,redactionNotice:`Se ocultan los formatos de credenciales reconocidos. Otros valores escritos en los workflows pueden seguir visibles en esta vista local; revísalos antes de compartirla.`,before:`Antes`,after:`Después`,absent:`Ausente`,disabled:`Desactivado`,retained:`Conservado`,blockers:`Requiere atención`,registry:`Registro de perfiles`,inventory:`Descubrimiento de runners`,profiles:`Perfiles reutilizables`,observed:`Grupos y etiquetas observados`,limited:`Se muestran los primeros 10 runners. Sigue disponible la entrada manual.`,available:`Disponible`,incomplete:`Incompleto`,missing:`Ausente`,invalid:`Inválido: corrige el registro o introduce un perfil manual`,unavailable:`No disponible`,confirmed:`Acceso del repositorio confirmado`,unknown:`Acceso sin verificar`,ready:`Capacidad disponible observada`,hosted:`Runners de GitHub`,"pending-capacity":`Capacidad pendiente: ocupado o desconectado`,"access-unknown":`Acceso sin verificar`,shared:`Compartido/generado`,"source-only":`Extensión propia: conservada`,customized:`Personalizado: revisar`,incompatible:`Generador incompatible: revisar antes de sustituir`,agent:`Jobs del agente`,"credential-health":`Verificación de credenciales`,validation:`Validación ordinaria`,observer:`Observador de aprobación fiable`,publication:`Publicación`,isolated:`Check aislado de la cola de fusión`,retain:`Conservar rutas instaladas (recomendado)`,"organization-profile":`Reutilizar un perfil compartido existente`,"manual-self-hosted":`Elegir un runner self-hosted existente`,"validation-agent":`Usar el runner del agente elegido`,"validation-hosted":`Usar runners de GitHub (recomendado)`},fr:{title:`Runners et parité de l’installation`,help:`Accès et capacité sont des observations. Vérifiez séparément l’authentification. Occupé/hors ligne attend la capacité ; l’accès inconnu exige une vérification administrateur. La route ne change jamais automatiquement.`,assets:`Inventaire des fichiers`,redactionNotice:`Le masquage couvre les formats de secrets reconnus. D’autres valeurs littérales peuvent rester visibles dans cette vue locale ; vérifiez-les avant de la partager.`,changes:`Modifications complètes (formats d’identifiants reconnus masqués)`,before:`Avant`,after:`Après`,absent:`Absent`,disabled:`Désactivé`,retained:`Conservé`,blockers:`Attention requise`,registry:`Registre des profils`,inventory:`Découverte des runners`,profiles:`Profils réutilisables`,observed:`Groupes et étiquettes observés`,limited:`Les 10 premiers runners sont affichés. La saisie manuelle reste disponible.`,available:`Disponible`,incomplete:`Incomplet`,missing:`Absent`,invalid:`Invalide : corrigez le registre ou saisissez un profil manuel`,unavailable:`Indisponible`,confirmed:`Accès du dépôt confirmé`,unknown:`Accès non vérifié`,ready:`Capacité disponible observée`,hosted:`Runners GitHub`,"pending-capacity":`Capacité en attente : occupé ou hors ligne`,"access-unknown":`Accès non vérifié`,shared:`Partagé/généré`,"source-only":`Extension source conservée`,customized:`Personnalisé : à vérifier`,incompatible:`Générateur incompatible : vérifiez avant remplacement`,agent:`Jobs de l’agent`,"credential-health":`Vérification des identifiants`,validation:`Validation ordinaire`,observer:`Observateur d’approbation fiable`,publication:`Publication`,isolated:`Vérification isolée de la file de fusion`,retain:`Conserver les routes installées (recommandé)`,"organization-profile":`Réutiliser un profil partagé existant`,"manual-self-hosted":`Choisir un runner auto-hébergé existant`,"validation-agent":`Utiliser le runner de l’agent sélectionné`,"validation-hosted":`Utiliser GitHub (recommandé)`},pt:{title:`Runners e paridade da instalação`,help:`Acesso e capacidade são observações. Verifique a autenticação separadamente. Ocupado/offline aguarda capacidade; acesso desconhecido exige verificação do administrador. A rota nunca muda automaticamente.`,assets:`Inventário de ficheiros`,redactionNotice:`São ocultados os formatos de credenciais reconhecidos. Outros valores escritos nos workflows podem continuar visíveis nesta vista local; reveja-os antes de a partilhar.`,changes:`Alterações completas (formatos de credenciais reconhecidos ocultos)`,before:`Antes`,after:`Depois`,absent:`Ausente`,disabled:`Desativado`,retained:`Mantido`,blockers:`Requer atenção`,registry:`Registo de perfis`,inventory:`Descoberta de runners`,profiles:`Perfis reutilizáveis`,observed:`Grupos e etiquetas observados`,limited:`São apresentados os primeiros 10 runners. A entrada manual continua disponível.`,available:`Disponível`,incomplete:`Incompleto`,missing:`Ausente`,invalid:`Inválido: corrija o registo ou introduza um perfil manual`,unavailable:`Indisponível`,confirmed:`Acesso do repositório confirmado`,unknown:`Acesso não verificado`,ready:`Capacidade disponível observada`,hosted:`Runners GitHub`,"pending-capacity":`Capacidade pendente: ocupado ou offline`,"access-unknown":`Acesso não verificado`,shared:`Partilhado/gerado`,"source-only":`Extensão própria mantida`,customized:`Personalizado: rever`,incompatible:`Gerador incompatível: reveja antes de substituir`,agent:`Jobs do agente`,"credential-health":`Verificação de credenciais`,validation:`Validação normal`,observer:`Observador de aprovação fiável`,publication:`Publicação`,isolated:`Verificação isolada da fila de fusão`,retain:`Manter rotas instaladas (recomendado)`,"organization-profile":`Reutilizar um perfil partilhado existente`,"manual-self-hosted":`Escolher um runner self-hosted existente`,"validation-agent":`Usar o runner do agente selecionado`,"validation-hosted":`Usar GitHub (recomendado)`}},Da={en:`This plan cannot be applied. Retain the existing asset or restore it with a compatible generator, then review again. No installation change has been applied. Open the details to identify the affected file.`,es:`Este plan no se puede aplicar. Conserva el archivo existente o restáuralo con un generador compatible y vuelve a revisar. No se ha aplicado ningún cambio de instalación. Abre los detalles para identificar el archivo afectado.`,fr:`Ce plan ne peut pas être appliqué. Conservez le fichier existant ou restaurez-le avec un générateur compatible, puis révisez le plan. Aucune modification d’installation n’a été appliquée. Ouvrez les détails pour identifier le fichier concerné.`,pt:`Este plano não pode ser aplicado. Mantenha o ficheiro existente ou restaure-o com um gerador compatível e reveja o plano. Nenhuma alteração de instalação foi aplicada. Abra os detalhes para identificar o ficheiro afetado.`};function $(e,t){return e===`blockedAction`?Da[t]:Ea[t][e]??Ea.en[e]??e}var Oa={es:{All:`Todos`,prompt:`Preguntar antes de crear el enlace`,"create-if-missing":`Crear el enlace si falta`,disabled:`Desactivado`,replace:`Sustituir`,append:`Añadir`,preserve:`Conservar`,info:`Informativa`,low:`Baja`,medium:`Media`,high:`Alta`,smart:`Adaptativa`,default:`Predeterminado`,auto:`Automático`,always:`Reinstalar siempre`,recommend:`Recomendar aprobación`,guarded:`Aprobar solo con garantías`,off:`Desactivado`,check:`Check de CI que exige la cobertura`,numeric:`Informe numérico verificable`,repository:`Repositorio`,organization:`Organización`,selected:`Repositorios seleccionados`,private:`Repositorios privados`,all:`Todos los repositorios`,"production-lineage":`Conservar el linaje de producción`,"canonical-gitflow":`Git-Flow canónico`,manual:`Manual`,"auto-merge":`Fusionar automáticamente`,"merge-queue":`Cola de integración`,"create-only":`Solo crear PR`,direct:`Integración directa`,"sync-branch":`Mediante rama de sincronización`,"prefer-release":`Priorizar la release`,development:`Desarrollo`,both:`Ambos destinos`,"source-only":`Solo rama de origen`,"sync-only":`Solo rama de sincronización`,none:`Ninguna`,close:`Cerrar el issue`,"keep-open":`Mantener abierto`,guided:`Guiado`,compact:`Compacto`,quiet:`Mínimo`,update:`Actualizar el comentario`,milestones:`Publicar en hitos`,feature:`Funcionalidad`,bugfix:`Corrección`,documentation:`Documentación`,chore:`Mantenimiento`,help:`Ayuda o pregunta`,hotfix:`Arreglo urgente`,release:`Release`},fr:{All:`Tous`,prompt:`Demander avant de créer le renvoi`,"create-if-missing":`Créer le renvoi s’il manque`,disabled:`Désactivé`,replace:`Remplacer`,append:`Ajouter`,preserve:`Conserver`,info:`Information`,low:`Faible`,medium:`Moyenne`,high:`Élevée`,smart:`Adaptatif`,default:`Par défaut`,auto:`Automatique`,always:`Toujours réinstaller`,recommend:`Recommander une approbation`,guarded:`Approuver sous garde`,off:`Désactivé`,check:`Vérification CI imposant la couverture`,numeric:`Rapport numérique vérifiable`,repository:`Dépôt`,organization:`Organisation`,selected:`Dépôts sélectionnés`,private:`Dépôts privés`,all:`Tous les dépôts`,"production-lineage":`Préserver la filiation de production`,"canonical-gitflow":`Git-Flow canonique`,manual:`Manuel`,"auto-merge":`Fusionner automatiquement`,"merge-queue":`File de fusion`,"create-only":`Créer la PR uniquement`,direct:`Fusion directe`,"sync-branch":`Par branche de synchronisation`,"prefer-release":`Privilégier la version`,development:`Développement`,both:`Les deux destinations`,"source-only":`Branche source seulement`,"sync-only":`Branche de synchronisation seulement`,none:`Aucune`,close:`Fermer le ticket`,"keep-open":`Garder ouvert`,guided:`Guidé`,compact:`Compact`,quiet:`Minimal`,update:`Mettre le commentaire à jour`,milestones:`Publier aux étapes clés`,feature:`Fonctionnalité`,bugfix:`Correction`,documentation:`Documentation`,chore:`Maintenance`,help:`Aide ou question`,hotfix:`Correctif urgent`,release:`Version`},pt:{All:`Todos`,prompt:`Perguntar antes de criar o apontador`,"create-if-missing":`Criar o apontador se faltar`,disabled:`Desativado`,replace:`Substituir`,append:`Acrescentar`,preserve:`Conservar`,info:`Informação`,low:`Baixa`,medium:`Média`,high:`Alta`,smart:`Adaptativo`,default:`Predefinido`,auto:`Automático`,always:`Reinstalar sempre`,recommend:`Recomendar aprovação`,guarded:`Aprovar sob condições`,off:`Desativado`,check:`Verificação CI que exige cobertura`,numeric:`Relatório numérico verificável`,repository:`Repositório`,organization:`Organização`,selected:`Repositórios selecionados`,private:`Repositórios privados`,all:`Todos os repositórios`,"production-lineage":`Preservar a linhagem de produção`,"canonical-gitflow":`Git-Flow canónico`,manual:`Manual`,"auto-merge":`Integrar automaticamente`,"merge-queue":`Fila de integração`,"create-only":`Criar apenas a PR`,direct:`Integração direta`,"sync-branch":`Através de ramo de sincronização`,"prefer-release":`Priorizar a release`,development:`Desenvolvimento`,both:`Ambos os destinos`,"source-only":`Apenas ramo de origem`,"sync-only":`Apenas ramo de sincronização`,none:`Nenhum`,close:`Fechar a questão`,"keep-open":`Manter aberta`,guided:`Guiado`,compact:`Compacto`,quiet:`Mínimo`,update:`Atualizar o comentário`,milestones:`Publicar nos marcos`,feature:`Funcionalidade`,bugfix:`Correção`,documentation:`Documentação`,chore:`Manutenção`,help:`Ajuda ou pergunta`,hotfix:`Hotfix`,release:`Release`}},ka=new Set([`codex`,`opencode`,`cursor`,`openai`,`anthropic`,`google`,`openrouter`,`local`]);function Aa(e,t,n){if(e===`runners.mode`)return $(t,n);if(e===`runners.validation`)return $(`validation-${t}`,n);if(n===`en`||ka.has(t))return t;let r=Oa[n];if(e===`issueWorkflows.enabled`&&t.includes(` — `)){let e=t.split(` — `,1)[0];if(r[e])return`${e} — ${r[e]}`}return e===`repository.reconciliationCleanup`&&t===`all`?{es:`Todas las ramas temporales`,fr:`Toutes les branches temporaires`,pt:`Todos os ramos temporários`}[n]:r[t]??t}function ja(e,t){return typeof e.defaultValue==`boolean`?Z(e.defaultValue?`yes`:`no`,t):e.defaultValue===void 0||e.defaultValue===``?Z(`none`,t):e.kind===`choice`||e.kind===`multi-select`?Aa(e.id,String(e.defaultValue),t):String(e.defaultValue)}var Ma={en:Sa,es:Ca,fr:wa,pt:Ta};function Na(e,t){if(e.managementState)return ta(t)[e.managementState];if(!e.copyId)return t===`en`?e.text:Z(`unknownLocalError`,t);let n=Ma[t][e.copyId],r=e.copyValues??{},i=e.copyId===`permission.preview`?{...r,issues:(r.issues??``).split(`|`).map(e=>Aa(`issueWorkflows.enabled`,e,t)).join(`, `),approval:Aa(`pullRequestApproval.mode`,r.approval??``,t),secrets:Aa(`storage.secrets.defaultScope`,r.secrets??``,t),variables:Aa(`storage.variables.defaultScope`,r.variables??``,t),projects:Aa(`projects.ids`,r.projects??``,t)}:r,a=n.replace(/\{([a-zA-Z]\w*)\}/gu,(e,t)=>i[t]??``);return e.copyId!==`credential.checks`||!e.credentialChecks?.length?a:`${a}\n${e.credentialChecks.map(e=>{let n=`credential.status.${e.status}`;return`${e.name}: ${Ma[t][n]}`}).join(` -`)}`}var Pa={en:va,es:ya,fr:ba,pt:xa};function Fa(e,t){return e.replace(/\{([a-zA-Z]\w*)\}/gu,(e,n)=>t[n]??``)}function Ia(e,t){if(!e.copyId)return;let n=Pa[t][e.copyId],r={...e.copyValues??{}};if(e.copyId===`credential.existing`&&r.status&&[`valid`,`invalid`,`missing`,`unverifiable`,`not_required`].includes(r.status)){let e=`credential.status.${r.status}`;r.status=Ma[t][e]}return{title:Fa(n.title,r),description:Fa(n.description,r),...n.choices?{choices:n.choices}:{}}}function La(e,t,n){return Ia(e,t)?.choices?.[n]??e.choices[n]}var Ra=H(`

      `,1);function za(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`view`,8);Tn(()=>(V(o()),n(),Ia),()=>{N(a,o()?.batch?Z(o().batch.phase===`review`?`batchReviewTitle`:o().batch.phase===`applying`?`batchProgressTitle`:`batchResultTitle`,n()):o()?.outcome===`complete`?Z(`completeTitle`,n()):o()?.outcome===`dry-run`?Z(`previewTitle`,n()):o()?.outcome===`cancelled`?Z(`cancelledTitle`,n()):o()?.outcome?Z(`blockedTitle`,n()):o()?.prompt?.kind===`repositories`?Z(`batchReviewSelection`,n()):o()?.prompt?.kind===`question`?Z(`choices`,n()):o()?.prompt?.kind===`plan`?Z(`plan`,n()):o()?.prompt?Ia(o().prompt,n())?.title??o().prompt.title:Z(`preparing`,n()))}),En(),ji();var s=Ra(),c=F(s),l=L(P(c)),u=I(L(l));D(c);var d=L(c,2),f=I(d,!0),p=I(L(d,2),!0);R((e,t,n)=>{W(l,` ${e??``} `),W(u,`${t??``} / 06`),W(f,z(a)),W(p,n)},[()=>(V(Zi),V(o()),n(),B(()=>Zi(o()?.journey?.current,n()).toUpperCase())),()=>(V(o()),B(()=>String(o()?.journey?.position??1).padStart(2,`0`))),()=>(V(o()),V(Z),n(),B(()=>o()?.outcome?Z(`resultLede`,n()):Z(`activeLede`,n())))]),U(e,s),k(),i()}var Ba={tutorial:`https://docs.page/vypdev/copilot/setup-web`,firstWorkflow:`https://docs.page/vypdev/copilot/first-workflow`,recovery:`https://docs.page/vypdev/copilot/security-operations/operations/troubleshooting`},Va=H(``);function Ha(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi();ji();var a=Va(),o=P(a),s=P(o),c=I(s),l=L(s,2),u=I(l),d=L(l,2),f=I(d);D(o);var p=I(L(o,2),!0);D(a),R((e,t,n,r,i)=>{J(a,`aria-label`,e),J(s,`href`,Ba.tutorial),W(c,`${t??``} ↗`),J(l,`href`,Ba.firstWorkflow),W(u,`${n??``} ↗`),J(d,`href`,Ba.recovery),W(f,`${r??``} ↗`),W(p,i)},[()=>Z(`setupHelp`,n()),()=>Z(`setupTutorial`,n()),()=>Z(`firstWorkflowGuide`,n()),()=>Z(`setupRecovery`,n()),()=>Z(`setupHelpHint`,n())]),U(e,a),k(),i()}function Ua(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&(t.pathname===`/settings/personal-access-tokens`||t.pathname.startsWith(`/settings/personal-access-tokens/`))?t.toString():void 0}catch{return}}function Wa(e){return e&&/^[A-Za-z0-9-]{1,39}\/(?!\.{1,2}$)[A-Za-z0-9._-]{1,100}$/u.test(e)?`https://github.com/${e}/settings/secrets/actions`:void 0}function Ga(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&!t.username&&!t.password&&!t.search&&!t.hash&&/^\/[A-Za-z0-9-]{1,39}\/[A-Za-z0-9._-]{1,100}\/actions\/runs\/[1-9][0-9]*$/u.test(t.pathname)?t.toString():void 0}catch{return}}function Ka(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&!t.username&&!t.password&&!t.search&&!t.hash&&/^\/[A-Za-z0-9-]{1,39}\/[A-Za-z0-9._-]{1,100}\/rules\/[1-9][0-9]*$/u.test(t.pathname)?t.toString():void 0}catch{return}}function qa(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&!t.username&&!t.password&&!t.search&&!t.hash&&/^\/(?:orgs|users)\/[A-Za-z0-9-]{1,39}\/projects\/[1-9][0-9]*$/u.test(t.pathname)?t.toString():void 0}catch{return}}var Ja=H(``),Ya=H(``);function Xa(e,t){let n=X(t,`label`,8),r=X(t,`variant`,8,`primary`),i=X(t,`disabled`,8,!1),a=X(t,`arrow`,8,!1),o=X(t,`onClick`,8);var s=Ya(),c=P(s,!0),l=L(c),u=e=>{U(e,Ja())};G(l,e=>{a()&&e(u)}),D(s),R(()=>{ui(s,1,si(r())),s.disabled=i(),W(c,n())}),wr(`click`,s,function(...e){o()?.apply(this,e)}),U(e,s)}Tr([`click`]);var Za=H(` `),Qa=H(`

      `);function $a(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`tone`,8,`info`),s=X(t,`title`,8),c=X(t,`message`,8),l=X(t,`link`,8,void 0),u=X(t,`actionLabel`,8,void 0),d=X(t,`onAction`,8,void 0);Tn(()=>V(l()),()=>{N(a,Ua(l()))}),En(),ji();var f=Qa(),p=P(f),m=I(p,!0),h=L(p),g=I(h,!0),_=L(h,2),v=e=>{var t=Za(),r=I(t,!0);R(e=>{J(t,`href`,z(a)),W(r,e)},[()=>(V(Z),n(),B(()=>Z(`githubLink`,n())))]),U(e,t)};G(_,e=>{z(a)&&e(v)});var y=L(_,2),b=e=>{Xa(e,{get label(){return u()},variant:`secondary`,get onClick(){return d()}})};G(y,e=>{u()&&d()&&e(b)}),D(f),R(()=>{ui(f,1,`banner ${o()??``}`),J(f,`role`,o()===`error`?`alert`:`status`),W(m,s()),W(g,c())}),U(e,f),k(),i()}var eo=H(`
    1. :
    2. `),to=H(`
        `),no=H(`
      • `),ro=H(`
      • `),io=H(`

        `),ao=H(`
            `),oo=H(`

            `);function so(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`question`,8);ji();var o=Pr(),s=F(o),c=e=>{var t=oo(),r=P(t),i=I(r,!0),o=L(r,2),s=P(o),c=L(s),l=e=>{var t=Nr();R(e=>W(t,`(${e??``})`),[()=>(V(Z),V(a()),n(),B(()=>Z(a().runnerRegistryScope===`repository`?`scopeRepository`:`scopeOrganization`,n())))]),U(e,t)};G(c,e=>{V(a()),B(()=>a().runnerRegistryScope)&&e(l)});var u=L(c);D(o);var d=L(o,2),f=e=>{var t=to(),r=P(t),i=I(r,!0),o=L(r,2);q(o,5,()=>(V(a()),B(()=>a().runnerProfiles)),K,(e,t)=>{var n=eo(),r=P(n),i=I(r,!0),a=I(L(r,2));D(n),R(e=>{W(i,(z(t),B(()=>z(t).id))),W(a,`${z(t),B(()=>z(t).group||`—`)??``} · ${e??``}`)},[()=>(z(t),B(()=>z(t).labels.join(`, `)))]),U(e,n)}),D(o),D(t),R(e=>W(i,e),[()=>(V($),n(),B(()=>$(`profiles`,n())))]),U(e,t)};G(d,e=>{V(a()),B(()=>a().runnerProfiles?.length)&&e(f)});var p=L(d,2),m=e=>{var t=ao(),r=P(t),i=I(r,!0),o=L(r,2);q(o,5,()=>(V(a()),B(()=>a().runnerInventory.groups)),K,(e,t)=>{var r=no(),i=P(r),a=I(i,!0),o=L(i);D(r),R(e=>{W(a,(z(t),B(()=>z(t).name))),W(o,`: ${e??``}`)},[()=>(V($),z(t),n(),B(()=>$(z(t).access,n())))]),U(e,r)}),D(o);var s=L(o,2);q(s,5,()=>(V(a()),B(()=>a().runnerInventory.candidates.slice(0,10))),K,(e,t)=>{var n=ro(),r=I(P(n),!0);D(n),R(e=>W(r,e),[()=>(z(t),B(()=>z(t).labels.join(`, `)))]),U(e,n)}),D(s);var c=L(s,2),l=e=>{var t=io(),r=I(t,!0);R(e=>W(r,e),[()=>(V($),n(),B(()=>$(`limited`,n())))]),U(e,t)};G(c,e=>{V(a()),B(()=>a().runnerInventory.candidates.length>10)&&e(l)}),D(t),R(e=>W(i,e),[()=>(V($),n(),B(()=>$(`observed`,n())))]),U(e,t)};G(p,e=>{V(a()),B(()=>a().runnerInventory)&&e(m)}),D(t),R((e,t,n,r,a)=>{W(i,e),W(s,`${t??``}: ${n??``}`),W(u,` · ${r??``}: ${a??``}`)},[()=>(V($),n(),B(()=>$(`help`,n()))),()=>(V($),n(),B(()=>$(`registry`,n()))),()=>(V($),V(a()),n(),B(()=>$(a().runnerRegistryStatus??`unavailable`,n()))),()=>(V($),n(),B(()=>$(`inventory`,n()))),()=>(V($),V(a()),n(),B(()=>$(a().runnerInventory?.status??`unavailable`,n())))]),U(e,t)},l=gt(()=>(V(a()),B(()=>a().id.startsWith(`runners.`)&&a().id!==`runners.discover`)));G(s,e=>{z(l)&&e(c)}),U(e,o),k(),i()}function co(e){let t=String(e.question.defaultValue),n=t.split(`,`).map(e=>e.trim()).filter(Boolean),r=e.question.kind===`multi-select`?n.includes(`All`)&&e.question.choices?.includes(`All`)?[`All`]:(e.question.choices??[]).filter(e=>e!==`All`&&n.includes(e.split(` — `)[0])):e.question.kind===`scope-overrides`?n:e.question.kind===`producer-select`?t.split(`;`).map(e=>e.trim()).filter(Boolean):e.question.kind===`project-select`?n.filter(t=>e.question.projectCandidates?.some(e=>String(e.number)===t)):[],i=e.question.kind===`project-select`?n.filter(e=>!r.includes(e)).join(`,`):t;return{value:e.question.kind===`producer-select`?``:i,selected:r}}function lo(e,t){return t===`All`?e.includes(`All`)?[]:[`All`]:e.includes(t)?e.filter(e=>e!==t):[...e.filter(e=>e!==`All`),t]}function uo(e,t,n){return e.question.kind===`scope-overrides`||e.question.kind===`multi-select`?n.length?n.join(`,`):`none`:e.question.kind===`producer-select`?[...n,...t.split(`;`).map(e=>e.trim()).filter(Boolean)].join(`;`):e.question.kind===`project-select`?[...n,...t.split(`,`).map(e=>e.trim()).filter(Boolean)].join(`,`)||`none`:t}var fo={issueCreated:`projectTransitionIssueCreated`,pullRequestCreated:`projectTransitionPullRequestCreated`,issueInProgress:`projectTransitionIssueInProgress`,pullRequestInProgress:`projectTransitionPullRequestInProgress`};function po(e){if(e)try{let t=new URL(e);if(t.protocol!==`https:`||t.username||t.password||t.search)return;if(t.hostname===`docs.page`&&t.port===``&&t.pathname.startsWith(`/vypdev/copilot/`)||t.hostname===`docs.github.com`&&t.port===``&&t.pathname.startsWith(`/en/`))return t.href}catch{return}}var mo=H(`

            `),ho=H(`

            `),go=H(` `,1);function _o(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`kind`,8),s=X(t,`status`,8),c=X(t,`truncated`,8,!1),l={observed:`checksObserved`,"no-recent-runs":`checksNoRecent`,"no-verifiable-checks":`checksNoVerifiable`,"permission-denied":`checksDenied`,unavailable:`checksUnavailable`},u={observed:`projectsObserved`,empty:`projectsEmpty`,"permission-denied":`projectsDenied`,unavailable:`projectsUnavailable`,unsupported:`projectsUnsupported`};Tn(()=>(V(s()),V(o())),()=>{N(a,s()?o()===`checks`?l[s()]:u[s()]:void 0)}),En(),ji();var d=go(),f=F(d),p=e=>{var t=mo(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),z(a),n(),B(()=>Z(z(a),n())))]),U(e,t)};G(f,e=>{z(a)&&e(p)});var m=L(f,2),h=e=>{var t=ho(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),V(o()),n(),B(()=>Z(o()===`checks`?`checksDiscoveryScope`:`projectsDiscoveryScope`,n())))]),U(e,t)};G(m,e=>{(s()===`observed`||s()===`empty`||s()===`no-recent-runs`||s()===`no-verifiable-checks`)&&e(h)});var g=L(m,2),_=e=>{var t=ho(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`discoveryTruncated`,n())))]),U(e,t)};G(g,e=>{c()&&e(_)}),U(e,d),k(),i()}var vo={en:{success:`Passed`,failure:`Failed`,cancelled:`Cancelled`,neutral:`Neutral`,skipped:`Skipped`,timed_out:`Timed out`,action_required:`Action required`,stale:`Stale`,startup_failure:`Failed to start`,unknown:`Unknown outcome`},es:{success:`Correcto`,failure:`Falló`,cancelled:`Cancelado`,neutral:`Neutral`,skipped:`Omitido`,timed_out:`Agotó el tiempo`,action_required:`Requiere intervención`,stale:`Obsoleto`,startup_failure:`Falló al iniciar`,unknown:`Resultado desconocido`},fr:{success:`Réussi`,failure:`Échoué`,cancelled:`Annulé`,neutral:`Neutre`,skipped:`Ignoré`,timed_out:`Délai dépassé`,action_required:`Action nécessaire`,stale:`Obsolète`,startup_failure:`Échec au démarrage`,unknown:`Résultat inconnu`},pt:{success:`Concluído`,failure:`Falhou`,cancelled:`Cancelado`,neutral:`Neutro`,skipped:`Ignorado`,timed_out:`Tempo esgotado`,action_required:`Ação necessária`,stale:`Obsoleto`,startup_failure:`Falha ao iniciar`,unknown:`Resultado desconhecido`}};function yo(e,t){return vo[t][e]??vo[t].unknown}function bo(e,t,n){let r=e.trim(),i=n.trim(),a=String(t??``).trim(),o=Number(a);if(!(!r||!i||r.length>100||i.length>100||/[|;\r\n]/u.test(r+i)||!/^[1-9]\d*$/u.test(a)||!Number.isSafeInteger(o)))return`${r}|${o}|${i}`}var xo=H(` `),So=H(`
            `),Co=H(`
          • `),wo=H(`
              `),To=H(``),Eo=H(`

              `,1);function Do(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=M(),s=X(t,`candidates`,8),c=X(t,`selected`,12),l=X(t,`controller`,8),u=M(``),d=M(``),f=M(``),p=M(!1);function m(){let e=bo(z(u),z(d),z(f));if(!e||c().length>=8){N(p,!0);return}N(p,!1),c().includes(e)||c([...c(),e]),N(u,``),N(d,``),N(f,``)}Tn(()=>V(s()),()=>{N(a,new Set(s().map(e=>`${e.name}|${e.sourceAppId}|${e.workflowName}`)))}),Tn(()=>(V(c()),z(a)),()=>{N(o,c().filter(e=>!z(a).has(e)))}),En(),ji();var h=Eo(),g=F(h);q(g,5,s,K,(e,t)=>{let r=A(()=>(z(t),B(()=>`${z(t).name}|${z(t).sourceAppId}|${z(t).workflowName}`)));var i=So(),a=P(i),o=P(a);xi(o);var s=L(o,2),u=P(s),d=I(P(u),!0);D(u);var f=L(u),p=I(P(f));D(f);var m=I(L(f),!0);D(s),D(a);var h=L(a,2),g=P(h),_=e=>{var r=xo(),i=I(r,!0);R((e,t)=>{J(r,`href`,e),W(i,t)},[()=>(V(Ga),z(t),B(()=>Ga(z(t).runUrl))),()=>(V(Z),n(),B(()=>Z(`ciRun`,n())))]),U(e,r)},v=gt(()=>(V(Ga),z(t),B(()=>Ga(z(t).runUrl))));G(g,e=>{z(v)&&e(_)});var y=L(g,2),b=e=>{var r=xo(),i=I(r,!0);R((e,t)=>{J(r,`href`,e),W(i,t)},[()=>(V(Ka),z(t),B(()=>Ka(z(t).requiredByRuleset?.sourceUrl))),()=>(V(Z),n(),B(()=>Z(`ciRule`,n())))]),U(e,r)},x=gt(()=>(V(Ka),z(t),B(()=>Ka(z(t).requiredByRuleset?.sourceUrl))));G(y,e=>{z(x)&&e(b)}),D(h),D(i),R((e,n,r,i,a,s)=>{Si(o,e),o.disabled=n,W(d,(z(t),B(()=>z(t).name))),W(p,`${z(t),B(()=>z(t).workflowName)??``} · ${z(t),B(()=>z(t).sourceAppName??`GitHub App`)??``} ${z(t),B(()=>z(t).sourceAppId)??``} · ${r??``} · ${i??``} · ${a??``}`),W(m,s)},[()=>(V(c()),V(z(r)),B(()=>c().includes(z(r)))),()=>(V(l()),V(c()),V(z(r)),B(()=>!l()||c().length>=8&&!c().includes(z(r)))),()=>(V(yo),z(t),n(),B(()=>yo(z(t).conclusion,n()))),()=>(z(t),B(()=>z(t).headSha.slice(0,7))),()=>(z(t),V(Z),n(),B(()=>z(t).observedAt??Z(`observationTimeUnknown`,n()))),()=>(z(t),V(Z),n(),B(()=>z(t).requiredByRuleset?Z(`branchRequirementObserved`,n(),{branch:z(t).requiredByRuleset.branch}):Z(`branchRequirementUnknown`,n())))]),wr(`change`,o,()=>c(lo(c(),z(r)))),U(e,i)}),D(g);var _=L(g,2),v=e=>{var t=wo();q(t,5,()=>z(o),K,(e,t)=>{var r=Co(),i=P(r),a=I(i,!0),o=L(i,2),s=I(o,!0);D(r),R(e=>{W(a,z(t)),o.disabled=!l(),W(s,e)},[()=>(V(Z),n(),B(()=>Z(`producerRemove`,n())))]),wr(`click`,o,()=>c(lo(c(),z(t)))),U(e,r)}),D(t),U(e,t)};G(_,e=>{z(o),B(()=>z(o).length)&&e(v)});var y=L(_,2),b=I(y,!0),x=L(y,2),S=P(x),C=P(S,!0),w=L(C);xi(w),D(S);var ee=L(S,2),te=P(ee,!0),ne=L(te);xi(ne),D(ee);var re=L(ee,2),ie=P(re,!0),ae=L(ie);xi(ae),D(re),D(x);var oe=L(x,2),se=I(oe,!0),ce=L(oe,2),le=e=>{var t=To(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`producerManualInvalid`,n())))]),U(e,t)};G(ce,e=>{z(p)&&e(le)}),R((e,t,n,r,i,a)=>{J(g,`aria-label`,e),W(b,t),W(C,n),w.disabled=!l(),W(te,r),ne.disabled=!l(),W(ie,i),ae.disabled=!l(),oe.disabled=!l(),W(se,a)},[()=>(V(Z),n(),B(()=>Z(`checksObserved`,n()))),()=>(V(Z),n(),B(()=>Z(`producerManualHelp`,n()))),()=>(V(Z),n(),B(()=>Z(`producerName`,n()))),()=>(V(Z),n(),B(()=>Z(`producerAppId`,n()))),()=>(V(Z),n(),B(()=>Z(`producerWorkflow`,n()))),()=>(V(Z),n(),B(()=>Z(`producerAdd`,n())))]),Ei(w,()=>z(u),e=>N(u,e)),Ei(ne,()=>z(d),e=>N(d,e)),Ei(ae,()=>z(f),e=>N(f,e)),wr(`click`,oe,m),U(e,h),k(),i()}Tr([`change`,`click`]);var Oo=H(` `),ko=H(`
              `),Ao=H(`
            • `),jo=H(`

                `,1),Mo=H(`
                `,1);function No(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=M(),s=X(t,`candidates`,8),c=X(t,`selected`,12),l=X(t,`value`,12),u=X(t,`controller`,8);Tn(()=>V(s()),()=>{N(a,new Set(s().map(e=>String(e.number))))}),Tn(()=>(V(c()),z(a)),()=>{N(o,c().filter(e=>!z(a).has(e)))}),En(),ji();var d=Mo(),f=F(d);q(f,5,s,K,(e,t)=>{var r=ko(),i=P(r),a=P(i);xi(a);var o=L(a,2),s=P(o),l=I(P(s),!0);D(s);var d=L(s),f=I(P(d));D(d),D(o),D(i);var p=L(i,2),m=e=>{var r=Oo(),i=I(r,!0);R((e,t)=>{J(r,`href`,e),W(i,t)},[()=>(V(qa),z(t),B(()=>qa(z(t).url))),()=>(V(Z),n(),B(()=>Z(`projectUrl`,n())))]),U(e,r)},h=gt(()=>(V(qa),z(t),B(()=>qa(z(t).url))));G(p,e=>{z(h)&&e(m)}),D(r),R((e,n)=>{Si(a,e),a.disabled=n,W(l,(z(t),B(()=>z(t).title))),W(f,`${z(t),B(()=>z(t).owner)??``} · #${z(t),B(()=>z(t).number)??``}`)},[()=>(V(c()),z(t),B(()=>c().includes(String(z(t).number)))),()=>(V(u()),V(c()),z(t),B(()=>!u()||c().length>=10&&!c().includes(String(z(t).number))))]),wr(`change`,a,()=>c(lo(c(),String(z(t).number)))),U(e,r)}),D(f);var p=L(f,2),m=e=>{var t=jo(),r=F(t),i=I(r,!0),a=L(r,2);q(a,5,()=>z(o),K,(e,t)=>{var r=Ao(),i=P(r),a=I(i),o=L(i,2),s=I(o,!0);D(r),R(e=>{W(a,`#${z(t)??``}`),o.disabled=!u(),W(s,e)},[()=>(V(Z),n(),B(()=>Z(`removeSelection`,n())))]),wr(`click`,o,()=>c(lo(c(),z(t)))),U(e,r)}),D(a),R(e=>W(i,e),[()=>(V(Z),n(),B(()=>Z(`projectSelectionNotObserved`,n())))]),U(e,t)};G(p,e=>{z(o),B(()=>z(o).length)&&e(m)});var h=L(p,2),g=P(h),_=I(g,!0),v=L(g,2);xi(v),D(h),R((e,t)=>{J(f,`aria-label`,e),W(_,t),v.disabled=!u()},[()=>(V(Z),n(),B(()=>Z(`projectsObserved`,n()))),()=>(V(Z),n(),B(()=>Z(`projectManual`,n())))]),Ei(v,l),U(e,d),k(),i()}Tr([`change`,`click`]);var Po=H(``),Fo=H(`
                `),Io=H(` `,1);function Lo(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`explanation`,8),o=X(t,`helpUrl`,8);ji();var s=Io(),c=F(s),l=e=>{var t=Po(),r=P(t),i=I(r);D(t),R(e=>{J(r,`href`,o()),W(i,`${e??``} ↗`)},[()=>(V(Z),n(),B(()=>Z(`learnMore`,n())))]),U(e,t)};G(c,e=>{o()&&e(l)});var u=L(c,2),d=e=>{var t=Fo(),r=P(t),i=I(r,!0),o=L(r),s=P(o),c=I(s,!0),l=L(s),u=I(l,!0),d=L(l,2),f=I(d,!0),p=L(d),m=I(p,!0),h=L(p,2),g=I(h,!0),_=L(h),v=I(_,!0),y=L(_,2),b=I(y,!0),x=L(y),S=I(x,!0),C=L(x,2),w=I(C,!0),ee=L(C),te=I(ee,!0),ne=L(ee,2),re=I(ne,!0),ie=L(ne),ae=I(ie,!0),oe=L(ie,2),se=I(oe,!0),ce=I(L(oe),!0);D(o),D(t),R((e,t,n,r,o,s,l,d)=>{W(i,e),W(c,t),W(u,(V(a()),B(()=>a().when))),W(f,n),W(m,(V(a()),B(()=>a().where))),W(g,r),W(v,(V(a()),B(()=>a().how))),W(b,o),W(S,(V(a()),B(()=>a().why))),W(w,s),W(te,(V(a()),B(()=>a().example))),W(re,l),W(ae,(V(a()),B(()=>a().effect))),W(se,d),W(ce,(V(a()),B(()=>a().verify)))},[()=>(V(Z),n(),B(()=>Z(`whyMatters`,n()))),()=>(V(Z),n(),B(()=>Z(`whenApplies`,n()))),()=>(V(Z),n(),B(()=>Z(`whereConfigured`,n()))),()=>(V(Z),n(),B(()=>Z(`howToChoose`,n()))),()=>(V(Z),n(),B(()=>Z(`whyRecommendation`,n()))),()=>(V(Z),n(),B(()=>Z(`example`,n()))),()=>(V(Z),n(),B(()=>Z(`effect`,n()))),()=>(V(Z),n(),B(()=>Z(`verify`,n())))]),U(e,t)};G(u,e=>{a()&&e(d)}),U(e,s),k(),i()}var Ro=H(`· `,1),zo=H(`

                `,1);function Bo(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`candidate`,8);ji();var o=zo(),s=F(o),c=P(s),l=I(c),u=L(c,2),d=e=>{var t=Ro(),r=L(F(t)),i=I(r,!0);R((e,t)=>{J(r,`href`,e),W(i,t)},[()=>(V(Ga),V(a()),B(()=>Ga(a().runUrl))),()=>(V(Z),n(),B(()=>Z(`ciRun`,n())))]),U(e,t)},f=gt(()=>(V(Ga),V(a()),B(()=>Ga(a().runUrl))));G(u,e=>{z(f)&&e(d)}),D(s);var p=L(s,2),m=P(p),h=I(m),g=L(m),_=L(g),v=e=>{var t=Ro(),r=L(F(t)),i=I(r,!0);R((e,t)=>{J(r,`href`,e),W(i,t)},[()=>(V(Ka),V(a()),B(()=>Ka(a().requiredByRuleset?.sourceUrl))),()=>(V(Z),n(),B(()=>Z(`ciRule`,n())))]),U(e,t)},y=gt(()=>(V(Ka),V(a()),B(()=>Ka(a().requiredByRuleset?.sourceUrl))));G(_,e=>{z(y)&&e(v)}),D(p),R((e,t,n,r)=>{W(l,`${V(a()),B(()=>a().workflowName)??``} · GitHub App ${V(a()),B(()=>a().sourceAppId)??``}`),W(h,`${e??``} · ${t??``} · ${n??``}`),W(g,` · ${r??``} `)},[()=>(V(yo),V(a()),n(),B(()=>yo(a().conclusion,n()))),()=>(V(a()),B(()=>a().headSha.slice(0,7))),()=>(V(a()),V(Z),n(),B(()=>a().observedAt??Z(`observationTimeUnknown`,n()))),()=>(V(a()),V(Z),n(),B(()=>a().requiredByRuleset?Z(`branchRequirementObserved`,n(),{branch:a().requiredByRuleset.branch}):Z(`branchRequirementUnknown`,n())))]),U(e,o),k(),i()}var Vo=H(`

                `);function Ho(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`question`,8);ji();var o=Pr(),s=F(o),c=e=>{var t=Vo(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`fixedIssuesRequired`,n())))]),U(e,t)},l=e=>{var t=Pr();q(F(t),1,()=>(V(a()),B(()=>Object.entries(a().fixedWorkflowFeatures).filter(([,e])=>e!==void 0))),K,(e,t)=>{var r=gt(()=>b(z(t),2));let i=()=>z(r)[0],a=()=>z(r)[1];var o=Vo(),s=I(o,!0);R(e=>W(s,e),[()=>(V(Z),a(),n(),i(),B(()=>Z(a()?`fixedWorkflowEnabled`:`fixedWorkflowDisabled`,n(),{kind:i()})))]),U(e,o)}),U(e,t)};G(s,e=>{V(a()),B(()=>a().id===`features.issues`&&(a().fixedWorkflowFeatures?.release||a().fixedWorkflowFeatures?.hotfix))?e(c):(V(a()),B(()=>a().fixedWorkflowFeatures)&&e(l,1))}),U(e,o),k(),i()}var Uo=H(` `),Wo=H(`

                `),Go=H(`

                `),Ko=H(` `,1),qo=H(`

                `),Jo=H(`
                `),Yo=H(`

                `),Xo=H(``),Zo=H(`
              • `),Qo=H(`
                  `),$o=H(`
                  `),es=H(``),ts=H(``),ns=H(` `,1),rs=H(``),is=H(`
                  `),as=H(``),os=H(``),ss=H(`

                  `,1);function cs(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=M(),s=M(),c=X(t,`prompt`,8),l=X(t,`controller`,8),u=X(t,`busy`,8),d=X(t,`onSubmit`,8),f=X(t,`onRetryDiscovery`,8),p=X(t,`onBack`,8),m=co(c()),h=M(m.value),g=M(m.selected);Tn(()=>(V(c()),n()),()=>{N(a,c().presentation?.[n()])}),Tn(()=>z(a),()=>{N(o,po(z(a)?.documentation?.url))}),Tn(()=>(V(c()),n()),()=>{N(s,ja(c().question,n()))}),En(),ji();var _=ss(),v=F(_),y=P(v),b=I(y,!0),x=L(y),S=e=>{var t=Uo(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`permissionPreview`,n())))]),U(e,t)};G(x,e=>{V(c()),B(()=>c().phase===`permission-intent`)&&e(S)}),D(v);var C=L(v,2),w=e=>{var t=Wo(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),V(c()),B(()=>Z(`questionProgress`,n(),{current:String(c().progress.groupPosition),total:String(c().progress.groupTotal),overall:String(c().progress.position),all:String(c().progress.total)})))]),U(e,t)};G(C,e=>{V(c()),B(()=>c().progress)&&e(w)});var ee=L(C,2),te=e=>{var t=Go(),n=I(t,!0);R(()=>W(n,(z(a),B(()=>z(a).summary)))),U(e,t)};G(ee,e=>{z(a)&&e(te)});var ne=L(ee,2),re=e=>{_o(e,{kind:`checks`,get status(){return V(c()),B(()=>c().question.discoveryStatus)},get truncated(){return V(c()),B(()=>c().question.discoveryTruncated)}})};G(ne,e=>{V(c()),B(()=>c().question.id===`pullRequestApproval.testChecks`)&&e(re)});var ie=L(ne,2),ae=e=>{_o(e,{kind:`projects`,get status(){return V(c()),B(()=>c().question.discoveryStatus)},get truncated(){return V(c()),B(()=>c().question.discoveryTruncated)}})};G(ie,e=>{V(c()),B(()=>c().question.id===`projects.ids`)&&e(ae)});var oe=L(ie,2),se=e=>{var t=Jo(),r=P(t),i=e=>{var t=Ko(),r=F(t),i=I(r,!0),a=I(L(r,2),!0);R((e,t)=>{r.disabled=!l()||u(),W(i,e),W(a,t)},[()=>(V(Z),n(),B(()=>Z(`retryDiscovery`,n()))),()=>(V(Z),n(),V(c()),B(()=>Z(`retryRemaining`,n(),{count:String(c().question.discoveryRetryRemaining)})))]),wr(`click`,r,function(...e){f()?.apply(this,e)}),U(e,t)},a=e=>{var t=qo(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`retryExhausted`,n())))]),U(e,t)};G(r,e=>{V(c()),B(()=>c().question.discoveryRetryRemaining>0)?e(i):e(a,-1)}),D(t),U(e,t)};G(oe,e=>{V(c()),B(()=>c().question.discoveryRetryRemaining!==void 0)&&e(se)});var ce=L(oe,2),le=e=>{var t=Yo(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`projectStatusUnavailable`,n())))]),U(e,t)};G(ce,e=>{V(c()),B(()=>c().question.statusOptionState===`unavailable`)&&e(le)});var ue=L(ce,2),de=e=>{var t=Xo(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`projectStatusIncompatible`,n())))]),U(e,t)};G(ue,e=>{V(c()),B(()=>c().question.statusOptionState===`incompatible`)&&e(de)});var fe=L(ue,2),pe=e=>{var t=qo(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`projectSharedStatus`,n())))]),U(e,t)};G(fe,e=>{V(c()),B(()=>c().question.id===`projects.ids`)&&e(pe)});var me=L(fe,2);Ho(me,{get question(){return V(c()),B(()=>c().question)}});var he=L(me,2),ge=e=>{var t=Qo();q(t,5,()=>(V(c()),B(()=>c().question.projectStatusValues)),K,(e,t)=>{var r=Zo(),i=P(r),a=L(i),o=I(P(a),!0);D(a),D(r),R(e=>{W(i,`${e??``}: `),W(o,(z(t),B(()=>z(t).value)))},[()=>(V(Z),V(fo),z(t),n(),B(()=>Z(fo[z(t).transition],n())))]),U(e,r)}),D(t),U(e,t)};G(he,e=>{V(c()),B(()=>c().question.projectStatusValues)&&e(ge)});var _e=L(he,2),ve=e=>{var t=$o(),r=P(t);let i;var o=I(r,!0),s=L(r);let u;var d=I(s,!0);D(t),R((e,n)=>{J(t,`aria-label`,(z(a),V(c()),B(()=>z(a)?.label??c().question.label))),J(r,`aria-pressed`,z(h)===`yes`||z(h)===`true`),r.disabled=!l(),i=ui(r,1,``,null,i,{selected:z(h)===`yes`||z(h)===`true`}),W(o,e),J(s,`aria-pressed`,z(h)===`no`||z(h)===`false`),s.disabled=!l(),u=ui(s,1,``,null,u,{selected:z(h)===`no`||z(h)===`false`}),W(d,n)},[()=>(V(Z),n(),B(()=>Z(`yes`,n()))),()=>(V(Z),n(),B(()=>Z(`no`,n())))]),wr(`click`,r,()=>N(h,`yes`)),wr(`click`,s,()=>N(h,`no`)),U(e,t)},ye=e=>{var t=ns(),r=F(t),i=P(r),o=e=>{var t=es(),r=I(t,!0);t.value=t.__value=``,R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`selectOne`,n())))]),U(e,t)};G(i,e=>{V(c()),B(()=>!c().question.defaultValue)&&e(o)}),q(L(i),1,()=>(V(c()),B(()=>c().question.choices??[])),K,(e,t)=>{let r=A(()=>(V(c()),z(t),B(()=>c().question.id===`pullRequestApproval.coverage.checkName`?c().question.trustedProducers?.find(e=>e.name===z(t)):void 0)));var i=ts(),a=I(i,!0),o={};R(e=>{W(a,e),o!==(o=z(t))&&(i.value=(i.__value=o)??``)},[()=>(V(z(r)),z(t),V(Aa),V(c()),n(),B(()=>z(r)?`${z(t)} — ${z(r).workflowName} · App ${z(r).sourceAppId}`:Aa(c().question.id,z(t),n())))]),U(e,i)}),D(r),mi(r);var s=L(r,2),u=e=>{var t=Pr();q(F(t),1,()=>(V(c()),z(h),B(()=>(c().question.producerCandidates??[]).filter(e=>e.name===z(h)))),K,(e,t)=>{Bo(e,{get candidate(){return z(t)}})}),U(e,t)};G(s,e=>{V(c()),B(()=>c().question.id===`pullRequestApproval.coverage.checkName`)&&e(u)}),R(()=>{J(r,`aria-label`,(z(a),V(c()),B(()=>z(a)?.label??c().question.label))),r.disabled=!l()}),hi(r,()=>z(h),e=>N(h,e)),U(e,t)},be=e=>{{let t=A(()=>(V(c()),B(()=>c().question.producerCandidates??[])));Do(e,{get candidates(){return z(t)},get controller(){return l()},get selected(){return z(g)},set selected(e){N(g,e)},$$legacy:!0})}},xe=e=>{{let t=A(()=>(V(c()),B(()=>c().question.projectCandidates??[])));No(e,{get candidates(){return z(t)},get controller(){return l()},get selected(){return z(g)},set selected(e){N(g,e)},get value(){return z(h)},set value(e){N(h,e)},$$legacy:!0})}},Se=e=>{var t=is();q(t,5,()=>(V(c()),B(()=>c().question.kind===`multi-select`?c().question.choices??[]:c().question.allowedNames??[])),K,(e,t)=>{var r=rs(),i=P(r);xi(i);var a=I(L(i),!0);D(r),R((e,t)=>{Si(i,e),i.disabled=!l(),W(a,t)},[()=>(z(g),z(t),B(()=>z(g).includes(z(t)))),()=>(V(c()),V(Aa),z(t),n(),B(()=>c().question.kind===`multi-select`?Aa(c().question.id,z(t),n()):z(t)))]),wr(`change`,i,()=>N(g,lo(z(g),z(t)))),U(e,r)}),D(t),R(()=>J(t,`aria-label`,(z(a),V(c()),B(()=>z(a)?.label??c().question.label)))),U(e,t)},Ce=e=>{var t=Pr(),n=F(t),r=e=>{var t=as();it(t),R(()=>{J(t,`aria-label`,(z(a),V(c()),B(()=>z(a)?.label??c().question.label))),t.disabled=!l()}),Ei(t,()=>z(h),e=>N(h,e)),U(e,t)},i=e=>{var t=os();xi(t),R(()=>{J(t,`aria-label`,(z(a),V(c()),B(()=>z(a)?.label??c().question.label))),J(t,`type`,(V(c()),B(()=>c().question.kind===`number`?`number`:`text`))),J(t,`min`,(V(c()),B(()=>c().question.kind===`number`?0:void 0))),t.disabled=!l()}),Ei(t,()=>z(h),e=>N(h,e)),U(e,t)};G(n,e=>{V(c()),B(()=>c().question.id===`ai.bugbotOrganizationRules`)?e(r):e(i,-1)}),U(e,t)};G(_e,e=>{V(c()),B(()=>c().question.kind===`boolean`)?e(ve):(V(c()),B(()=>c().question.kind===`choice`)?e(ye,1):(V(c()),B(()=>c().question.kind===`producer-select`)?e(be,2):(V(c()),B(()=>c().question.kind===`project-select`)?e(xe,3):(V(c()),B(()=>c().question.kind===`multi-select`||c().question.kind===`scope-overrides`)?e(Se,4):e(Ce,-1)))))});var we=L(_e,2),T=I(we,!0),Te=L(we,2),E=e=>{var t=Wo(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),V(c()),n(),B(()=>Z(c().question.suggestionSource===`github`?`sourceGithub`:c().question.suggestionSource===`local`?`sourceLocal`:c().question.suggestionSource===`configuration`?`sourceConfig`:`sourceDefault`,n())))]),U(e,t)};G(Te,e=>{V(c()),B(()=>c().question.suggestionSource)&&e(E)});var Ee=L(Te,2);so(Ee,{get question(){return V(c()),B(()=>c().question)}});var De=L(Ee,2);Lo(De,{get explanation(){return z(a)},get helpUrl(){return z(o)}});var Oe=L(De,2),ke=P(Oe),Ae=e=>{{let t=A(()=>(V(Z),n(),B(()=>Z(`previousQuestion`,n())))),r=A(()=>!l()||u());Xa(e,{get label(){return z(t)},variant:`secondary`,get onClick(){return p()},get disabled(){return z(r)}})}};G(ke,e=>{V(c()),B(()=>c().canGoBack)&&e(Ae)});var je=L(ke,2);{let e=A(()=>(V(Z),n(),B(()=>Z(`continue`,n())))),t=A(()=>!l()||u());Xa(je,{get label(){return z(e)},arrow:!0,onClick:()=>d()(uo(c(),z(h),z(g))),get disabled(){return z(t)}})}D(Oe),R((e,t)=>{W(b,e),W(T,t)},[()=>(z(a),V(c()),B(()=>z(a)?.label??c().question.label.replace(` (Space toggles, Enter confirms)`,``))),()=>(V(Z),n(),z(s),B(()=>Z(`suggested`,n(),{answer:z(s)})))]),U(e,_),k(),i()}Tr([`click`,`change`]);var ls=H(` `),us=H(``),ds=H(`
                  `,1);function fs(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`prompt`,8),s=X(t,`controller`,8),c=X(t,`busy`,8),l=X(t,`onSubmit`,8);Tn(()=>(V(o()),Wa),()=>{N(a,o().copyId===`botPat.scopeConflict`||o().copyId===`botPat.scopeConflictUnavailable`?Wa(o().copyValues?.repository):void 0)}),En(),ji();var u=ds(),d=F(u),f=e=>{var t=ls(),r=P(t);Oe(),D(t),R(e=>{J(t,`href`,z(a)),W(r,`${e??``} `)},[()=>(V(Z),n(),B(()=>Z(`repositorySecretSettings`,n())))]),U(e,t)};G(d,e=>{z(a)&&e(f)});var p=L(d,2);q(p,5,()=>(V(o()),B(()=>o().choices)),K,(e,t,r)=>{var i=us(),a=I(P(i),!0);Oe(),D(i),R(e=>{i.disabled=!s()||c(),W(a,e)},[()=>(V(La),V(o()),n(),B(()=>La(o(),n(),r)))]),wr(`click`,i,()=>l()(z(t))),U(e,i)}),D(p),U(e,u),k(),i()}Tr([`click`]);var ps=H(`

                  `),ms=H(`

                  `,1),hs=H(``);function gs(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`storage`,8);ji();var o=hs(),s=P(o),c=I(s,!0),l=L(s,2),u=I(l,!0),d=L(l,2),f=e=>{var t=ms(),r=F(t),i=I(r,!0),o=L(r,2),s=e=>{var t=ps(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`patOrganizationImpact`,n())))]),U(e,t)};G(o,e=>{V(a()),B(()=>a().scope===`organization`&&a().replacesExisting)&&e(s)}),R(e=>W(i,e),[()=>(V(Z),n(),B(()=>Z(`patReplacementChecks`,n())))]),U(e,t)};G(d,e=>{V(a()),B(()=>a().operation!==`retain`)&&e(f)}),D(o),R((e,t)=>{W(c,e),W(u,t)},[()=>(V(Z),n(),B(()=>Z(`patStorageTitle`,n()))),()=>(V(Z),V(a()),n(),B(()=>Z(a().operation===`retain`?`patStorageRetain`:a().replacesExisting?a().scope===`repository`?`patRepositoryReplace`:`patOrganizationReplace`:a().scope===`repository`?`patRepositoryCreate`:`patOrganizationCreate`,n(),{destination:a().destination})))]),U(e,o),k(),i()}var _s=H(``),vs=H(`

                  `,1),ys=H(`

                  `),bs=H(`
                  `,1);function xs(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=M(),s=M(),c=M(),l=X(t,`prompt`,8),u=X(t,`controller`,8),d=X(t,`busy`,8),f=X(t,`onSubmit`,8),p=M(``);function m(){let e=z(p);l().kind===`secret`&&N(p,``),f()(e)}Tn(()=>V(l()),()=>{N(a,Ua(l().link))}),Tn(()=>V(l()),()=>{N(o,l().copyId===`botPat.entry.guided`?l().copyValues?.account:void 0)}),Tn(()=>V(l()),()=>{N(s,l().copyId===`botPat.entry.guided`||l().copyId===`botPat.entry.manual`)}),Tn(()=>(z(s),V(l())),()=>{N(c,z(s)?l().copyValues?.storageScope:void 0)}),En(),ji();var h=bs(),g=F(h),_=e=>{var t=vs(),r=F(t),i=e=>{var t=_s(),r=P(t),i=I(r,!0),a=I(L(r,2),!0);D(t),R((e,t)=>{W(i,e),W(a,t)},[()=>(V(Z),n(),z(o),B(()=>Z(`botAccountWarning`,n(),{account:z(o)}))),()=>(V(Z),n(),B(()=>Z(`botAccountHelp`,n())))]),U(e,t)};G(r,e=>{z(o)&&e(i)});var s=L(r,2),c=P(s);Oe(),D(s);var l=I(L(s,2),!0);R((e,t)=>{J(s,`href`,z(a)),J(s,`aria-describedby`,z(o)?`bot-account-warning`:void 0),W(c,`${e??``} `),W(l,t)},[()=>(z(o),V(Z),n(),B(()=>z(o)?Z(`botGithubForm`,n(),{account:z(o)}):Z(`githubForm`,n()))),()=>(V(Z),n(),B(()=>Z(`githubFormHelp`,n())))]),U(e,t)};G(g,e=>{z(a)&&e(_)});var v=L(g,2),y=e=>{{let t=A(()=>(z(c),V(l()),B(()=>({scope:z(c),destination:l().copyValues.storageDestination,replacesExisting:l().copyValues.storageReplacesExisting===`true`}))));gs(e,{get storage(){return z(t)}})}};G(v,e=>{z(c),V(l()),B(()=>(z(c)===`repository`||z(c)===`organization`)&&l().copyValues?.storageDestination)&&e(y)});var b=L(v,2),x=I(b,!0),S=L(b,2);xi(S);var C=L(S,2),w=e=>{var t=ys(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`secretHelp`,n())))]),U(e,t)};G(C,e=>{V(l()),B(()=>l().kind===`secret`)&&e(w)});var ee=L(C,2),te=P(ee);{let e=A(()=>(V(Z),n(),B(()=>Z(`continue`,n())))),t=A(()=>(V(u()),V(d()),V(l()),z(p),B(()=>!u()||d()||!l().optional&&!z(p).trim())));Xa(te,{get label(){return z(e)},arrow:!0,onClick:m,get disabled(){return z(t)}})}D(ee),R((e,t)=>{W(x,e),J(S,`type`,(V(l()),B(()=>l().kind===`secret`?`password`:`text`))),S.disabled=!u(),J(S,`placeholder`,t)},[()=>(V(Z),V(l()),n(),B(()=>Z(l().kind===`secret`?`pasteHere`:`yourAnswer`,n()))),()=>(V(Z),V(l()),n(),B(()=>Z(l().kind===`secret`?`hiddenAfter`:`typeAnswer`,n())))]),Ei(S,()=>z(p),e=>N(p,e)),U(e,h),k(),i()}var Ss={"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`Help / question issues remain branchless even when issue-managed-branches is enabled.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`Release automation is installed, but release issue events are disabled by the selected issue workflow profile.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Release and hotfix workflows require the workflow PAT Secret and a writable token.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.`,"Cursor is an experimental runtime in Copilot and requires a compatible CLI plus CURSOR_API_KEY; the Action installs the official CLI when the default executable is absent.":`Cursor is an experimental runtime in Copilot and requires a compatible CLI plus CURSOR_API_KEY; the Action installs the official CLI when the default executable is absent.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.`},Cs={en:Ss,es:{"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`No has activado ningún tipo de flujo de incidencias. Sus eventos no se gestionarán hasta que actives un formulario de incidencia y su entrada en el perfil.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`Las incidencias de ayuda y consulta no crean ramas, aunque actives las ramas gestionadas por incidencias.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`La automatización de versiones ya está instalada, pero el perfil elegido desactiva los eventos de incidencias de versiones.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`La automatización de correcciones urgentes ya está instalada, pero el perfil elegido desactiva los eventos de sus incidencias.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`Has desactivado la generación de instrucciones para agentes del repositorio. Los colaboradores no recibirán el perfil ni la guía del flujo de trabajo generados.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Los flujos de versiones y correcciones urgentes requieren el Secret con el PAT de la Action y un token con permisos de escritura.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`La cola de merge bloqueará la operación si cada productor obligatorio no se verifica automáticamente o no dispone de una certificación exacta revisada.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`Está activado el cierre de incidencias inactivas. Las que estén en espera se cerrarán tras el plazo configurado y podrán reabrirse con un comentario.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`El PAT del bot debe tener acceso a los Projects seleccionados, y los cuatro valores de Status configurados deben existir en cada uno de ellos.`,"Cursor is an experimental runtime in Copilot and requires a compatible CLI plus CURSOR_API_KEY; the Action installs the official CLI when the default executable is absent.":`Cursor es un entorno experimental en Copilot y requiere un CLI compatible y CURSOR_API_KEY; la Action instala el CLI oficial si falta el ejecutable predeterminado.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Los Secrets y Variables de organización requieren permisos en ella. Limitar el acceso a los repositorios elegidos es la opción más segura; los valores del repositorio tienen prioridad.`},fr:{"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`Aucun type de flux de travail pour les tickets n’est activé. Leurs événements ne seront pas gérés tant qu’un formulaire de ticket pris en charge et son entrée de profil ne seront pas activés.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`Les tickets d’aide ou de question ne créent pas de branche, même lorsque les branches gérées par les tickets sont activées.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`L’automatisation des versions est déjà installée, mais le profil choisi désactive les événements des tickets de version.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`L’automatisation des correctifs urgents est déjà installée, mais le profil choisi désactive les événements des tickets correspondants.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`La génération des consignes pour les agents du dépôt est désactivée. Les collaborateurs ne recevront ni le profil ni le guide de flux de travail générés.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Les flux de version et de correctif urgent nécessitent le Secret contenant le PAT de l’Action et un jeton autorisé à écrire.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`La file de fusion bloque l’opération si chaque producteur requis n’est pas vérifié automatiquement ou couvert par une attestation exacte et examinée.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`La fermeture des tickets inactifs est activée. Les tickets en attente seront fermés après le délai configuré et pourront être rouverts par un nouveau commentaire.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`Le PAT du bot doit avoir accès aux Projects sélectionnés, et les quatre valeurs Status configurées doivent exister dans chacun de ces Projects.`,"Cursor is an experimental runtime in Copilot and requires a compatible CLI plus CURSOR_API_KEY; the Action installs the official CLI when the default executable is absent.":`Cursor est un environnement expérimental dans Copilot et nécessite un CLI compatible ainsi que CURSOR_API_KEY ; l’Action installe le CLI officiel si l’exécutable par défaut est absent.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Les Secrets et Variables d’organisation nécessitent des droits sur celle-ci. Limiter l’accès aux dépôts sélectionnés est le choix le plus sûr ; les valeurs du dépôt prévalent.`},pt:{"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`Não está ativo nenhum tipo de fluxo de trabalho para issues. Os respetivos eventos não serão geridos até ativar um formulário de issue suportado e a entrada correspondente no perfil.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`As issues de ajuda ou perguntas não criam ramos, mesmo com os ramos geridos por issues ativados.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`A automação de versões já está instalada, mas o perfil escolhido desativa os eventos das issues de versão.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`A automação de correções urgentes já está instalada, mas o perfil escolhido desativa os eventos das respetivas issues.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`A criação de orientações para agentes do repositório está desativada. Os colaboradores não receberão o perfil nem o guia do fluxo de trabalho gerados.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Os fluxos de versão e correção urgente exigem o Secret com o PAT da Action e um token com permissão de escrita.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`A fila de integração bloqueia a operação se cada produtor obrigatório não for verificado automaticamente ou coberto por uma declaração exata e revista.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`O fecho de issues inativas está ativado. As que aguardam resposta serão fechadas após o prazo configurado e poderão ser reabertas com um novo comentário.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`O PAT do bot tem de ter acesso aos Projects selecionados, e os quatro valores de Status configurados têm de existir em cada Project.`,"Cursor is an experimental runtime in Copilot and requires a compatible CLI plus CURSOR_API_KEY; the Action installs the official CLI when the default executable is absent.":`O Cursor é um ambiente experimental no Copilot e requer um CLI compatível e CURSOR_API_KEY; a Action instala o CLI oficial se o executável padrão não estiver disponível.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Os Secrets e Variables da organização exigem permissões nessa organização. Restringir o acesso aos repositórios selecionados é a opção mais segura; os valores do repositório prevalecem.`}};function ws(e,t){let n=Cs[t]??Ss;return Object.prototype.hasOwnProperty.call(n,e)?n[e]:t===`en`?e:Z(`planUnknownWarning`,t)}var Ts={en:{issues:`Issues`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Issue comments`,pullRequestComments:`Pull-request comments`,release:`Releases`,hotfix:`Hotfixes`,agentProvisioning:`Agent provisioning`,credentialHealth:`Credential health`,inactiveIssueClosure:`Inactive issue closure`,issueTemplates:`Issue templates`,pullRequestTemplate:`Pull-request template`},es:{issues:`Issues`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Comentarios en issues`,pullRequestComments:`Comentarios en pull requests`,release:`Releases`,hotfix:`Correcciones urgentes`,agentProvisioning:`Instalación de agentes`,credentialHealth:`Estado de credenciales`,inactiveIssueClosure:`Cierre de issues inactivos`,issueTemplates:`Plantillas de issues`,pullRequestTemplate:`Plantilla de pull requests`},fr:{issues:`Tickets`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Commentaires des tickets`,pullRequestComments:`Commentaires des pull requests`,release:`Versions`,hotfix:`Correctifs urgents`,agentProvisioning:`Installation des agents`,credentialHealth:`État des identifiants`,inactiveIssueClosure:`Fermeture des tickets inactifs`,issueTemplates:`Modèles de tickets`,pullRequestTemplate:`Modèle de pull request`},pt:{issues:`Questões`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Comentários nas questões`,pullRequestComments:`Comentários nas pull requests`,release:`Versões`,hotfix:`Correções urgentes`,agentProvisioning:`Instalação de agentes`,credentialHealth:`Estado das credenciais`,inactiveIssueClosure:`Fecho de questões inativas`,issueTemplates:`Modelos de questões`,pullRequestTemplate:`Modelo de pull request`}};function Es(e,t){return Ts[t][e]??e}var Ds={en:{planner:`Planner`,findings:`Findings analyst`,reviewer:`Reviewer`,fixer:`Fixer`,tester:`Tester`},es:{planner:`Planificador`,findings:`Analista de hallazgos`,reviewer:`Revisor`,fixer:`Corrector`,tester:`Probador`},fr:{planner:`Planificateur`,findings:`Analyste des problèmes`,reviewer:`Réviseur`,fixer:`Correcteur`,tester:`Testeur`},pt:{planner:`Planeador`,findings:`Analista de problemas`,reviewer:`Revisor`,fixer:`Corretor`,tester:`Testador`}};function Os(e,t){return Ds[t][e]??e}var ks=H(`
                • `),As=H(`
                • `),js=H(`
                    `),Ms=H(`· `,1),Ns=H(`
                    `,1),Ps=H(`
                    `,1),Fs=H(`
                      `),Is=H(`

                        /

                        `);function Ls(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`decisions`,8);function o(e){return Z(e===`repository`?`scopeRepository`:e===`organization`?`scopeOrganization`:`scopeDisabled`,n())}function s(e){return Z(e===`guarded`?`approvalGuarded`:e===`recommend`?`approvalRecommend`:`approvalOff`,n())}ji();var c=Is(),l=P(c),u=I(l,!0),d=L(l,2),f=P(d),p=P(f),m=I(p,!0),h=I(L(p),!0);D(f);var g=L(f,2),_=P(g),v=I(_,!0),y=I(L(_),!0);D(g);var b=L(g,2),x=P(b),S=I(x,!0),C=L(x),w=P(C);q(w,5,()=>(V(a()),B(()=>a().agentRouting)),K,(e,t)=>{var r=ks(),i=P(r),a=I(L(i));D(r),R(e=>{W(i,`${e??``}: `),W(a,`${z(t),B(()=>z(t).provider)??``} · ${z(t),B(()=>z(t).modelProvider)??``}/${z(t),B(()=>z(t).model)??``}`)},[()=>(V(Os),z(t),n(),B(()=>Os(z(t).role,n())))]),U(e,r)}),D(w),D(C),D(b);var ee=L(b,2),te=P(ee),ne=I(te,!0),re=L(te),ie=P(re),ae=I(ie,!0),oe=I(L(ie,2),!0);D(re),D(ee);var se=L(ee,2),ce=P(se),le=I(ce,!0),ue=I(L(ce),!0);D(se);var de=L(se,2),fe=e=>{var t=Ps(),r=F(t),i=P(r),o=I(i,!0),s=L(i),c=P(s),l=e=>{var t=js();q(t,5,()=>(V(a()),B(()=>a().trustedChecks)),K,(e,t)=>{var r=As(),i=P(r),a=I(i,!0),o=L(i),s=I(L(o),!0);D(r),R(e=>{W(a,(z(t),B(()=>z(t).name))),W(o,` · ${e??``} ${z(t),B(()=>z(t).sourceAppId)??``} · `),W(s,(z(t),B(()=>z(t).workflowName)))},[()=>(V(Z),n(),B(()=>Z(`producerAppId`,n())))]),U(e,r)}),D(t),U(e,t)},u=e=>{var t=Nr();R(e=>W(t,e),[()=>(V(Z),n(),B(()=>Z(`none`,n())))]),U(e,t)};G(c,e=>{V(a()),B(()=>a().trustedChecks.length)?e(l):e(u,-1)}),D(s),D(r);var d=L(r,2),f=P(d),p=I(f,!0),m=I(L(f),!0);D(d);var h=L(d,2),g=P(h),_=I(g,!0),v=L(g),y=P(v,!0),b=L(y),x=e=>{var t=Ms(),n=I(L(F(t)),!0);R(()=>W(n,(V(a()),B(()=>a().coverageCheck)))),U(e,t)};G(b,e=>{V(a()),B(()=>a().coverageCheck)&&e(x)}),D(v),D(h);var S=L(h,2),C=e=>{var t=Ns(),r=F(t),i=P(r),o=I(i,!0),s=I(L(i),!0);D(r);var c=L(r,2),l=P(c),u=I(l,!0),d=L(l),f=I(P(d),!0);D(d),D(c);var p=L(c,2),m=P(p),h=I(m,!0),g=I(L(m),!0);D(p),R((e,t,n,r,i,a)=>{W(o,e),W(s,t),W(u,n),W(f,r),W(h,i),W(g,a)},[()=>(V(Z),n(),B(()=>Z(`planCoverageThreshold`,n()))),()=>(V(a()),V(Z),n(),B(()=>a().coverageMinimum===void 0?Z(`none`,n()):`${a().coverageMinimum}%`)),()=>(V(Z),n(),B(()=>Z(`planCoverageReporter`,n()))),()=>(V(a()),V(Z),n(),B(()=>a().coverageArtifactWorkflow||Z(`none`,n()))),()=>(V(Z),n(),B(()=>Z(`planReporterAttested`,n()))),()=>(V(Z),V(a()),n(),B(()=>Z(a().coverageReporterAttested?`yes`:`no`,n())))]),U(e,t)};G(S,e=>{V(a()),B(()=>a().coverageMode===`numeric`)&&e(C)}),R((e,t,n,r,i)=>{W(o,e),W(p,t),W(m,n),W(_,r),W(y,i)},[()=>(V(Z),n(),B(()=>Z(`planTrustedChecks`,n()))),()=>(V(Z),n(),B(()=>Z(`planProducerAttested`,n()))),()=>(V(Z),V(a()),n(),B(()=>Z(a().producerAttested?`yes`:`no`,n()))),()=>(V(Z),n(),B(()=>Z(`planCoverage`,n()))),()=>(V(Aa),V(a()),n(),B(()=>Aa(`pullRequestApproval.coverage.mode`,a().coverageMode,n())))]),U(e,t)};G(de,e=>{V(a()),B(()=>a().approvalMode!==`off`)&&e(fe)});var pe=L(de,2),me=P(pe),he=I(me,!0),ge=I(L(me),!0);D(pe);var _e=L(pe,2),ve=e=>{var t=Fs(),r=P(t),i=I(r,!0),o=L(r),s=P(o);q(s,5,()=>(V(a()),B(()=>a().projectStatuses)),K,(e,t)=>{var r=ks(),i=P(r),a=I(L(i),!0);D(r),R(e=>{W(i,`${e??``}: `),W(a,(z(t),B(()=>z(t).value)))},[()=>(V(Z),V(fo),z(t),n(),B(()=>Z(fo[z(t).transition],n())))]),U(e,r)}),D(s),D(o),D(t),R(e=>W(i,e),[()=>(V(Z),n(),B(()=>Z(`planProjectStatuses`,n())))]),U(e,t)};G(_e,e=>{V(a()),B(()=>a().projectNumbers.length)&&e(ve)});var ye=L(_e,2),be=P(ye),xe=I(be,!0),Se=I(L(be),!0);D(ye);var Ce=L(ye,2),we=P(Ce),T=I(we,!0),Te=I(L(we),!0);D(Ce);var E=L(Ce,2),Ee=P(E),De=I(Ee,!0),Oe=I(L(Ee),!0);D(E);var ke=L(E,2),Ae=P(ke),je=I(Ae,!0),Me=I(L(Ae),!0);D(ke),D(d);var Ne=I(L(d,2),!0);D(c),R((e,t,n,r,i,o,s,c,l,d,f,p,g,_,b,x,C,w,ee,te)=>{W(u,e),W(m,t),W(h,n),W(v,r),W(y,i),W(S,o),W(ne,s),W(ae,(V(a()),B(()=>a().productionBranch))),W(oe,(V(a()),B(()=>a().developmentBranch))),W(le,c),W(ue,l),W(he,d),W(ge,f),W(xe,p),W(Se,g),W(T,_),W(Te,b),W(De,x),W(Oe,C),W(je,w),W(Me,ee),W(Ne,te)},[()=>(V(Z),n(),B(()=>Z(`planChoices`,n()))),()=>(V(Z),n(),B(()=>Z(`planEnabledCapabilities`,n()))),()=>(V(a()),V(Es),n(),V(Z),B(()=>a().enabledCapabilities.length?a().enabledCapabilities.map(e=>Es(e,n())).join(`, `):Z(`none`,n()))),()=>(V(Z),n(),B(()=>Z(`planIssueWorkflows`,n()))),()=>(V(a()),V(Aa),n(),V(Z),B(()=>a().issueWorkflows.length?a().issueWorkflows.map(e=>Aa(`issueWorkflows.enabled`,e,n())).join(`, `):Z(`none`,n()))),()=>(V(Z),n(),B(()=>Z(`planAgentRouting`,n()))),()=>(V(Z),n(),B(()=>Z(`planBranchRoles`,n()))),()=>(V(Z),n(),B(()=>Z(`planApprovalMode`,n()))),()=>(V(a()),B(()=>s(a().approvalMode))),()=>(V(Z),n(),B(()=>Z(`editProjects`,n()))),()=>(V(a()),V(Z),n(),B(()=>a().projectNumbers.length?a().projectNumbers.map(e=>`#${e}`).join(`, `):Z(`none`,n()))),()=>(V(Z),n(),B(()=>Z(`planVariableScope`,n()))),()=>(V(a()),B(()=>o(a().variableScope))),()=>(V(Z),n(),B(()=>Z(`planSecretScope`,n()))),()=>(V(a()),B(()=>o(a().secretScope))),()=>(V(Z),n(),B(()=>Z(`planIssueResources`,n()))),()=>(V(Z),n(),B(()=>Z(`planIssueResourcesValue`,n()))),()=>(V(Z),n(),B(()=>Z(`planInitialTag`,n()))),()=>(V(Z),V(a()),n(),B(()=>Z(a().initialTag?`yes`:`no`,n()))),()=>(V(Z),n(),B(()=>Z(`planAdvancedDefaults`,n())))]),U(e,c),k(),i()}var Rs=H(`
                      • `),zs=H(`

                          `,1),Bs=H(`
                        • ·

                        • `),Vs=H(`
                        • `),Hs=H(`

                           

                           
                          `),Us=H(`

                              `);function Ws(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`review`,8);ji();var o=Us(),s=P(o),c=I(s,!0),l=L(s,2),u=I(l,!0),d=L(l,2),f=e=>{var t=zs(),r=F(t),i=I(r,!0),o=L(r),s=P(o),c=I(s,!0),l=L(s);q(l,5,()=>(V(a()),B(()=>a().blockers)),K,(e,t)=>{var n=Rs(),r=I(n,!0);R(()=>W(r,z(t))),U(e,n)}),D(l),D(o),R((e,t)=>{W(i,e),W(c,t)},[()=>(V($),n(),B(()=>$(`blockedAction`,n()))),()=>(V($),n(),B(()=>$(`blockers`,n())))]),U(e,t)};G(d,e=>{V(a()),B(()=>a().blockers.length)&&e(f)});var p=L(d,2);q(p,5,()=>(V(a()),B(()=>a().jobs)),K,(e,t)=>{var r=Bs(),i=P(r),a=I(i,!0),o=L(i,2),s=I(o,!0),c=L(o,2),l=e=>{var t=Nr();R(e=>W(t,`· ${e??``}`),[()=>(V($),n(),B(()=>$(`retained`,n())))]),U(e,t)};G(c,e=>{z(t),B(()=>z(t).retained)&&e(l)});var u=L(c,2),d=I(P(u));D(u);var f=I(L(u));D(r),R((e,n,r)=>{W(a,e),W(s,n),W(d,`${z(t),B(()=>z(t).file)??``} / ${z(t),B(()=>z(t).job)??``}`),W(f,`runs-on: ${r??``}`)},[()=>(V($),z(t),n(),B(()=>$(z(t).role,n()))),()=>(V($),z(t),n(),B(()=>$(z(t).status,n()))),()=>(z(t),B(()=>JSON.stringify(z(t).runsOn)))]),U(e,r)}),D(p);var m=L(p,2),h=P(m),g=I(h),_=L(h,2);q(_,5,()=>(V(a()),B(()=>a().assets)),K,(e,t)=>{var r=Vs(),i=P(r),a=I(i,!0),o=L(i),s=L(o),c=e=>{var t=Nr();R(e=>W(t,`· ${e??``}`),[()=>(V($),n(),B(()=>$(`disabled`,n())))]),U(e,t)};G(s,e=>{z(t),B(()=>!z(t).enabled)&&e(c)}),D(r),R(e=>{W(a,(z(t),B(()=>z(t).path))),W(o,`: ${e??``}`)},[()=>(V($),z(t),n(),B(()=>$(z(t).status,n())))]),U(e,r)}),D(_),D(m);var v=L(m,2),y=P(v),b=I(y),x=L(y,2),S=I(x,!0);q(L(x,2),1,()=>(V(a()),B(()=>a().changes)),K,(e,t)=>{var r=Hs(),i=P(r),a=I(P(i),!0);D(i);var o=L(i,2),s=I(o,!0),c=L(o),l=I(c,!0),u=L(c,2),d=I(u,!0),f=I(L(u),!0);D(r),R((e,n,r,i)=>{W(a,(z(t),B(()=>z(t).path))),W(s,e),W(l,n),W(d,r),W(f,i)},[()=>(V($),n(),B(()=>$(`before`,n()))),()=>(z(t),V($),n(),B(()=>z(t).before??$(`absent`,n()))),()=>(V($),n(),B(()=>$(`after`,n()))),()=>(z(t),V($),n(),B(()=>z(t).after??$(`absent`,n())))]),U(e,r)}),D(v),D(o),R((e,t,n,r,i)=>{W(c,e),W(u,t),W(g,`${n??``} (${V(a()),B(()=>a().assets.length)??``})`),W(b,`${r??``} (${V(a()),B(()=>a().changes.length)??``})`),W(S,i)},[()=>(V($),n(),B(()=>$(`title`,n()))),()=>(V($),n(),B(()=>$(`help`,n()))),()=>(V($),n(),B(()=>$(`assets`,n()))),()=>(V($),n(),B(()=>$(`changes`,n()))),()=>(V($),n(),B(()=>$(`redactionNotice`,n())))]),U(e,o),k(),i()}var Gs={"Self-hosted runners":`Self-hosted runners`,Metadata:`Metadata`,Contents:`Contents`,Secrets:`Secrets`,Variables:`Variables`,Issues:`Issues`,Actions:`Actions`,Checks:`Checks`,Administration:`Administration`,Workflows:`Workflows`,"Issue Types":`Issue Types`,Projects:`Projects`,"Pull requests":`Pull requests`,Members:`Members`},Ks={repository:`repository`,organization:`organization`,read:`Read`,write:`Write`,required:`Required`,conditional:`Conditional`,verified:`Verified`,available:`Read available`,missing:`Missing`,unverifiable:`Unverifiable`},qs={"Self-hosted runners":`Runners autohospedados`,Metadata:`Metadatos`,Contents:`Contenido`,Secrets:`Secretos`,Variables:`Variables`,Issues:`Incidencias`,Actions:`Acciones`,Checks:`Comprobaciones`,Administration:`Administración`,Workflows:`Flujos de trabajo`,"Issue Types":`Tipos de incidencia`,Projects:`Proyectos`,"Pull requests":`Solicitudes de cambio`,Members:`Miembros`},Js={repository:`repositorio`,organization:`organización`,read:`Lectura`,write:`Escritura`,required:`Obligatorio`,conditional:`Condicional`,verified:`Verificado`,available:`Lectura disponible`,missing:`Faltante`,unverifiable:`No verificable`},Ys={"Self-hosted runners":`Runners auto-hébergés`,Metadata:`Métadonnées`,Contents:`Contenu`,Secrets:`Secrets`,Variables:`Variables`,Issues:`Tickets`,Actions:`Actions`,Checks:`Vérifications`,Administration:`Administration`,Workflows:`Flux de travail`,"Issue Types":`Types de ticket`,Projects:`Projets`,"Pull requests":`Demandes de tirage`,Members:`Membres`},Xs={repository:`dépôt`,organization:`organisation`,read:`Lecture`,write:`Écriture`,required:`Obligatoire`,conditional:`Conditionnel`,verified:`Vérifié`,available:`Lecture disponible`,missing:`Manquant`,unverifiable:`Non vérifiable`},Zs={"Self-hosted runners":`Runners autoalojados`,Metadata:`Metadados`,Contents:`Conteúdo`,Secrets:`Segredos`,Variables:`Variáveis`,Issues:`Questões`,Actions:`Ações`,Checks:`Verificações`,Administration:`Administração`,Workflows:`Fluxos de trabalho`,"Issue Types":`Tipos de questão`,Projects:`Projetos`,"Pull requests":`Pedidos de alteração`,Members:`Membros`},Qs={repository:`repositório`,organization:`organização`,read:`Leitura`,write:`Escrita`,required:`Obrigatório`,conditional:`Condicional`,verified:`Verificado`,available:`Leitura disponível`,missing:`Em falta`,unverifiable:`Não verificável`},$s={en:Gs,es:qs,fr:Ys,pt:Zs},ec={en:Ks,es:Js,fr:Xs,pt:Qs};function tc(e,t){return ec[e][t]}function nc(e,t){return Object.prototype.hasOwnProperty.call($s[e],t)?$s[e][t]:t}function rc(e,t){if(t===`verified`||t===`available`||t===`missing`||t===`unverifiable`)return ec[e][t]}var ic=H(`

                              `),ac=H(`
                            • `),oc=H(`

                              `),sc=H(`

                                `),cc=H(`
                              • `),lc=H(`
                                  `),uc=H(`

                                    `),dc=H(``),fc=H(`

                                    `),pc=H(`

                                      `);function mc(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`prompt`,8),s=X(t,`controller`,8),c=X(t,`busy`,8),l=X(t,`onSubmit`,8),u={capabilities:`editCapabilities`,"agent-runtime":`editRuntimes`,"agent-model-defaults":`editModels`,"agent-role-overrides":`editRoleModels`,repository:`editRepository`,deployment:`editDeployment`,bugbot:`editBugbot`,"pull-request-approval":`editApproval`,projects:`editProjects`,provisioning:`editProvisioning`,storage:`editStorage`};Tn(()=>(n(),V(o())),()=>{N(a,[{title:Z(`files`,n()),items:o().plan.files},{title:Z(`workflows`,n()),items:o().plan.workflows},{title:Z(`variables`,n()),items:o().plan.variables},{title:Z(`secretNames`,n()),items:o().plan.secrets}])}),En(),ji();var d=pc(),f=P(d),p=I(f,!0),m=L(f,2),h=P(m),g=I(h,!0),_=L(h,2),v=I(_,!0),y=L(_,2),b=e=>{var t=ic(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`planActionsProbePrerequisites`,n())))]),U(e,t)},x=gt(()=>(V(o()),B(()=>o().plan.permissionProbes?.some(e=>e.permission===`Actions`))));G(y,e=>{z(x)&&e(b)});var S=L(y,2),C=e=>{var t=ic(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`planSecretProbeLimit`,n())))]),U(e,t)},w=gt(()=>(V(o()),B(()=>o().plan.permissionProbes?.some(e=>e.permission===`Secrets`))));G(S,e=>{z(w)&&e(C)});var ee=L(S,2);q(ee,5,()=>(V(o()),B(()=>o().plan.permissionProbes)),K,(e,t)=>{var r=ac(),i=I(r);R((e,t)=>W(i,`${e??``}: ${t??``}`),[()=>(V(tc),n(),z(t),B(()=>tc(n(),z(t).scope))),()=>(V(nc),n(),z(t),B(()=>nc(n(),z(t).permission)))]),U(e,r)},e=>{var t=ac(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`none`,n())))]),U(e,t)}),D(ee),D(m);var te=L(m,2),ne=e=>{var t=oc(),r=P(t),i=I(r,!0),a=L(r,2),s=I(a,!0),c=L(a,2),l=P(c),u=I(l,!0),d=I(L(l),!0);D(c),D(t),R((e,t,n,r)=>{W(i,e),W(s,t),W(u,n),W(d,r)},[()=>(V(Z),n(),B(()=>Z(`organizationReuseTitle`,n()))),()=>(V(Z),n(),V(o()),B(()=>Z(`organizationReuseBody`,n(),{imported:String(o().plan.organizationReuse.imported),shared:String(o().plan.organizationReuse.organizationVariables.length),overrides:String(o().plan.organizationReuse.repositoryVariables.length),writes:String(o().plan.organizationReuse.repositoryWrites.length)}))),()=>(V(Z),n(),B(()=>Z(`batchRepositoryOverrides`,n()))),()=>(V(o()),V(Z),n(),B(()=>o().plan.organizationReuse.repositoryWrites.join(`, `)||Z(`none`,n())))]),U(e,t)};G(te,e=>{V(o()),B(()=>o().plan.organizationReuse)&&e(ne)});var re=L(te,2);Ls(re,{get decisions(){return V(o()),B(()=>o().plan.decisions)}});var ie=L(re,2),ae=e=>{Ws(e,{get review(){return V(o()),B(()=>o().plan.installationReview)}})};G(ie,e=>{V(o()),B(()=>o().plan.installationReview)&&e(ae)});var oe=L(ie,2),se=e=>{gs(e,{get storage(){return V(o()),B(()=>o().plan.workflowPatStorage)}})};G(oe,e=>{V(o()),B(()=>o().plan.workflowPatStorage)&&e(se)});var ce=L(oe,2),le=e=>{var t=sc(),r=P(t),i=I(r,!0),a=L(r,2);q(a,5,()=>(V(o()),B(()=>o().plan.presentationDefaults)),K,(e,t)=>{var r=ac(),i=I(r);R(e=>W(i,`${e??``}: ${z(t),B(()=>z(t).count)??``}`),[()=>(z(t),V(Z),n(),B(()=>u[z(t).group]?Z(u[z(t).group],n()):z(t).group))]),U(e,r)}),D(a),D(t),R(e=>W(i,e),[()=>(V(Z),n(),B(()=>Z(`planBasicDefaultsIntro`,n())))]),U(e,t)};G(ce,e=>{V(o()),B(()=>o().plan.presentationDefaults.length)&&e(le)});var ue=L(ce,2);q(ue,5,()=>z(a),K,(e,t)=>{var r=lc(),i=P(r),a=P(i),o=I(a,!0),s=I(L(a),!0);D(i);var c=L(i);q(c,5,()=>(z(t),B(()=>z(t).items)),K,(e,t)=>{var n=cc(),r=I(P(n),!0);D(n),R(()=>W(r,z(t))),U(e,n)},e=>{var t=ac(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`none`,n())))]),U(e,t)}),D(c),D(r),R(()=>{W(o,(z(t),B(()=>z(t).title))),W(s,(z(t),B(()=>z(t).items.length)))}),U(e,r)}),D(ue);var de=L(ue,2),fe=e=>{var t=uc(),r=P(t),i=I(r,!0),a=L(r);q(a,5,()=>(V(o()),B(()=>o().plan.warnings)),K,(e,t)=>{var r=ac(),i=I(r,!0);R(e=>W(i,e),[()=>(V(ws),z(t),n(),B(()=>ws(z(t),n())))]),U(e,r)}),D(a),D(t),R(e=>W(i,e),[()=>(V(Z),n(),B(()=>Z(`beforeContinue`,n())))]),U(e,t)};G(de,e=>{V(o()),B(()=>o().plan.warnings.length)&&e(fe)});var pe=L(de,2),me=e=>{var t=fc(),r=P(t),i=I(r,!0),a=L(r),d=I(a,!0),f=L(a,2);q(f,5,()=>(V(o()),B(()=>o().editGroups)),K,(e,t)=>{var r=dc(),i=I(r,!0);R(e=>{r.disabled=!s()||c(),W(i,e)},[()=>(V(Z),n(),z(t),B(()=>Z(`changeSection`,n(),{section:Z(u[z(t)],n())})))]),wr(`click`,r,()=>l()(`revise:${z(t)}`)),U(e,r)}),D(f),D(t),R((e,t)=>{W(i,e),W(d,t)},[()=>(V(Z),n(),B(()=>Z(`changeAnswersTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`changeAnswersHelp`,n())))]),U(e,t)};G(pe,e=>{V(o()),B(()=>o().editGroups?.length)&&e(me)});var he=L(pe,2),ge=P(he);{let e=A(()=>(V(Z),n(),B(()=>Z(`stopHere`,n())))),t=A(()=>!s()||c());Xa(ge,{get label(){return z(e)},variant:`secondary`,onClick:()=>l()(`decline`),get disabled(){return z(t)}})}var _e=L(ge);{let e=A(()=>(V(Z),V(o()),n(),B(()=>Z(o().plan.deliveryMode===`pull-request`?`batchUseConfiguration`:`approvePlan`,n())))),t=A(()=>(V(s()),V(c()),V(o()),B(()=>!s()||c()||!!o().plan.installationReview?.blockers.length)));Xa(_e,{get label(){return z(e)},arrow:!0,onClick:()=>l()(`approve`),get disabled(){return z(t)}})}D(he),D(d),R((e,t,n,r)=>{W(p,e),J(m,`aria-label`,t),W(g,n),W(v,r)},[()=>(V(Z),V(o()),n(),B(()=>Z(o().plan.deliveryMode===`pull-request`?`batchConfigurationPreview`:o().plan.organizationReuse?`planReuseBody`:`planBody`,n()))),()=>(V(Z),n(),B(()=>Z(`planPermissionProbeTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`planPermissionProbeTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`planPermissionProbeBody`,n())))]),U(e,d),k(),i()}Tr([`click`]);var hc=H(`

                                      `),gc=H(`
                                    • `),_c=H(`
                                      `,1),vc=H(`
                                      `,1),yc=H(`

                                      `),bc=H(`

                                        `,1);function xc(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`view`,8);Tn(()=>n(),()=>{N(a,ta(n()))}),En(),ji();var s=bc(),c=F(s),l=P(c),u=I(l,!0),d=L(l),f=I(d,!0),p=L(d,2),m=e=>{var t=hc(),n=I(t,!0);R(()=>W(n,(z(a),B(()=>z(a).unknown)))),U(e,t)};G(p,e=>{V(o()),B(()=>o().secretInventory!==`available`)&&e(m)});var h=L(p,2);q(h,5,()=>(V(o()),B(()=>o().secrets)),K,(e,t)=>{var n=gc(),r=P(n),i=I(r,!0),o=L(r),s=L(o),c=e=>{var t=Nr();R(()=>W(t,`· ${z(a),B(()=>z(a).shadowed)??``}`)),U(e,t)};G(s,e=>{z(t),B(()=>z(t).shadowed)&&e(c)}),D(n),R(()=>{W(i,(z(t),B(()=>z(t).name))),W(o,` · ${z(a),z(t),B(()=>z(a)[z(t).scope])??``} `)}),U(e,n)}),D(h),D(c);var g=L(c,2),_=P(g),v=I(_),y=L(_,2),b=e=>{var t=hc(),n=I(t,!0);R(()=>W(n,(z(a),B(()=>z(a).empty)))),U(e,t)};G(y,e=>{V(o()),B(()=>!o().variables.length)&&e(b)});var x=L(y,2);q(x,5,()=>(V(o()),B(()=>o().variables)),K,(e,t)=>{var n=_c(),r=F(n),i=P(r),o=L(i),s=e=>{var t=Nr();R(()=>W(t,`· ${z(a),B(()=>z(a).shadowed)??``}`)),U(e,t)};G(o,e=>{z(t),B(()=>z(t).shadowed)&&e(s)}),D(r);var c=I(L(r),!0);R(()=>{W(i,`${z(t),B(()=>z(t).name)??``} · ${z(a),z(t),B(()=>z(a)[z(t).scope])??``} `),W(c,(z(t),B(()=>z(t).value)))}),U(e,n)}),D(x),D(g);var S=L(g,2),C=P(S),w=I(C);q(L(C,2),1,()=>(V(o()),B(()=>o().workflows)),K,(e,t)=>{var n=yc(),r=P(n),i=I(r,!0),o=L(r,2),s=I(o,!0),c=L(o,2);q(c,5,()=>(z(t),B(()=>z(t).inputs)),K,(e,t)=>{var n=vc(),r=F(n),i=I(r,!0),o=L(r),s=P(o,!0),c=L(s),l=e=>{var n=Nr();R(()=>W(n,`· ${z(a),B(()=>z(a).workflow)??``}: ${z(t),B(()=>z(t).fallback)??``}`)),U(e,n)};G(c,e=>{z(t),B(()=>z(t).fallback!==void 0)&&e(l)}),D(o),R(()=>{W(i,(z(t),B(()=>z(t).name))),W(s,(z(t),z(a),B(()=>z(t).unsupported?z(a).unknown:z(t).variable?`vars.${z(t).variable}`:z(t).literal)))}),U(e,n)}),D(c),D(n),R(()=>{W(i,(z(t),B(()=>z(t).file))),W(s,(z(t),B(()=>z(t).action)))}),U(e,n)}),D(S),R(()=>{W(u,(z(a),B(()=>z(a).credentials))),W(f,(z(a),B(()=>z(a).secretHelp))),W(v,`${z(a),B(()=>z(a).variables)??``} (${V(o()),B(()=>o().variables.length)??``})`),W(w,`${z(a),B(()=>z(a).details)??``} (${V(o()),B(()=>o().workflows.length)??``})`)}),U(e,s),k(),i()}var Sc=H(`

                                        `),Cc=H(``),wc=H(``),Tc=H(`

                                        `),Ec=H(`

                                        `,1),Dc=H(`

                                        `,1);function Oc(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`view`,8),s=X(t,`controller`,8),c=X(t,`busy`,8),l=X(t,`onSubmit`,8);Tn(()=>n(),()=>{N(a,ta(n()))}),En(),ji();var u=Dc(),d=F(u),f=I(d,!0),p=L(d,2),m=I(p,!0),h=L(p,2),g=I(h,!0),_=L(h,2),v=e=>{var t=Sc(),n=I(t,!0);R(()=>W(n,(z(a),B(()=>z(a).local)))),U(e,t)};G(_,e=>{V(o()),B(()=>o().github===`not-connected`&&o().status!==`unconfigured`)&&e(v)});var y=L(_,2),b=e=>{var t=Cc(),n=I(t,!0);R(()=>W(n,(z(a),B(()=>z(a).githubIncomplete)))),U(e,t)};G(y,e=>{V(o()),B(()=>o().github===`incomplete`)&&e(b)});var x=L(y,2),S=P(x),C=e=>{var t=wc(),n=I(t,!0);R(()=>{t.disabled=!s()||c(),W(n,(V(o()),z(a),B(()=>o().github===`not-connected`?z(a).connect:z(a).refresh)))}),wr(`click`,t,()=>l()(o().github===`not-connected`?`connect`:`refresh`)),U(e,t)};G(S,e=>{V(o()),B(()=>o().status!==`unconfigured`)&&e(C)});var w=L(S,2);let ee;var te=I(w,!0);D(x);var ne=L(x,2),re=e=>{var t=Ec(),r=F(t),i=P(r),u=I(i,!0),d=L(i),f=I(d,!0),p=L(d,2);q(p,5,()=>(V(o()),B(()=>o().settings)),K,(e,t)=>{var r=Tc(),i=P(r),o=P(i),u=I(o,!0),d=L(o),f=P(d,!0),p=L(f),m=e=>{var n=Nr();R(()=>W(n,` · ${z(a),z(t),B(()=>z(a)[z(t).source])??``}`)),U(e,n)};G(p,e=>{z(t),B(()=>z(t).source!==`unknown`)&&e(m)}),D(d),D(i);var h=L(i,2),g=I(h,!0);D(r),R((e,n,r)=>{W(u,e),W(f,n),J(h,`aria-label`,r),h.disabled=(V(s()),V(c()),z(t),B(()=>!s()||c()||!z(t).editable)),W(g,(z(a),B(()=>z(a).edit)))},[()=>(V(na),z(t),n(),B(()=>na(z(t).id,n()))),()=>(z(t),z(a),V(ia),n(),B(()=>z(t).value===void 0?z(a).unknown:ia(z(t).value,n()))),()=>(z(a),V(na),z(t),n(),B(()=>`${z(a).edit}: ${na(z(t).id,n())}`))]),wr(`click`,h,()=>l()(`edit:${z(t).id}`)),U(e,r)}),D(p),D(r),xc(L(r,2),{get view(){return o()}}),R(()=>{W(u,(z(a),B(()=>z(a).quick))),W(f,(z(a),B(()=>z(a).quickHelp)))}),U(e,t)};G(ne,e=>{V(o()),B(()=>o().status!==`unconfigured`)&&e(re)});var ie=L(ne,2),ae=I(ie,!0),oe=L(ie,2),se=P(oe),ce=I(se,!0);D(oe),R(()=>{W(f,(z(a),B(()=>z(a).title))),W(m,(z(a),V(o()),B(()=>z(a)[o().status]))),W(g,(V(o()),z(a),B(()=>o().status===`unconfigured`?z(a).startHelp:z(a).intro))),ee=ui(w,1,`button`,null,ee,{primary:o().status===`unconfigured`,secondary:o().status!==`unconfigured`}),w.disabled=!s()||c(),W(te,(V(o()),z(a),B(()=>o().status===`unconfigured`?z(a).start:z(a).wizard))),W(ae,(z(a),B(()=>z(a).limits))),se.disabled=!s()||c(),W(ce,(z(a),B(()=>z(a).finish)))}),wr(`click`,w,()=>l()(`wizard`)),wr(`click`,se,()=>l()(`close`)),U(e,u),k(),i()}Tr([`click`]);var kc=H(``),Ac=H(``),jc=H(`
                                      • `),Mc=H(`
                                          `),Nc=H(`

                                          `),Pc=H(` `),Fc=H(`

                                            `),Ic=H(`
                                             
                                            `),Lc=H(`
                                            `),Rc=H(`
                                            `),zc=H(`

                                            `),Bc=H(`
                                          • `),Vc=H(`
                                              `),Hc=H(`

                                              `,1),Uc=H(`

                                              →

                                              `),Wc=H(`
                                              `),Gc=H(``),Kc=H(``),qc=H(`
                                              `),Jc=H(`

                                              `);function Yc(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`batch`,8),s=X(t,`controller`,8),c=X(t,`busy`,8),l=X(t,`mode`,8,`progress`),u=X(t,`onSubmit`,8,async()=>void 0),d=X(t,`onStop`,8,async()=>void 0),f={ready:`batchStatusReady`,blocked:`batchStatusBlocked`,applying:`batchStatusApplying`,partial:`batchStatusPartial`,"waiting-for-merge":`batchStatusWaiting`,"verification-pending":`batchStatusPending`,unchanged:`batchStatusUnchanged`,cancelled:`batchStatusCancelled`};function p(e){return e&&/^https:\/\/github\.com\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/pull\/[1-9][0-9]*$/.test(e)?e:void 0}Tn(()=>V(o()),()=>{N(a,o().targets.some(e=>e.cleanupPending)?[]:o().targets.filter(e=>[`ready`,`partial`,`cancelled`,`applying`].includes(e.status)))}),En(),ji();var m=Jc(),h=P(m),g=I(h,!0),_=L(h,2),v=I(_,!0),y=L(_,2),b=e=>{var t=kc(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`batchStopping`,n())))]),U(e,t)};G(y,e=>{V(o()),B(()=>o().stopRequested)&&e(b)});var x=L(y,2);q(x,5,()=>(V(o()),B(()=>o().targets)),e=>e.repositoryId,(e,t)=>{var r=Uc(),i=P(r),a=I(i,!0),o=L(i,2),s=e=>{Ws(e,{get review(){return z(t),B(()=>z(t).installationReview)}})};G(o,e=>{z(t),B(()=>z(t).installationReview)&&e(s)});var c=L(o,2),l=I(c,!0),u=L(c,2),d=e=>{var t=Ac(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`batchCleanupPending`,n())))]),U(e,t)};G(u,e=>{z(t),B(()=>z(t).cleanupPending)&&e(d)});var m=L(u,2),h=e=>{var n=Mc();q(n,5,()=>(z(t),B(()=>z(t).blockers)),K,(e,t)=>{var n=jc(),r=I(n,!0);R(()=>W(r,z(t))),U(e,n)}),D(n),U(e,n)};G(m,e=>{z(t),B(()=>z(t).blockers?.length)&&e(h)});var g=L(m,2),_=e=>{var r=Nc(),i=I(r,!0);R(e=>W(i,e),[()=>(V(Z),z(t),n(),B(()=>Z(z(t).reason===`drift`||z(t).reason===`ownership`?`batchReasonDrift`:z(t).reason===`provider`?`batchReasonProvider`:z(t).reason===`cancelled`?`batchReasonCancelled`:`batchReasonPreflight`,n())))]),U(e,r)};G(g,e=>{z(t),B(()=>z(t).reason&&!z(t).cleanupPending)&&e(_)});var v=L(g,2),y=P(v),b=I(y,!0),x=L(y),S=P(x),C=I(S,!0),w=I(L(S,2),!0);D(x);var ee=I(L(x),!0);D(v);var te=L(v,2),ne=e=>{var r=Pc(),i=I(r);R((e,t)=>{J(r,`href`,e),W(i,`${t??``} ↗`)},[()=>(z(t),B(()=>p(z(t).pullRequestUrl))),()=>(V(Z),n(),B(()=>Z(`batchOpenPull`,n())))]),U(e,r)},re=gt(()=>(z(t),B(()=>p(z(t).pullRequestUrl))));G(te,e=>{z(re)&&e(ne)});var ie=L(te,2),ae=e=>{var r=Hc(),i=F(r),a=P(i),o=I(a,!0),s=L(a,2),c=I(s,!0),l=I(L(s,2),!0);D(i);var u=L(i,2),d=e=>{var r=Nc(),i=I(r);R((e,t)=>W(i,`${e??``}: ${t??``}.`),[()=>(V(Z),n(),B(()=>Z(`batchRetainedSecrets`,n()))),()=>(z(t),B(()=>z(t).retainedSecrets.join(`, `)))]),U(e,r)};G(u,e=>{z(t),B(()=>z(t).retainedSecrets.length)&&e(d)});var f=L(u,2),p=I(f,!0),m=L(f,2),h=e=>{var r=Fc(),i=P(r),a=I(i,!0),o=L(i,2),s=I(o,!0),c=L(o,2);q(c,5,()=>(z(t),B(()=>z(t).permissionProbes)),K,(e,t)=>{var r=jc(),i=I(r);R((e,t)=>W(i,`${e??``}: ${t??``}`),[()=>(V(tc),n(),z(t),B(()=>tc(n(),z(t).scope))),()=>(V(nc),n(),z(t),B(()=>nc(n(),z(t).permission)))]),U(e,r)}),D(c);var l=L(c,2),u=e=>{var t=Nc(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`planSecretProbeLimit`,n())))]),U(e,t)},d=gt(()=>(z(t),B(()=>z(t).permissionProbes.some(e=>e.permission===`Secrets`))));G(l,e=>{z(d)&&e(u)}),D(r),R((e,t)=>{W(a,e),W(s,t)},[()=>(V(Z),n(),B(()=>Z(`planPermissionProbeTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`planPermissionProbeBody`,n())))]),U(e,r)};G(m,e=>{z(t),B(()=>z(t).permissionProbes?.length)&&e(h)});var g=L(m,2),_=e=>{var r=Rc(),i=P(r),a=I(i,!0);q(L(i,2),1,()=>(z(t),B(()=>z(t).files)),K,(e,t)=>{var r=Lc(),i=P(r),a=I(P(i),!0);D(i);var o=L(i,2),s=e=>{var t=Nc(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`batchDeleteFile`,n())))]),U(e,t)},c=e=>{var n=Ic(),r=I(n,!0);R(()=>W(r,(z(t),B(()=>z(t).content)))),U(e,n)};G(o,e=>{z(t),B(()=>z(t).content===null)?e(s):e(c,-1)}),D(r),R(()=>W(a,(z(t),B(()=>z(t).path)))),U(e,r)}),D(r),R(e=>W(a,e),[()=>(V(Z),n(),B(()=>Z(`batchReviewFiles`,n())))]),U(e,r)};G(g,e=>{z(t),B(()=>z(t).files.length)&&e(_)});var v=L(g,2),y=e=>{var r=zc(),i=P(r),a=I(i,!0),o=I(L(i),!0);D(r),R((e,t)=>{W(a,e),W(o,t)},[()=>(V(Z),n(),B(()=>Z(`batchRepositoryOverrides`,n()))),()=>(z(t),B(()=>z(t).repositoryVariables.join(`, `)))]),U(e,r)};G(v,e=>{z(t),B(()=>z(t).repositoryVariables.length)&&e(y)});var b=L(v,2),x=e=>{var r=Vc(),i=P(r),a=I(i,!0),o=L(i);q(o,5,()=>(z(t),B(()=>z(t).grants)),K,(e,t)=>{var n=Bc(),r=P(n),i=I(L(r),!0);D(n),R(()=>{W(r,`${z(t),B(()=>z(t).kind===`secret`?`Secret`:`Variable`)??``} `),W(i,(z(t),B(()=>z(t).name)))}),U(e,n)}),D(o),D(r),R(e=>W(a,e),[()=>(V(Z),n(),B(()=>Z(`batchReviewedAccess`,n())))]),U(e,r)};G(b,e=>{z(t),B(()=>z(t).grants.length)&&e(x)}),R((e,t,n,r)=>{W(o,e),W(c,t),W(l,n),W(p,r)},[()=>(V(Z),n(),z(t),B(()=>Z(`batchFilesCount`,n(),{count:String(z(t).files.length)}))),()=>(V(Z),n(),z(t),B(()=>Z(`batchVariablesCount`,n(),{count:String(z(t).repositoryVariables.length)}))),()=>(V(Z),n(),z(t),B(()=>Z(`batchGrantsCount`,n(),{count:String(z(t).grants.length)}))),()=>(V(Z),n(),B(()=>Z(`batchResourcesExplanation`,n())))]),U(e,r)},oe=gt(()=>(z(t),B(()=>![`waiting-for-merge`,`verification-pending`,`unchanged`].includes(z(t).status))));G(ie,e=>{z(oe)&&e(ae)}),D(r),R((e,n)=>{W(a,(z(t),B(()=>z(t).repository))),W(l,e),W(b,n),W(C,(z(t),B(()=>z(t).installationBranch))),W(w,(z(t),B(()=>z(t).baseBranch))),W(ee,(z(t),B(()=>z(t).baseSha)))},[()=>(V(Z),z(t),n(),B(()=>Z(f[z(t).status],n()))),()=>(V(Z),n(),B(()=>Z(`batchBranchReview`,n())))]),U(e,r)}),D(x);var S=L(x,2),C=e=>{var t=Wc(),r=P(t),i=I(r,!0),o=L(r,2),l=I(o,!0);D(t),R((e,t)=>{r.disabled=(V(s()),V(c()),z(a),B(()=>!s()||c()||!z(a).length)),W(i,e),o.disabled=!s()||c(),W(l,t)},[()=>(V(Z),n(),B(()=>Z(`batchApplyPlans`,n()))),()=>(V(Z),n(),B(()=>Z(`batchLeavePreview`,n())))]),wr(`click`,r,()=>u()(`approve`)),wr(`click`,o,()=>u()(`decline`)),U(e,t)},w=e=>{var t=Gc(),r=I(t,!0);R(e=>{t.disabled=(V(s()),V(c()),V(o()),B(()=>!s()||c()||o().stopRequested)),W(r,e)},[()=>(V(Z),n(),B(()=>Z(`batchStopPending`,n())))]),wr(`click`,t,function(...e){d()?.apply(this,e)}),U(e,t)},ee=e=>{var t=qc(),r=P(t),i=e=>{var t=Kc(),r=I(t,!0);R(e=>{t.disabled=!s()||c(),W(r,e)},[()=>(V(Z),n(),B(()=>Z(`batchRetryPending`,n())))]),wr(`click`,t,()=>u()(`retry`)),U(e,t)};G(r,e=>{z(a),V(o()),B(()=>z(a).length&&o().retryRemaining>0)&&e(i)});var l=L(r,2),d=I(l,!0);D(t),R(e=>{l.disabled=!s()||c(),W(d,e)},[()=>(V(Z),n(),B(()=>Z(`batchFinish`,n())))]),wr(`click`,l,()=>u()(`finish`)),U(e,t)};G(S,e=>{l()===`review`?e(C):l()===`progress`?e(w,1):l()===`result`&&e(ee,2)});var te=L(S,2),ne=P(te),re=I(ne,!0),ie=I(L(ne),!0);D(te),D(m),R((e,t,n)=>{W(g,e),W(v,t),W(re,n),W(ie,(V(o()),B(()=>o().operationId)))},[()=>(V(Z),V(l()),n(),B(()=>Z(l()===`review`?`batchReviewTitle`:l()===`progress`?`batchProgressTitle`:`batchResultTitle`,n()))),()=>(V(Z),V(l()),n(),B(()=>Z(l()===`review`?`batchReviewBody`:l()===`progress`?`batchProgressBody`:`batchResultBody`,n()))),()=>(V(Z),n(),B(()=>Z(`batchTechnical`,n())))]),U(e,m),k(),i()}Tr([`click`]);var Xc=H(``),Zc=H(``),Qc=H(`

                                              `),$c=H(`
                                              `),el=H(`

                                              `,1);function tl(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=M(),s=M(),c=X(t,`selection`,8),l=X(t,`controller`,8),u=X(t,`busy`,8),d=X(t,`onSubmit`,8),f=M([...c().selectedIds]),p=M(``),m=M(``),h=M(0);function g(e){N(f,z(f).includes(e)?z(f).filter(t=>t!==e):[...z(f),e])}function _(e){d()(JSON.stringify({action:e,selectedIds:z(f),...e===`resolve`?{name:z(m).trim()}:{}}))}Tn(()=>(V(c()),z(p)),()=>{N(a,c().candidates.filter(e=>e.name.toLowerCase().includes(z(p).toLowerCase())))}),Tn(()=>(z(h),z(a)),()=>{z(h)>0&&z(h)*25>=z(a).length&&N(h,0)}),Tn(()=>(z(a),z(h)),()=>{N(o,z(a).slice(z(h)*25,(z(h)+1)*25))}),Tn(()=>(z(f),V(c())),()=>{N(s,z(f).some(e=>!c().candidates.some(t=>t.id===e&&!t.unavailable)))}),En(),ji();var v=el(),y=F(v),b=I(y,!0),x=L(y,2),S=e=>{var t=Xc(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`batchDiscoveryUnavailable`,n())))]),U(e,t)};G(x,e=>{V(c()),B(()=>c().discoveryStatus===`unavailable`)&&e(S)});var C=L(x,2),w=e=>{var t=Xc(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),V(c()),n(),B(()=>Z(c().message===`lookup-unavailable`?`batchLookupUnavailable`:c().message===`selection-invalid`?`batchSelectionInvalid`:`batchAccessUnavailable`,n())))]),U(e,t)};G(C,e=>{V(c()),B(()=>c().message)&&e(w)});var ee=L(C,2),te=e=>{var t=Xc(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`batchDiscoveryTruncated`,n())))]),U(e,t)};G(ee,e=>{V(c()),B(()=>c().truncated)&&e(te)});var ne=L(ee,2),re=I(ne,!0),ie=L(ne,2);xi(ie);var ae=L(ie,2),oe=I(ae,!0),se=L(ae,2),ce=P(se),le=I(ce,!0),ue=L(ce,2);q(ue,5,()=>z(o),e=>e.id,(e,t)=>{var r=Zc(),i=P(r);xi(i);var a=L(i,2),o=P(a),s=I(o,!0),l=L(o),u=P(l),d=L(u),p=e=>{var t=Nr();R(e=>W(t,`· ${e??``}`),[()=>(V(Z),n(),B(()=>Z(`batchCurrent`,n())))]),U(e,t)};G(d,e=>{z(t),V(c()),B(()=>z(t).id===c().currentRepositoryId)&&e(p)});var m=L(d,2),h=e=>{var r=Nr();R(e=>W(r,`· ${e??``}`),[()=>(V(Z),z(t),n(),B(()=>Z(z(t).unavailable===`archived`?`batchArchived`:z(t).unavailable===`disabled`?`batchDisabled`:z(t).unavailable===`access-unavailable`?`batchAccessUnavailable`:`batchReadOnly`,n())))]),U(e,r)};G(m,e=>{z(t),B(()=>z(t).unavailable)&&e(h)}),D(l),D(a),D(r),R((e,n,r)=>{Si(i,e),i.disabled=n,W(s,(z(t),B(()=>z(t).name))),W(u,`${r??``} `)},[()=>(z(f),z(t),B(()=>z(f).includes(z(t).id))),()=>(z(f),z(t),B(()=>!z(f).includes(z(t).id)&&(!!z(t).unavailable||z(f).length>=25))),()=>(V(Z),z(t),n(),B(()=>Z(z(t).private?`batchPrivate`:`batchPublic`,n())))]),wr(`change`,i,()=>g(z(t).id)),U(e,r)}),D(ue),D(se);var de=L(se,2),fe=e=>{var t=Qc(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`batchNoMatches`,n())))]),U(e,t)};G(de,e=>{z(a),B(()=>!z(a).length)&&e(fe)});var pe=L(de,2),me=e=>{var t=$c(),r=P(t),i=I(r,!0),o=L(r,2),s=I(o),c=L(o,2),d=I(c,!0);D(t),R((e,t,n)=>{r.disabled=z(h)===0||!l()||u(),W(i,e),W(s,`${z(h)+1} / ${t??``}`),c.disabled=(z(h),z(a),V(l()),V(u()),B(()=>(z(h)+1)*25>=z(a).length||!l()||u())),W(d,n)},[()=>(V(Z),n(),B(()=>Z(`batchPrevious`,n()))),()=>(z(a),B(()=>Math.ceil(z(a).length/25))),()=>(V(Z),n(),B(()=>Z(`batchNext`,n())))]),wr(`click`,r,()=>N(h,z(h)-1)),wr(`click`,c,()=>N(h,z(h)+1)),U(e,t)};G(pe,e=>{z(a),B(()=>z(a).length>25)&&e(me)});var he=L(pe,2),ge=P(he),_e=I(ge,!0),ve=L(ge,2),ye=I(ve,!0),be=L(ve,2),xe=I(be,!0),Se=L(be,2);xi(Se);var Ce=L(Se,2),we=P(Ce),T=I(we,!0),Te=L(we,2),E=I(Te,!0);D(Ce),D(he);var Ee=L(he,2),De=I(Ee,!0);R((e,t,n,r,i,a,o,c,d,p,m)=>{W(b,e),W(re,t),ie.disabled=!l()||u(),W(oe,n),se.disabled=!l()||u(),W(le,r),W(_e,i),W(ye,a),W(xe,o),Se.disabled=!l()||u(),we.disabled=c,W(T,d),Te.disabled=!l()||u(),W(E,p),Ee.disabled=(V(l()),V(u()),z(s),z(f),B(()=>!l()||u()||z(s)||z(f).length<1||z(f).length>25)),W(De,m)},[()=>(V(Z),n(),V(c()),B(()=>Z(`batchSelectionBody`,n(),{organization:c().organization}))),()=>(V(Z),n(),B(()=>Z(`batchFilter`,n()))),()=>(V(Z),n(),z(f),B(()=>Z(`batchSelectedCount`,n(),{count:String(z(f).length)}))),()=>(V(Z),n(),B(()=>Z(`batchRepositories`,n()))),()=>(V(Z),n(),B(()=>Z(`batchMissingRepository`,n()))),()=>(V(Z),n(),B(()=>Z(`batchAccessExplanation`,n()))),()=>(V(Z),n(),B(()=>Z(`batchExactName`,n()))),()=>(V(l()),V(u()),z(m),B(()=>!l()||u()||!/^[A-Za-z0-9][A-Za-z0-9_.-]{0,99}$/.test(z(m).trim()))),()=>(V(Z),n(),B(()=>Z(`batchFindRepository`,n()))),()=>(V(Z),n(),B(()=>Z(`batchChangeAccess`,n()))),()=>(V(Z),n(),B(()=>Z(`batchReviewSelection`,n())))]),wr(`input`,ie,()=>N(h,0)),Ei(ie,()=>z(p),e=>N(p,e)),Ei(Se,()=>z(m),e=>N(m,e)),wr(`click`,we,()=>_(`resolve`)),wr(`click`,Te,()=>_(`access`)),wr(`click`,Ee,()=>_(`select`)),U(e,v),k(),i()}Tr([`input`,`change`,`click`]);var nl=H(`

                                              `,1),rl=H(``),il=H(``),al=H(``),ol=H(`

                                              `,1),sl=H(`

                                              `,1);function cl(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`prompt`,8),s=X(t,`controller`,8),c=X(t,`busy`,8),l=X(t,`onSubmit`,8),u=M(o().kind===`quick-edit`?o().current:``);Tn(()=>n(),()=>{N(a,ta(n()))}),En(),ji();var d=Pr(),f=F(d),p=e=>{var t=ol(),r=F(t),i=I(r,!0),d=L(r,2),f=e=>{var t=nl(),r=F(t),i=I(r,!0),a=L(r,2);{let e=A(()=>(V(po),V(o()),n(),B(()=>po(o().presentation[n()].documentation.url))));Lo(a,{get explanation(){return V(o()),n(),B(()=>o().presentation[n()])},get helpUrl(){return z(e)}})}R(()=>W(i,(V(o()),n(),B(()=>o().presentation[n()].summary)))),U(e,t)};G(d,e=>{V(o()),B(()=>o().presentation)&&e(f)});var p=L(d,2),m=I(p),h=L(p,2),g=P(h),_=I(g,!0),v=L(g,2),y=e=>{var t=il();q(t,5,()=>(V(o()),B(()=>o().choices)),K,(e,t)=>{var r=rl(),i=I(r,!0),a={};R(e=>{W(i,e),a!==(a=z(t))&&(r.value=(r.__value=a)??``)},[()=>(V(ia),z(t),n(),B(()=>ia(z(t),n())))]),U(e,r)}),D(t),mi(t),R(()=>t.disabled=!s()||c()),hi(t,()=>z(u),e=>N(u,e)),U(e,t)},b=e=>{var t=al();xi(t),R(()=>{J(t,`min`,(V(o()),B(()=>o().min))),J(t,`max`,(V(o()),B(()=>o().max))),t.disabled=!s()||c()}),Ei(t,()=>z(u),e=>N(u,e)),U(e,t)};G(v,e=>{V(o()),B(()=>o().choices)?e(y):e(b,-1)});var x=L(v,2),S=P(x),C=I(S,!0),w=L(S),ee=I(w,!0);D(x),D(h),R((e,t)=>{W(i,e),W(m,`${z(a),B(()=>z(a).current)??``}: ${t??``}`),W(_,(z(a),B(()=>z(a).next))),S.disabled=!s()||c(),W(C,(z(a),B(()=>z(a).back))),w.disabled=!s()||c(),W(ee,(z(a),B(()=>z(a).preview)))},[()=>(V(na),V(o()),n(),B(()=>na(o().id,n()))),()=>(V(ia),V(o()),n(),B(()=>ia(o().current,n())))]),Cr(`submit`,h,e=>{e.preventDefault(),l()(String(z(u)??``))}),wr(`click`,S,()=>l()(`cancel`)),U(e,t)},m=e=>{var t=sl(),r=F(t),i=I(r,!0),u=L(r),d=I(u,!0),f=L(u,2),p=P(f),m=I(p,!0),h=L(p),g=I(h,!0),_=L(h),v=I(_,!0),y=L(_),b=I(y,!0),x=L(y),S=I(x,!0),C=I(L(x),!0);D(f);var w=L(f,2);let ee;var te=I(w,!0),ne=L(w,2),re=I(ne,!0),ie=L(ne,2),ae=P(ie),oe=I(ae,!0),se=L(ae),ce=I(se,!0);D(ie),R((e,t,n)=>{W(i,(z(a),B(()=>z(a).review))),W(d,e),W(m,(z(a),B(()=>z(a).current))),W(g,t),W(v,(z(a),B(()=>z(a).next))),W(b,n),W(S,(z(a),B(()=>z(a).source))),W(C,(z(a),V(o()),B(()=>z(a)[o().change.scope]))),ee=ui(w,1,`banner`,null,ee,{warning:o().change.scope===`organization`}),W(te,(V(o()),z(a),B(()=>o().change.scope===`organization`?z(a).orgImpact:z(a).repoImpact))),W(re,(z(a),B(()=>z(a).effect))),ae.disabled=!s()||c(),W(oe,(z(a),B(()=>z(a).back))),se.disabled=!s()||c(),W(ce,(z(a),B(()=>z(a).apply)))},[()=>(V(na),V(o()),n(),B(()=>na(o().change.id,n()))),()=>(V(ia),V(o()),n(),B(()=>ia(o().change.before,n()))),()=>(V(ia),V(o()),n(),B(()=>ia(o().change.after,n())))]),wr(`click`,ae,()=>l()(`cancel`)),wr(`click`,se,()=>l()(`approve`)),U(e,t)};G(f,e=>{V(o()),B(()=>o().kind===`quick-edit`)?e(p):e(m,-1)}),U(e,d),k(),i()}Tr([`click`]);function ll(e,t){let n=t,r=!0,i=()=>queueMicrotask(()=>{if(!r||!e.isConnected)return;let t=e.querySelector?.(`h2`);t?.isConnected?(t.setAttribute(`tabindex`,`-1`),t.focus({preventScroll:!1})):e.focus({preventScroll:!1})});return i(),{update(e){e!==n&&(n=e,i())},destroy(){r=!1}}}var ul=H(`

                                              `),dl=H(`

                                              `),fl=H(`
                                              `);function pl(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`prompt`,8),s=X(t,`revision`,8),c=X(t,`promptRevision`,8),l=X(t,`controller`,8),u=X(t,`busy`,8),d=X(t,`onSubmit`,8),f=X(t,`onRetryDiscovery`,8),p=X(t,`onBack`,8);Tn(()=>(V(o()),n()),()=>{N(a,Ia(o(),n()))}),En(),ji();var m=fl(),h=P(m),g=P(h),_=I(g,!0),v=I(L(g));D(h);var y=L(h,2),b=e=>{var t=ul(),r=I(t,!0);R(e=>W(r,e),[()=>(V(o()),V(Z),n(),z(a),B(()=>o().kind===`repositories`?Z(`batchReviewSelection`,n()):z(a)?.title??o().title))]),U(e,t)},x=gt(()=>(V(o()),B(()=>![`question`,`management`,`quick-edit`,`quick-review`,`batch-plan`,`batch-result`].includes(o().kind))));G(y,e=>{z(x)&&e(b)});var S=L(y,2),C=e=>{var t=dl(),n=I(t,!0);R(()=>W(n,(z(a),V(o()),B(()=>z(a)?.description??(`description`in o()?o().description:``))))),U(e,t)};G(S,e=>{z(a),V(o()),B(()=>z(a)?.description||`description`in o()&&o().description)&&e(C)}),Yr(L(S,2),c,e=>{var t=Pr(),n=F(t),r=e=>{{let t=A(()=>(V(o()),B(()=>o().kind===`batch-plan`?`review`:`result`)));Yc(e,{get batch(){return V(o()),B(()=>o().batch)},get mode(){return z(t)},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})}},i=e=>{tl(e,{get selection(){return V(o()),B(()=>o().selection)},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})},a=e=>{cs(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()},get onRetryDiscovery(){return f()},get onBack(){return p()}})},s=e=>{fs(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})},c=e=>{xs(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})},m=e=>{mc(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})},h=e=>{Oc(e,{get view(){return V(o()),B(()=>o().management)},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})},g=e=>{cl(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})};G(n,e=>{V(o()),B(()=>o().kind===`batch-plan`||o().kind===`batch-result`)?e(r):(V(o()),B(()=>o().kind===`repositories`)?e(i,1):(V(o()),B(()=>o().kind===`question`)?e(a,2):(V(o()),B(()=>o().kind===`choice`||o().kind===`confirm`)?e(s,3):(V(o()),B(()=>o().kind===`text`||o().kind===`secret`)?e(c,4):(V(o()),B(()=>o().kind===`plan`)?e(m,5):(V(o()),B(()=>o().kind===`management`)?e(h,6):(V(o()),B(()=>o().kind===`quick-edit`||o().kind===`quick-review`)&&e(g,7))))))))}),U(e,t)}),D(m),ii(m,(e,t)=>ll?.(e,t),c),R((e,t,n)=>{J(m,`aria-label`,e),W(_,t),W(v,`${n??``} ${s()??``}`)},[()=>(V(Z),n(),B(()=>Z(`currentDecision`,n()))),()=>(V(Z),n(),B(()=>Z(`currentDecision`,n()))),()=>(V(Z),n(),B(()=>Z(`session`,n())))]),U(e,m),k(),i()}var ml=`Optional runner discovery selected(Optional organization runner discovery selected(List existing repository self-hosted runners without changing access.(List existing eligible runner groups and their runners; manual routing remains available without this grant.(Create the reviewed installation commit and installer-owned branch.(Include reviewed workflow files in the installation PR.(Create the reviewed installation PR without merging it.(Add only the reviewed repository access to an existing selected resource.(Inspect reusable organization configuration without changing its values.(Inspect effective repository overrides.(Inspect existing Secret names without reading their values.(Inspect inherited Secret access without replacing existing bindings.(Inspect existing trusted credential-health evidence.(Resolve repository identity and visibility.(Inspect installed workflows and repository files.(Inspect and provision selected GitHub Actions Secrets.(Inspect and provision selected GitHub Actions Variables.(Provision labels and issue resources.(Inspect and dispatch credential-health workflows.(Inspect CI workflow runs and jobs for exact producer identities.(Discover exact CI check and producer identities for guarded approval.(Inspect branch protection and rulesets.(Bootstrap a missing credential-health workflow.(Inspect and provision organization Actions Secrets.(Inspect and provision organization Actions Variables.(Provision and assign configured issue types.(Inspect selected Projects and their Status options; setup does not edit Project items.(Create the initial repository tag when no version tag exists.(Create an isolated branch for the Actions permission check.(Create the initial tag and an isolated branch for the Actions permission check.(Create the initial tag or an isolated branch for the Actions permission check.(Inspect and provision selected repository Actions Secrets.(Inspect and provision selected repository Actions Variables.(Provision labels for the selected issue workflows.(Dispatch credential-health checks for existing Secrets.(Prepare and clean isolated Actions checks for the bot PAT and any existing credentials.(Prepare a verified no-job workflow for the bot Actions check.(Inspect CI workflow runs and jobs for approval evidence.(Temporarily install credential health when its workflow is not confirmed installed.(Inspect branch protection and effective rulesets.(Inspect and provision selected organization Actions Secrets.(Inspect and provision selected organization Actions Variables.(Provision native issue types for the selected workflows.(Resolve repository and collaborator metadata.(Read repository branches, commits, and files for enabled runtime routes.(Dispatch selected release or hotfix workflows and check previous runs.(Check previous workflow runs before executing an enabled route.(Create managed branches, edit files, or merge selected release/hotfix changes.(Manage selected issue lifecycles, comments, and progress.(Manage selected pull request workflows, reviews, or autofix.(Verify current-head required checks and producer identities.(Load the PR approval assessment policy.(Select or authorize organization members for enabled workflows.(Assign configured organization issue types.(Update selected organization Projects.(Load the organization-scoped approval policy.(Secret provisioning enabled(Variable provisioning enabled(Issue workflows enabled(Credential health enabled(Initial tag or credential-health check enabled(Pull-request approval enabled(Guarded pull-request approval enabled(Release, hotfix, or guarded approval enabled(Temporary health workflow required(Organization Secret storage selected(Organization Variable storage selected(Issue type automation enabled(Organization Projects selected`.split(`(`),hl={"Optional runner discovery selected":`Consulta opcional de runners seleccionada`,"Optional organization runner discovery selected":`Consulta opcional de runners de organización seleccionada`,"List existing repository self-hosted runners without changing access.":`Consultar los runners self-hosted existentes del repositorio sin cambiar su acceso.`,"List existing eligible runner groups and their runners; manual routing remains available without this grant.":`Consultar los grupos de runners accesibles y sus runners; la configuración manual sigue disponible sin este permiso.`,"Create the reviewed installation commit and installer-owned branch.":`Crear el commit de instalación revisado y la rama del instalador.`,"Include reviewed workflow files in the installation PR.":`Incluir los workflows revisados en la PR de instalación.`,"Create the reviewed installation PR without merging it.":`Crear la PR de instalación revisada sin fusionarla.`,"Add only the reviewed repository access to an existing selected resource.":`Añadir solo el acceso del repositorio revisado a un recurso existente de visibilidad seleccionada.`,"Inspect reusable organization configuration without changing its values.":`Inspeccionar la configuración reutilizable de la organización sin cambiar sus valores.`,"Inspect effective repository overrides.":`Inspeccionar los ajustes efectivos del repositorio.`,"Inspect existing Secret names without reading their values.":`Inspeccionar los nombres de los Secrets existentes sin leer sus valores.`,"Inspect inherited Secret access without replacing existing bindings.":`Inspeccionar el acceso a los Secrets heredados sin sustituir los existentes.`,"Inspect existing trusted credential-health evidence.":`Inspeccionar la evidencia fiable existente sobre las credenciales.`,"Resolve repository identity and visibility.":`Comprobar la identidad y visibilidad del repositorio.`,"Inspect installed workflows and repository files.":`Examinar los workflows instalados y los archivos del repositorio.`,"Inspect and provision selected GitHub Actions Secrets.":`Examinar y configurar los Secrets de GitHub Actions seleccionados.`,"Inspect and provision selected GitHub Actions Variables.":`Examinar y configurar las Variables de GitHub Actions seleccionadas.`,"Provision labels and issue resources.":`Crear etiquetas y recursos de issues.`,"Inspect and dispatch credential-health workflows.":`Examinar y ejecutar los workflows de comprobación de credenciales.`,"Inspect CI workflow runs and jobs for exact producer identities.":`Examinar ejecuciones y jobs de CI para identificar sus productores exactos.`,"Discover exact CI check and producer identities for guarded approval.":`Identificar los checks de CI y sus productores exactos para la aprobación protegida.`,"Inspect branch protection and rulesets.":`Examinar la protección de ramas y sus reglas.`,"Bootstrap a missing credential-health workflow.":`Instalar provisionalmente el workflow de comprobación de credenciales que falta.`,"Inspect and provision organization Actions Secrets.":`Examinar y configurar Secrets de Actions en la organización.`,"Inspect and provision organization Actions Variables.":`Examinar y configurar Variables de Actions en la organización.`,"Provision and assign configured issue types.":`Crear y asignar los tipos de issue configurados.`,"Inspect selected Projects and their Status options; setup does not edit Project items.":`Consultar los Projects seleccionados y sus opciones de Status; el setup no modifica los elementos de los Projects.`,"Create the initial repository tag when no version tag exists.":`Crear el tag inicial si el repositorio aún no tiene ninguno de versión.`,"Create an isolated branch for the Actions permission check.":`Crear una rama aislada para comprobar el permiso de Actions.`,"Create the initial tag and an isolated branch for the Actions permission check.":`Crear el tag inicial y una rama aislada para comprobar el permiso de Actions.`,"Create the initial tag or an isolated branch for the Actions permission check.":`Crear el tag inicial o una rama aislada para comprobar el permiso de Actions.`,"Inspect and provision selected repository Actions Secrets.":`Examinar y configurar los Secrets de Actions seleccionados en el repositorio.`,"Inspect and provision selected repository Actions Variables.":`Examinar y configurar las Variables de Actions seleccionadas en el repositorio.`,"Provision labels for the selected issue workflows.":`Crear las etiquetas de los flujos de issues seleccionados.`,"Dispatch credential-health checks for existing Secrets.":`Ejecutar comprobaciones de credenciales para los Secrets existentes.`,"Prepare and clean isolated Actions checks for the bot PAT and any existing credentials.":`Preparar y limpiar las pruebas aisladas de Actions para el PAT del bot y las credenciales existentes.`,"Prepare a verified no-job workflow for the bot Actions check.":`Preparar un workflow verificado con los jobs desactivados para comprobar Actions con el PAT del bot.`,"Inspect CI workflow runs and jobs for approval evidence.":`Examinar ejecuciones y jobs de CI como prueba para la aprobación.`,"Temporarily install credential health when its workflow is not confirmed installed.":`Instalar temporalmente la comprobación de credenciales si su workflow no está confirmado.`,"Inspect branch protection and effective rulesets.":`Examinar la protección de ramas y las reglas efectivas.`,"Inspect and provision selected organization Actions Secrets.":`Examinar y configurar los Secrets de Actions seleccionados en la organización.`,"Inspect and provision selected organization Actions Variables.":`Examinar y configurar las Variables de Actions seleccionadas en la organización.`,"Provision native issue types for the selected workflows.":`Crear tipos de issue nativos para los flujos seleccionados.`,"Resolve repository and collaborator metadata.":`Consultar los metadatos del repositorio y sus colaboradores.`,"Read repository branches, commits, and files for enabled runtime routes.":`Leer ramas, commits y archivos del repositorio para las rutas de ejecución habilitadas.`,"Dispatch selected release or hotfix workflows and check previous runs.":`Ejecutar los flujos de release o hotfix seleccionados y comprobar ejecuciones anteriores.`,"Check previous workflow runs before executing an enabled route.":`Comprobar ejecuciones anteriores antes de iniciar un flujo habilitado.`,"Create managed branches, edit files, or merge selected release/hotfix changes.":`Crear ramas gestionadas, editar archivos o integrar cambios de release y hotfix.`,"Manage selected issue lifecycles, comments, and progress.":`Gestionar el ciclo de vida, los comentarios y el progreso de los issues seleccionados.`,"Manage selected pull request workflows, reviews, or autofix.":`Gestionar flujos de pull requests, revisiones o correcciones automáticas.`,"Verify current-head required checks and producer identities.":`Verificar los checks obligatorios y productores del commit actual.`,"Load the PR approval assessment policy.":`Leer la política de evaluación de aprobación de PRs.`,"Select or authorize organization members for enabled workflows.":`Seleccionar o autorizar miembros de la organización para los flujos activos.`,"Assign configured organization issue types.":`Asignar los tipos de issue configurados en la organización.`,"Update selected organization Projects.":`Actualizar los Projects seleccionados de la organización.`,"Load the organization-scoped approval policy.":`Leer la política de aprobación guardada en la organización.`,"Secret provisioning enabled":`Configuración de Secrets activada`,"Variable provisioning enabled":`Configuración de Variables activada`,"Issue workflows enabled":`Flujos de issues activados`,"Credential health enabled":`Comprobación de credenciales activada`,"Initial tag or credential-health check enabled":`Tag inicial o comprobación de credenciales activados`,"Pull-request approval enabled":`Aprobación de pull requests activada`,"Guarded pull-request approval enabled":`Aprobación protegida de pull requests activada`,"Release, hotfix, or guarded approval enabled":`Release, hotfix o aprobación protegida activados`,"Temporary health workflow required":`Hace falta un workflow temporal de comprobación`,"Organization Secret storage selected":`Se eligió guardar Secrets en la organización`,"Organization Variable storage selected":`Se eligió guardar Variables en la organización`,"Issue type automation enabled":`Automatización de tipos de issue activada`,"Organization Projects selected":`Se seleccionaron Projects de la organización`},gl={"Optional runner discovery selected":`Consultation facultative des runners sélectionnée`,"Optional organization runner discovery selected":`Consultation facultative des runners de l’organisation sélectionnée`,"List existing repository self-hosted runners without changing access.":`Consulter les runners auto-hébergés existants du dépôt sans modifier leurs accès.`,"List existing eligible runner groups and their runners; manual routing remains available without this grant.":`Consulter les groupes accessibles et leurs runners ; la configuration manuelle reste possible sans ce droit.`,"Create the reviewed installation commit and installer-owned branch.":`Créer le commit d’installation validé et la branche de l’installateur.`,"Include reviewed workflow files in the installation PR.":`Inclure les workflows validés dans la PR d’installation.`,"Create the reviewed installation PR without merging it.":`Créer la PR d’installation validée sans la fusionner.`,"Add only the reviewed repository access to an existing selected resource.":`Ajouter uniquement l’accès validé du dépôt à une ressource existante de visibilité sélectionnée.`,"Inspect reusable organization configuration without changing its values.":`Lire la configuration réutilisable de l’organisation sans modifier ses valeurs.`,"Inspect effective repository overrides.":`Lire les réglages effectifs du dépôt.`,"Inspect existing Secret names without reading their values.":`Lire les noms des Secrets existants sans accéder à leurs valeurs.`,"Inspect inherited Secret access without replacing existing bindings.":`Vérifier l’accès aux Secrets hérités sans remplacer les liaisons existantes.`,"Inspect existing trusted credential-health evidence.":`Lire les preuves fiables existantes de vérification des identifiants.`,"Resolve repository identity and visibility.":`Vérifier l’identité et la visibilité du dépôt.`,"Inspect installed workflows and repository files.":`Examiner les workflows installés et les fichiers du dépôt.`,"Inspect and provision selected GitHub Actions Secrets.":`Examiner et configurer les Secrets GitHub Actions choisis.`,"Inspect and provision selected GitHub Actions Variables.":`Examiner et configurer les Variables GitHub Actions choisies.`,"Provision labels and issue resources.":`Créer des étiquettes et des ressources pour les tickets.`,"Inspect and dispatch credential-health workflows.":`Examiner et lancer les workflows de vérification des identifiants.`,"Inspect CI workflow runs and jobs for exact producer identities.":`Examiner les exécutions et jobs CI pour identifier exactement leurs producteurs.`,"Discover exact CI check and producer identities for guarded approval.":`Identifier précisément les vérifications CI et leurs producteurs pour l’approbation encadrée.`,"Inspect branch protection and rulesets.":`Examiner la protection des branches et les ensembles de règles.`,"Bootstrap a missing credential-health workflow.":`Installer provisoirement le workflow de vérification des identifiants manquant.`,"Inspect and provision organization Actions Secrets.":`Examiner et configurer les Secrets Actions de l’organisation.`,"Inspect and provision organization Actions Variables.":`Examiner et configurer les Variables Actions de l’organisation.`,"Provision and assign configured issue types.":`Créer et attribuer les types de ticket configurés.`,"Inspect selected Projects and their Status options; setup does not edit Project items.":`Consulter les Projects sélectionnés et leurs options Status ; la configuration ne modifie aucun élément de Project.`,"Create the initial repository tag when no version tag exists.":`Créer le tag initial si le dépôt ne possède encore aucun tag de version.`,"Create an isolated branch for the Actions permission check.":`Créer une branche isolée pour vérifier l’autorisation Actions.`,"Create the initial tag and an isolated branch for the Actions permission check.":`Créer le tag initial et une branche isolée pour vérifier l’autorisation Actions.`,"Create the initial tag or an isolated branch for the Actions permission check.":`Créer le tag initial ou une branche isolée pour vérifier l’autorisation Actions.`,"Inspect and provision selected repository Actions Secrets.":`Examiner et configurer les Secrets Actions choisis dans le dépôt.`,"Inspect and provision selected repository Actions Variables.":`Examiner et configurer les Variables Actions choisies dans le dépôt.`,"Provision labels for the selected issue workflows.":`Créer les étiquettes des workflows de ticket choisis.`,"Dispatch credential-health checks for existing Secrets.":`Lancer des vérifications d’identifiants pour les Secrets existants.`,"Prepare and clean isolated Actions checks for the bot PAT and any existing credentials.":`Préparer et nettoyer les tests Actions isolés du PAT du bot et des identifiants existants.`,"Prepare a verified no-job workflow for the bot Actions check.":`Préparer un workflow vérifié aux jobs désactivés pour tester Actions avec le PAT du bot.`,"Inspect CI workflow runs and jobs for approval evidence.":`Examiner les exécutions et jobs CI comme preuve pour l’approbation.`,"Temporarily install credential health when its workflow is not confirmed installed.":`Installer provisoirement la vérification des identifiants si son workflow n’est pas confirmé.`,"Inspect branch protection and effective rulesets.":`Examiner la protection des branches et les règles applicables.`,"Inspect and provision selected organization Actions Secrets.":`Examiner et configurer les Secrets Actions choisis dans l’organisation.`,"Inspect and provision selected organization Actions Variables.":`Examiner et configurer les Variables Actions choisies dans l’organisation.`,"Provision native issue types for the selected workflows.":`Créer des types de ticket natifs pour les workflows choisis.`,"Resolve repository and collaborator metadata.":`Consulter les métadonnées du dépôt et de ses collaborateurs.`,"Read repository branches, commits, and files for enabled runtime routes.":`Lire les branches, commits et fichiers du dépôt pour les parcours d’exécution activés.`,"Dispatch selected release or hotfix workflows and check previous runs.":`Lancer les workflows de version ou correctif urgent choisis et vérifier les exécutions précédentes.`,"Check previous workflow runs before executing an enabled route.":`Vérifier les exécutions précédentes avant de lancer un parcours activé.`,"Create managed branches, edit files, or merge selected release/hotfix changes.":`Créer des branches gérées, modifier des fichiers ou fusionner les changements de version et correctif.`,"Manage selected issue lifecycles, comments, and progress.":`Gérer le cycle de vie, les commentaires et la progression des tickets choisis.`,"Manage selected pull request workflows, reviews, or autofix.":`Gérer les workflows de pull request, les revues ou les corrections automatiques.`,"Verify current-head required checks and producer identities.":`Vérifier les contrôles requis et leurs producteurs pour le commit courant.`,"Load the PR approval assessment policy.":`Lire la politique d’évaluation de l’approbation des PR.`,"Select or authorize organization members for enabled workflows.":`Sélectionner ou autoriser des membres de l’organisation pour les workflows activés.`,"Assign configured organization issue types.":`Attribuer les types de ticket configurés dans l’organisation.`,"Update selected organization Projects.":`Mettre à jour les projets de l’organisation choisis.`,"Load the organization-scoped approval policy.":`Lire la politique d’approbation stockée dans l’organisation.`,"Secret provisioning enabled":`Configuration des Secrets activée`,"Variable provisioning enabled":`Configuration des Variables activée`,"Issue workflows enabled":`Workflows de ticket activés`,"Credential health enabled":`Vérification des identifiants activée`,"Initial tag or credential-health check enabled":`Tag initial ou vérification des identifiants activés`,"Pull-request approval enabled":`Approbation des pull requests activée`,"Guarded pull-request approval enabled":`Approbation encadrée des pull requests activée`,"Release, hotfix, or guarded approval enabled":`Version, correctif urgent ou approbation encadrée activés`,"Temporary health workflow required":`Workflow temporaire de vérification requis`,"Organization Secret storage selected":`Stockage des Secrets dans l’organisation choisi`,"Organization Variable storage selected":`Stockage des Variables dans l’organisation choisi`,"Issue type automation enabled":`Automatisation des types de ticket activée`,"Organization Projects selected":`Projets de l’organisation choisis`},_l={"Optional runner discovery selected":`Consulta opcional de runners selecionada`,"Optional organization runner discovery selected":`Consulta opcional de runners da organização selecionada`,"List existing repository self-hosted runners without changing access.":`Consultar os runners self-hosted existentes do repositório sem alterar o acesso.`,"List existing eligible runner groups and their runners; manual routing remains available without this grant.":`Consultar os grupos acessíveis e os seus runners; a configuração manual continua disponível sem esta permissão.`,"Create the reviewed installation commit and installer-owned branch.":`Criar o commit de instalação revisto e o ramo do instalador.`,"Include reviewed workflow files in the installation PR.":`Incluir os workflows revistos na PR de instalação.`,"Create the reviewed installation PR without merging it.":`Criar a PR de instalação revista sem a integrar.`,"Add only the reviewed repository access to an existing selected resource.":`Adicionar apenas o acesso revisto do repositório a um recurso existente de visibilidade selecionada.`,"Inspect reusable organization configuration without changing its values.":`Consultar a configuração reutilizável da organização sem alterar os seus valores.`,"Inspect effective repository overrides.":`Consultar os ajustes efetivos do repositório.`,"Inspect existing Secret names without reading their values.":`Consultar os nomes dos Secrets existentes sem ler os seus valores.`,"Inspect inherited Secret access without replacing existing bindings.":`Consultar o acesso aos Secrets herdados sem substituir as ligações existentes.`,"Inspect existing trusted credential-health evidence.":`Consultar as provas fiáveis existentes da verificação das credenciais.`,"Resolve repository identity and visibility.":`Verificar a identidade e visibilidade do repositório.`,"Inspect installed workflows and repository files.":`Inspecionar os fluxos instalados e os ficheiros do repositório.`,"Inspect and provision selected GitHub Actions Secrets.":`Inspecionar e configurar os Secrets do GitHub Actions selecionados.`,"Inspect and provision selected GitHub Actions Variables.":`Inspecionar e configurar as Variables do GitHub Actions selecionadas.`,"Provision labels and issue resources.":`Criar etiquetas e recursos para questões.`,"Inspect and dispatch credential-health workflows.":`Inspecionar e executar os fluxos de verificação de credenciais.`,"Inspect CI workflow runs and jobs for exact producer identities.":`Inspecionar execuções e jobs CI para identificar exatamente os seus produtores.`,"Discover exact CI check and producer identities for guarded approval.":`Identificar as verificações CI e os seus produtores exatos para a aprovação protegida.`,"Inspect branch protection and rulesets.":`Inspecionar a proteção de ramos e os conjuntos de regras.`,"Bootstrap a missing credential-health workflow.":`Instalar temporariamente o fluxo de verificação de credenciais em falta.`,"Inspect and provision organization Actions Secrets.":`Inspecionar e configurar os Secrets de Actions da organização.`,"Inspect and provision organization Actions Variables.":`Inspecionar e configurar as Variables de Actions da organização.`,"Provision and assign configured issue types.":`Criar e atribuir os tipos de questão configurados.`,"Inspect selected Projects and their Status options; setup does not edit Project items.":`Consultar os Projects selecionados e as suas opções de Status; a configuração não altera os itens dos Projects.`,"Create the initial repository tag when no version tag exists.":`Criar a etiqueta inicial se o repositório ainda não tiver etiquetas de versão.`,"Create an isolated branch for the Actions permission check.":`Criar um ramo isolado para verificar a permissão de Actions.`,"Create the initial tag and an isolated branch for the Actions permission check.":`Criar a etiqueta inicial e um ramo isolado para verificar a permissão de Actions.`,"Create the initial tag or an isolated branch for the Actions permission check.":`Criar a etiqueta inicial ou um ramo isolado para verificar a permissão de Actions.`,"Inspect and provision selected repository Actions Secrets.":`Inspecionar e configurar os Secrets de Actions selecionados no repositório.`,"Inspect and provision selected repository Actions Variables.":`Inspecionar e configurar as Variables de Actions selecionadas no repositório.`,"Provision labels for the selected issue workflows.":`Criar etiquetas para os fluxos de questões selecionados.`,"Dispatch credential-health checks for existing Secrets.":`Executar verificações de credenciais para os Secrets existentes.`,"Prepare and clean isolated Actions checks for the bot PAT and any existing credentials.":`Preparar e limpar os testes isolados de Actions para o PAT do bot e as credenciais existentes.`,"Prepare a verified no-job workflow for the bot Actions check.":`Preparar um workflow verificado com os jobs desativados para testar Actions com o PAT do bot.`,"Inspect CI workflow runs and jobs for approval evidence.":`Inspecionar execuções e jobs CI como prova para aprovação.`,"Temporarily install credential health when its workflow is not confirmed installed.":`Instalar temporariamente a verificação de credenciais se o fluxo não estiver confirmado.`,"Inspect branch protection and effective rulesets.":`Inspecionar a proteção de ramos e as regras aplicáveis.`,"Inspect and provision selected organization Actions Secrets.":`Inspecionar e configurar os Secrets de Actions selecionados na organização.`,"Inspect and provision selected organization Actions Variables.":`Inspecionar e configurar as Variables de Actions selecionadas na organização.`,"Provision native issue types for the selected workflows.":`Criar tipos de questão nativos para os fluxos selecionados.`,"Resolve repository and collaborator metadata.":`Consultar os metadados do repositório e dos colaboradores.`,"Read repository branches, commits, and files for enabled runtime routes.":`Ler branches, commits e arquivos do repositório para os fluxos de execução habilitados.`,"Dispatch selected release or hotfix workflows and check previous runs.":`Executar os fluxos de release ou hotfix selecionados e verificar execuções anteriores.`,"Check previous workflow runs before executing an enabled route.":`Verificar execuções anteriores antes de iniciar um percurso ativo.`,"Create managed branches, edit files, or merge selected release/hotfix changes.":`Criar ramos geridos, editar ficheiros ou integrar alterações de release e hotfix.`,"Manage selected issue lifecycles, comments, and progress.":`Gerir o ciclo de vida, os comentários e o progresso das questões selecionadas.`,"Manage selected pull request workflows, reviews, or autofix.":`Gerir fluxos de pull requests, revisões ou correções automáticas.`,"Verify current-head required checks and producer identities.":`Verificar as verificações obrigatórias e os produtores do commit atual.`,"Load the PR approval assessment policy.":`Ler a política de avaliação de aprovação de PRs.`,"Select or authorize organization members for enabled workflows.":`Selecionar ou autorizar membros da organização para os fluxos ativos.`,"Assign configured organization issue types.":`Atribuir os tipos de questão configurados na organização.`,"Update selected organization Projects.":`Atualizar os Projetos selecionados da organização.`,"Load the organization-scoped approval policy.":`Ler a política de aprovação guardada na organização.`,"Secret provisioning enabled":`Configuração de Secrets ativa`,"Variable provisioning enabled":`Configuração de Variables ativa`,"Issue workflows enabled":`Fluxos de questões ativos`,"Credential health enabled":`Verificação de credenciais ativa`,"Initial tag or credential-health check enabled":`Etiqueta inicial ou verificação de credenciais ativas`,"Pull-request approval enabled":`Aprovação de pull requests ativa`,"Guarded pull-request approval enabled":`Aprovação protegida de pull requests ativa`,"Release, hotfix, or guarded approval enabled":`Release, hotfix ou aprovação protegida ativos`,"Temporary health workflow required":`É necessário um fluxo temporário de verificação`,"Organization Secret storage selected":`Armazenamento dos Secrets na organização selecionado`,"Organization Variable storage selected":`Armazenamento das Variables na organização selecionado`,"Issue type automation enabled":`Automatização de tipos de questão ativa`,"Organization Projects selected":`Projetos da organização selecionados`},vl=new Set(ml),yl={es:hl,fr:gl,pt:_l};function bl(e,t){return e===`en`?t:vl.has(t)?yl[e][t]:Z(`permissionUnknown`,e)}var xl={en:{"contents-write":`Actions was not tested because its temporary branch could not be created. Check repository Contents Write, repository selection and organization authorization.`,"contents-workflows-write":`Actions was not tested because its temporary workflow could not be written. Check repository Contents and Workflows Write, repository selection and organization authorization. Unverifiable does not mean Actions is missing.`,"dispatch-workflow":`Actions was not tested because no active workflow_dispatch workflow was found on the default branch. Install an eligible workflow before retrying.`},es:{"contents-write":`No se comprobó Actions porque no se pudo crear su rama temporal. Revisa Contents Write del repositorio, la selección del repositorio y la autorización de la organización.`,"contents-workflows-write":`No se comprobó Actions porque no se pudo escribir su workflow temporal. Revisa Contents y Workflows Write del repositorio, la selección del repositorio y la autorización de la organización. No verificable no significa que falte Actions.`,"dispatch-workflow":`No se comprobó Actions porque no se encontró un workflow activo con workflow_dispatch en la rama predeterminada. Instala uno antes de reintentar.`},fr:{"contents-write":`Actions n’a pas été testé car sa branche temporaire n’a pas pu être créée. Vérifiez Contents Write du dépôt, la sélection du dépôt et l’autorisation de l’organisation.`,"contents-workflows-write":`Actions n’a pas été testé car son workflow temporaire n’a pas pu être écrit. Vérifiez Contents et Workflows Write du dépôt, la sélection du dépôt et l’autorisation de l’organisation. Non vérifiable ne signifie pas qu’Actions manque.`,"dispatch-workflow":`Actions n’a pas été testé car aucun workflow actif avec workflow_dispatch n’a été trouvé sur la branche par défaut. Installez-en un avant de réessayer.`},pt:{"contents-write":`Actions não foi testado porque não foi possível criar a sua branch temporária. Verifique Contents Write do repositório, a seleção do repositório e a autorização da organização.`,"contents-workflows-write":`Actions não foi testado porque não foi possível escrever o seu workflow temporário. Verifique Contents e Workflows Write do repositório, a seleção do repositório e a autorização da organização. Não verificável não significa que falte Actions.`,"dispatch-workflow":`Actions não foi testado porque não foi encontrado um workflow ativo com workflow_dispatch na branch predefinida. Instale um antes de tentar novamente.`}};function Sl(e,t){if(e===`contents-write`||e===`contents-workflows-write`||e===`dispatch-workflow`)return xl[t][e]}function Cl(e,t){if(e.status===`unverifiable`&&e.permission===`Actions`&&e.level===`write`){let n=Sl(e.prerequisite,t);if(n)return n}return e.status===`verified`?Z(e.level===`write`?`permissionEvidenceVerifiedWrite`:e.scope===`organization`&&e.permission===`Projects`&&e.level===`read`?`permissionEvidencePrivateProject`:`permissionEvidenceVerified`,t):e.status===`missing`?Z(`permissionEvidenceMissing`,t):e.status===`available`?Z(e.publicReadEvidence===`public-organization-projects`?`permissionEvidencePublicProjects`:`permissionEvidencePublic`,t):e.level===`write`?Z(`permissionEvidenceWrite`,t):e.publicReadEvidence===`public-organization-projects`?Z(`permissionEvidencePublicProjects`,t):e.publicReadEvidence===`public-repository`?Z(`permissionEvidencePublic`,t):Z(`permissionEvidenceUnknownRead`,t)}var wl=H(` `),Tl=H(` `),El=H(`
                                            • `),Dl=H(`

                                                `),Ol=H(`

                                                `),kl=H(``);function Al(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`view`,8);ji();var o=kl(),s=P(o),c=L(P(s)),l=I(c,!0),u=L(c),d=I(u,!0),f=L(u),p=I(P(f),!0);D(f),D(s);var m=L(s,2),h=e=>{var t=Dl(),r=L(P(t)),i=I(r),o=L(r),s=I(o,!0),c=L(o,2);q(c,5,()=>(V(a()),B(()=>a().permissions.report?.checks??a().permissions.requirements??[])),K,(e,t)=>{var r=El(),i=P(r),a=P(i,!0),o=L(a),s=e=>{var n=wl(),r=I(P(n));D(n),R(()=>W(r,`GitHub · ${z(t),B(()=>z(t).permission)??``}`)),U(e,n)},c=gt(()=>(n(),V(nc),z(t),B(()=>n()!==`en`&&nc(n(),z(t).permission)!==z(t).permission)));G(o,e=>{z(c)&&e(s)});var l=L(o),u=I(l),d=L(l),f=I(d,!0),p=L(d),m=e=>{var r=Tl(),i=I(r,!0);R(e=>W(i,e),[()=>(V(bl),n(),z(t),B(()=>bl(n(),z(t).condition)))]),U(e,r)};G(p,e=>{z(t),B(()=>z(t).condition)&&e(m)});var h=L(p),g=e=>{var r=Tl(),i=I(r,!0);R(e=>W(i,e),[()=>(V(Cl),z(t),n(),B(()=>Cl(z(t),n())))]),U(e,r)};G(h,e=>{`status`in z(t)&&e(g)}),D(i);var _=L(i),v=P(_,!0),y=L(v),b=e=>{var r=Tl(),i=I(r,!0);R(e=>W(i,e),[()=>(V(rc),n(),z(t),B(()=>rc(n(),z(t).status)))]),U(e,r)},x=gt(()=>(z(t),V(rc),n(),B(()=>`status`in z(t)&&rc(n(),z(t).status))));G(y,e=>{z(x)&&e(b)}),D(_),D(r),R((e,t,n,r,i)=>{W(a,e),W(u,`${t??``} · ${n??``}`),W(f,r),W(v,i)},[()=>(V(nc),n(),z(t),B(()=>nc(n(),z(t).permission))),()=>(V(tc),n(),z(t),B(()=>tc(n(),z(t).scope))),()=>(V(tc),n(),z(t),B(()=>tc(n(),z(t).applicability))),()=>(V(bl),n(),z(t),B(()=>bl(n(),z(t).reason))),()=>(V(tc),n(),z(t),B(()=>tc(n(),z(t).level)))]),U(e,r)}),D(c);var l=I(L(c,2),!0);D(t),R((e,t,n,r)=>{W(i,`${e??``} ${t??``}`),W(s,n),W(l,r)},[()=>(V(a()),V(Z),n(),B(()=>a().permissions.role===`setup`?Z(`setupPat`,n()):Z(`botPat`,n()))),()=>(V(Z),n(),B(()=>Z(`access`,n()))),()=>(V(a()),V(Z),n(),B(()=>a().permissions.report?Z(`readOnlyCheck`,n()):Z(`provisionalGrants`,n()))),()=>(V(Z),n(),B(()=>Z(`conditionalGrants`,n())))]),U(e,t)},g=e=>{var t=Ol(),r=L(P(t)),i=I(r,!0),a=I(L(r),!0);D(t),R((e,t)=>{W(i,e),W(a,t)},[()=>(V(Z),n(),B(()=>Z(`permissionsFollow`,n()))),()=>(V(Z),n(),B(()=>Z(`permissionsFollowBody`,n())))]),U(e,t)};G(m,e=>{V(a()),B(()=>a().permissions)?e(h):e(g,-1)}),D(o),R((e,t,n)=>{J(o,`aria-label`,e),W(l,t),W(d,n),W(p,(V(a()),B(()=>a().batch?.organization??a().repository)))},[()=>(V(Z),n(),B(()=>Z(`setup`,n()))),()=>(V(Z),V(a()),n(),B(()=>Z(a().batch?`batchFocusTitle`:`repoFocus`,n()))),()=>(V(a()),V(Z),n(),B(()=>a().batch?Z(`batchFocusBody`,n(),{count:String(a().batch.targets.length)}):Z(`repoFocusBody`,n())))]),U(e,o),k(),i()}function jl(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`report`,8,void 0);ji();var o=Pr(),s=F(o),c=e=>{{let t=A(()=>(V(Z),n(),B(()=>Z(`permissionSecretCollision`,n())))),r=A(()=>(V(Z),n(),B(()=>Z(`permissionSecretCollisionAction`,n()))));$a(e,{tone:`warning`,get title(){return z(t)},get message(){return z(r)}})}},l=gt(()=>(V(a()),B(()=>a()?.checks.some(e=>e.incident===`secret-collision`)))),u=e=>{{let t=A(()=>(V(Z),n(),B(()=>Z(`permissionProbeCleanupPending`,n())))),r=A(()=>(V(Z),n(),B(()=>Z(`permissionProbeCleanupAction`,n()))));$a(e,{tone:`warning`,get title(){return z(t)},get message(){return z(r)}})}},d=gt(()=>(V(a()),B(()=>a()?.checks.some(e=>e.cleanupPending))));G(s,e=>{z(l)?e(c):z(d)&&e(u,1)}),U(e,o),k(),i()}var Ml=H(`
                                              • `),Nl=H(`

                                                  `);function Pl(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`effects`,8),o={files:`receiptFiles`,secrets:`receiptSecrets`,labels:`receiptLabels`,"issue-types":`receiptIssueTypes`,variables:`receiptVariables`,"initial-tag":`receiptInitialTag`},s={completed:`effectCompleted`,skipped:`effectSkipped`,"needs-inspection":`effectInspect`,"not-started":`effectNotStarted`,"in-progress":`effectInProgress`},c={local:`scopeLocal`,repository:`scopeRepository`,organization:`scopeOrganization`,mixed:`scopeMixed`};ji();var l=Nl(),u=P(l),d=I(u,!0),f=L(u,2);q(f,5,a,e=>e.id,(e,t)=>{var r=Ml(),i=P(r),a=I(i,!0),l=L(i),u=L(l),d=e=>{var r=Nr();R(e=>W(r,`· ${e??``}`),[()=>(V(Z),z(t),n(),B(()=>Z(c[z(t).scope],n())))]),U(e,r)};G(u,e=>{z(t),B(()=>z(t).scope)&&e(d)}),D(r),R((e,t)=>{W(a,e),W(l,` — ${t??``}`)},[()=>(z(t),V(Z),n(),B(()=>o[z(t).id]?Z(o[z(t).id],n()):z(t).id)),()=>(V(Z),z(t),n(),B(()=>Z(s[z(t).state],n())))]),U(e,r)}),D(f),D(l),R(e=>W(d,e),[()=>(V(Z),n(),B(()=>Z(`resourceReceipt`,n())))]),U(e,l),k(),i()}var Fl=H(`
                                                • `),Il=H(`

                                                    `,1),Ll=H(`

                                                    `);function Rl(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`correction`,8);ji();var o=Ll(),s=P(o),c=I(s,!0),l=L(s,2),u=I(l,!0),d=L(l,2),f=e=>{var t=Il(),r=F(t),i=I(P(r));D(r);var o=L(r,2);q(o,5,()=>(V(a()),B(()=>a().addedGrants)),K,(e,t)=>{var n=Fl(),r=I(P(n),!0);D(n),R(()=>W(r,z(t))),U(e,n)}),D(o),R(e=>W(i,`${e??``}:`),[()=>(V(Z),n(),B(()=>Z(`updatedSetupPatGrants`,n())))]),U(e,t)};G(d,e=>{V(a()),B(()=>a().stage===`final`&&a().addedGrants.length)&&e(f)});var p=L(d,2),m=I(p);D(o),R((e,t,n,r)=>{J(o,`aria-label`,e),W(c,t),W(u,n),J(p,`href`,(V(a()),B(()=>a().url))),W(m,`${r??``} ↗`)},[()=>(V(Z),n(),B(()=>Z(`updatedSetupPatTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`updatedSetupPatTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`updatedSetupPatBody`,n()))),()=>(V(Z),n(),B(()=>Z(`updatedSetupPatLink`,n())))]),U(e,o),k(),i()}var zl=H(`

                                                    `,1);function Bl(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi();ji();var a=zl(),o=F(a),s=I(o,!0),c=L(o,2),l=P(c),u=L(l),d=I(u);D(c),R((e,t,n)=>{W(s,e),W(l,`${t??``} `),J(u,`href`,Ba.firstWorkflow),W(d,`${n??``} ↗`)},[()=>Z(`botRenewal`,n()),()=>Z(`setupNextWorkflow`,n()),()=>Z(`firstWorkflowGuide`,n())]),U(e,a),k(),i()}var Vl=H(`

                                                    `),Hl=H(`

                                                    `),Ul=H(`

                                                    `),Wl=H(` `),Gl=H(`

                                                    `),Kl=H(`
                                                  • `),ql=H(`
                                                      `),Jl=H(`

                                                      `),Yl=H(`
                                                      `),Xl=H(`copilot doctor --read-only`),Zl=H(`

                                                      `);function Ql(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=M(),s=M(),c=M(),l=M(),u=M(),d=M(),f=M(),p=M(),m=X(t,`management`,8,!1),h=X(t,`batch`,8,!1),g=X(t,`outcome`,8),_=X(t,`controller`,8),v=X(t,`onClose`,8),y=X(t,`onDoctor`,8,async()=>void 0),b=X(t,`doctor`,8,void 0),x=X(t,`detail`,8,void 0),S=X(t,`permissionReport`,8,void 0),C=X(t,`setupPatCorrection`,8,void 0),w={permissions:[`reasonPermissions`,`nextPermissions`],storage:[`reasonStorage`,`nextStorage`],configuration:[`reasonConfiguration`,`nextConfiguration`],"session-expired":[`reasonExpired`,`nextExpired`],cancelled:[`reasonCancelled`,`nextCancelled`],provider:[`reasonProvider`,`nextProvider`],"rate-limit":[`reasonRateLimit`,`nextRateLimit`],unknown:[`reasonUnknown`,`nextUnknown`]};Tn(()=>V(x()),()=>{N(a,x()?.effects?.some(e=>e.state===`completed`)===!0)}),Tn(()=>(V(h()),n(),V(m()),V(g()),z(a)),()=>{N(o,h()?Z(`batchNextActions`,n()):m()?ta(n())[g()===`complete`&&z(a)?`finished`:g()===`partial`?`inspectAdjustment`:g()===`complete`?`inspectionFinished`:`inspectionStopped`]:g()===`complete`?Z(`resultApplied`,n()):g()===`dry-run`?Z(`resultNoChanges`,n()):g()===`cancelled`||g()===`blocked`?Z(`resultStopped`,n()):Z(`resultPartial`,n()))}),Tn(()=>(V(h()),n(),V(m()),V(g()),z(a)),()=>{N(s,h()?Z(`batchResultBody`,n()):m()?ta(n())[g()===`complete`&&z(a)?`finishedBody`:g()===`partial`?`partial`:`inspectionBody`]:g()===`complete`?Z(`resultCompleteBody`,n()):g()===`partial`?Z(`resultPartialBody`,n()):Z(`resultNoChangesBody`,n()))}),Tn(()=>(V(g()),V(x()),V(S())),()=>{N(c,(g()===`blocked`||g()===`partial`)&&x()?.reasonCode===`permissions`?S():void 0)}),Tn(()=>z(c),()=>{N(l,z(c)?.checks.some(e=>e.cleanupPending===!0)===!0)}),Tn(()=>z(c),()=>{N(u,z(c)?.checks.some(e=>e.incident===`secret-collision`)===!0)}),Tn(()=>(z(c),V(x())),()=>{N(d,z(c)?.role===`workflow`?`reasonWorkflowPermissions`:w[x()?.reasonCode??`unknown`][0])}),Tn(()=>(V(g()),V(h()),V(x()),z(l),z(u),V(C())),()=>{N(f,(g()===`blocked`||h()&&g()===`partial`)&&x()?.reasonCode===`permissions`&&(h()||x().mutationStarted===!1)&&!z(l)&&!z(u)&&C())}),Tn(()=>z(c),()=>{N(p,z(c)?z(c).checks.filter(e=>e.applicability===`required`&&e.status!==`verified`&&e.status!==`available`):[])}),En(),ji();var ee=Zl(),te=P(ee),ne=I(te,!0),re=L(te),ie=I(re,!0),ae=L(re,2),oe=e=>{var t=Ul(),r=P(t),i=P(r),a=I(i),o=L(i);D(r);var s=L(r,2),c=e=>{var t=Vl(),r=P(t),i=I(r),a=L(r);D(t),R((e,t)=>{W(i,`${e??``}:`),W(a,` ${t??``}`)},[()=>(V(Z),n(),B(()=>Z(`progress`,n()))),()=>(V(Zi),V(x()),n(),B(()=>Zi(x().stoppedStage,n())))]),U(e,t)};G(s,e=>{V(x()),B(()=>x()?.stoppedStage)&&e(c)});var f=L(s,2),p=P(f),m=I(p),h=L(p);D(f);var _=L(f,2),v=P(_),y=I(v),b=L(v);D(_);var S=L(_,2),C=e=>{var t=Hl(),r=P(t),i=I(r),a=I(L(r,2),!0);D(t),R(e=>{W(i,`${e??``}:`),W(a,(V(x()),B(()=>x().diagnosticRef)))},[()=>(V(Z),n(),B(()=>Z(`diagnosticReference`,n())))]),U(e,t)};G(S,e=>{V(x()),B(()=>x()?.diagnosticRef)&&e(C)}),D(t),R((e,t,n,r,i,s)=>{W(a,`${e??``}:`),W(o,` ${t??``}`),W(m,`${n??``}:`),W(h,` ${r??``}`),W(y,`${i??``}:`),W(b,` ${s??``}`)},[()=>(V(Z),n(),B(()=>Z(`whatHappened`,n()))),()=>(V(Z),z(d),n(),B(()=>Z(z(d),n()))),()=>(V(Z),n(),B(()=>Z(`alreadyChanged`,n()))),()=>(z(u),V(Z),n(),z(l),V(x()),V(g()),B(()=>z(u)?Z(`permissionSecretCollision`,n()):z(l)?Z(`permissionProbeCleanupPending`,n()):x()?.mutationStarted||g()===`partial`?Z(`inspectPartial`,n()):Z(`noChanges`,n()))),()=>(V(Z),n(),B(()=>Z(`nextAction`,n()))),()=>(z(u),V(Z),n(),z(l),V(g()),V(x()),B(()=>z(u)?Z(`permissionSecretCollisionAction`,n()):z(l)?Z(`permissionProbeCleanupAction`,n()):g()===`partial`?`${Z(`inspectPartial`,n())} ${Z(w[x()?.reasonCode??`unknown`][1],n())}`:Z(w[x()?.reasonCode??`unknown`][1],n())))]),U(e,t)};G(ae,e=>{(g()===`blocked`||g()===`cancelled`||g()===`partial`)&&e(oe)});var se=L(ae,2),ce=e=>{var t=Jl(),r=P(t),i=I(r,!0),a=L(r,2),o=I(a,!0),s=L(a,2),l=P(s),u=I(l),d=L(l);D(s);var f=L(s,2),m=e=>{var t=ql();q(t,5,()=>z(p),K,(e,t)=>{var r=Kl(),i=P(r),a=I(i,!0),o=L(i),s=e=>{var n=Wl(),r=I(P(n));D(n),R(()=>W(r,`GitHub · ${z(t),B(()=>z(t).permission)??``}`)),U(e,n)},l=gt(()=>(n(),V(nc),z(t),B(()=>n()!==`en`&&nc(n(),z(t).permission)!==z(t).permission)));G(o,e=>{z(l)&&e(s)});var u=L(o),d=L(u),f=I(d,!0),p=L(d),m=e=>{var r=Gl(),i=I(r,!0);R(e=>W(i,e),[()=>(V(Cl),z(t),n(),B(()=>Cl(z(t),n())))]),U(e,r)};G(p,e=>{z(c),B(()=>z(c).identityStatus===`valid`)&&e(m)}),D(r),R((e,t,n,r)=>{W(a,e),W(u,` — ${t??``} · ${n??``} · `),W(f,r)},[()=>(V(nc),n(),z(t),B(()=>nc(n(),z(t).permission))),()=>(V(tc),n(),z(t),B(()=>tc(n(),z(t).scope))),()=>(V(tc),n(),z(t),B(()=>tc(n(),z(t).level))),()=>(z(c),V(tc),n(),z(t),V(Z),B(()=>z(c).identityStatus===`valid`?tc(n(),z(t).status):Z(`permissionGrantNotChecked`,n())))]),U(e,r)}),D(t),U(e,t)},h=e=>{var t=Gl(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`permissionReportNoFailedGrant`,n())))]),U(e,t)};G(f,e=>{z(p),B(()=>z(p).length)?e(m):(z(c),B(()=>z(c).identityStatus===`valid`)&&e(h,1))}),D(t),R((e,n,r,a,s)=>{J(t,`aria-label`,e),W(i,n),W(o,r),W(u,`${a??``}:`),W(d,` ${s??``}`)},[()=>(V(Z),n(),B(()=>Z(`permissionReportTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`permissionReportTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`permissionReportLead`,n()))),()=>(V(Z),n(),B(()=>Z(`permissionIdentity`,n()))),()=>(V(Z),z(c),n(),B(()=>Z(z(c).identityStatus===`valid`?`permissionIdentityValid`:z(c).identityStatus===`invalid`?`permissionIdentityInvalid`:`permissionIdentityUnknown`,n())))]),U(e,t)};G(se,e=>{z(c)&&e(ce)});var le=L(se,2),ue=e=>{Pl(e,{get effects(){return V(x()),B(()=>x().effects)}})};G(le,e=>{V(x()),B(()=>x()?.effects?.length)&&e(ue)});var de=L(le,2),fe=e=>{Rl(e,{get correction(){return C()}})};G(de,e=>{z(f)&&C()&&e(fe)});var pe=L(de,2),me=I(pe,!0),he=L(pe,2),ge=e=>{var t=Gl(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`batchCleanup`,n())))]),U(e,t)};G(he,e=>{h()&&e(ge)});var _e=L(he,2),ve=e=>{Bl(e,{})};G(_e,e=>{g()===`complete`&&!m()&&!h()&&e(ve)});var ye=L(_e,2),be=e=>{var t=Gl(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`doctorHelp`,n())))]),U(e,t)};G(ye,e=>{!m()&&!h()&&e(be)});var xe=L(ye,2),Se=e=>{var t=Yl(),r=P(t),i=e=>{var t=Gl(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`doctorRunning`,n())))]),U(e,t)},a=e=>{var t=Gl(),r=I(t);R((e,t,n)=>W(r,`${e??``} ${t??``} ${n??``}`),[()=>(V(Z),V(b()),n(),B(()=>Z(b().healthy?`doctorPassed`:`doctorWarnings`,n()))),()=>(V(Z),n(),V(b()),B(()=>Z(`doctorCounts`,n(),{pass:String(b().pass??0),warn:String(b().warn??0),fail:String(b().fail??0),skipped:String(b().skipped??0)}))),()=>(V(Z),n(),B(()=>Z(`doctorSecretLimit`,n())))]),U(e,t)},o=e=>{var t=Gl(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`doctorFailed`,n())))]),U(e,t)};G(r,e=>{V(b()),B(()=>b()?.status===`running`)?e(i):(V(b()),B(()=>b()?.status===`complete`)?e(a,1):(V(b()),B(()=>b()?.status===`failed`)&&e(o,2)))});var s=L(r,2),c=e=>{{let t=A(()=>(V(Z),n(),B(()=>Z(`doctorRun`,n()))));Xa(e,{get label(){return z(t)},variant:`secondary`,get onClick(){return y()}})}};G(s,e=>{V(_()),V(b()),B(()=>_()&&b()?.status!==`running`&&b()?.status!==`complete`)&&e(c)}),D(t),U(e,t)};G(xe,e=>{g()===`complete`&&!m()&&!h()&&e(Se)});var Ce=L(xe,2),we=P(Ce),T=I(we,!0),Te=L(we),E=e=>{U(e,Xl())};G(Te,e=>{h()||e(E)}),D(Ce);var Ee=L(Ce),De=e=>{{let t=A(()=>(V(Z),n(),B(()=>Z(`closeSession`,n()))));Xa(e,{get label(){return z(t)},get onClick(){return v()}})}};G(Ee,e=>{_()&&e(De)}),D(ee),ii(ee,(e,t)=>ll?.(e,t),()=>1),R((e,t)=>{W(ne,g()===`complete`?`✓`:`!`),W(ie,z(o)),W(me,e),W(T,t)},[()=>(z(u),V(Z),n(),z(l),z(s),B(()=>z(u)?Z(`permissionSecretCollision`,n()):z(l)?Z(`permissionProbeCleanupPending`,n()):z(s))),()=>(V(Z),n(),B(()=>Z(`patSettings`,n())))]),U(e,ee),k(),i()}var $l=H(`

                                                      `);function eu(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`effects`,8,void 0);ji();var o=$l(),s=L(P(o)),c=I(s,!0),l=L(s),u=I(l,!0),d=L(l),f=e=>{Pl(e,{get effects(){return a()}})};G(d,e=>{V(a()),B(()=>a()?.length)&&e(f)}),D(o),R((e,t)=>{W(c,e),W(u,t)},[()=>(V(Z),n(),B(()=>Z(`working`,n()))),()=>(V(Z),n(),B(()=>Z(`workingBody`,n())))]),U(e,o),k(),i()}var tu={en:{title:`Checking PAT access`,lead:`Each permission is checked separately. Temporary test resources are removed after verification.`,pending:`Waiting`,checking:`Checking read access`,creating:`Creating temporary resource`,reading:`Reading temporary resource`,deleting:`Removing temporary resource`,verified:`Verified`,failed:`Needs attention`,skipped:`Checked after plan approval if required`},es:{title:`Comprobando el acceso del PAT`,lead:`Cada permiso se comprueba por separado. Los recursos temporales se eliminan tras verificarlos.`,pending:`Pendiente`,checking:`Comprobando lectura`,creating:`Creando recurso temporal`,reading:`Leyendo recurso temporal`,deleting:`Eliminando recurso temporal`,verified:`Verificado`,failed:`Requiere atención`,skipped:`Se comprobará tras aprobar el plan si es necesario`},fr:{title:`Vérification des accès du PAT`,lead:`Chaque permission est vérifiée séparément. Les ressources temporaires sont supprimées après vérification.`,pending:`En attente`,checking:`Vérification de la lecture`,creating:`Création d’une ressource temporaire`,reading:`Lecture de la ressource temporaire`,deleting:`Suppression de la ressource temporaire`,verified:`Vérifié`,failed:`Intervention nécessaire`,skipped:`Vérifiée après approbation du plan si nécessaire`},pt:{title:`A verificar o acesso do PAT`,lead:`Cada permissão é verificada separadamente. Os recursos temporários são removidos após a verificação.`,pending:`Pendente`,checking:`A verificar a leitura`,creating:`A criar recurso temporário`,reading:`A ler recurso temporário`,deleting:`A remover recurso temporário`,verified:`Verificado`,failed:`Requer atenção`,skipped:`Verificada após a aprovação do plano se necessário`}};function nu(e,t){return tu[e][t]}var ru={en:{unavailable:`The check did not complete. Review the terminal result.`,"cleanup-pending":`Cleanup is unresolved; recovery is required before retrying.`,"secret-collision":`GitHub reported an existing Secret at the random test name. Setup stopped; inspect the GitHub Secret audit trail.`,unsupported:`No isolated probe exists for this permission yet.`},es:{unavailable:`La comprobación no terminó. Revisa el resultado en el terminal.`,"cleanup-pending":`La limpieza está pendiente; hay que recuperarla antes de reintentar.`,"secret-collision":`GitHub encontró un Secret existente con el nombre aleatorio de prueba. El setup se detuvo; revisa el historial del Secret.`,unsupported:`Aún no hay una prueba aislada para este permiso.`},fr:{unavailable:`La vérification n’a pas abouti. Consultez le résultat dans le terminal.`,"cleanup-pending":`Le nettoyage reste à terminer avant de réessayer.`,"secret-collision":`GitHub a trouvé un Secret existant sous le nom de test aléatoire. La configuration s’est arrêtée ; consultez l’historique du Secret.`,unsupported:`Aucun test isolé n’existe encore pour cette permission.`},pt:{unavailable:`A verificação não terminou. Consulte o resultado no terminal.`,"cleanup-pending":`A limpeza está pendente; é necessária recuperação antes de tentar novamente.`,"secret-collision":`O GitHub encontrou um Secret existente com o nome aleatório de teste. A configuração parou; consulte o histórico do Secret.`,unsupported:`Ainda não existe um teste isolado para esta permissão.`}},iu={en:{closed:e=>`Temporary Issue #${e} was closed but could not be deleted. Remove it in GitHub before retrying.`,unresolved:e=>`Temporary Issue #${e} could not be deleted or confirmed closed. Inspect it in GitHub before retrying.`},es:{closed:e=>`El Issue temporal #${e} se cerró, pero no se pudo borrar. Elimínalo en GitHub antes de reintentar.`,unresolved:e=>`No se pudo borrar ni confirmar el cierre del Issue temporal #${e}. Revísalo en GitHub antes de reintentar.`},fr:{closed:e=>`L’Issue temporaire n° ${e} a été fermée mais n’a pas pu être supprimée. Supprimez-la dans GitHub avant de réessayer.`,unresolved:e=>`La suppression et la fermeture de l’Issue temporaire n° ${e} n’ont pas pu être confirmées. Vérifiez-la dans GitHub avant de réessayer.`},pt:{closed:e=>`A Issue temporária n.º ${e} foi fechada, mas não pôde ser eliminada. Elimine-a no GitHub antes de tentar novamente.`,unresolved:e=>`Não foi possível eliminar nem confirmar o fecho da Issue temporária n.º ${e}. Verifique-a no GitHub antes de tentar novamente.`}},au={en:e=>`GitHub HTTP ${e}`,es:e=>`Error HTTP ${e} de GitHub`,fr:e=>`Erreur HTTP ${e} de GitHub`,pt:e=>`Erro HTTP ${e} do GitHub`};function ou(e,t){let n=Sl(t,e);if(n)return n;let r=/^issue-(closed|unresolved)-([1-9][0-9]*)$/u.exec(t);return r?iu[e][r[1]](r[2]):/^http-[1-5][0-9]{2}$/u.test(t)?au[e](t.slice(5)):t===`unavailable`||t===`cleanup-pending`||t===`secret-collision`||t===`unsupported`?ru[e][t]:ru[e].unavailable}var su=H(` `),cu=H(`
                                                    • `),lu=H(`

                                                        `);function uu(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`permissions`,8);function s(e){return o().progress?.filter(t=>t.requirementId===e).at(-1)}Tn(()=>V(o()),()=>{N(a,o().progress?.at(-1))}),En(),ji();var c=lu(),l=P(c),u=I(l,!0),d=L(l,2),f=I(d,!0),p=L(d,2),m=P(p),h=e=>{var t=Nr();R((e,n)=>W(t,`${e??``}: ${n??``}`),[()=>(V(nc),n(),V(o()),z(a),B(()=>nc(n(),o().requirements?.find(e=>e.id===z(a).requirementId)?.permission??z(a).requirementId))),()=>(V(nu),n(),z(a),B(()=>nu(n(),z(a).phase)))]),U(e,t)};G(m,e=>{z(a)&&e(h)}),D(p);var g=L(p,2);q(g,5,()=>(V(o()),B(()=>o().requirements??[])),e=>e.id,(e,t)=>{let r=A(()=>(z(t),B(()=>s(z(t).id))));var i=cu();let a;var o=P(i),c=I(o,!0),l=L(o,2),u=P(l),d=I(u,!0),f=L(u),p=I(f),m=L(f),h=e=>{var t=su(),i=I(t,!0);R(e=>W(i,e),[()=>(V(ou),n(),V(z(r)),B(()=>ou(n(),z(r).detail)))]),U(e,t)};G(m,e=>{V(z(r)),B(()=>z(r)?.phase===`failed`&&z(r).detail)&&e(h)}),D(l);var g=I(L(l,2),!0);D(i),R((e,t,n,o)=>{a=ui(i,1,``,null,a,{"permission-progress-done":z(r)?.phase===`verified`,"permission-progress-failed":z(r)?.phase===`failed`}),W(c,(V(z(r)),B(()=>z(r)?.phase===`verified`?`✓`:z(r)?.phase===`failed`?`!`:z(r)?`◌`:`·`))),W(d,e),W(p,`${t??``} · ${n??``}`),W(g,o)},[()=>(V(nc),n(),z(t),B(()=>nc(n(),z(t).permission))),()=>(V(tc),n(),z(t),B(()=>tc(n(),z(t).scope))),()=>(V(tc),n(),z(t),B(()=>tc(n(),z(t).level))),()=>(V(nu),n(),V(z(r)),B(()=>nu(n(),z(r)?.phase??`pending`)))]),U(e,i)}),D(g),D(c),R((e,t)=>{W(u,e),W(f,t)},[()=>(V(nu),n(),B(()=>nu(n(),`title`))),()=>(V(nu),n(),B(()=>nu(n(),`lead`)))]),U(e,c),k(),i()}function du(e,t){return!t&&/^[A-Fa-f0-9]{16}$/u.test(e.trim())}var fu=H(`

                                                        `);function pu(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`busy`,8),o=X(t,`onPair`,8),s=X(t,`mode`,8,`pair`),c=M(``),l=M();async function u(){if(!du(z(c),a()))return;let e=z(c).trim();N(c,``),await o()(e),await hr(),z(l)?.isConnected&&!z(l).disabled&&z(l).focus()}ji();var d=fu(),f=P(d),p=I(P(f),!0);D(f);var m=L(f,2),h=I(P(m),!0);D(m);var g=L(m,2),_=I(g,!0),v=L(g,2),y=P(v),b=I(y,!0),x=L(y,2);xi(x),Ai(x,e=>N(l,e),()=>z(l));var S=L(x,2),C=I(S,!0),w=L(S,2),ee=P(w);{let e=A(()=>(V(Z),V(s()),n(),B(()=>Z(s()===`pair`?`pairButton`:`takeOver`,n())))),t=A(()=>(V(du),z(c),V(a()),B(()=>!du(z(c),a()))));Xa(ee,{get label(){return z(e)},arrow:!0,onClick:u,get disabled(){return z(t)}})}D(w),D(v),D(d),R((e,t,n,r,i,o,s)=>{J(d,`aria-label`,e),W(p,t),W(h,n),W(_,r),W(b,i),x.disabled=a(),J(x,`placeholder`,o),W(C,s)},[()=>(V(Z),V(s()),n(),B(()=>Z(s()===`pair`?`pairTitle`:`takeOver`,n()))),()=>(V(Z),n(),B(()=>Z(`privateSession`,n()))),()=>(V(Z),V(s()),n(),B(()=>Z(s()===`pair`?`pairTitle`:`takeOver`,n()))),()=>(V(Z),V(s()),n(),B(()=>Z(s()===`pair`?`pairBody`:`readOnlyBody`,n()))),()=>(V(Z),n(),B(()=>Z(`pairLabel`,n()))),()=>(V(Z),n(),B(()=>Z(`pairPlaceholder`,n()))),()=>(V(Z),n(),B(()=>Z(`pairHelp`,n())))]),Cr(`submit`,v,e=>{e.preventDefault(),u()}),Ei(x,()=>z(c),e=>N(c,e)),U(e,d),k(),i()}var mu={"Could not close the local session. Check the terminal before trying again.":`The local session could not be confirmed closed. The result is retained. Check the terminal before trying again.`,"The local setup session is unavailable.":`The local setup session is unavailable. Check the terminal; you may need to restart setup.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Connection lost. The CLI may have stopped. Check the terminal before trying again.`,"Could not join this local session.":`Could not join this local session. Check the terminal and pair again.`,"Could not connect to the local setup session. Check the terminal and pair again.":`Could not connect to the local setup session. Check the terminal and pair again.`,"Pairing was rejected.":`Pairing was rejected. Check the code in the launching terminal.`,"Invalid local pairing response.":`The local pairing response was invalid. Restart setup from the terminal.`,"Could not pair this browser.":`Could not pair this browser. Check the terminal and try again.`,"The request was rejected.":`The local request was rejected. Refresh the page and check the terminal.`,"Could not submit this answer.":`Could not submit this answer. Refresh the page and try again.`,"Cancellation failed.":`Cancellation failed. Check whether setup has already started applying before closing.`,"Takeover failed.":`Could not take control. Re-enter the pairing code from the launching terminal.`,"Invalid local host or request context.":`The local request context was rejected. Open the exact URL printed in the terminal.`,"Invalid request origin.":`The request came from another origin. Open the exact local URL printed in the terminal.`,"JSON required.":`The local request format was invalid. Refresh the page and try again.`,"Too many pairing attempts. Restart setup.":`Too many incorrect pairing attempts. Restart setup from the terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Too many incorrect pairing attempts. Wait 30 seconds and try the code again; terminal setup remains available.`,"Incorrect pairing code. Check the terminal.":`Incorrect pairing code. Check the launching terminal.`,"Incorrect pairing code. Check the launching output.":`Incorrect pairing code. Check the launching output.`,"Pair this browser using the code printed by the CLI.":`Pair this browser using the code printed by the CLI.`,"This tab is read-only.":`This tab is read-only. Enter the pairing code again to take control.`,"Invalid answer.":`The answer was invalid. Review the current question and try again.`,"Control moved to another tab.":`Control moved to another tab. This tab is now read-only.`,"This question changed. Refresh the current state.":`This question changed. Refresh the page before answering again.`,"This setup has already started applying or ended.":`Setup has already started applying or ended. Inspect the current result before retrying.`,"Only the controller can close a finished session.":`Only the controlling tab can close this finished session.`,"Method not allowed.":`This local request is not allowed. Refresh the page.`,"Not found.":`The requested local page was not found. Open the URL printed in the terminal.`,"Invalid local request.":`The local request was invalid. Refresh the page and try again.`,"Body too large.":`The submitted answer is too large. Shorten it and try again.`,"JSON object required.":`The local request format was invalid. Refresh the page and try again.`,"Could not retry discovery.":`Could not refresh the GitHub suggestions. Retry or use verified manual entry.`,"Could not return to the previous question.":`Could not return to the previous question. Refresh the page and try again.`,"Invalid question revision.":`The question changed. Refresh the page before going back.`,"No earlier question is available here.":`There is no earlier question in this stage. Continue or return to the plan review.`,"Read-only verification failed.":`Read-only verification failed. Check the terminal and retry once.`,"Read-only verification failed. Check the terminal.":`Read-only verification failed. Check the terminal and retry once.`,"Read-only verification is unavailable or already running.":`Read-only verification is unavailable or already running. Check the current result before retrying.`},hu={en:mu,es:{"Could not close the local session. Check the terminal before trying again.":`No se ha podido confirmar el cierre de la sesión local. El resultado se conserva. Consulta la terminal antes de volver a intentarlo.`,"The local setup session is unavailable.":`La sesión local no está disponible. Revisa la terminal; quizá debas reiniciar la configuración.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Se perdió la conexión. Es posible que el CLI se haya detenido. Revisa la terminal antes de reintentar.`,"Could not join this local session.":`No se pudo acceder a esta sesión local. Revisa la terminal y vuelve a vincular el navegador.`,"Could not connect to the local setup session. Check the terminal and pair again.":`No se pudo conectar con la sesión local. Revisa la terminal y vuelve a vincular el navegador.`,"Pairing was rejected.":`Se rechazó la vinculación. Comprueba el código en la terminal que inició el proceso.`,"Invalid local pairing response.":`La respuesta de vinculación local no es válida. Reinicia la configuración desde la terminal.`,"Could not pair this browser.":`No se pudo vincular este navegador. Revisa la terminal y vuelve a intentarlo.`,"The request was rejected.":`Se rechazó la petición local. Actualiza la página y revisa la terminal.`,"Could not submit this answer.":`No se pudo enviar la respuesta. Actualiza la página y vuelve a intentarlo.`,"Cancellation failed.":`No se pudo cancelar. Comprueba si ya se han empezado a aplicar cambios antes de cerrar.`,"Takeover failed.":`No se pudo tomar el control. Vuelve a introducir el código de la terminal inicial.`,"Invalid local host or request context.":`Se rechazó el contexto de la petición local. Abre la URL exacta que aparece en la terminal.`,"Invalid request origin.":`La petición llegó desde otro origen. Abre la URL local exacta de la terminal.`,"JSON required.":`El formato de la petición local no es válido. Actualiza la página y reinténtalo.`,"Too many pairing attempts. Restart setup.":`Demasiados intentos de vinculación fallidos. Reinicia la configuración desde la terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Demasiados intentos de vinculación fallidos. Espera 30 segundos y vuelve a probar el código; puedes seguir con el setup en la terminal.`,"Incorrect pairing code. Check the terminal.":`Código de vinculación incorrecto. Comprueba la terminal inicial.`,"Incorrect pairing code. Check the launching output.":`Código de vinculación incorrecto. Comprueba la salida de inicio.`,"Pair this browser using the code printed by the CLI.":`Vincula este navegador con el código mostrado por el CLI.`,"This tab is read-only.":`Esta pestaña es de solo lectura. Introduce otra vez el código para tomar el control.`,"Invalid answer.":`La respuesta no es válida. Revisa la pregunta actual e inténtalo de nuevo.`,"Control moved to another tab.":`El control pasó a otra pestaña. Esta ahora es de solo lectura.`,"This question changed. Refresh the current state.":`La pregunta cambió. Actualiza la página antes de volver a responder.`,"This setup has already started applying or ended.":`La configuración ya empezó a aplicarse o terminó. Revisa el resultado antes de reintentar.`,"Only the controller can close a finished session.":`Solo la pestaña que tiene el control puede cerrar esta sesión finalizada.`,"Method not allowed.":`Esta petición local no está permitida. Actualiza la página.`,"Not found.":`No se encontró la página local solicitada. Abre la URL de la terminal.`,"Invalid local request.":`La petición local no es válida. Actualiza la página y reinténtalo.`,"Body too large.":`La respuesta enviada es demasiado larga. Acórtala y reinténtalo.`,"JSON object required.":`El formato de la petición local no es válido. Actualiza la página y reinténtalo.`,"Could not retry discovery.":`No se pudieron actualizar las sugerencias de GitHub. Reinténtalo o introduce datos verificados manualmente.`,"Could not return to the previous question.":`No se pudo volver a la pregunta anterior. Actualiza la página y reinténtalo.`,"Invalid question revision.":`La pregunta cambió. Actualiza la página antes de volver atrás.`,"No earlier question is available here.":`No hay una pregunta anterior en esta etapa. Continúa o vuelve a revisar el plan.`,"Read-only verification failed.":`Falló la comprobación de solo lectura. Revisa la terminal y vuelve a intentarlo una vez.`,"Read-only verification failed. Check the terminal.":`Falló la comprobación de solo lectura. Revisa la terminal y vuelve a intentarlo una vez.`,"Read-only verification is unavailable or already running.":`La comprobación de solo lectura no está disponible o ya se está ejecutando. Revisa el resultado antes de reintentar.`},fr:{"Could not close the local session. Check the terminal before trying again.":`La fermeture de la session locale n’a pas pu être confirmée. Le résultat est conservé. Consultez le terminal avant de réessayer.`,"The local setup session is unavailable.":`La session locale est indisponible. Vérifiez le terminal ; vous devrez peut-être relancer la configuration.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Connexion perdue. Le CLI s’est peut-être arrêté. Vérifiez le terminal avant de réessayer.`,"Could not join this local session.":`Impossible de rejoindre cette session locale. Vérifiez le terminal et associez de nouveau le navigateur.`,"Could not connect to the local setup session. Check the terminal and pair again.":`Impossible de se connecter à la session locale. Vérifiez le terminal et associez de nouveau le navigateur.`,"Pairing was rejected.":`L’association a été refusée. Vérifiez le code dans le terminal de lancement.`,"Invalid local pairing response.":`La réponse d’association locale est invalide. Relancez la configuration depuis le terminal.`,"Could not pair this browser.":`Impossible d’associer ce navigateur. Vérifiez le terminal et réessayez.`,"The request was rejected.":`La demande locale a été refusée. Actualisez la page et vérifiez le terminal.`,"Could not submit this answer.":`Impossible d’envoyer cette réponse. Actualisez la page et réessayez.`,"Cancellation failed.":`Annulation impossible. Vérifiez si des changements ont déjà commencé avant de fermer.`,"Takeover failed.":`Impossible de prendre le contrôle. Ressaisissez le code du terminal de lancement.`,"Invalid local host or request context.":`Le contexte de la demande locale a été refusé. Ouvrez l’URL exacte affichée dans le terminal.`,"Invalid request origin.":`La demande vient d’une autre origine. Ouvrez l’URL locale exacte du terminal.`,"JSON required.":`Le format de la demande locale est invalide. Actualisez la page et réessayez.`,"Too many pairing attempts. Restart setup.":`Trop de tentatives d’association incorrectes. Relancez la configuration depuis le terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Trop de tentatives d’association incorrectes. Attendez 30 secondes puis ressaisissez le code ; la configuration par terminal reste disponible.`,"Incorrect pairing code. Check the terminal.":`Code d’association incorrect. Vérifiez le terminal de lancement.`,"Incorrect pairing code. Check the launching output.":`Code d’association incorrect. Vérifiez la sortie de lancement.`,"Pair this browser using the code printed by the CLI.":`Associez ce navigateur avec le code affiché par le CLI.`,"This tab is read-only.":`Cet onglet est en lecture seule. Ressaisissez le code pour prendre le contrôle.`,"Invalid answer.":`La réponse est invalide. Revoyez la question actuelle et réessayez.`,"Control moved to another tab.":`Le contrôle est passé à un autre onglet. Celui-ci est maintenant en lecture seule.`,"This question changed. Refresh the current state.":`La question a changé. Actualisez la page avant de répondre de nouveau.`,"This setup has already started applying or ended.":`La configuration est déjà en cours d’application ou terminée. Inspectez le résultat avant de réessayer.`,"Only the controller can close a finished session.":`Seul l’onglet qui détient le contrôle peut fermer cette session terminée.`,"Method not allowed.":`Cette demande locale n’est pas autorisée. Actualisez la page.`,"Not found.":`La page locale demandée est introuvable. Ouvrez l’URL affichée dans le terminal.`,"Invalid local request.":`La demande locale est invalide. Actualisez la page et réessayez.`,"Body too large.":`La réponse envoyée est trop longue. Raccourcissez-la et réessayez.`,"JSON object required.":`Le format de la demande locale est invalide. Actualisez la page et réessayez.`,"Could not retry discovery.":`Impossible d’actualiser les suggestions GitHub. Réessayez ou saisissez des données vérifiées manuellement.`,"Could not return to the previous question.":`Impossible de revenir à la question précédente. Actualisez la page et réessayez.`,"Invalid question revision.":`La question a changé. Actualisez la page avant de revenir en arrière.`,"No earlier question is available here.":`Il n’y a pas de question précédente à cette étape. Continuez ou revenez à la révision du plan.`,"Read-only verification failed.":`La vérification en lecture seule a échoué. Consultez le terminal et réessayez une fois.`,"Read-only verification failed. Check the terminal.":`La vérification en lecture seule a échoué. Consultez le terminal et réessayez une fois.`,"Read-only verification is unavailable or already running.":`La vérification en lecture seule est indisponible ou déjà en cours. Consultez le résultat avant de réessayer.`},pt:{"Could not close the local session. Check the terminal before trying again.":`Não foi possível confirmar o encerramento da sessão local. O resultado foi preservado. Consulte o terminal antes de tentar novamente.`,"The local setup session is unavailable.":`A sessão local não está disponível. Verifique o terminal; poderá ter de reiniciar a configuração.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Ligação perdida. O CLI pode ter parado. Verifique o terminal antes de tentar novamente.`,"Could not join this local session.":`Não foi possível entrar nesta sessão local. Verifique o terminal e volte a emparelhar o navegador.`,"Could not connect to the local setup session. Check the terminal and pair again.":`Não foi possível ligar à sessão local. Verifique o terminal e volte a emparelhar o navegador.`,"Pairing was rejected.":`O emparelhamento foi recusado. Confirme o código no terminal de lançamento.`,"Invalid local pairing response.":`A resposta de emparelhamento local é inválida. Reinicie a configuração a partir do terminal.`,"Could not pair this browser.":`Não foi possível emparelhar este navegador. Verifique o terminal e tente novamente.`,"The request was rejected.":`O pedido local foi recusado. Atualize a página e verifique o terminal.`,"Could not submit this answer.":`Não foi possível enviar a resposta. Atualize a página e tente novamente.`,"Cancellation failed.":`Não foi possível cancelar. Confirme se a aplicação das alterações já começou antes de fechar.`,"Takeover failed.":`Não foi possível assumir o controlo. Volte a introduzir o código do terminal de lançamento.`,"Invalid local host or request context.":`O contexto do pedido local foi recusado. Abra o URL exato apresentado no terminal.`,"Invalid request origin.":`O pedido veio de outra origem. Abra o URL local exato do terminal.`,"JSON required.":`O formato do pedido local é inválido. Atualize a página e tente novamente.`,"Too many pairing attempts. Restart setup.":`Demasiadas tentativas incorretas de emparelhamento. Reinicie a configuração no terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Demasiadas tentativas incorretas de emparelhamento. Aguarde 30 segundos e volte a introduzir o código; a configuração no terminal continua disponível.`,"Incorrect pairing code. Check the terminal.":`Código de emparelhamento incorreto. Verifique o terminal de lançamento.`,"Incorrect pairing code. Check the launching output.":`Código de emparelhamento incorreto. Verifique a saída de lançamento.`,"Pair this browser using the code printed by the CLI.":`Emparelhe este navegador com o código apresentado pelo CLI.`,"This tab is read-only.":`Este separador é apenas de leitura. Reintroduza o código para assumir o controlo.`,"Invalid answer.":`A resposta é inválida. Reveja a pergunta atual e tente novamente.`,"Control moved to another tab.":`O controlo passou para outro separador. Este é agora apenas de leitura.`,"This question changed. Refresh the current state.":`A pergunta mudou. Atualize a página antes de voltar a responder.`,"This setup has already started applying or ended.":`A configuração já começou a ser aplicada ou terminou. Inspecione o resultado antes de tentar novamente.`,"Only the controller can close a finished session.":`Só o separador que detém o controlo pode fechar esta sessão terminada.`,"Method not allowed.":`Este pedido local não é permitido. Atualize a página.`,"Not found.":`A página local pedida não foi encontrada. Abra o URL apresentado no terminal.`,"Invalid local request.":`O pedido local é inválido. Atualize a página e tente novamente.`,"Body too large.":`A resposta enviada é demasiado longa. Encurte-a e tente novamente.`,"JSON object required.":`O formato do pedido local é inválido. Atualize a página e tente novamente.`,"Could not retry discovery.":`Não foi possível atualizar as sugestões do GitHub. Tente novamente ou introduza dados verificados manualmente.`,"Could not return to the previous question.":`Não foi possível voltar à pergunta anterior. Atualize a página e tente novamente.`,"Invalid question revision.":`A pergunta mudou. Atualize a página antes de voltar atrás.`,"No earlier question is available here.":`Não há uma pergunta anterior nesta etapa. Continue ou volte à revisão do plano.`,"Read-only verification failed.":`A verificação só de leitura falhou. Consulte o terminal e tente mais uma vez.`,"Read-only verification failed. Check the terminal.":`A verificação só de leitura falhou. Consulte o terminal e tente mais uma vez.`,"Read-only verification is unavailable or already running.":`A verificação só de leitura não está disponível ou já está em curso. Consulte o resultado antes de tentar novamente.`}};function gu(e,t){let n=hu[t]??mu;return Object.prototype.hasOwnProperty.call(n,e)?n[e]:Z(`unknownLocalError`,t)}var _u=H(`
                                                        `),vu=H(`
                                                        `),yu=H(` `,1),bu=H(``),xu=H(`
                                                        `,1),Su=H(`
                                                        `);function Cu(e,t){O(t,!1);let n=()=>Y(o,`$session`,i),r=()=>Y(Q,`$setupLocale`,i),[i,a]=zi(),o=Hi();Kr(()=>{let e=Q.subscribe(e=>{document.documentElement.lang=e,document.documentElement.dir=`ltr`,document.title=`Copilot · ${Z(`studio`,e)}`}),t=window.setInterval(()=>{n().paired&&!n().closed&&!n().view?.outcome&&o.poll()},900);return()=>{window.clearInterval(t),e()}});async function s(){window.confirm(Z(n().view?.batch?.phase===`applying`?`batchStopConfirm`:`cancelConfirm`,r()))&&await o.cancel()}async function c(e){let t=n().view?.promptRevision;t!==void 0&&await o.submit(t,e)}async function l(){let e=n().view?.promptRevision;e!==void 0&&await o.retryDiscovery(e)}async function u(){let e=n().view?.promptRevision;e!==void 0&&await o.back(e)}ji();var d=Su(),f=P(d);{let e=A(()=>n().view?.journey),t=A(()=>n().view?.surface===`management`);la(f,{get journey(){return z(e)},get management(){return z(t)}})}var p=L(f,2),m=P(p);{let e=A(()=>n().view?.repository),t=A(()=>n().closed===!0);_a(m,{get repository(){return z(e)},get closed(){return z(t)}})}var h=L(m,2),g=P(h);Ha(g,{});var _=L(g,2),v=e=>{{let t=A(()=>Z(`translationPreviewTitle`,r())),n=A(()=>Z(`translationPreviewBody`,r()));$a(e,{tone:`warning`,get title(){return z(t)},get message(){return z(n)}})}};G(_,e=>{r()!==`en`&&e(v)});var y=L(_,2),b=e=>{za(e,{get view(){return n().view}})};G(y,e=>{n().paired&&n().view?.surface!==`management`&&e(b)});var x=L(y,2),S=e=>{var t=_u(),i=L(P(t));D(t),R(e=>W(i,` ${e??``}`),[()=>Z(`reviewPass`,r(),{pass:String(n().view.journey.choiceReviewPass)})]),U(e,t)};G(x,e=>{n().view?.journey?.choiceReviewPass&&n().view.journey.choiceReviewPass>1&&!n().view.outcome&&e(S)});var C=L(x,2),w=e=>{var t=vu(),n=P(t);{let e=A(()=>Z(`sessionClosed`,r())),t=A(()=>Z(`sessionClosedBody`,r()));$a(n,{tone:`success`,get title(){return z(e)},get message(){return z(t)}})}D(t),ii(t,(e,t)=>ll?.(e,t),()=>1),R(e=>J(t,`aria-label`,e),[()=>Z(`sessionClosed`,r())]),U(e,t)};G(C,e=>{n().closed&&e(w)});var ee=L(C,2),te=e=>{var t=yu(),i=F(t);{let e=A(()=>Z(`readOnly`,r())),t=A(()=>Z(`readOnlyBody`,r()));$a(i,{tone:`warning`,get title(){return z(e)},get message(){return z(t)}})}pu(L(i,2),{mode:`takeover`,get busy(){return n().busy},get onPair(){return o.takeOver}}),U(e,t)};G(ee,e=>{!n().closed&&!n().controller&&n().view&&e(te)});var ne=L(ee,2),re=e=>{{let t=A(()=>Z(`attention`,r())),i=A(()=>gu(n().error,r()));$a(e,{tone:`error`,get title(){return z(t)},get message(){return z(i)}})}};G(ne,e=>{n().error&&e(re)});var ie=L(ne,2),ae=e=>{{let t=A(()=>Z(n().view.message.tone===`success`?`checked`:n().view.message.tone===`warning`?`pleaseNote`:n().view.message.tone===`error`?`attention`:`progressUpdate`,r())),i=A(()=>Na(n().view.message,r()));$a(e,{get tone(){return n().view.message.tone},get title(){return z(t)},get message(){return z(i)},get link(){return n().view.message.link}})}};G(ie,e=>{n().view?.message&&!n().view.outcome&&e(ae)});var oe=L(ie,2),se=e=>{{let t=A(()=>n().view.permissions?.report);jl(e,{get report(){return z(t)}})}};G(oe,e=>{n().view?.batch&&e(se)});var ce=L(oe,2),le=e=>{pu(e,{get busy(){return n().busy},get onPair(){return o.pair}})},ue=e=>{var t=yu(),r=F(t),i=e=>{Yc(e,{get batch(){return n().view.batch},mode:`closed`,get controller(){return n().controller},get busy(){return n().busy}})};G(r,e=>{n().view.batch&&e(i)});var a=L(r,2);{let e=A(()=>!!n().view.batch),t=A(()=>n().view.surface===`management`),r=A(()=>n().view.permissions?.report);Ql(a,{get batch(){return z(e)},get management(){return z(t)},get outcome(){return n().view.outcome},get detail(){return n().view.resultDetail},get permissionReport(){return z(r)},get setupPatCorrection(){return n().view.setupPatCorrection},get doctor(){return n().view.doctor},get controller(){return n().controller},get onDoctor(){return o.runDoctor},get onClose(){return o.close}})}U(e,t)},de=e=>{var t=xu(),i=F(t),a=P(i);pl(a,{get prompt(){return n().view.prompt},get revision(){return n().view.revision},get promptRevision(){return n().view.promptRevision},get controller(){return n().controller},get busy(){return n().busy},onSubmit:c,onRetryDiscovery:l,onBack:u}),Al(L(a,2),{get view(){return n().view}}),D(i);var o=L(i,2),d=e=>{var t=bu(),i=I(t,!0);R(e=>{t.disabled=n().busy,W(i,e)},[()=>Z(`cancelSetup`,r())]),wr(`click`,t,s),U(e,t)};G(o,e=>{n().controller&&n().view.journey?.current!==`Apply`&&e(d)}),U(e,t)},fe=e=>{var t=yu(),r=F(t);Yc(r,{get batch(){return n().view.batch},mode:`progress`,get controller(){return n().controller},get busy(){return n().busy},onStop:s});var i=L(r,2),a=e=>{uu(e,{get permissions(){return n().view.permissions}})};G(i,e=>{n().view.permissions?.progress?.length&&!n().view.permissions.report&&e(a)}),U(e,t)},pe=e=>{uu(e,{get permissions(){return n().view.permissions}})},me=e=>{{let t=A(()=>n().view?.resultDetail?.effects);eu(e,{get effects(){return z(t)}})}};G(ce,e=>{n().paired?n().view?.outcome?e(ue,1):n().view?.prompt?e(de,2):n().view?.batch?e(fe,3):n().view?.permissions?.progress?.length&&!n().view.permissions.report?e(pe,4):e(me,-1):e(le)});var he=L(ce,2),ge=P(he),_e=L(ge,2),ve=L(_e,2);D(he),D(h),D(p),D(d),R((e,t,n)=>{W(ge,`${e??``} `),W(_e,` ${t??``} `),W(ve,` ${n??``}`)},[()=>Z(`footerLocal`,r()),()=>Z(`footerCloud`,r()),()=>Z(`footerGithub`,r())]),U(e,d),k(),a()}Tr([`click`]),Vr(Cu,{target:document.getElementById(`app`)}); \ No newline at end of file +`)}`}var Pa={en:va,es:ya,fr:ba,pt:xa};function Fa(e,t){return e.replace(/\{([a-zA-Z]\w*)\}/gu,(e,n)=>t[n]??``)}function Ia(e,t){if(!e.copyId)return;let n=Pa[t][e.copyId],r={...e.copyValues??{}};if(e.copyId===`credential.existing`&&r.status&&[`valid`,`invalid`,`missing`,`unverifiable`,`not_required`].includes(r.status)){let e=`credential.status.${r.status}`;r.status=Ma[t][e]}return{title:Fa(n.title,r),description:Fa(n.description,r),...n.choices?{choices:n.choices}:{}}}function La(e,t,n){return Ia(e,t)?.choices?.[n]??e.choices[n]}var Ra=H(`

                                                        `,1);function za(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`view`,8);Tn(()=>(V(o()),n(),Ia),()=>{N(a,o()?.batch?Z(o().batch.phase===`review`?`batchReviewTitle`:o().batch.phase===`applying`?`batchProgressTitle`:`batchResultTitle`,n()):o()?.outcome===`complete`?Z(`completeTitle`,n()):o()?.outcome===`dry-run`?Z(`previewTitle`,n()):o()?.outcome===`cancelled`?Z(`cancelledTitle`,n()):o()?.outcome?Z(`blockedTitle`,n()):o()?.prompt?.kind===`repositories`?Z(`batchReviewSelection`,n()):o()?.prompt?.kind===`question`?Z(`choices`,n()):o()?.prompt?.kind===`plan`?Z(`plan`,n()):o()?.prompt?Ia(o().prompt,n())?.title??o().prompt.title:Z(`preparing`,n()))}),En(),ji();var s=Ra(),c=F(s),l=L(P(c)),u=I(L(l));D(c);var d=L(c,2),f=I(d,!0),p=I(L(d,2),!0);R((e,t,n)=>{W(l,` ${e??``} `),W(u,`${t??``} / 06`),W(f,z(a)),W(p,n)},[()=>(V(Zi),V(o()),n(),B(()=>Zi(o()?.journey?.current,n()).toUpperCase())),()=>(V(o()),B(()=>String(o()?.journey?.position??1).padStart(2,`0`))),()=>(V(o()),V(Z),n(),B(()=>o()?.outcome?Z(`resultLede`,n()):Z(`activeLede`,n())))]),U(e,s),k(),i()}var Ba={tutorial:`https://docs.page/vypdev/copilot/setup-web`,firstWorkflow:`https://docs.page/vypdev/copilot/first-workflow`,recovery:`https://docs.page/vypdev/copilot/security-operations/operations/troubleshooting`,verification:`https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-owned-setup`},Va={en:{title:`Verification setup`,create:`Create the starter only if missing`,preserve:`Preserve the existing project action byte-for-byte`,blocked:`Blocked: inspect the unsafe action path`,enabled:`VERIFICATION_SETUP: enabled`,disabled:`VERIFICATION_SETUP: disabled`,main:`Trusted main branch`,next:`The starter fails until customized. Review and merge the project dependencies onto configured MAIN_BRANCH, then run a real verification. An installer PR does not prove runtime readiness.`,result:`Inspect .github/actions/copilot-verification-setup/action.yml. Setup creates it only if missing and preserves existing project actions. Customize the placeholder and review on MAIN_BRANCH before enabling VERIFICATION_SETUP, then run a real verification.`,guide:`Verification setup and upgrade guide`},es:{title:`Preparación de la verificación`,create:`Crear la plantilla solo si falta`,preserve:`Conservar intacta la acción existente del proyecto`,blocked:`Bloqueado: revisa la ruta insegura de la acción`,enabled:`VERIFICATION_SETUP: activado`,disabled:`VERIFICATION_SETUP: desactivado`,main:`Rama principal de confianza`,next:`La plantilla falla hasta personalizarla. Revisa y fusiona las dependencias del proyecto en la MAIN_BRANCH configurada y ejecuta una verificación real. Una PR de instalación no demuestra que el entorno funcione.`,result:`Revisa .github/actions/copilot-verification-setup/action.yml. Setup lo crea solo si falta y conserva la acción existente. Personaliza la plantilla y revísala en MAIN_BRANCH antes de activar VERIFICATION_SETUP; después ejecuta una verificación real.`,guide:`Guía de preparación y actualización de la verificación`},fr:{title:`Préparation de la vérification`,create:`Créer le modèle seulement si absent`,preserve:`Conserver intégralement l’action existante du projet`,blocked:`Bloqué : inspectez le chemin non sûr de l’action`,enabled:`VERIFICATION_SETUP : activé`,disabled:`VERIFICATION_SETUP : désactivé`,main:`Branche principale de confiance`,next:`Le modèle échoue avant personnalisation. Révisez et fusionnez les dépendances du projet sur MAIN_BRANCH, puis lancez une vraie vérification. Une PR d’installation ne prouve pas le fonctionnement.`,result:`Inspectez .github/actions/copilot-verification-setup/action.yml. Setup le crée seulement si absent et conserve l’action existante. Personnalisez et révisez le modèle sur MAIN_BRANCH avant d’activer VERIFICATION_SETUP, puis lancez une vraie vérification.`,guide:`Guide de préparation et de mise à niveau de la vérification`},pt:{title:`Preparação da verificação`,create:`Criar o modelo só se faltar`,preserve:`Preservar integralmente a ação existente do projeto`,blocked:`Bloqueado: inspecione o caminho inseguro da ação`,enabled:`VERIFICATION_SETUP: ativo`,disabled:`VERIFICATION_SETUP: desativado`,main:`Ramo principal de confiança`,next:`O modelo falha até ser personalizado. Reveja e faça merge das dependências na MAIN_BRANCH configurada, depois execute uma verificação real. Uma PR de instalação não comprova o funcionamento.`,result:`Inspecione .github/actions/copilot-verification-setup/action.yml. Setup cria-o só se faltar e preserva a ação existente. Personalize e reveja o modelo na MAIN_BRANCH antes de ativar VERIFICATION_SETUP, depois execute uma verificação real.`,guide:`Guia de preparação e atualização da verificação`}};function Ha(e,t){return Va[t][e]}var Ua=H(``);function Wa(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi();ji();var a=Ua(),o=P(a),s=P(o),c=I(s),l=L(s,2),u=I(l),d=L(l,2),f=I(d),p=L(d,2),m=I(p);D(o);var h=I(L(o,2),!0);D(a),R((e,t,n,r,i,o)=>{J(a,`aria-label`,e),J(s,`href`,Ba.tutorial),W(c,`${t??``} ↗`),J(l,`href`,Ba.firstWorkflow),W(u,`${n??``} ↗`),J(d,`href`,Ba.recovery),W(f,`${r??``} ↗`),J(p,`href`,Ba.verification),W(m,`${i??``} ↗`),W(h,o)},[()=>Z(`setupHelp`,n()),()=>Z(`setupTutorial`,n()),()=>Z(`firstWorkflowGuide`,n()),()=>Z(`setupRecovery`,n()),()=>Ha(`guide`,n()),()=>Z(`setupHelpHint`,n())]),U(e,a),k(),i()}function Ga(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&(t.pathname===`/settings/personal-access-tokens`||t.pathname.startsWith(`/settings/personal-access-tokens/`))?t.toString():void 0}catch{return}}function Ka(e){return e&&/^[A-Za-z0-9-]{1,39}\/(?!\.{1,2}$)[A-Za-z0-9._-]{1,100}$/u.test(e)?`https://github.com/${e}/settings/secrets/actions`:void 0}function qa(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&!t.username&&!t.password&&!t.search&&!t.hash&&/^\/[A-Za-z0-9-]{1,39}\/[A-Za-z0-9._-]{1,100}\/actions\/runs\/[1-9][0-9]*$/u.test(t.pathname)?t.toString():void 0}catch{return}}function Ja(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&!t.username&&!t.password&&!t.search&&!t.hash&&/^\/[A-Za-z0-9-]{1,39}\/[A-Za-z0-9._-]{1,100}\/rules\/[1-9][0-9]*$/u.test(t.pathname)?t.toString():void 0}catch{return}}function Ya(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&!t.username&&!t.password&&!t.search&&!t.hash&&/^\/(?:orgs|users)\/[A-Za-z0-9-]{1,39}\/projects\/[1-9][0-9]*$/u.test(t.pathname)?t.toString():void 0}catch{return}}var Xa=H(``),Za=H(``);function Qa(e,t){let n=X(t,`label`,8),r=X(t,`variant`,8,`primary`),i=X(t,`disabled`,8,!1),a=X(t,`arrow`,8,!1),o=X(t,`onClick`,8);var s=Za(),c=P(s,!0),l=L(c),u=e=>{U(e,Xa())};G(l,e=>{a()&&e(u)}),D(s),R(()=>{ui(s,1,si(r())),s.disabled=i(),W(c,n())}),wr(`click`,s,function(...e){o()?.apply(this,e)}),U(e,s)}Tr([`click`]);var $a=H(` `),eo=H(`

                                                        `);function to(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`tone`,8,`info`),s=X(t,`title`,8),c=X(t,`message`,8),l=X(t,`link`,8,void 0),u=X(t,`actionLabel`,8,void 0),d=X(t,`onAction`,8,void 0);Tn(()=>V(l()),()=>{N(a,Ga(l()))}),En(),ji();var f=eo(),p=P(f),m=I(p,!0),h=L(p),g=I(h,!0),_=L(h,2),v=e=>{var t=$a(),r=I(t,!0);R(e=>{J(t,`href`,z(a)),W(r,e)},[()=>(V(Z),n(),B(()=>Z(`githubLink`,n())))]),U(e,t)};G(_,e=>{z(a)&&e(v)});var y=L(_,2),b=e=>{Qa(e,{get label(){return u()},variant:`secondary`,get onClick(){return d()}})};G(y,e=>{u()&&d()&&e(b)}),D(f),R(()=>{ui(f,1,`banner ${o()??``}`),J(f,`role`,o()===`error`?`alert`:`status`),W(m,s()),W(g,c())}),U(e,f),k(),i()}var no=H(`
                                                      1. :
                                                      2. `),ro=H(`
                                                          `),io=H(`
                                                        • `),ao=H(`
                                                        • `),oo=H(`

                                                          `),so=H(`
                                                              `),co=H(`

                                                              `);function lo(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`question`,8);ji();var o=Pr(),s=F(o),c=e=>{var t=co(),r=P(t),i=I(r,!0),o=L(r,2),s=P(o),c=L(s),l=e=>{var t=Nr();R(e=>W(t,`(${e??``})`),[()=>(V(Z),V(a()),n(),B(()=>Z(a().runnerRegistryScope===`repository`?`scopeRepository`:`scopeOrganization`,n())))]),U(e,t)};G(c,e=>{V(a()),B(()=>a().runnerRegistryScope)&&e(l)});var u=L(c);D(o);var d=L(o,2),f=e=>{var t=ro(),r=P(t),i=I(r,!0),o=L(r,2);q(o,5,()=>(V(a()),B(()=>a().runnerProfiles)),K,(e,t)=>{var n=no(),r=P(n),i=I(r,!0),a=I(L(r,2));D(n),R(e=>{W(i,(z(t),B(()=>z(t).id))),W(a,`${z(t),B(()=>z(t).group||`—`)??``} · ${e??``}`)},[()=>(z(t),B(()=>z(t).labels.join(`, `)))]),U(e,n)}),D(o),D(t),R(e=>W(i,e),[()=>(V($),n(),B(()=>$(`profiles`,n())))]),U(e,t)};G(d,e=>{V(a()),B(()=>a().runnerProfiles?.length)&&e(f)});var p=L(d,2),m=e=>{var t=so(),r=P(t),i=I(r,!0),o=L(r,2);q(o,5,()=>(V(a()),B(()=>a().runnerInventory.groups)),K,(e,t)=>{var r=io(),i=P(r),a=I(i,!0),o=L(i);D(r),R(e=>{W(a,(z(t),B(()=>z(t).name))),W(o,`: ${e??``}`)},[()=>(V($),z(t),n(),B(()=>$(z(t).access,n())))]),U(e,r)}),D(o);var s=L(o,2);q(s,5,()=>(V(a()),B(()=>a().runnerInventory.candidates.slice(0,10))),K,(e,t)=>{var n=ao(),r=I(P(n),!0);D(n),R(e=>W(r,e),[()=>(z(t),B(()=>z(t).labels.join(`, `)))]),U(e,n)}),D(s);var c=L(s,2),l=e=>{var t=oo(),r=I(t,!0);R(e=>W(r,e),[()=>(V($),n(),B(()=>$(`limited`,n())))]),U(e,t)};G(c,e=>{V(a()),B(()=>a().runnerInventory.candidates.length>10)&&e(l)}),D(t),R(e=>W(i,e),[()=>(V($),n(),B(()=>$(`observed`,n())))]),U(e,t)};G(p,e=>{V(a()),B(()=>a().runnerInventory)&&e(m)}),D(t),R((e,t,n,r,a)=>{W(i,e),W(s,`${t??``}: ${n??``}`),W(u,` · ${r??``}: ${a??``}`)},[()=>(V($),n(),B(()=>$(`help`,n()))),()=>(V($),n(),B(()=>$(`registry`,n()))),()=>(V($),V(a()),n(),B(()=>$(a().runnerRegistryStatus??`unavailable`,n()))),()=>(V($),n(),B(()=>$(`inventory`,n()))),()=>(V($),V(a()),n(),B(()=>$(a().runnerInventory?.status??`unavailable`,n())))]),U(e,t)},l=gt(()=>(V(a()),B(()=>a().id.startsWith(`runners.`)&&a().id!==`runners.discover`)));G(s,e=>{z(l)&&e(c)}),U(e,o),k(),i()}function uo(e){let t=String(e.question.defaultValue),n=t.split(`,`).map(e=>e.trim()).filter(Boolean),r=e.question.kind===`multi-select`?n.includes(`All`)&&e.question.choices?.includes(`All`)?[`All`]:(e.question.choices??[]).filter(e=>e!==`All`&&n.includes(e.split(` — `)[0])):e.question.kind===`scope-overrides`?n:e.question.kind===`producer-select`?t.split(`;`).map(e=>e.trim()).filter(Boolean):e.question.kind===`project-select`?n.filter(t=>e.question.projectCandidates?.some(e=>String(e.number)===t)):[],i=e.question.kind===`project-select`?n.filter(e=>!r.includes(e)).join(`,`):t;return{value:e.question.kind===`producer-select`?``:i,selected:r}}function fo(e,t){return t===`All`?e.includes(`All`)?[]:[`All`]:e.includes(t)?e.filter(e=>e!==t):[...e.filter(e=>e!==`All`),t]}function po(e,t,n){return e.question.kind===`scope-overrides`||e.question.kind===`multi-select`?n.length?n.join(`,`):`none`:e.question.kind===`producer-select`?[...n,...t.split(`;`).map(e=>e.trim()).filter(Boolean)].join(`;`):e.question.kind===`project-select`?[...n,...t.split(`,`).map(e=>e.trim()).filter(Boolean)].join(`,`)||`none`:t}var mo={issueCreated:`projectTransitionIssueCreated`,pullRequestCreated:`projectTransitionPullRequestCreated`,issueInProgress:`projectTransitionIssueInProgress`,pullRequestInProgress:`projectTransitionPullRequestInProgress`};function ho(e){if(e)try{let t=new URL(e);if(t.protocol!==`https:`||t.username||t.password||t.search)return;if(t.hostname===`docs.page`&&t.port===``&&t.pathname.startsWith(`/vypdev/copilot/`)||t.hostname===`docs.github.com`&&t.port===``&&t.pathname.startsWith(`/en/`))return t.href}catch{return}}var go=H(`

                                                              `),_o=H(`

                                                              `),vo=H(` `,1);function yo(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`kind`,8),s=X(t,`status`,8),c=X(t,`truncated`,8,!1),l={observed:`checksObserved`,"no-recent-runs":`checksNoRecent`,"no-verifiable-checks":`checksNoVerifiable`,"permission-denied":`checksDenied`,unavailable:`checksUnavailable`},u={observed:`projectsObserved`,empty:`projectsEmpty`,"permission-denied":`projectsDenied`,unavailable:`projectsUnavailable`,unsupported:`projectsUnsupported`};Tn(()=>(V(s()),V(o())),()=>{N(a,s()?o()===`checks`?l[s()]:u[s()]:void 0)}),En(),ji();var d=vo(),f=F(d),p=e=>{var t=go(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),z(a),n(),B(()=>Z(z(a),n())))]),U(e,t)};G(f,e=>{z(a)&&e(p)});var m=L(f,2),h=e=>{var t=_o(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),V(o()),n(),B(()=>Z(o()===`checks`?`checksDiscoveryScope`:`projectsDiscoveryScope`,n())))]),U(e,t)};G(m,e=>{(s()===`observed`||s()===`empty`||s()===`no-recent-runs`||s()===`no-verifiable-checks`)&&e(h)});var g=L(m,2),_=e=>{var t=_o(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`discoveryTruncated`,n())))]),U(e,t)};G(g,e=>{c()&&e(_)}),U(e,d),k(),i()}var bo={en:{success:`Passed`,failure:`Failed`,cancelled:`Cancelled`,neutral:`Neutral`,skipped:`Skipped`,timed_out:`Timed out`,action_required:`Action required`,stale:`Stale`,startup_failure:`Failed to start`,unknown:`Unknown outcome`},es:{success:`Correcto`,failure:`Falló`,cancelled:`Cancelado`,neutral:`Neutral`,skipped:`Omitido`,timed_out:`Agotó el tiempo`,action_required:`Requiere intervención`,stale:`Obsoleto`,startup_failure:`Falló al iniciar`,unknown:`Resultado desconocido`},fr:{success:`Réussi`,failure:`Échoué`,cancelled:`Annulé`,neutral:`Neutre`,skipped:`Ignoré`,timed_out:`Délai dépassé`,action_required:`Action nécessaire`,stale:`Obsolète`,startup_failure:`Échec au démarrage`,unknown:`Résultat inconnu`},pt:{success:`Concluído`,failure:`Falhou`,cancelled:`Cancelado`,neutral:`Neutro`,skipped:`Ignorado`,timed_out:`Tempo esgotado`,action_required:`Ação necessária`,stale:`Obsoleto`,startup_failure:`Falha ao iniciar`,unknown:`Resultado desconhecido`}};function xo(e,t){return bo[t][e]??bo[t].unknown}function So(e,t,n){let r=e.trim(),i=n.trim(),a=String(t??``).trim(),o=Number(a);if(!(!r||!i||r.length>100||i.length>100||/[|;\r\n]/u.test(r+i)||!/^[1-9]\d*$/u.test(a)||!Number.isSafeInteger(o)))return`${r}|${o}|${i}`}var Co=H(` `),wo=H(`
                                                              `),To=H(`
                                                            • `),Eo=H(`
                                                                `),Do=H(``),Oo=H(`

                                                                `,1);function ko(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=M(),s=X(t,`candidates`,8),c=X(t,`selected`,12),l=X(t,`controller`,8),u=M(``),d=M(``),f=M(``),p=M(!1);function m(){let e=So(z(u),z(d),z(f));if(!e||c().length>=8){N(p,!0);return}N(p,!1),c().includes(e)||c([...c(),e]),N(u,``),N(d,``),N(f,``)}Tn(()=>V(s()),()=>{N(a,new Set(s().map(e=>`${e.name}|${e.sourceAppId}|${e.workflowName}`)))}),Tn(()=>(V(c()),z(a)),()=>{N(o,c().filter(e=>!z(a).has(e)))}),En(),ji();var h=Oo(),g=F(h);q(g,5,s,K,(e,t)=>{let r=A(()=>(z(t),B(()=>`${z(t).name}|${z(t).sourceAppId}|${z(t).workflowName}`)));var i=wo(),a=P(i),o=P(a);xi(o);var s=L(o,2),u=P(s),d=I(P(u),!0);D(u);var f=L(u),p=I(P(f));D(f);var m=I(L(f),!0);D(s),D(a);var h=L(a,2),g=P(h),_=e=>{var r=Co(),i=I(r,!0);R((e,t)=>{J(r,`href`,e),W(i,t)},[()=>(V(qa),z(t),B(()=>qa(z(t).runUrl))),()=>(V(Z),n(),B(()=>Z(`ciRun`,n())))]),U(e,r)},v=gt(()=>(V(qa),z(t),B(()=>qa(z(t).runUrl))));G(g,e=>{z(v)&&e(_)});var y=L(g,2),b=e=>{var r=Co(),i=I(r,!0);R((e,t)=>{J(r,`href`,e),W(i,t)},[()=>(V(Ja),z(t),B(()=>Ja(z(t).requiredByRuleset?.sourceUrl))),()=>(V(Z),n(),B(()=>Z(`ciRule`,n())))]),U(e,r)},x=gt(()=>(V(Ja),z(t),B(()=>Ja(z(t).requiredByRuleset?.sourceUrl))));G(y,e=>{z(x)&&e(b)}),D(h),D(i),R((e,n,r,i,a,s)=>{Si(o,e),o.disabled=n,W(d,(z(t),B(()=>z(t).name))),W(p,`${z(t),B(()=>z(t).workflowName)??``} · ${z(t),B(()=>z(t).sourceAppName??`GitHub App`)??``} ${z(t),B(()=>z(t).sourceAppId)??``} · ${r??``} · ${i??``} · ${a??``}`),W(m,s)},[()=>(V(c()),V(z(r)),B(()=>c().includes(z(r)))),()=>(V(l()),V(c()),V(z(r)),B(()=>!l()||c().length>=8&&!c().includes(z(r)))),()=>(V(xo),z(t),n(),B(()=>xo(z(t).conclusion,n()))),()=>(z(t),B(()=>z(t).headSha.slice(0,7))),()=>(z(t),V(Z),n(),B(()=>z(t).observedAt??Z(`observationTimeUnknown`,n()))),()=>(z(t),V(Z),n(),B(()=>z(t).requiredByRuleset?Z(`branchRequirementObserved`,n(),{branch:z(t).requiredByRuleset.branch}):Z(`branchRequirementUnknown`,n())))]),wr(`change`,o,()=>c(fo(c(),z(r)))),U(e,i)}),D(g);var _=L(g,2),v=e=>{var t=Eo();q(t,5,()=>z(o),K,(e,t)=>{var r=To(),i=P(r),a=I(i,!0),o=L(i,2),s=I(o,!0);D(r),R(e=>{W(a,z(t)),o.disabled=!l(),W(s,e)},[()=>(V(Z),n(),B(()=>Z(`producerRemove`,n())))]),wr(`click`,o,()=>c(fo(c(),z(t)))),U(e,r)}),D(t),U(e,t)};G(_,e=>{z(o),B(()=>z(o).length)&&e(v)});var y=L(_,2),b=I(y,!0),x=L(y,2),S=P(x),C=P(S,!0),w=L(C);xi(w),D(S);var ee=L(S,2),te=P(ee,!0),ne=L(te);xi(ne),D(ee);var re=L(ee,2),ie=P(re,!0),ae=L(ie);xi(ae),D(re),D(x);var oe=L(x,2),se=I(oe,!0),ce=L(oe,2),le=e=>{var t=Do(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`producerManualInvalid`,n())))]),U(e,t)};G(ce,e=>{z(p)&&e(le)}),R((e,t,n,r,i,a)=>{J(g,`aria-label`,e),W(b,t),W(C,n),w.disabled=!l(),W(te,r),ne.disabled=!l(),W(ie,i),ae.disabled=!l(),oe.disabled=!l(),W(se,a)},[()=>(V(Z),n(),B(()=>Z(`checksObserved`,n()))),()=>(V(Z),n(),B(()=>Z(`producerManualHelp`,n()))),()=>(V(Z),n(),B(()=>Z(`producerName`,n()))),()=>(V(Z),n(),B(()=>Z(`producerAppId`,n()))),()=>(V(Z),n(),B(()=>Z(`producerWorkflow`,n()))),()=>(V(Z),n(),B(()=>Z(`producerAdd`,n())))]),Ei(w,()=>z(u),e=>N(u,e)),Ei(ne,()=>z(d),e=>N(d,e)),Ei(ae,()=>z(f),e=>N(f,e)),wr(`click`,oe,m),U(e,h),k(),i()}Tr([`change`,`click`]);var Ao=H(` `),jo=H(`
                                                                `),Mo=H(`
                                                              • `),No=H(`

                                                                  `,1),Po=H(`
                                                                  `,1);function Fo(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=M(),s=X(t,`candidates`,8),c=X(t,`selected`,12),l=X(t,`value`,12),u=X(t,`controller`,8);Tn(()=>V(s()),()=>{N(a,new Set(s().map(e=>String(e.number))))}),Tn(()=>(V(c()),z(a)),()=>{N(o,c().filter(e=>!z(a).has(e)))}),En(),ji();var d=Po(),f=F(d);q(f,5,s,K,(e,t)=>{var r=jo(),i=P(r),a=P(i);xi(a);var o=L(a,2),s=P(o),l=I(P(s),!0);D(s);var d=L(s),f=I(P(d));D(d),D(o),D(i);var p=L(i,2),m=e=>{var r=Ao(),i=I(r,!0);R((e,t)=>{J(r,`href`,e),W(i,t)},[()=>(V(Ya),z(t),B(()=>Ya(z(t).url))),()=>(V(Z),n(),B(()=>Z(`projectUrl`,n())))]),U(e,r)},h=gt(()=>(V(Ya),z(t),B(()=>Ya(z(t).url))));G(p,e=>{z(h)&&e(m)}),D(r),R((e,n)=>{Si(a,e),a.disabled=n,W(l,(z(t),B(()=>z(t).title))),W(f,`${z(t),B(()=>z(t).owner)??``} · #${z(t),B(()=>z(t).number)??``}`)},[()=>(V(c()),z(t),B(()=>c().includes(String(z(t).number)))),()=>(V(u()),V(c()),z(t),B(()=>!u()||c().length>=10&&!c().includes(String(z(t).number))))]),wr(`change`,a,()=>c(fo(c(),String(z(t).number)))),U(e,r)}),D(f);var p=L(f,2),m=e=>{var t=No(),r=F(t),i=I(r,!0),a=L(r,2);q(a,5,()=>z(o),K,(e,t)=>{var r=Mo(),i=P(r),a=I(i),o=L(i,2),s=I(o,!0);D(r),R(e=>{W(a,`#${z(t)??``}`),o.disabled=!u(),W(s,e)},[()=>(V(Z),n(),B(()=>Z(`removeSelection`,n())))]),wr(`click`,o,()=>c(fo(c(),z(t)))),U(e,r)}),D(a),R(e=>W(i,e),[()=>(V(Z),n(),B(()=>Z(`projectSelectionNotObserved`,n())))]),U(e,t)};G(p,e=>{z(o),B(()=>z(o).length)&&e(m)});var h=L(p,2),g=P(h),_=I(g,!0),v=L(g,2);xi(v),D(h),R((e,t)=>{J(f,`aria-label`,e),W(_,t),v.disabled=!u()},[()=>(V(Z),n(),B(()=>Z(`projectsObserved`,n()))),()=>(V(Z),n(),B(()=>Z(`projectManual`,n())))]),Ei(v,l),U(e,d),k(),i()}Tr([`change`,`click`]);var Io=H(``),Lo=H(`
                                                                  `),Ro=H(` `,1);function zo(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`explanation`,8),o=X(t,`helpUrl`,8);ji();var s=Ro(),c=F(s),l=e=>{var t=Io(),r=P(t),i=I(r);D(t),R(e=>{J(r,`href`,o()),W(i,`${e??``} ↗`)},[()=>(V(Z),n(),B(()=>Z(`learnMore`,n())))]),U(e,t)};G(c,e=>{o()&&e(l)});var u=L(c,2),d=e=>{var t=Lo(),r=P(t),i=I(r,!0),o=L(r),s=P(o),c=I(s,!0),l=L(s),u=I(l,!0),d=L(l,2),f=I(d,!0),p=L(d),m=I(p,!0),h=L(p,2),g=I(h,!0),_=L(h),v=I(_,!0),y=L(_,2),b=I(y,!0),x=L(y),S=I(x,!0),C=L(x,2),w=I(C,!0),ee=L(C),te=I(ee,!0),ne=L(ee,2),re=I(ne,!0),ie=L(ne),ae=I(ie,!0),oe=L(ie,2),se=I(oe,!0),ce=I(L(oe),!0);D(o),D(t),R((e,t,n,r,o,s,l,d)=>{W(i,e),W(c,t),W(u,(V(a()),B(()=>a().when))),W(f,n),W(m,(V(a()),B(()=>a().where))),W(g,r),W(v,(V(a()),B(()=>a().how))),W(b,o),W(S,(V(a()),B(()=>a().why))),W(w,s),W(te,(V(a()),B(()=>a().example))),W(re,l),W(ae,(V(a()),B(()=>a().effect))),W(se,d),W(ce,(V(a()),B(()=>a().verify)))},[()=>(V(Z),n(),B(()=>Z(`whyMatters`,n()))),()=>(V(Z),n(),B(()=>Z(`whenApplies`,n()))),()=>(V(Z),n(),B(()=>Z(`whereConfigured`,n()))),()=>(V(Z),n(),B(()=>Z(`howToChoose`,n()))),()=>(V(Z),n(),B(()=>Z(`whyRecommendation`,n()))),()=>(V(Z),n(),B(()=>Z(`example`,n()))),()=>(V(Z),n(),B(()=>Z(`effect`,n()))),()=>(V(Z),n(),B(()=>Z(`verify`,n())))]),U(e,t)};G(u,e=>{a()&&e(d)}),U(e,s),k(),i()}var Bo=H(`· `,1),Vo=H(`

                                                                  `,1);function Ho(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`candidate`,8);ji();var o=Vo(),s=F(o),c=P(s),l=I(c),u=L(c,2),d=e=>{var t=Bo(),r=L(F(t)),i=I(r,!0);R((e,t)=>{J(r,`href`,e),W(i,t)},[()=>(V(qa),V(a()),B(()=>qa(a().runUrl))),()=>(V(Z),n(),B(()=>Z(`ciRun`,n())))]),U(e,t)},f=gt(()=>(V(qa),V(a()),B(()=>qa(a().runUrl))));G(u,e=>{z(f)&&e(d)}),D(s);var p=L(s,2),m=P(p),h=I(m),g=L(m),_=L(g),v=e=>{var t=Bo(),r=L(F(t)),i=I(r,!0);R((e,t)=>{J(r,`href`,e),W(i,t)},[()=>(V(Ja),V(a()),B(()=>Ja(a().requiredByRuleset?.sourceUrl))),()=>(V(Z),n(),B(()=>Z(`ciRule`,n())))]),U(e,t)},y=gt(()=>(V(Ja),V(a()),B(()=>Ja(a().requiredByRuleset?.sourceUrl))));G(_,e=>{z(y)&&e(v)}),D(p),R((e,t,n,r)=>{W(l,`${V(a()),B(()=>a().workflowName)??``} · GitHub App ${V(a()),B(()=>a().sourceAppId)??``}`),W(h,`${e??``} · ${t??``} · ${n??``}`),W(g,` · ${r??``} `)},[()=>(V(xo),V(a()),n(),B(()=>xo(a().conclusion,n()))),()=>(V(a()),B(()=>a().headSha.slice(0,7))),()=>(V(a()),V(Z),n(),B(()=>a().observedAt??Z(`observationTimeUnknown`,n()))),()=>(V(a()),V(Z),n(),B(()=>a().requiredByRuleset?Z(`branchRequirementObserved`,n(),{branch:a().requiredByRuleset.branch}):Z(`branchRequirementUnknown`,n())))]),U(e,o),k(),i()}var Uo=H(`

                                                                  `);function Wo(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`question`,8);ji();var o=Pr(),s=F(o),c=e=>{var t=Uo(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`fixedIssuesRequired`,n())))]),U(e,t)},l=e=>{var t=Pr();q(F(t),1,()=>(V(a()),B(()=>Object.entries(a().fixedWorkflowFeatures).filter(([,e])=>e!==void 0))),K,(e,t)=>{var r=gt(()=>b(z(t),2));let i=()=>z(r)[0],a=()=>z(r)[1];var o=Uo(),s=I(o,!0);R(e=>W(s,e),[()=>(V(Z),a(),n(),i(),B(()=>Z(a()?`fixedWorkflowEnabled`:`fixedWorkflowDisabled`,n(),{kind:i()})))]),U(e,o)}),U(e,t)};G(s,e=>{V(a()),B(()=>a().id===`features.issues`&&(a().fixedWorkflowFeatures?.release||a().fixedWorkflowFeatures?.hotfix))?e(c):(V(a()),B(()=>a().fixedWorkflowFeatures)&&e(l,1))}),U(e,o),k(),i()}var Go=H(` `),Ko=H(`

                                                                  `),qo=H(`

                                                                  `),Jo=H(` `,1),Yo=H(`

                                                                  `),Xo=H(`
                                                                  `),Zo=H(`

                                                                  `),Qo=H(``),$o=H(`
                                                                • `),es=H(`
                                                                    `),ts=H(`
                                                                    `),ns=H(``),rs=H(``),is=H(` `,1),as=H(``),os=H(`
                                                                    `),ss=H(``),cs=H(``),ls=H(`

                                                                    `,1);function us(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=M(),s=M(),c=X(t,`prompt`,8),l=X(t,`controller`,8),u=X(t,`busy`,8),d=X(t,`onSubmit`,8),f=X(t,`onRetryDiscovery`,8),p=X(t,`onBack`,8),m=uo(c()),h=M(m.value),g=M(m.selected);Tn(()=>(V(c()),n()),()=>{N(a,c().presentation?.[n()])}),Tn(()=>z(a),()=>{N(o,ho(z(a)?.documentation?.url))}),Tn(()=>(V(c()),n()),()=>{N(s,ja(c().question,n()))}),En(),ji();var _=ls(),v=F(_),y=P(v),b=I(y,!0),x=L(y),S=e=>{var t=Go(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`permissionPreview`,n())))]),U(e,t)};G(x,e=>{V(c()),B(()=>c().phase===`permission-intent`)&&e(S)}),D(v);var C=L(v,2),w=e=>{var t=Ko(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),V(c()),B(()=>Z(`questionProgress`,n(),{current:String(c().progress.groupPosition),total:String(c().progress.groupTotal),overall:String(c().progress.position),all:String(c().progress.total)})))]),U(e,t)};G(C,e=>{V(c()),B(()=>c().progress)&&e(w)});var ee=L(C,2),te=e=>{var t=qo(),n=I(t,!0);R(()=>W(n,(z(a),B(()=>z(a).summary)))),U(e,t)};G(ee,e=>{z(a)&&e(te)});var ne=L(ee,2),re=e=>{yo(e,{kind:`checks`,get status(){return V(c()),B(()=>c().question.discoveryStatus)},get truncated(){return V(c()),B(()=>c().question.discoveryTruncated)}})};G(ne,e=>{V(c()),B(()=>c().question.id===`pullRequestApproval.testChecks`)&&e(re)});var ie=L(ne,2),ae=e=>{yo(e,{kind:`projects`,get status(){return V(c()),B(()=>c().question.discoveryStatus)},get truncated(){return V(c()),B(()=>c().question.discoveryTruncated)}})};G(ie,e=>{V(c()),B(()=>c().question.id===`projects.ids`)&&e(ae)});var oe=L(ie,2),se=e=>{var t=Xo(),r=P(t),i=e=>{var t=Jo(),r=F(t),i=I(r,!0),a=I(L(r,2),!0);R((e,t)=>{r.disabled=!l()||u(),W(i,e),W(a,t)},[()=>(V(Z),n(),B(()=>Z(`retryDiscovery`,n()))),()=>(V(Z),n(),V(c()),B(()=>Z(`retryRemaining`,n(),{count:String(c().question.discoveryRetryRemaining)})))]),wr(`click`,r,function(...e){f()?.apply(this,e)}),U(e,t)},a=e=>{var t=Yo(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`retryExhausted`,n())))]),U(e,t)};G(r,e=>{V(c()),B(()=>c().question.discoveryRetryRemaining>0)?e(i):e(a,-1)}),D(t),U(e,t)};G(oe,e=>{V(c()),B(()=>c().question.discoveryRetryRemaining!==void 0)&&e(se)});var ce=L(oe,2),le=e=>{var t=Zo(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`projectStatusUnavailable`,n())))]),U(e,t)};G(ce,e=>{V(c()),B(()=>c().question.statusOptionState===`unavailable`)&&e(le)});var ue=L(ce,2),de=e=>{var t=Qo(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`projectStatusIncompatible`,n())))]),U(e,t)};G(ue,e=>{V(c()),B(()=>c().question.statusOptionState===`incompatible`)&&e(de)});var fe=L(ue,2),pe=e=>{var t=Yo(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`projectSharedStatus`,n())))]),U(e,t)};G(fe,e=>{V(c()),B(()=>c().question.id===`projects.ids`)&&e(pe)});var me=L(fe,2);Wo(me,{get question(){return V(c()),B(()=>c().question)}});var he=L(me,2),ge=e=>{var t=es();q(t,5,()=>(V(c()),B(()=>c().question.projectStatusValues)),K,(e,t)=>{var r=$o(),i=P(r),a=L(i),o=I(P(a),!0);D(a),D(r),R(e=>{W(i,`${e??``}: `),W(o,(z(t),B(()=>z(t).value)))},[()=>(V(Z),V(mo),z(t),n(),B(()=>Z(mo[z(t).transition],n())))]),U(e,r)}),D(t),U(e,t)};G(he,e=>{V(c()),B(()=>c().question.projectStatusValues)&&e(ge)});var _e=L(he,2),ve=e=>{var t=ts(),r=P(t);let i;var o=I(r,!0),s=L(r);let u;var d=I(s,!0);D(t),R((e,n)=>{J(t,`aria-label`,(z(a),V(c()),B(()=>z(a)?.label??c().question.label))),J(r,`aria-pressed`,z(h)===`yes`||z(h)===`true`),r.disabled=!l(),i=ui(r,1,``,null,i,{selected:z(h)===`yes`||z(h)===`true`}),W(o,e),J(s,`aria-pressed`,z(h)===`no`||z(h)===`false`),s.disabled=!l(),u=ui(s,1,``,null,u,{selected:z(h)===`no`||z(h)===`false`}),W(d,n)},[()=>(V(Z),n(),B(()=>Z(`yes`,n()))),()=>(V(Z),n(),B(()=>Z(`no`,n())))]),wr(`click`,r,()=>N(h,`yes`)),wr(`click`,s,()=>N(h,`no`)),U(e,t)},ye=e=>{var t=is(),r=F(t),i=P(r),o=e=>{var t=ns(),r=I(t,!0);t.value=t.__value=``,R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`selectOne`,n())))]),U(e,t)};G(i,e=>{V(c()),B(()=>!c().question.defaultValue)&&e(o)}),q(L(i),1,()=>(V(c()),B(()=>c().question.choices??[])),K,(e,t)=>{let r=A(()=>(V(c()),z(t),B(()=>c().question.id===`pullRequestApproval.coverage.checkName`?c().question.trustedProducers?.find(e=>e.name===z(t)):void 0)));var i=rs(),a=I(i,!0),o={};R(e=>{W(a,e),o!==(o=z(t))&&(i.value=(i.__value=o)??``)},[()=>(V(z(r)),z(t),V(Aa),V(c()),n(),B(()=>z(r)?`${z(t)} — ${z(r).workflowName} · App ${z(r).sourceAppId}`:Aa(c().question.id,z(t),n())))]),U(e,i)}),D(r),mi(r);var s=L(r,2),u=e=>{var t=Pr();q(F(t),1,()=>(V(c()),z(h),B(()=>(c().question.producerCandidates??[]).filter(e=>e.name===z(h)))),K,(e,t)=>{Ho(e,{get candidate(){return z(t)}})}),U(e,t)};G(s,e=>{V(c()),B(()=>c().question.id===`pullRequestApproval.coverage.checkName`)&&e(u)}),R(()=>{J(r,`aria-label`,(z(a),V(c()),B(()=>z(a)?.label??c().question.label))),r.disabled=!l()}),hi(r,()=>z(h),e=>N(h,e)),U(e,t)},be=e=>{{let t=A(()=>(V(c()),B(()=>c().question.producerCandidates??[])));ko(e,{get candidates(){return z(t)},get controller(){return l()},get selected(){return z(g)},set selected(e){N(g,e)},$$legacy:!0})}},xe=e=>{{let t=A(()=>(V(c()),B(()=>c().question.projectCandidates??[])));Fo(e,{get candidates(){return z(t)},get controller(){return l()},get selected(){return z(g)},set selected(e){N(g,e)},get value(){return z(h)},set value(e){N(h,e)},$$legacy:!0})}},Se=e=>{var t=os();q(t,5,()=>(V(c()),B(()=>c().question.kind===`multi-select`?c().question.choices??[]:c().question.allowedNames??[])),K,(e,t)=>{var r=as(),i=P(r);xi(i);var a=I(L(i),!0);D(r),R((e,t)=>{Si(i,e),i.disabled=!l(),W(a,t)},[()=>(z(g),z(t),B(()=>z(g).includes(z(t)))),()=>(V(c()),V(Aa),z(t),n(),B(()=>c().question.kind===`multi-select`?Aa(c().question.id,z(t),n()):z(t)))]),wr(`change`,i,()=>N(g,fo(z(g),z(t)))),U(e,r)}),D(t),R(()=>J(t,`aria-label`,(z(a),V(c()),B(()=>z(a)?.label??c().question.label)))),U(e,t)},Ce=e=>{var t=Pr(),n=F(t),r=e=>{var t=ss();it(t),R(()=>{J(t,`aria-label`,(z(a),V(c()),B(()=>z(a)?.label??c().question.label))),t.disabled=!l()}),Ei(t,()=>z(h),e=>N(h,e)),U(e,t)},i=e=>{var t=cs();xi(t),R(()=>{J(t,`aria-label`,(z(a),V(c()),B(()=>z(a)?.label??c().question.label))),J(t,`type`,(V(c()),B(()=>c().question.kind===`number`?`number`:`text`))),J(t,`min`,(V(c()),B(()=>c().question.kind===`number`?0:void 0))),t.disabled=!l()}),Ei(t,()=>z(h),e=>N(h,e)),U(e,t)};G(n,e=>{V(c()),B(()=>c().question.id===`ai.bugbotOrganizationRules`)?e(r):e(i,-1)}),U(e,t)};G(_e,e=>{V(c()),B(()=>c().question.kind===`boolean`)?e(ve):(V(c()),B(()=>c().question.kind===`choice`)?e(ye,1):(V(c()),B(()=>c().question.kind===`producer-select`)?e(be,2):(V(c()),B(()=>c().question.kind===`project-select`)?e(xe,3):(V(c()),B(()=>c().question.kind===`multi-select`||c().question.kind===`scope-overrides`)?e(Se,4):e(Ce,-1)))))});var we=L(_e,2),T=I(we,!0),Te=L(we,2),E=e=>{var t=Ko(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),V(c()),n(),B(()=>Z(c().question.suggestionSource===`github`?`sourceGithub`:c().question.suggestionSource===`local`?`sourceLocal`:c().question.suggestionSource===`configuration`?`sourceConfig`:`sourceDefault`,n())))]),U(e,t)};G(Te,e=>{V(c()),B(()=>c().question.suggestionSource)&&e(E)});var Ee=L(Te,2);lo(Ee,{get question(){return V(c()),B(()=>c().question)}});var De=L(Ee,2);zo(De,{get explanation(){return z(a)},get helpUrl(){return z(o)}});var Oe=L(De,2),ke=P(Oe),Ae=e=>{{let t=A(()=>(V(Z),n(),B(()=>Z(`previousQuestion`,n())))),r=A(()=>!l()||u());Qa(e,{get label(){return z(t)},variant:`secondary`,get onClick(){return p()},get disabled(){return z(r)}})}};G(ke,e=>{V(c()),B(()=>c().canGoBack)&&e(Ae)});var je=L(ke,2);{let e=A(()=>(V(Z),n(),B(()=>Z(`continue`,n())))),t=A(()=>!l()||u());Qa(je,{get label(){return z(e)},arrow:!0,onClick:()=>d()(po(c(),z(h),z(g))),get disabled(){return z(t)}})}D(Oe),R((e,t)=>{W(b,e),W(T,t)},[()=>(z(a),V(c()),B(()=>z(a)?.label??c().question.label.replace(` (Space toggles, Enter confirms)`,``))),()=>(V(Z),n(),z(s),B(()=>Z(`suggested`,n(),{answer:z(s)})))]),U(e,_),k(),i()}Tr([`click`,`change`]);var ds=H(` `),fs=H(``),ps=H(`
                                                                    `,1);function ms(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`prompt`,8),s=X(t,`controller`,8),c=X(t,`busy`,8),l=X(t,`onSubmit`,8);Tn(()=>(V(o()),Ka),()=>{N(a,o().copyId===`botPat.scopeConflict`||o().copyId===`botPat.scopeConflictUnavailable`?Ka(o().copyValues?.repository):void 0)}),En(),ji();var u=ps(),d=F(u),f=e=>{var t=ds(),r=P(t);Oe(),D(t),R(e=>{J(t,`href`,z(a)),W(r,`${e??``} `)},[()=>(V(Z),n(),B(()=>Z(`repositorySecretSettings`,n())))]),U(e,t)};G(d,e=>{z(a)&&e(f)});var p=L(d,2);q(p,5,()=>(V(o()),B(()=>o().choices)),K,(e,t,r)=>{var i=fs(),a=I(P(i),!0);Oe(),D(i),R(e=>{i.disabled=!s()||c(),W(a,e)},[()=>(V(La),V(o()),n(),B(()=>La(o(),n(),r)))]),wr(`click`,i,()=>l()(z(t))),U(e,i)}),D(p),U(e,u),k(),i()}Tr([`click`]);var hs=H(`

                                                                    `),gs=H(`

                                                                    `,1),_s=H(``);function vs(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`storage`,8);ji();var o=_s(),s=P(o),c=I(s,!0),l=L(s,2),u=I(l,!0),d=L(l,2),f=e=>{var t=gs(),r=F(t),i=I(r,!0),o=L(r,2),s=e=>{var t=hs(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`patOrganizationImpact`,n())))]),U(e,t)};G(o,e=>{V(a()),B(()=>a().scope===`organization`&&a().replacesExisting)&&e(s)}),R(e=>W(i,e),[()=>(V(Z),n(),B(()=>Z(`patReplacementChecks`,n())))]),U(e,t)};G(d,e=>{V(a()),B(()=>a().operation!==`retain`)&&e(f)}),D(o),R((e,t)=>{W(c,e),W(u,t)},[()=>(V(Z),n(),B(()=>Z(`patStorageTitle`,n()))),()=>(V(Z),V(a()),n(),B(()=>Z(a().operation===`retain`?`patStorageRetain`:a().replacesExisting?a().scope===`repository`?`patRepositoryReplace`:`patOrganizationReplace`:a().scope===`repository`?`patRepositoryCreate`:`patOrganizationCreate`,n(),{destination:a().destination})))]),U(e,o),k(),i()}var ys=H(``),bs=H(`

                                                                    `,1),xs=H(`

                                                                    `),Ss=H(`
                                                                    `,1);function Cs(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=M(),s=M(),c=M(),l=X(t,`prompt`,8),u=X(t,`controller`,8),d=X(t,`busy`,8),f=X(t,`onSubmit`,8),p=M(``);function m(){let e=z(p);l().kind===`secret`&&N(p,``),f()(e)}Tn(()=>V(l()),()=>{N(a,Ga(l().link))}),Tn(()=>V(l()),()=>{N(o,l().copyId===`botPat.entry.guided`?l().copyValues?.account:void 0)}),Tn(()=>V(l()),()=>{N(s,l().copyId===`botPat.entry.guided`||l().copyId===`botPat.entry.manual`)}),Tn(()=>(z(s),V(l())),()=>{N(c,z(s)?l().copyValues?.storageScope:void 0)}),En(),ji();var h=Ss(),g=F(h),_=e=>{var t=bs(),r=F(t),i=e=>{var t=ys(),r=P(t),i=I(r,!0),a=I(L(r,2),!0);D(t),R((e,t)=>{W(i,e),W(a,t)},[()=>(V(Z),n(),z(o),B(()=>Z(`botAccountWarning`,n(),{account:z(o)}))),()=>(V(Z),n(),B(()=>Z(`botAccountHelp`,n())))]),U(e,t)};G(r,e=>{z(o)&&e(i)});var s=L(r,2),c=P(s);Oe(),D(s);var l=I(L(s,2),!0);R((e,t)=>{J(s,`href`,z(a)),J(s,`aria-describedby`,z(o)?`bot-account-warning`:void 0),W(c,`${e??``} `),W(l,t)},[()=>(z(o),V(Z),n(),B(()=>z(o)?Z(`botGithubForm`,n(),{account:z(o)}):Z(`githubForm`,n()))),()=>(V(Z),n(),B(()=>Z(`githubFormHelp`,n())))]),U(e,t)};G(g,e=>{z(a)&&e(_)});var v=L(g,2),y=e=>{{let t=A(()=>(z(c),V(l()),B(()=>({scope:z(c),destination:l().copyValues.storageDestination,replacesExisting:l().copyValues.storageReplacesExisting===`true`}))));vs(e,{get storage(){return z(t)}})}};G(v,e=>{z(c),V(l()),B(()=>(z(c)===`repository`||z(c)===`organization`)&&l().copyValues?.storageDestination)&&e(y)});var b=L(v,2),x=I(b,!0),S=L(b,2);xi(S);var C=L(S,2),w=e=>{var t=xs(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`secretHelp`,n())))]),U(e,t)};G(C,e=>{V(l()),B(()=>l().kind===`secret`)&&e(w)});var ee=L(C,2),te=P(ee);{let e=A(()=>(V(Z),n(),B(()=>Z(`continue`,n())))),t=A(()=>(V(u()),V(d()),V(l()),z(p),B(()=>!u()||d()||!l().optional&&!z(p).trim())));Qa(te,{get label(){return z(e)},arrow:!0,onClick:m,get disabled(){return z(t)}})}D(ee),R((e,t)=>{W(x,e),J(S,`type`,(V(l()),B(()=>l().kind===`secret`?`password`:`text`))),S.disabled=!u(),J(S,`placeholder`,t)},[()=>(V(Z),V(l()),n(),B(()=>Z(l().kind===`secret`?`pasteHere`:`yourAnswer`,n()))),()=>(V(Z),V(l()),n(),B(()=>Z(l().kind===`secret`?`hiddenAfter`:`typeAnswer`,n())))]),Ei(S,()=>z(p),e=>N(p,e)),U(e,h),k(),i()}var ws={"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`Help / question issues remain branchless even when issue-managed-branches is enabled.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`Release automation is installed, but release issue events are disabled by the selected issue workflow profile.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Release and hotfix workflows require the workflow PAT Secret and a writable token.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.`,"Cursor is an experimental runtime in Copilot and requires a compatible CLI plus CURSOR_API_KEY; the Action installs the official CLI when the default executable is absent.":`Cursor is an experimental runtime in Copilot and requires a compatible CLI plus CURSOR_API_KEY; the Action installs the official CLI when the default executable is absent.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.`},Ts={en:ws,es:{"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`No has activado ningún tipo de flujo de incidencias. Sus eventos no se gestionarán hasta que actives un formulario de incidencia y su entrada en el perfil.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`Las incidencias de ayuda y consulta no crean ramas, aunque actives las ramas gestionadas por incidencias.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`La automatización de versiones ya está instalada, pero el perfil elegido desactiva los eventos de incidencias de versiones.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`La automatización de correcciones urgentes ya está instalada, pero el perfil elegido desactiva los eventos de sus incidencias.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`Has desactivado la generación de instrucciones para agentes del repositorio. Los colaboradores no recibirán el perfil ni la guía del flujo de trabajo generados.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Los flujos de versiones y correcciones urgentes requieren el Secret con el PAT de la Action y un token con permisos de escritura.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`La cola de merge bloqueará la operación si cada productor obligatorio no se verifica automáticamente o no dispone de una certificación exacta revisada.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`Está activado el cierre de incidencias inactivas. Las que estén en espera se cerrarán tras el plazo configurado y podrán reabrirse con un comentario.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`El PAT del bot debe tener acceso a los Projects seleccionados, y los cuatro valores de Status configurados deben existir en cada uno de ellos.`,"Cursor is an experimental runtime in Copilot and requires a compatible CLI plus CURSOR_API_KEY; the Action installs the official CLI when the default executable is absent.":`Cursor es un entorno experimental en Copilot y requiere un CLI compatible y CURSOR_API_KEY; la Action instala el CLI oficial si falta el ejecutable predeterminado.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Los Secrets y Variables de organización requieren permisos en ella. Limitar el acceso a los repositorios elegidos es la opción más segura; los valores del repositorio tienen prioridad.`},fr:{"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`Aucun type de flux de travail pour les tickets n’est activé. Leurs événements ne seront pas gérés tant qu’un formulaire de ticket pris en charge et son entrée de profil ne seront pas activés.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`Les tickets d’aide ou de question ne créent pas de branche, même lorsque les branches gérées par les tickets sont activées.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`L’automatisation des versions est déjà installée, mais le profil choisi désactive les événements des tickets de version.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`L’automatisation des correctifs urgents est déjà installée, mais le profil choisi désactive les événements des tickets correspondants.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`La génération des consignes pour les agents du dépôt est désactivée. Les collaborateurs ne recevront ni le profil ni le guide de flux de travail générés.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Les flux de version et de correctif urgent nécessitent le Secret contenant le PAT de l’Action et un jeton autorisé à écrire.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`La file de fusion bloque l’opération si chaque producteur requis n’est pas vérifié automatiquement ou couvert par une attestation exacte et examinée.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`La fermeture des tickets inactifs est activée. Les tickets en attente seront fermés après le délai configuré et pourront être rouverts par un nouveau commentaire.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`Le PAT du bot doit avoir accès aux Projects sélectionnés, et les quatre valeurs Status configurées doivent exister dans chacun de ces Projects.`,"Cursor is an experimental runtime in Copilot and requires a compatible CLI plus CURSOR_API_KEY; the Action installs the official CLI when the default executable is absent.":`Cursor est un environnement expérimental dans Copilot et nécessite un CLI compatible ainsi que CURSOR_API_KEY ; l’Action installe le CLI officiel si l’exécutable par défaut est absent.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Les Secrets et Variables d’organisation nécessitent des droits sur celle-ci. Limiter l’accès aux dépôts sélectionnés est le choix le plus sûr ; les valeurs du dépôt prévalent.`},pt:{"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`Não está ativo nenhum tipo de fluxo de trabalho para issues. Os respetivos eventos não serão geridos até ativar um formulário de issue suportado e a entrada correspondente no perfil.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`As issues de ajuda ou perguntas não criam ramos, mesmo com os ramos geridos por issues ativados.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`A automação de versões já está instalada, mas o perfil escolhido desativa os eventos das issues de versão.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`A automação de correções urgentes já está instalada, mas o perfil escolhido desativa os eventos das respetivas issues.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`A criação de orientações para agentes do repositório está desativada. Os colaboradores não receberão o perfil nem o guia do fluxo de trabalho gerados.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Os fluxos de versão e correção urgente exigem o Secret com o PAT da Action e um token com permissão de escrita.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`A fila de integração bloqueia a operação se cada produtor obrigatório não for verificado automaticamente ou coberto por uma declaração exata e revista.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`O fecho de issues inativas está ativado. As que aguardam resposta serão fechadas após o prazo configurado e poderão ser reabertas com um novo comentário.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`O PAT do bot tem de ter acesso aos Projects selecionados, e os quatro valores de Status configurados têm de existir em cada Project.`,"Cursor is an experimental runtime in Copilot and requires a compatible CLI plus CURSOR_API_KEY; the Action installs the official CLI when the default executable is absent.":`O Cursor é um ambiente experimental no Copilot e requer um CLI compatível e CURSOR_API_KEY; a Action instala o CLI oficial se o executável padrão não estiver disponível.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Os Secrets e Variables da organização exigem permissões nessa organização. Restringir o acesso aos repositórios selecionados é a opção mais segura; os valores do repositório prevalecem.`}};function Es(e,t){let n=Ts[t]??ws;return Object.prototype.hasOwnProperty.call(n,e)?n[e]:t===`en`?e:Z(`planUnknownWarning`,t)}var Ds={en:{issues:`Issues`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Issue comments`,pullRequestComments:`Pull-request comments`,release:`Releases`,hotfix:`Hotfixes`,agentProvisioning:`Agent provisioning`,credentialHealth:`Credential health`,inactiveIssueClosure:`Inactive issue closure`,issueTemplates:`Issue templates`,pullRequestTemplate:`Pull-request template`},es:{issues:`Issues`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Comentarios en issues`,pullRequestComments:`Comentarios en pull requests`,release:`Releases`,hotfix:`Correcciones urgentes`,agentProvisioning:`Instalación de agentes`,credentialHealth:`Estado de credenciales`,inactiveIssueClosure:`Cierre de issues inactivos`,issueTemplates:`Plantillas de issues`,pullRequestTemplate:`Plantilla de pull requests`},fr:{issues:`Tickets`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Commentaires des tickets`,pullRequestComments:`Commentaires des pull requests`,release:`Versions`,hotfix:`Correctifs urgents`,agentProvisioning:`Installation des agents`,credentialHealth:`État des identifiants`,inactiveIssueClosure:`Fermeture des tickets inactifs`,issueTemplates:`Modèles de tickets`,pullRequestTemplate:`Modèle de pull request`},pt:{issues:`Questões`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Comentários nas questões`,pullRequestComments:`Comentários nas pull requests`,release:`Versões`,hotfix:`Correções urgentes`,agentProvisioning:`Instalação de agentes`,credentialHealth:`Estado das credenciais`,inactiveIssueClosure:`Fecho de questões inativas`,issueTemplates:`Modelos de questões`,pullRequestTemplate:`Modelo de pull request`}};function Os(e,t){return Ds[t][e]??e}var ks={en:{planner:`Planner`,findings:`Findings analyst`,reviewer:`Reviewer`,fixer:`Fixer`,tester:`Tester`},es:{planner:`Planificador`,findings:`Analista de hallazgos`,reviewer:`Revisor`,fixer:`Corrector`,tester:`Probador`},fr:{planner:`Planificateur`,findings:`Analyste des problèmes`,reviewer:`Réviseur`,fixer:`Correcteur`,tester:`Testeur`},pt:{planner:`Planeador`,findings:`Analista de problemas`,reviewer:`Revisor`,fixer:`Corretor`,tester:`Testador`}};function As(e,t){return ks[t][e]??e}var js=H(`
                                                                  • `),Ms=H(`
                                                                  • `),Ns=H(`
                                                                      `),Ps=H(`· `,1),Fs=H(`
                                                                      `,1),Is=H(`
                                                                      `,1),Ls=H(`
                                                                        `),Rs=H(`

                                                                          /

                                                                          `);function zs(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`decisions`,8);function o(e){return Z(e===`repository`?`scopeRepository`:e===`organization`?`scopeOrganization`:`scopeDisabled`,n())}function s(e){return Z(e===`guarded`?`approvalGuarded`:e===`recommend`?`approvalRecommend`:`approvalOff`,n())}ji();var c=Rs(),l=P(c),u=I(l,!0),d=L(l,2),f=P(d),p=P(f),m=I(p,!0),h=I(L(p),!0);D(f);var g=L(f,2),_=P(g),v=I(_,!0),y=I(L(_),!0);D(g);var b=L(g,2),x=P(b),S=I(x,!0),C=L(x),w=P(C);q(w,5,()=>(V(a()),B(()=>a().agentRouting)),K,(e,t)=>{var r=js(),i=P(r),a=I(L(i));D(r),R(e=>{W(i,`${e??``}: `),W(a,`${z(t),B(()=>z(t).provider)??``} · ${z(t),B(()=>z(t).modelProvider)??``}/${z(t),B(()=>z(t).model)??``}`)},[()=>(V(As),z(t),n(),B(()=>As(z(t).role,n())))]),U(e,r)}),D(w),D(C),D(b);var ee=L(b,2),te=P(ee),ne=I(te,!0),re=L(te),ie=P(re),ae=I(ie,!0),oe=I(L(ie,2),!0);D(re),D(ee);var se=L(ee,2),ce=P(se),le=I(ce,!0),ue=I(L(ce),!0);D(se);var de=L(se,2),fe=e=>{var t=Is(),r=F(t),i=P(r),o=I(i,!0),s=L(i),c=P(s),l=e=>{var t=Ns();q(t,5,()=>(V(a()),B(()=>a().trustedChecks)),K,(e,t)=>{var r=Ms(),i=P(r),a=I(i,!0),o=L(i),s=I(L(o),!0);D(r),R(e=>{W(a,(z(t),B(()=>z(t).name))),W(o,` · ${e??``} ${z(t),B(()=>z(t).sourceAppId)??``} · `),W(s,(z(t),B(()=>z(t).workflowName)))},[()=>(V(Z),n(),B(()=>Z(`producerAppId`,n())))]),U(e,r)}),D(t),U(e,t)},u=e=>{var t=Nr();R(e=>W(t,e),[()=>(V(Z),n(),B(()=>Z(`none`,n())))]),U(e,t)};G(c,e=>{V(a()),B(()=>a().trustedChecks.length)?e(l):e(u,-1)}),D(s),D(r);var d=L(r,2),f=P(d),p=I(f,!0),m=I(L(f),!0);D(d);var h=L(d,2),g=P(h),_=I(g,!0),v=L(g),y=P(v,!0),b=L(y),x=e=>{var t=Ps(),n=I(L(F(t)),!0);R(()=>W(n,(V(a()),B(()=>a().coverageCheck)))),U(e,t)};G(b,e=>{V(a()),B(()=>a().coverageCheck)&&e(x)}),D(v),D(h);var S=L(h,2),C=e=>{var t=Fs(),r=F(t),i=P(r),o=I(i,!0),s=I(L(i),!0);D(r);var c=L(r,2),l=P(c),u=I(l,!0),d=L(l),f=I(P(d),!0);D(d),D(c);var p=L(c,2),m=P(p),h=I(m,!0),g=I(L(m),!0);D(p),R((e,t,n,r,i,a)=>{W(o,e),W(s,t),W(u,n),W(f,r),W(h,i),W(g,a)},[()=>(V(Z),n(),B(()=>Z(`planCoverageThreshold`,n()))),()=>(V(a()),V(Z),n(),B(()=>a().coverageMinimum===void 0?Z(`none`,n()):`${a().coverageMinimum}%`)),()=>(V(Z),n(),B(()=>Z(`planCoverageReporter`,n()))),()=>(V(a()),V(Z),n(),B(()=>a().coverageArtifactWorkflow||Z(`none`,n()))),()=>(V(Z),n(),B(()=>Z(`planReporterAttested`,n()))),()=>(V(Z),V(a()),n(),B(()=>Z(a().coverageReporterAttested?`yes`:`no`,n())))]),U(e,t)};G(S,e=>{V(a()),B(()=>a().coverageMode===`numeric`)&&e(C)}),R((e,t,n,r,i)=>{W(o,e),W(p,t),W(m,n),W(_,r),W(y,i)},[()=>(V(Z),n(),B(()=>Z(`planTrustedChecks`,n()))),()=>(V(Z),n(),B(()=>Z(`planProducerAttested`,n()))),()=>(V(Z),V(a()),n(),B(()=>Z(a().producerAttested?`yes`:`no`,n()))),()=>(V(Z),n(),B(()=>Z(`planCoverage`,n()))),()=>(V(Aa),V(a()),n(),B(()=>Aa(`pullRequestApproval.coverage.mode`,a().coverageMode,n())))]),U(e,t)};G(de,e=>{V(a()),B(()=>a().approvalMode!==`off`)&&e(fe)});var pe=L(de,2),me=P(pe),he=I(me,!0),ge=I(L(me),!0);D(pe);var _e=L(pe,2),ve=e=>{var t=Ls(),r=P(t),i=I(r,!0),o=L(r),s=P(o);q(s,5,()=>(V(a()),B(()=>a().projectStatuses)),K,(e,t)=>{var r=js(),i=P(r),a=I(L(i),!0);D(r),R(e=>{W(i,`${e??``}: `),W(a,(z(t),B(()=>z(t).value)))},[()=>(V(Z),V(mo),z(t),n(),B(()=>Z(mo[z(t).transition],n())))]),U(e,r)}),D(s),D(o),D(t),R(e=>W(i,e),[()=>(V(Z),n(),B(()=>Z(`planProjectStatuses`,n())))]),U(e,t)};G(_e,e=>{V(a()),B(()=>a().projectNumbers.length)&&e(ve)});var ye=L(_e,2),be=P(ye),xe=I(be,!0),Se=I(L(be),!0);D(ye);var Ce=L(ye,2),we=P(Ce),T=I(we,!0),Te=I(L(we),!0);D(Ce);var E=L(Ce,2),Ee=P(E),De=I(Ee,!0),Oe=I(L(Ee),!0);D(E);var ke=L(E,2),Ae=P(ke),je=I(Ae,!0),Me=I(L(Ae),!0);D(ke),D(d);var Ne=I(L(d,2),!0);D(c),R((e,t,n,r,i,o,s,c,l,d,f,p,g,_,b,x,C,w,ee,te)=>{W(u,e),W(m,t),W(h,n),W(v,r),W(y,i),W(S,o),W(ne,s),W(ae,(V(a()),B(()=>a().productionBranch))),W(oe,(V(a()),B(()=>a().developmentBranch))),W(le,c),W(ue,l),W(he,d),W(ge,f),W(xe,p),W(Se,g),W(T,_),W(Te,b),W(De,x),W(Oe,C),W(je,w),W(Me,ee),W(Ne,te)},[()=>(V(Z),n(),B(()=>Z(`planChoices`,n()))),()=>(V(Z),n(),B(()=>Z(`planEnabledCapabilities`,n()))),()=>(V(a()),V(Os),n(),V(Z),B(()=>a().enabledCapabilities.length?a().enabledCapabilities.map(e=>Os(e,n())).join(`, `):Z(`none`,n()))),()=>(V(Z),n(),B(()=>Z(`planIssueWorkflows`,n()))),()=>(V(a()),V(Aa),n(),V(Z),B(()=>a().issueWorkflows.length?a().issueWorkflows.map(e=>Aa(`issueWorkflows.enabled`,e,n())).join(`, `):Z(`none`,n()))),()=>(V(Z),n(),B(()=>Z(`planAgentRouting`,n()))),()=>(V(Z),n(),B(()=>Z(`planBranchRoles`,n()))),()=>(V(Z),n(),B(()=>Z(`planApprovalMode`,n()))),()=>(V(a()),B(()=>s(a().approvalMode))),()=>(V(Z),n(),B(()=>Z(`editProjects`,n()))),()=>(V(a()),V(Z),n(),B(()=>a().projectNumbers.length?a().projectNumbers.map(e=>`#${e}`).join(`, `):Z(`none`,n()))),()=>(V(Z),n(),B(()=>Z(`planVariableScope`,n()))),()=>(V(a()),B(()=>o(a().variableScope))),()=>(V(Z),n(),B(()=>Z(`planSecretScope`,n()))),()=>(V(a()),B(()=>o(a().secretScope))),()=>(V(Z),n(),B(()=>Z(`planIssueResources`,n()))),()=>(V(Z),n(),B(()=>Z(`planIssueResourcesValue`,n()))),()=>(V(Z),n(),B(()=>Z(`planInitialTag`,n()))),()=>(V(Z),V(a()),n(),B(()=>Z(a().initialTag?`yes`:`no`,n()))),()=>(V(Z),n(),B(()=>Z(`planAdvancedDefaults`,n())))]),U(e,c),k(),i()}var Bs=H(`

                                                                          .github/actions/copilot-verification-setup/action.yml

                                                                          `),Vs=H(`
                                                                        • `),Hs=H(`

                                                                            `,1),Us=H(`
                                                                          • ·

                                                                          • `),Ws=H(`
                                                                          • `),Gs=H(`

                                                                             

                                                                             
                                                                            `),Ks=H(`

                                                                                `);function qs(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`review`,8);ji();var o=Ks(),s=P(o),c=e=>{var t=Bs(),r=P(t),i=I(r,!0),o=L(r,2),s=P(o);Oe(),D(o);var c=L(o,2),l=I(P(c),!0);D(c);var u=L(c,2),d=P(u),f=I(L(d),!0);D(u);var p=I(L(u,2),!0);D(t),R((e,t,n,r,o)=>{W(i,e),W(s,`${t??``}: `),W(l,n),W(d,`${r??``}: `),W(f,(V(a()),B(()=>a().verificationSetup.mainBranch))),W(p,o)},[()=>(V(Ha),n(),B(()=>Ha(`title`,n()))),()=>(V(Ha),V(a()),n(),B(()=>Ha(a().verificationSetup.action,n()))),()=>(V(Ha),V(a()),n(),B(()=>Ha(a().verificationSetup.enabled?`enabled`:`disabled`,n()))),()=>(V(Ha),n(),B(()=>Ha(`main`,n()))),()=>(V(Ha),n(),B(()=>Ha(`next`,n())))]),U(e,t)};G(s,e=>{V(a()),B(()=>a().verificationSetup)&&e(c)});var l=L(s,2),u=I(l,!0),d=L(l,2),f=I(d,!0),p=L(d,2),m=e=>{var t=Hs(),r=F(t),i=I(r,!0),o=L(r),s=P(o),c=I(s,!0),l=L(s);q(l,5,()=>(V(a()),B(()=>a().blockers)),K,(e,t)=>{var n=Vs(),r=I(n,!0);R(()=>W(r,z(t))),U(e,n)}),D(l),D(o),R((e,t)=>{W(i,e),W(c,t)},[()=>(V($),n(),B(()=>$(`blockedAction`,n()))),()=>(V($),n(),B(()=>$(`blockers`,n())))]),U(e,t)};G(p,e=>{V(a()),B(()=>a().blockers.length)&&e(m)});var h=L(p,2);q(h,5,()=>(V(a()),B(()=>a().jobs)),K,(e,t)=>{var r=Us(),i=P(r),a=I(i,!0),o=L(i,2),s=I(o,!0),c=L(o,2),l=e=>{var t=Nr();R(e=>W(t,`· ${e??``}`),[()=>(V($),n(),B(()=>$(`retained`,n())))]),U(e,t)};G(c,e=>{z(t),B(()=>z(t).retained)&&e(l)});var u=L(c,2),d=I(P(u));D(u);var f=I(L(u));D(r),R((e,n,r)=>{W(a,e),W(s,n),W(d,`${z(t),B(()=>z(t).file)??``} / ${z(t),B(()=>z(t).job)??``}`),W(f,`runs-on: ${r??``}`)},[()=>(V($),z(t),n(),B(()=>$(z(t).role,n()))),()=>(V($),z(t),n(),B(()=>$(z(t).status,n()))),()=>(z(t),B(()=>JSON.stringify(z(t).runsOn)))]),U(e,r)}),D(h);var g=L(h,2),_=P(g),v=I(_),y=L(_,2);q(y,5,()=>(V(a()),B(()=>a().assets)),K,(e,t)=>{var r=Ws(),i=P(r),a=I(i,!0),o=L(i),s=L(o),c=e=>{var t=Nr();R(e=>W(t,`· ${e??``}`),[()=>(V($),n(),B(()=>$(`disabled`,n())))]),U(e,t)};G(s,e=>{z(t),B(()=>!z(t).enabled)&&e(c)}),D(r),R(e=>{W(a,(z(t),B(()=>z(t).path))),W(o,`: ${e??``}`)},[()=>(V($),z(t),n(),B(()=>$(z(t).status,n())))]),U(e,r)}),D(y),D(g);var b=L(g,2),x=P(b),S=I(x),C=L(x,2),w=I(C,!0);q(L(C,2),1,()=>(V(a()),B(()=>a().changes)),K,(e,t)=>{var r=Gs(),i=P(r),a=I(P(i),!0);D(i);var o=L(i,2),s=I(o,!0),c=L(o),l=I(c,!0),u=L(c,2),d=I(u,!0),f=I(L(u),!0);D(r),R((e,n,r,i)=>{W(a,(z(t),B(()=>z(t).path))),W(s,e),W(l,n),W(d,r),W(f,i)},[()=>(V($),n(),B(()=>$(`before`,n()))),()=>(z(t),V($),n(),B(()=>z(t).before??$(`absent`,n()))),()=>(V($),n(),B(()=>$(`after`,n()))),()=>(z(t),V($),n(),B(()=>z(t).after??$(`absent`,n())))]),U(e,r)}),D(b),D(o),R((e,t,n,r,i)=>{W(u,e),W(f,t),W(v,`${n??``} (${V(a()),B(()=>a().assets.length)??``})`),W(S,`${r??``} (${V(a()),B(()=>a().changes.length)??``})`),W(w,i)},[()=>(V($),n(),B(()=>$(`title`,n()))),()=>(V($),n(),B(()=>$(`help`,n()))),()=>(V($),n(),B(()=>$(`assets`,n()))),()=>(V($),n(),B(()=>$(`changes`,n()))),()=>(V($),n(),B(()=>$(`redactionNotice`,n())))]),U(e,o),k(),i()}var Js={"Self-hosted runners":`Self-hosted runners`,Metadata:`Metadata`,Contents:`Contents`,Secrets:`Secrets`,Variables:`Variables`,Issues:`Issues`,Actions:`Actions`,Checks:`Checks`,Administration:`Administration`,Workflows:`Workflows`,"Issue Types":`Issue Types`,Projects:`Projects`,"Pull requests":`Pull requests`,Members:`Members`},Ys={repository:`repository`,organization:`organization`,read:`Read`,write:`Write`,required:`Required`,conditional:`Conditional`,verified:`Verified`,available:`Read available`,missing:`Missing`,unverifiable:`Unverifiable`},Xs={"Self-hosted runners":`Runners autohospedados`,Metadata:`Metadatos`,Contents:`Contenido`,Secrets:`Secretos`,Variables:`Variables`,Issues:`Incidencias`,Actions:`Acciones`,Checks:`Comprobaciones`,Administration:`Administración`,Workflows:`Flujos de trabajo`,"Issue Types":`Tipos de incidencia`,Projects:`Proyectos`,"Pull requests":`Solicitudes de cambio`,Members:`Miembros`},Zs={repository:`repositorio`,organization:`organización`,read:`Lectura`,write:`Escritura`,required:`Obligatorio`,conditional:`Condicional`,verified:`Verificado`,available:`Lectura disponible`,missing:`Faltante`,unverifiable:`No verificable`},Qs={"Self-hosted runners":`Runners auto-hébergés`,Metadata:`Métadonnées`,Contents:`Contenu`,Secrets:`Secrets`,Variables:`Variables`,Issues:`Tickets`,Actions:`Actions`,Checks:`Vérifications`,Administration:`Administration`,Workflows:`Flux de travail`,"Issue Types":`Types de ticket`,Projects:`Projets`,"Pull requests":`Demandes de tirage`,Members:`Membres`},$s={repository:`dépôt`,organization:`organisation`,read:`Lecture`,write:`Écriture`,required:`Obligatoire`,conditional:`Conditionnel`,verified:`Vérifié`,available:`Lecture disponible`,missing:`Manquant`,unverifiable:`Non vérifiable`},ec={"Self-hosted runners":`Runners autoalojados`,Metadata:`Metadados`,Contents:`Conteúdo`,Secrets:`Segredos`,Variables:`Variáveis`,Issues:`Questões`,Actions:`Ações`,Checks:`Verificações`,Administration:`Administração`,Workflows:`Fluxos de trabalho`,"Issue Types":`Tipos de questão`,Projects:`Projetos`,"Pull requests":`Pedidos de alteração`,Members:`Membros`},tc={repository:`repositório`,organization:`organização`,read:`Leitura`,write:`Escrita`,required:`Obrigatório`,conditional:`Condicional`,verified:`Verificado`,available:`Leitura disponível`,missing:`Em falta`,unverifiable:`Não verificável`},nc={en:Js,es:Xs,fr:Qs,pt:ec},rc={en:Ys,es:Zs,fr:$s,pt:tc};function ic(e,t){return rc[e][t]}function ac(e,t){return Object.prototype.hasOwnProperty.call(nc[e],t)?nc[e][t]:t}function oc(e,t){if(t===`verified`||t===`available`||t===`missing`||t===`unverifiable`)return rc[e][t]}var sc=H(`

                                                                                `),cc=H(`
                                                                              • `),lc=H(`

                                                                                `),uc=H(`

                                                                                  `),dc=H(`
                                                                                • `),fc=H(`
                                                                                    `),pc=H(`

                                                                                      `),mc=H(``),hc=H(`

                                                                                      `),gc=H(`

                                                                                        `);function _c(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`prompt`,8),s=X(t,`controller`,8),c=X(t,`busy`,8),l=X(t,`onSubmit`,8),u={capabilities:`editCapabilities`,"agent-runtime":`editRuntimes`,"agent-model-defaults":`editModels`,"agent-role-overrides":`editRoleModels`,repository:`editRepository`,deployment:`editDeployment`,bugbot:`editBugbot`,"pull-request-approval":`editApproval`,projects:`editProjects`,provisioning:`editProvisioning`,storage:`editStorage`};Tn(()=>(n(),V(o())),()=>{N(a,[{title:Z(`files`,n()),items:o().plan.files},{title:Z(`workflows`,n()),items:o().plan.workflows},{title:Z(`variables`,n()),items:o().plan.variables},{title:Z(`secretNames`,n()),items:o().plan.secrets}])}),En(),ji();var d=gc(),f=P(d),p=I(f,!0),m=L(f,2),h=P(m),g=I(h,!0),_=L(h,2),v=I(_,!0),y=L(_,2),b=e=>{var t=sc(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`planActionsProbePrerequisites`,n())))]),U(e,t)},x=gt(()=>(V(o()),B(()=>o().plan.permissionProbes?.some(e=>e.permission===`Actions`))));G(y,e=>{z(x)&&e(b)});var S=L(y,2),C=e=>{var t=sc(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`planSecretProbeLimit`,n())))]),U(e,t)},w=gt(()=>(V(o()),B(()=>o().plan.permissionProbes?.some(e=>e.permission===`Secrets`))));G(S,e=>{z(w)&&e(C)});var ee=L(S,2);q(ee,5,()=>(V(o()),B(()=>o().plan.permissionProbes)),K,(e,t)=>{var r=cc(),i=I(r);R((e,t)=>W(i,`${e??``}: ${t??``}`),[()=>(V(ic),n(),z(t),B(()=>ic(n(),z(t).scope))),()=>(V(ac),n(),z(t),B(()=>ac(n(),z(t).permission)))]),U(e,r)},e=>{var t=cc(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`none`,n())))]),U(e,t)}),D(ee),D(m);var te=L(m,2),ne=e=>{var t=lc(),r=P(t),i=I(r,!0),a=L(r,2),s=I(a,!0),c=L(a,2),l=P(c),u=I(l,!0),d=I(L(l),!0);D(c),D(t),R((e,t,n,r)=>{W(i,e),W(s,t),W(u,n),W(d,r)},[()=>(V(Z),n(),B(()=>Z(`organizationReuseTitle`,n()))),()=>(V(Z),n(),V(o()),B(()=>Z(`organizationReuseBody`,n(),{imported:String(o().plan.organizationReuse.imported),shared:String(o().plan.organizationReuse.organizationVariables.length),overrides:String(o().plan.organizationReuse.repositoryVariables.length),writes:String(o().plan.organizationReuse.repositoryWrites.length)}))),()=>(V(Z),n(),B(()=>Z(`batchRepositoryOverrides`,n()))),()=>(V(o()),V(Z),n(),B(()=>o().plan.organizationReuse.repositoryWrites.join(`, `)||Z(`none`,n())))]),U(e,t)};G(te,e=>{V(o()),B(()=>o().plan.organizationReuse)&&e(ne)});var re=L(te,2);zs(re,{get decisions(){return V(o()),B(()=>o().plan.decisions)}});var ie=L(re,2),ae=e=>{qs(e,{get review(){return V(o()),B(()=>o().plan.installationReview)}})};G(ie,e=>{V(o()),B(()=>o().plan.installationReview)&&e(ae)});var oe=L(ie,2),se=e=>{vs(e,{get storage(){return V(o()),B(()=>o().plan.workflowPatStorage)}})};G(oe,e=>{V(o()),B(()=>o().plan.workflowPatStorage)&&e(se)});var ce=L(oe,2),le=e=>{var t=uc(),r=P(t),i=I(r,!0),a=L(r,2);q(a,5,()=>(V(o()),B(()=>o().plan.presentationDefaults)),K,(e,t)=>{var r=cc(),i=I(r);R(e=>W(i,`${e??``}: ${z(t),B(()=>z(t).count)??``}`),[()=>(z(t),V(Z),n(),B(()=>u[z(t).group]?Z(u[z(t).group],n()):z(t).group))]),U(e,r)}),D(a),D(t),R(e=>W(i,e),[()=>(V(Z),n(),B(()=>Z(`planBasicDefaultsIntro`,n())))]),U(e,t)};G(ce,e=>{V(o()),B(()=>o().plan.presentationDefaults.length)&&e(le)});var ue=L(ce,2);q(ue,5,()=>z(a),K,(e,t)=>{var r=fc(),i=P(r),a=P(i),o=I(a,!0),s=I(L(a),!0);D(i);var c=L(i);q(c,5,()=>(z(t),B(()=>z(t).items)),K,(e,t)=>{var n=dc(),r=I(P(n),!0);D(n),R(()=>W(r,z(t))),U(e,n)},e=>{var t=cc(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`none`,n())))]),U(e,t)}),D(c),D(r),R(()=>{W(o,(z(t),B(()=>z(t).title))),W(s,(z(t),B(()=>z(t).items.length)))}),U(e,r)}),D(ue);var de=L(ue,2),fe=e=>{var t=pc(),r=P(t),i=I(r,!0),a=L(r);q(a,5,()=>(V(o()),B(()=>o().plan.warnings)),K,(e,t)=>{var r=cc(),i=I(r,!0);R(e=>W(i,e),[()=>(V(Es),z(t),n(),B(()=>Es(z(t),n())))]),U(e,r)}),D(a),D(t),R(e=>W(i,e),[()=>(V(Z),n(),B(()=>Z(`beforeContinue`,n())))]),U(e,t)};G(de,e=>{V(o()),B(()=>o().plan.warnings.length)&&e(fe)});var pe=L(de,2),me=e=>{var t=hc(),r=P(t),i=I(r,!0),a=L(r),d=I(a,!0),f=L(a,2);q(f,5,()=>(V(o()),B(()=>o().editGroups)),K,(e,t)=>{var r=mc(),i=I(r,!0);R(e=>{r.disabled=!s()||c(),W(i,e)},[()=>(V(Z),n(),z(t),B(()=>Z(`changeSection`,n(),{section:Z(u[z(t)],n())})))]),wr(`click`,r,()=>l()(`revise:${z(t)}`)),U(e,r)}),D(f),D(t),R((e,t)=>{W(i,e),W(d,t)},[()=>(V(Z),n(),B(()=>Z(`changeAnswersTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`changeAnswersHelp`,n())))]),U(e,t)};G(pe,e=>{V(o()),B(()=>o().editGroups?.length)&&e(me)});var he=L(pe,2),ge=P(he);{let e=A(()=>(V(Z),n(),B(()=>Z(`stopHere`,n())))),t=A(()=>!s()||c());Qa(ge,{get label(){return z(e)},variant:`secondary`,onClick:()=>l()(`decline`),get disabled(){return z(t)}})}var _e=L(ge);{let e=A(()=>(V(Z),V(o()),n(),B(()=>Z(o().plan.deliveryMode===`pull-request`?`batchUseConfiguration`:`approvePlan`,n())))),t=A(()=>(V(s()),V(c()),V(o()),B(()=>!s()||c()||!!o().plan.installationReview?.blockers.length)));Qa(_e,{get label(){return z(e)},arrow:!0,onClick:()=>l()(`approve`),get disabled(){return z(t)}})}D(he),D(d),R((e,t,n,r)=>{W(p,e),J(m,`aria-label`,t),W(g,n),W(v,r)},[()=>(V(Z),V(o()),n(),B(()=>Z(o().plan.deliveryMode===`pull-request`?`batchConfigurationPreview`:o().plan.organizationReuse?`planReuseBody`:`planBody`,n()))),()=>(V(Z),n(),B(()=>Z(`planPermissionProbeTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`planPermissionProbeTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`planPermissionProbeBody`,n())))]),U(e,d),k(),i()}Tr([`click`]);var vc=H(`

                                                                                        `),yc=H(`
                                                                                      • `),bc=H(`
                                                                                        `,1),xc=H(`
                                                                                        `,1),Sc=H(`

                                                                                        `),Cc=H(`

                                                                                          `,1);function wc(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`view`,8);Tn(()=>n(),()=>{N(a,ta(n()))}),En(),ji();var s=Cc(),c=F(s),l=P(c),u=I(l,!0),d=L(l),f=I(d,!0),p=L(d,2),m=e=>{var t=vc(),n=I(t,!0);R(()=>W(n,(z(a),B(()=>z(a).unknown)))),U(e,t)};G(p,e=>{V(o()),B(()=>o().secretInventory!==`available`)&&e(m)});var h=L(p,2);q(h,5,()=>(V(o()),B(()=>o().secrets)),K,(e,t)=>{var n=yc(),r=P(n),i=I(r,!0),o=L(r),s=L(o),c=e=>{var t=Nr();R(()=>W(t,`· ${z(a),B(()=>z(a).shadowed)??``}`)),U(e,t)};G(s,e=>{z(t),B(()=>z(t).shadowed)&&e(c)}),D(n),R(()=>{W(i,(z(t),B(()=>z(t).name))),W(o,` · ${z(a),z(t),B(()=>z(a)[z(t).scope])??``} `)}),U(e,n)}),D(h),D(c);var g=L(c,2),_=P(g),v=I(_),y=L(_,2),b=e=>{var t=vc(),n=I(t,!0);R(()=>W(n,(z(a),B(()=>z(a).empty)))),U(e,t)};G(y,e=>{V(o()),B(()=>!o().variables.length)&&e(b)});var x=L(y,2);q(x,5,()=>(V(o()),B(()=>o().variables)),K,(e,t)=>{var n=bc(),r=F(n),i=P(r),o=L(i),s=e=>{var t=Nr();R(()=>W(t,`· ${z(a),B(()=>z(a).shadowed)??``}`)),U(e,t)};G(o,e=>{z(t),B(()=>z(t).shadowed)&&e(s)}),D(r);var c=I(L(r),!0);R(()=>{W(i,`${z(t),B(()=>z(t).name)??``} · ${z(a),z(t),B(()=>z(a)[z(t).scope])??``} `),W(c,(z(t),B(()=>z(t).value)))}),U(e,n)}),D(x),D(g);var S=L(g,2),C=P(S),w=I(C);q(L(C,2),1,()=>(V(o()),B(()=>o().workflows)),K,(e,t)=>{var n=Sc(),r=P(n),i=I(r,!0),o=L(r,2),s=I(o,!0),c=L(o,2);q(c,5,()=>(z(t),B(()=>z(t).inputs)),K,(e,t)=>{var n=xc(),r=F(n),i=I(r,!0),o=L(r),s=P(o,!0),c=L(s),l=e=>{var n=Nr();R(()=>W(n,`· ${z(a),B(()=>z(a).workflow)??``}: ${z(t),B(()=>z(t).fallback)??``}`)),U(e,n)};G(c,e=>{z(t),B(()=>z(t).fallback!==void 0)&&e(l)}),D(o),R(()=>{W(i,(z(t),B(()=>z(t).name))),W(s,(z(t),z(a),B(()=>z(t).unsupported?z(a).unknown:z(t).variable?`vars.${z(t).variable}`:z(t).literal)))}),U(e,n)}),D(c),D(n),R(()=>{W(i,(z(t),B(()=>z(t).file))),W(s,(z(t),B(()=>z(t).action)))}),U(e,n)}),D(S),R(()=>{W(u,(z(a),B(()=>z(a).credentials))),W(f,(z(a),B(()=>z(a).secretHelp))),W(v,`${z(a),B(()=>z(a).variables)??``} (${V(o()),B(()=>o().variables.length)??``})`),W(w,`${z(a),B(()=>z(a).details)??``} (${V(o()),B(()=>o().workflows.length)??``})`)}),U(e,s),k(),i()}var Tc=H(`

                                                                                          `),Ec=H(``),Dc=H(``),Oc=H(`

                                                                                          `),kc=H(`

                                                                                          `,1),Ac=H(`

                                                                                          `,1);function jc(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`view`,8),s=X(t,`controller`,8),c=X(t,`busy`,8),l=X(t,`onSubmit`,8);Tn(()=>n(),()=>{N(a,ta(n()))}),En(),ji();var u=Ac(),d=F(u),f=I(d,!0),p=L(d,2),m=I(p,!0),h=L(p,2),g=I(h,!0),_=L(h,2),v=e=>{var t=Tc(),n=I(t,!0);R(()=>W(n,(z(a),B(()=>z(a).local)))),U(e,t)};G(_,e=>{V(o()),B(()=>o().github===`not-connected`&&o().status!==`unconfigured`)&&e(v)});var y=L(_,2),b=e=>{var t=Ec(),n=I(t,!0);R(()=>W(n,(z(a),B(()=>z(a).githubIncomplete)))),U(e,t)};G(y,e=>{V(o()),B(()=>o().github===`incomplete`)&&e(b)});var x=L(y,2),S=P(x),C=e=>{var t=Dc(),n=I(t,!0);R(()=>{t.disabled=!s()||c(),W(n,(V(o()),z(a),B(()=>o().github===`not-connected`?z(a).connect:z(a).refresh)))}),wr(`click`,t,()=>l()(o().github===`not-connected`?`connect`:`refresh`)),U(e,t)};G(S,e=>{V(o()),B(()=>o().status!==`unconfigured`)&&e(C)});var w=L(S,2);let ee;var te=I(w,!0);D(x);var ne=L(x,2),re=e=>{var t=kc(),r=F(t),i=P(r),u=I(i,!0),d=L(i),f=I(d,!0),p=L(d,2);q(p,5,()=>(V(o()),B(()=>o().settings)),K,(e,t)=>{var r=Oc(),i=P(r),o=P(i),u=I(o,!0),d=L(o),f=P(d,!0),p=L(f),m=e=>{var n=Nr();R(()=>W(n,` · ${z(a),z(t),B(()=>z(a)[z(t).source])??``}`)),U(e,n)};G(p,e=>{z(t),B(()=>z(t).source!==`unknown`)&&e(m)}),D(d),D(i);var h=L(i,2),g=I(h,!0);D(r),R((e,n,r)=>{W(u,e),W(f,n),J(h,`aria-label`,r),h.disabled=(V(s()),V(c()),z(t),B(()=>!s()||c()||!z(t).editable)),W(g,(z(a),B(()=>z(a).edit)))},[()=>(V(na),z(t),n(),B(()=>na(z(t).id,n()))),()=>(z(t),z(a),V(ia),n(),B(()=>z(t).value===void 0?z(a).unknown:ia(z(t).value,n()))),()=>(z(a),V(na),z(t),n(),B(()=>`${z(a).edit}: ${na(z(t).id,n())}`))]),wr(`click`,h,()=>l()(`edit:${z(t).id}`)),U(e,r)}),D(p),D(r),wc(L(r,2),{get view(){return o()}}),R(()=>{W(u,(z(a),B(()=>z(a).quick))),W(f,(z(a),B(()=>z(a).quickHelp)))}),U(e,t)};G(ne,e=>{V(o()),B(()=>o().status!==`unconfigured`)&&e(re)});var ie=L(ne,2),ae=I(ie,!0),oe=L(ie,2),se=P(oe),ce=I(se,!0);D(oe),R(()=>{W(f,(z(a),B(()=>z(a).title))),W(m,(z(a),V(o()),B(()=>z(a)[o().status]))),W(g,(V(o()),z(a),B(()=>o().status===`unconfigured`?z(a).startHelp:z(a).intro))),ee=ui(w,1,`button`,null,ee,{primary:o().status===`unconfigured`,secondary:o().status!==`unconfigured`}),w.disabled=!s()||c(),W(te,(V(o()),z(a),B(()=>o().status===`unconfigured`?z(a).start:z(a).wizard))),W(ae,(z(a),B(()=>z(a).limits))),se.disabled=!s()||c(),W(ce,(z(a),B(()=>z(a).finish)))}),wr(`click`,w,()=>l()(`wizard`)),wr(`click`,se,()=>l()(`close`)),U(e,u),k(),i()}Tr([`click`]);var Mc=H(``),Nc=H(``),Pc=H(`
                                                                                        • `),Fc=H(`
                                                                                            `),Ic=H(`

                                                                                            `),Lc=H(` `),Rc=H(`

                                                                                              `),zc=H(`
                                                                                               
                                                                                              `),Bc=H(`
                                                                                              `),Vc=H(`
                                                                                              `),Hc=H(`

                                                                                              `),Uc=H(`
                                                                                            • `),Wc=H(`
                                                                                                `),Gc=H(`

                                                                                                `,1),Kc=H(`

                                                                                                →

                                                                                                `),qc=H(`
                                                                                                `),Jc=H(``),Yc=H(``),Xc=H(`
                                                                                                `),Zc=H(`

                                                                                                `);function Qc(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`batch`,8),s=X(t,`controller`,8),c=X(t,`busy`,8),l=X(t,`mode`,8,`progress`),u=X(t,`onSubmit`,8,async()=>void 0),d=X(t,`onStop`,8,async()=>void 0),f={ready:`batchStatusReady`,blocked:`batchStatusBlocked`,applying:`batchStatusApplying`,partial:`batchStatusPartial`,"waiting-for-merge":`batchStatusWaiting`,"verification-pending":`batchStatusPending`,unchanged:`batchStatusUnchanged`,cancelled:`batchStatusCancelled`};function p(e){return e&&/^https:\/\/github\.com\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/pull\/[1-9][0-9]*$/.test(e)?e:void 0}Tn(()=>V(o()),()=>{N(a,o().targets.some(e=>e.cleanupPending)?[]:o().targets.filter(e=>[`ready`,`partial`,`cancelled`,`applying`].includes(e.status)))}),En(),ji();var m=Zc(),h=P(m),g=I(h,!0),_=L(h,2),v=I(_,!0),y=L(_,2),b=e=>{var t=Mc(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`batchStopping`,n())))]),U(e,t)};G(y,e=>{V(o()),B(()=>o().stopRequested)&&e(b)});var x=L(y,2);q(x,5,()=>(V(o()),B(()=>o().targets)),e=>e.repositoryId,(e,t)=>{var r=Kc(),i=P(r),a=I(i,!0),o=L(i,2),s=e=>{qs(e,{get review(){return z(t),B(()=>z(t).installationReview)}})};G(o,e=>{z(t),B(()=>z(t).installationReview)&&e(s)});var c=L(o,2),l=I(c,!0),u=L(c,2),d=e=>{var t=Nc(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`batchCleanupPending`,n())))]),U(e,t)};G(u,e=>{z(t),B(()=>z(t).cleanupPending)&&e(d)});var m=L(u,2),h=e=>{var n=Fc();q(n,5,()=>(z(t),B(()=>z(t).blockers)),K,(e,t)=>{var n=Pc(),r=I(n,!0);R(()=>W(r,z(t))),U(e,n)}),D(n),U(e,n)};G(m,e=>{z(t),B(()=>z(t).blockers?.length)&&e(h)});var g=L(m,2),_=e=>{var r=Ic(),i=I(r,!0);R(e=>W(i,e),[()=>(V(Z),z(t),n(),B(()=>Z(z(t).reason===`drift`||z(t).reason===`ownership`?`batchReasonDrift`:z(t).reason===`provider`?`batchReasonProvider`:z(t).reason===`cancelled`?`batchReasonCancelled`:`batchReasonPreflight`,n())))]),U(e,r)};G(g,e=>{z(t),B(()=>z(t).reason&&!z(t).cleanupPending)&&e(_)});var v=L(g,2),y=P(v),b=I(y,!0),x=L(y),S=P(x),C=I(S,!0),w=I(L(S,2),!0);D(x);var ee=I(L(x),!0);D(v);var te=L(v,2),ne=e=>{var r=Lc(),i=I(r);R((e,t)=>{J(r,`href`,e),W(i,`${t??``} ↗`)},[()=>(z(t),B(()=>p(z(t).pullRequestUrl))),()=>(V(Z),n(),B(()=>Z(`batchOpenPull`,n())))]),U(e,r)},re=gt(()=>(z(t),B(()=>p(z(t).pullRequestUrl))));G(te,e=>{z(re)&&e(ne)});var ie=L(te,2),ae=e=>{var r=Gc(),i=F(r),a=P(i),o=I(a,!0),s=L(a,2),c=I(s,!0),l=I(L(s,2),!0);D(i);var u=L(i,2),d=e=>{var r=Ic(),i=I(r);R((e,t)=>W(i,`${e??``}: ${t??``}.`),[()=>(V(Z),n(),B(()=>Z(`batchRetainedSecrets`,n()))),()=>(z(t),B(()=>z(t).retainedSecrets.join(`, `)))]),U(e,r)};G(u,e=>{z(t),B(()=>z(t).retainedSecrets.length)&&e(d)});var f=L(u,2),p=I(f,!0),m=L(f,2),h=e=>{var r=Rc(),i=P(r),a=I(i,!0),o=L(i,2),s=I(o,!0),c=L(o,2);q(c,5,()=>(z(t),B(()=>z(t).permissionProbes)),K,(e,t)=>{var r=Pc(),i=I(r);R((e,t)=>W(i,`${e??``}: ${t??``}`),[()=>(V(ic),n(),z(t),B(()=>ic(n(),z(t).scope))),()=>(V(ac),n(),z(t),B(()=>ac(n(),z(t).permission)))]),U(e,r)}),D(c);var l=L(c,2),u=e=>{var t=Ic(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`planSecretProbeLimit`,n())))]),U(e,t)},d=gt(()=>(z(t),B(()=>z(t).permissionProbes.some(e=>e.permission===`Secrets`))));G(l,e=>{z(d)&&e(u)}),D(r),R((e,t)=>{W(a,e),W(s,t)},[()=>(V(Z),n(),B(()=>Z(`planPermissionProbeTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`planPermissionProbeBody`,n())))]),U(e,r)};G(m,e=>{z(t),B(()=>z(t).permissionProbes?.length)&&e(h)});var g=L(m,2),_=e=>{var r=Vc(),i=P(r),a=I(i,!0);q(L(i,2),1,()=>(z(t),B(()=>z(t).files)),K,(e,t)=>{var r=Bc(),i=P(r),a=I(P(i),!0);D(i);var o=L(i,2),s=e=>{var t=Ic(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`batchDeleteFile`,n())))]),U(e,t)},c=e=>{var n=zc(),r=I(n,!0);R(()=>W(r,(z(t),B(()=>z(t).content)))),U(e,n)};G(o,e=>{z(t),B(()=>z(t).content===null)?e(s):e(c,-1)}),D(r),R(()=>W(a,(z(t),B(()=>z(t).path)))),U(e,r)}),D(r),R(e=>W(a,e),[()=>(V(Z),n(),B(()=>Z(`batchReviewFiles`,n())))]),U(e,r)};G(g,e=>{z(t),B(()=>z(t).files.length)&&e(_)});var v=L(g,2),y=e=>{var r=Hc(),i=P(r),a=I(i,!0),o=I(L(i),!0);D(r),R((e,t)=>{W(a,e),W(o,t)},[()=>(V(Z),n(),B(()=>Z(`batchRepositoryOverrides`,n()))),()=>(z(t),B(()=>z(t).repositoryVariables.join(`, `)))]),U(e,r)};G(v,e=>{z(t),B(()=>z(t).repositoryVariables.length)&&e(y)});var b=L(v,2),x=e=>{var r=Wc(),i=P(r),a=I(i,!0),o=L(i);q(o,5,()=>(z(t),B(()=>z(t).grants)),K,(e,t)=>{var n=Uc(),r=P(n),i=I(L(r),!0);D(n),R(()=>{W(r,`${z(t),B(()=>z(t).kind===`secret`?`Secret`:`Variable`)??``} `),W(i,(z(t),B(()=>z(t).name)))}),U(e,n)}),D(o),D(r),R(e=>W(a,e),[()=>(V(Z),n(),B(()=>Z(`batchReviewedAccess`,n())))]),U(e,r)};G(b,e=>{z(t),B(()=>z(t).grants.length)&&e(x)}),R((e,t,n,r)=>{W(o,e),W(c,t),W(l,n),W(p,r)},[()=>(V(Z),n(),z(t),B(()=>Z(`batchFilesCount`,n(),{count:String(z(t).files.length)}))),()=>(V(Z),n(),z(t),B(()=>Z(`batchVariablesCount`,n(),{count:String(z(t).repositoryVariables.length)}))),()=>(V(Z),n(),z(t),B(()=>Z(`batchGrantsCount`,n(),{count:String(z(t).grants.length)}))),()=>(V(Z),n(),B(()=>Z(`batchResourcesExplanation`,n())))]),U(e,r)},oe=gt(()=>(z(t),B(()=>![`waiting-for-merge`,`verification-pending`,`unchanged`].includes(z(t).status))));G(ie,e=>{z(oe)&&e(ae)}),D(r),R((e,n)=>{W(a,(z(t),B(()=>z(t).repository))),W(l,e),W(b,n),W(C,(z(t),B(()=>z(t).installationBranch))),W(w,(z(t),B(()=>z(t).baseBranch))),W(ee,(z(t),B(()=>z(t).baseSha)))},[()=>(V(Z),z(t),n(),B(()=>Z(f[z(t).status],n()))),()=>(V(Z),n(),B(()=>Z(`batchBranchReview`,n())))]),U(e,r)}),D(x);var S=L(x,2),C=e=>{var t=qc(),r=P(t),i=I(r,!0),o=L(r,2),l=I(o,!0);D(t),R((e,t)=>{r.disabled=(V(s()),V(c()),z(a),B(()=>!s()||c()||!z(a).length)),W(i,e),o.disabled=!s()||c(),W(l,t)},[()=>(V(Z),n(),B(()=>Z(`batchApplyPlans`,n()))),()=>(V(Z),n(),B(()=>Z(`batchLeavePreview`,n())))]),wr(`click`,r,()=>u()(`approve`)),wr(`click`,o,()=>u()(`decline`)),U(e,t)},w=e=>{var t=Jc(),r=I(t,!0);R(e=>{t.disabled=(V(s()),V(c()),V(o()),B(()=>!s()||c()||o().stopRequested)),W(r,e)},[()=>(V(Z),n(),B(()=>Z(`batchStopPending`,n())))]),wr(`click`,t,function(...e){d()?.apply(this,e)}),U(e,t)},ee=e=>{var t=Xc(),r=P(t),i=e=>{var t=Yc(),r=I(t,!0);R(e=>{t.disabled=!s()||c(),W(r,e)},[()=>(V(Z),n(),B(()=>Z(`batchRetryPending`,n())))]),wr(`click`,t,()=>u()(`retry`)),U(e,t)};G(r,e=>{z(a),V(o()),B(()=>z(a).length&&o().retryRemaining>0)&&e(i)});var l=L(r,2),d=I(l,!0);D(t),R(e=>{l.disabled=!s()||c(),W(d,e)},[()=>(V(Z),n(),B(()=>Z(`batchFinish`,n())))]),wr(`click`,l,()=>u()(`finish`)),U(e,t)};G(S,e=>{l()===`review`?e(C):l()===`progress`?e(w,1):l()===`result`&&e(ee,2)});var te=L(S,2),ne=P(te),re=I(ne,!0),ie=I(L(ne),!0);D(te),D(m),R((e,t,n)=>{W(g,e),W(v,t),W(re,n),W(ie,(V(o()),B(()=>o().operationId)))},[()=>(V(Z),V(l()),n(),B(()=>Z(l()===`review`?`batchReviewTitle`:l()===`progress`?`batchProgressTitle`:`batchResultTitle`,n()))),()=>(V(Z),V(l()),n(),B(()=>Z(l()===`review`?`batchReviewBody`:l()===`progress`?`batchProgressBody`:`batchResultBody`,n()))),()=>(V(Z),n(),B(()=>Z(`batchTechnical`,n())))]),U(e,m),k(),i()}Tr([`click`]);var $c=H(``),el=H(``),tl=H(`

                                                                                                `),nl=H(`
                                                                                                `),rl=H(`

                                                                                                `,1);function il(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=M(),s=M(),c=X(t,`selection`,8),l=X(t,`controller`,8),u=X(t,`busy`,8),d=X(t,`onSubmit`,8),f=M([...c().selectedIds]),p=M(``),m=M(``),h=M(0);function g(e){N(f,z(f).includes(e)?z(f).filter(t=>t!==e):[...z(f),e])}function _(e){d()(JSON.stringify({action:e,selectedIds:z(f),...e===`resolve`?{name:z(m).trim()}:{}}))}Tn(()=>(V(c()),z(p)),()=>{N(a,c().candidates.filter(e=>e.name.toLowerCase().includes(z(p).toLowerCase())))}),Tn(()=>(z(h),z(a)),()=>{z(h)>0&&z(h)*25>=z(a).length&&N(h,0)}),Tn(()=>(z(a),z(h)),()=>{N(o,z(a).slice(z(h)*25,(z(h)+1)*25))}),Tn(()=>(z(f),V(c())),()=>{N(s,z(f).some(e=>!c().candidates.some(t=>t.id===e&&!t.unavailable)))}),En(),ji();var v=rl(),y=F(v),b=I(y,!0),x=L(y,2),S=e=>{var t=$c(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`batchDiscoveryUnavailable`,n())))]),U(e,t)};G(x,e=>{V(c()),B(()=>c().discoveryStatus===`unavailable`)&&e(S)});var C=L(x,2),w=e=>{var t=$c(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),V(c()),n(),B(()=>Z(c().message===`lookup-unavailable`?`batchLookupUnavailable`:c().message===`selection-invalid`?`batchSelectionInvalid`:`batchAccessUnavailable`,n())))]),U(e,t)};G(C,e=>{V(c()),B(()=>c().message)&&e(w)});var ee=L(C,2),te=e=>{var t=$c(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`batchDiscoveryTruncated`,n())))]),U(e,t)};G(ee,e=>{V(c()),B(()=>c().truncated)&&e(te)});var ne=L(ee,2),re=I(ne,!0),ie=L(ne,2);xi(ie);var ae=L(ie,2),oe=I(ae,!0),se=L(ae,2),ce=P(se),le=I(ce,!0),ue=L(ce,2);q(ue,5,()=>z(o),e=>e.id,(e,t)=>{var r=el(),i=P(r);xi(i);var a=L(i,2),o=P(a),s=I(o,!0),l=L(o),u=P(l),d=L(u),p=e=>{var t=Nr();R(e=>W(t,`· ${e??``}`),[()=>(V(Z),n(),B(()=>Z(`batchCurrent`,n())))]),U(e,t)};G(d,e=>{z(t),V(c()),B(()=>z(t).id===c().currentRepositoryId)&&e(p)});var m=L(d,2),h=e=>{var r=Nr();R(e=>W(r,`· ${e??``}`),[()=>(V(Z),z(t),n(),B(()=>Z(z(t).unavailable===`archived`?`batchArchived`:z(t).unavailable===`disabled`?`batchDisabled`:z(t).unavailable===`access-unavailable`?`batchAccessUnavailable`:`batchReadOnly`,n())))]),U(e,r)};G(m,e=>{z(t),B(()=>z(t).unavailable)&&e(h)}),D(l),D(a),D(r),R((e,n,r)=>{Si(i,e),i.disabled=n,W(s,(z(t),B(()=>z(t).name))),W(u,`${r??``} `)},[()=>(z(f),z(t),B(()=>z(f).includes(z(t).id))),()=>(z(f),z(t),B(()=>!z(f).includes(z(t).id)&&(!!z(t).unavailable||z(f).length>=25))),()=>(V(Z),z(t),n(),B(()=>Z(z(t).private?`batchPrivate`:`batchPublic`,n())))]),wr(`change`,i,()=>g(z(t).id)),U(e,r)}),D(ue),D(se);var de=L(se,2),fe=e=>{var t=tl(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`batchNoMatches`,n())))]),U(e,t)};G(de,e=>{z(a),B(()=>!z(a).length)&&e(fe)});var pe=L(de,2),me=e=>{var t=nl(),r=P(t),i=I(r,!0),o=L(r,2),s=I(o),c=L(o,2),d=I(c,!0);D(t),R((e,t,n)=>{r.disabled=z(h)===0||!l()||u(),W(i,e),W(s,`${z(h)+1} / ${t??``}`),c.disabled=(z(h),z(a),V(l()),V(u()),B(()=>(z(h)+1)*25>=z(a).length||!l()||u())),W(d,n)},[()=>(V(Z),n(),B(()=>Z(`batchPrevious`,n()))),()=>(z(a),B(()=>Math.ceil(z(a).length/25))),()=>(V(Z),n(),B(()=>Z(`batchNext`,n())))]),wr(`click`,r,()=>N(h,z(h)-1)),wr(`click`,c,()=>N(h,z(h)+1)),U(e,t)};G(pe,e=>{z(a),B(()=>z(a).length>25)&&e(me)});var he=L(pe,2),ge=P(he),_e=I(ge,!0),ve=L(ge,2),ye=I(ve,!0),be=L(ve,2),xe=I(be,!0),Se=L(be,2);xi(Se);var Ce=L(Se,2),we=P(Ce),T=I(we,!0),Te=L(we,2),E=I(Te,!0);D(Ce),D(he);var Ee=L(he,2),De=I(Ee,!0);R((e,t,n,r,i,a,o,c,d,p,m)=>{W(b,e),W(re,t),ie.disabled=!l()||u(),W(oe,n),se.disabled=!l()||u(),W(le,r),W(_e,i),W(ye,a),W(xe,o),Se.disabled=!l()||u(),we.disabled=c,W(T,d),Te.disabled=!l()||u(),W(E,p),Ee.disabled=(V(l()),V(u()),z(s),z(f),B(()=>!l()||u()||z(s)||z(f).length<1||z(f).length>25)),W(De,m)},[()=>(V(Z),n(),V(c()),B(()=>Z(`batchSelectionBody`,n(),{organization:c().organization}))),()=>(V(Z),n(),B(()=>Z(`batchFilter`,n()))),()=>(V(Z),n(),z(f),B(()=>Z(`batchSelectedCount`,n(),{count:String(z(f).length)}))),()=>(V(Z),n(),B(()=>Z(`batchRepositories`,n()))),()=>(V(Z),n(),B(()=>Z(`batchMissingRepository`,n()))),()=>(V(Z),n(),B(()=>Z(`batchAccessExplanation`,n()))),()=>(V(Z),n(),B(()=>Z(`batchExactName`,n()))),()=>(V(l()),V(u()),z(m),B(()=>!l()||u()||!/^[A-Za-z0-9][A-Za-z0-9_.-]{0,99}$/.test(z(m).trim()))),()=>(V(Z),n(),B(()=>Z(`batchFindRepository`,n()))),()=>(V(Z),n(),B(()=>Z(`batchChangeAccess`,n()))),()=>(V(Z),n(),B(()=>Z(`batchReviewSelection`,n())))]),wr(`input`,ie,()=>N(h,0)),Ei(ie,()=>z(p),e=>N(p,e)),Ei(Se,()=>z(m),e=>N(m,e)),wr(`click`,we,()=>_(`resolve`)),wr(`click`,Te,()=>_(`access`)),wr(`click`,Ee,()=>_(`select`)),U(e,v),k(),i()}Tr([`input`,`change`,`click`]);var al=H(`

                                                                                                `,1),ol=H(``),sl=H(``),cl=H(``),ll=H(`

                                                                                                `,1),ul=H(`

                                                                                                `,1);function dl(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`prompt`,8),s=X(t,`controller`,8),c=X(t,`busy`,8),l=X(t,`onSubmit`,8),u=M(o().kind===`quick-edit`?o().current:``);Tn(()=>n(),()=>{N(a,ta(n()))}),En(),ji();var d=Pr(),f=F(d),p=e=>{var t=ll(),r=F(t),i=I(r,!0),d=L(r,2),f=e=>{var t=al(),r=F(t),i=I(r,!0),a=L(r,2);{let e=A(()=>(V(ho),V(o()),n(),B(()=>ho(o().presentation[n()].documentation.url))));zo(a,{get explanation(){return V(o()),n(),B(()=>o().presentation[n()])},get helpUrl(){return z(e)}})}R(()=>W(i,(V(o()),n(),B(()=>o().presentation[n()].summary)))),U(e,t)};G(d,e=>{V(o()),B(()=>o().presentation)&&e(f)});var p=L(d,2),m=I(p),h=L(p,2),g=P(h),_=I(g,!0),v=L(g,2),y=e=>{var t=sl();q(t,5,()=>(V(o()),B(()=>o().choices)),K,(e,t)=>{var r=ol(),i=I(r,!0),a={};R(e=>{W(i,e),a!==(a=z(t))&&(r.value=(r.__value=a)??``)},[()=>(V(ia),z(t),n(),B(()=>ia(z(t),n())))]),U(e,r)}),D(t),mi(t),R(()=>t.disabled=!s()||c()),hi(t,()=>z(u),e=>N(u,e)),U(e,t)},b=e=>{var t=cl();xi(t),R(()=>{J(t,`min`,(V(o()),B(()=>o().min))),J(t,`max`,(V(o()),B(()=>o().max))),t.disabled=!s()||c()}),Ei(t,()=>z(u),e=>N(u,e)),U(e,t)};G(v,e=>{V(o()),B(()=>o().choices)?e(y):e(b,-1)});var x=L(v,2),S=P(x),C=I(S,!0),w=L(S),ee=I(w,!0);D(x),D(h),R((e,t)=>{W(i,e),W(m,`${z(a),B(()=>z(a).current)??``}: ${t??``}`),W(_,(z(a),B(()=>z(a).next))),S.disabled=!s()||c(),W(C,(z(a),B(()=>z(a).back))),w.disabled=!s()||c(),W(ee,(z(a),B(()=>z(a).preview)))},[()=>(V(na),V(o()),n(),B(()=>na(o().id,n()))),()=>(V(ia),V(o()),n(),B(()=>ia(o().current,n())))]),Cr(`submit`,h,e=>{e.preventDefault(),l()(String(z(u)??``))}),wr(`click`,S,()=>l()(`cancel`)),U(e,t)},m=e=>{var t=ul(),r=F(t),i=I(r,!0),u=L(r),d=I(u,!0),f=L(u,2),p=P(f),m=I(p,!0),h=L(p),g=I(h,!0),_=L(h),v=I(_,!0),y=L(_),b=I(y,!0),x=L(y),S=I(x,!0),C=I(L(x),!0);D(f);var w=L(f,2);let ee;var te=I(w,!0),ne=L(w,2),re=I(ne,!0),ie=L(ne,2),ae=P(ie),oe=I(ae,!0),se=L(ae),ce=I(se,!0);D(ie),R((e,t,n)=>{W(i,(z(a),B(()=>z(a).review))),W(d,e),W(m,(z(a),B(()=>z(a).current))),W(g,t),W(v,(z(a),B(()=>z(a).next))),W(b,n),W(S,(z(a),B(()=>z(a).source))),W(C,(z(a),V(o()),B(()=>z(a)[o().change.scope]))),ee=ui(w,1,`banner`,null,ee,{warning:o().change.scope===`organization`}),W(te,(V(o()),z(a),B(()=>o().change.scope===`organization`?z(a).orgImpact:z(a).repoImpact))),W(re,(z(a),B(()=>z(a).effect))),ae.disabled=!s()||c(),W(oe,(z(a),B(()=>z(a).back))),se.disabled=!s()||c(),W(ce,(z(a),B(()=>z(a).apply)))},[()=>(V(na),V(o()),n(),B(()=>na(o().change.id,n()))),()=>(V(ia),V(o()),n(),B(()=>ia(o().change.before,n()))),()=>(V(ia),V(o()),n(),B(()=>ia(o().change.after,n())))]),wr(`click`,ae,()=>l()(`cancel`)),wr(`click`,se,()=>l()(`approve`)),U(e,t)};G(f,e=>{V(o()),B(()=>o().kind===`quick-edit`)?e(p):e(m,-1)}),U(e,d),k(),i()}Tr([`click`]);function fl(e,t){let n=t,r=!0,i=()=>queueMicrotask(()=>{if(!r||!e.isConnected)return;let t=e.querySelector?.(`h2`);t?.isConnected?(t.setAttribute(`tabindex`,`-1`),t.focus({preventScroll:!1})):e.focus({preventScroll:!1})});return i(),{update(e){e!==n&&(n=e,i())},destroy(){r=!1}}}var pl=H(`

                                                                                                `),ml=H(`

                                                                                                `),hl=H(`
                                                                                                `);function gl(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`prompt`,8),s=X(t,`revision`,8),c=X(t,`promptRevision`,8),l=X(t,`controller`,8),u=X(t,`busy`,8),d=X(t,`onSubmit`,8),f=X(t,`onRetryDiscovery`,8),p=X(t,`onBack`,8);Tn(()=>(V(o()),n()),()=>{N(a,Ia(o(),n()))}),En(),ji();var m=hl(),h=P(m),g=P(h),_=I(g,!0),v=I(L(g));D(h);var y=L(h,2),b=e=>{var t=pl(),r=I(t,!0);R(e=>W(r,e),[()=>(V(o()),V(Z),n(),z(a),B(()=>o().kind===`repositories`?Z(`batchReviewSelection`,n()):z(a)?.title??o().title))]),U(e,t)},x=gt(()=>(V(o()),B(()=>![`question`,`management`,`quick-edit`,`quick-review`,`batch-plan`,`batch-result`].includes(o().kind))));G(y,e=>{z(x)&&e(b)});var S=L(y,2),C=e=>{var t=ml(),n=I(t,!0);R(()=>W(n,(z(a),V(o()),B(()=>z(a)?.description??(`description`in o()?o().description:``))))),U(e,t)};G(S,e=>{z(a),V(o()),B(()=>z(a)?.description||`description`in o()&&o().description)&&e(C)}),Yr(L(S,2),c,e=>{var t=Pr(),n=F(t),r=e=>{{let t=A(()=>(V(o()),B(()=>o().kind===`batch-plan`?`review`:`result`)));Qc(e,{get batch(){return V(o()),B(()=>o().batch)},get mode(){return z(t)},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})}},i=e=>{il(e,{get selection(){return V(o()),B(()=>o().selection)},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})},a=e=>{us(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()},get onRetryDiscovery(){return f()},get onBack(){return p()}})},s=e=>{ms(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})},c=e=>{Cs(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})},m=e=>{_c(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})},h=e=>{jc(e,{get view(){return V(o()),B(()=>o().management)},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})},g=e=>{dl(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})};G(n,e=>{V(o()),B(()=>o().kind===`batch-plan`||o().kind===`batch-result`)?e(r):(V(o()),B(()=>o().kind===`repositories`)?e(i,1):(V(o()),B(()=>o().kind===`question`)?e(a,2):(V(o()),B(()=>o().kind===`choice`||o().kind===`confirm`)?e(s,3):(V(o()),B(()=>o().kind===`text`||o().kind===`secret`)?e(c,4):(V(o()),B(()=>o().kind===`plan`)?e(m,5):(V(o()),B(()=>o().kind===`management`)?e(h,6):(V(o()),B(()=>o().kind===`quick-edit`||o().kind===`quick-review`)&&e(g,7))))))))}),U(e,t)}),D(m),ii(m,(e,t)=>fl?.(e,t),c),R((e,t,n)=>{J(m,`aria-label`,e),W(_,t),W(v,`${n??``} ${s()??``}`)},[()=>(V(Z),n(),B(()=>Z(`currentDecision`,n()))),()=>(V(Z),n(),B(()=>Z(`currentDecision`,n()))),()=>(V(Z),n(),B(()=>Z(`session`,n())))]),U(e,m),k(),i()}var _l=`Optional runner discovery selected(Optional organization runner discovery selected(List existing repository self-hosted runners without changing access.(List existing eligible runner groups and their runners; manual routing remains available without this grant.(Create the reviewed installation commit and installer-owned branch.(Include reviewed workflow files in the installation PR.(Create the reviewed installation PR without merging it.(Add only the reviewed repository access to an existing selected resource.(Inspect reusable organization configuration without changing its values.(Inspect effective repository overrides.(Inspect existing Secret names without reading their values.(Inspect inherited Secret access without replacing existing bindings.(Inspect existing trusted credential-health evidence.(Resolve repository identity and visibility.(Inspect installed workflows and repository files.(Inspect and provision selected GitHub Actions Secrets.(Inspect and provision selected GitHub Actions Variables.(Provision labels and issue resources.(Inspect and dispatch credential-health workflows.(Inspect CI workflow runs and jobs for exact producer identities.(Discover exact CI check and producer identities for guarded approval.(Inspect branch protection and rulesets.(Bootstrap a missing credential-health workflow.(Inspect and provision organization Actions Secrets.(Inspect and provision organization Actions Variables.(Provision and assign configured issue types.(Inspect selected Projects and their Status options; setup does not edit Project items.(Create the initial repository tag when no version tag exists.(Create an isolated branch for the Actions permission check.(Create the initial tag and an isolated branch for the Actions permission check.(Create the initial tag or an isolated branch for the Actions permission check.(Inspect and provision selected repository Actions Secrets.(Inspect and provision selected repository Actions Variables.(Provision labels for the selected issue workflows.(Dispatch credential-health checks for existing Secrets.(Prepare and clean isolated Actions checks for the bot PAT and any existing credentials.(Prepare a verified no-job workflow for the bot Actions check.(Inspect CI workflow runs and jobs for approval evidence.(Temporarily install credential health when its workflow is not confirmed installed.(Inspect branch protection and effective rulesets.(Inspect and provision selected organization Actions Secrets.(Inspect and provision selected organization Actions Variables.(Provision native issue types for the selected workflows.(Resolve repository and collaborator metadata.(Read repository branches, commits, and files for enabled runtime routes.(Dispatch selected release or hotfix workflows and check previous runs.(Check previous workflow runs before executing an enabled route.(Create managed branches, edit files, or merge selected release/hotfix changes.(Manage selected issue lifecycles, comments, and progress.(Manage selected pull request workflows, reviews, or autofix.(Verify current-head required checks and producer identities.(Load the PR approval assessment policy.(Select or authorize organization members for enabled workflows.(Assign configured organization issue types.(Update selected organization Projects.(Load the organization-scoped approval policy.(Secret provisioning enabled(Variable provisioning enabled(Issue workflows enabled(Credential health enabled(Initial tag or credential-health check enabled(Pull-request approval enabled(Guarded pull-request approval enabled(Release, hotfix, or guarded approval enabled(Temporary health workflow required(Organization Secret storage selected(Organization Variable storage selected(Issue type automation enabled(Organization Projects selected`.split(`(`),vl={"Optional runner discovery selected":`Consulta opcional de runners seleccionada`,"Optional organization runner discovery selected":`Consulta opcional de runners de organización seleccionada`,"List existing repository self-hosted runners without changing access.":`Consultar los runners self-hosted existentes del repositorio sin cambiar su acceso.`,"List existing eligible runner groups and their runners; manual routing remains available without this grant.":`Consultar los grupos de runners accesibles y sus runners; la configuración manual sigue disponible sin este permiso.`,"Create the reviewed installation commit and installer-owned branch.":`Crear el commit de instalación revisado y la rama del instalador.`,"Include reviewed workflow files in the installation PR.":`Incluir los workflows revisados en la PR de instalación.`,"Create the reviewed installation PR without merging it.":`Crear la PR de instalación revisada sin fusionarla.`,"Add only the reviewed repository access to an existing selected resource.":`Añadir solo el acceso del repositorio revisado a un recurso existente de visibilidad seleccionada.`,"Inspect reusable organization configuration without changing its values.":`Inspeccionar la configuración reutilizable de la organización sin cambiar sus valores.`,"Inspect effective repository overrides.":`Inspeccionar los ajustes efectivos del repositorio.`,"Inspect existing Secret names without reading their values.":`Inspeccionar los nombres de los Secrets existentes sin leer sus valores.`,"Inspect inherited Secret access without replacing existing bindings.":`Inspeccionar el acceso a los Secrets heredados sin sustituir los existentes.`,"Inspect existing trusted credential-health evidence.":`Inspeccionar la evidencia fiable existente sobre las credenciales.`,"Resolve repository identity and visibility.":`Comprobar la identidad y visibilidad del repositorio.`,"Inspect installed workflows and repository files.":`Examinar los workflows instalados y los archivos del repositorio.`,"Inspect and provision selected GitHub Actions Secrets.":`Examinar y configurar los Secrets de GitHub Actions seleccionados.`,"Inspect and provision selected GitHub Actions Variables.":`Examinar y configurar las Variables de GitHub Actions seleccionadas.`,"Provision labels and issue resources.":`Crear etiquetas y recursos de issues.`,"Inspect and dispatch credential-health workflows.":`Examinar y ejecutar los workflows de comprobación de credenciales.`,"Inspect CI workflow runs and jobs for exact producer identities.":`Examinar ejecuciones y jobs de CI para identificar sus productores exactos.`,"Discover exact CI check and producer identities for guarded approval.":`Identificar los checks de CI y sus productores exactos para la aprobación protegida.`,"Inspect branch protection and rulesets.":`Examinar la protección de ramas y sus reglas.`,"Bootstrap a missing credential-health workflow.":`Instalar provisionalmente el workflow de comprobación de credenciales que falta.`,"Inspect and provision organization Actions Secrets.":`Examinar y configurar Secrets de Actions en la organización.`,"Inspect and provision organization Actions Variables.":`Examinar y configurar Variables de Actions en la organización.`,"Provision and assign configured issue types.":`Crear y asignar los tipos de issue configurados.`,"Inspect selected Projects and their Status options; setup does not edit Project items.":`Consultar los Projects seleccionados y sus opciones de Status; el setup no modifica los elementos de los Projects.`,"Create the initial repository tag when no version tag exists.":`Crear el tag inicial si el repositorio aún no tiene ninguno de versión.`,"Create an isolated branch for the Actions permission check.":`Crear una rama aislada para comprobar el permiso de Actions.`,"Create the initial tag and an isolated branch for the Actions permission check.":`Crear el tag inicial y una rama aislada para comprobar el permiso de Actions.`,"Create the initial tag or an isolated branch for the Actions permission check.":`Crear el tag inicial o una rama aislada para comprobar el permiso de Actions.`,"Inspect and provision selected repository Actions Secrets.":`Examinar y configurar los Secrets de Actions seleccionados en el repositorio.`,"Inspect and provision selected repository Actions Variables.":`Examinar y configurar las Variables de Actions seleccionadas en el repositorio.`,"Provision labels for the selected issue workflows.":`Crear las etiquetas de los flujos de issues seleccionados.`,"Dispatch credential-health checks for existing Secrets.":`Ejecutar comprobaciones de credenciales para los Secrets existentes.`,"Prepare and clean isolated Actions checks for the bot PAT and any existing credentials.":`Preparar y limpiar las pruebas aisladas de Actions para el PAT del bot y las credenciales existentes.`,"Prepare a verified no-job workflow for the bot Actions check.":`Preparar un workflow verificado con los jobs desactivados para comprobar Actions con el PAT del bot.`,"Inspect CI workflow runs and jobs for approval evidence.":`Examinar ejecuciones y jobs de CI como prueba para la aprobación.`,"Temporarily install credential health when its workflow is not confirmed installed.":`Instalar temporalmente la comprobación de credenciales si su workflow no está confirmado.`,"Inspect branch protection and effective rulesets.":`Examinar la protección de ramas y las reglas efectivas.`,"Inspect and provision selected organization Actions Secrets.":`Examinar y configurar los Secrets de Actions seleccionados en la organización.`,"Inspect and provision selected organization Actions Variables.":`Examinar y configurar las Variables de Actions seleccionadas en la organización.`,"Provision native issue types for the selected workflows.":`Crear tipos de issue nativos para los flujos seleccionados.`,"Resolve repository and collaborator metadata.":`Consultar los metadatos del repositorio y sus colaboradores.`,"Read repository branches, commits, and files for enabled runtime routes.":`Leer ramas, commits y archivos del repositorio para las rutas de ejecución habilitadas.`,"Dispatch selected release or hotfix workflows and check previous runs.":`Ejecutar los flujos de release o hotfix seleccionados y comprobar ejecuciones anteriores.`,"Check previous workflow runs before executing an enabled route.":`Comprobar ejecuciones anteriores antes de iniciar un flujo habilitado.`,"Create managed branches, edit files, or merge selected release/hotfix changes.":`Crear ramas gestionadas, editar archivos o integrar cambios de release y hotfix.`,"Manage selected issue lifecycles, comments, and progress.":`Gestionar el ciclo de vida, los comentarios y el progreso de los issues seleccionados.`,"Manage selected pull request workflows, reviews, or autofix.":`Gestionar flujos de pull requests, revisiones o correcciones automáticas.`,"Verify current-head required checks and producer identities.":`Verificar los checks obligatorios y productores del commit actual.`,"Load the PR approval assessment policy.":`Leer la política de evaluación de aprobación de PRs.`,"Select or authorize organization members for enabled workflows.":`Seleccionar o autorizar miembros de la organización para los flujos activos.`,"Assign configured organization issue types.":`Asignar los tipos de issue configurados en la organización.`,"Update selected organization Projects.":`Actualizar los Projects seleccionados de la organización.`,"Load the organization-scoped approval policy.":`Leer la política de aprobación guardada en la organización.`,"Secret provisioning enabled":`Configuración de Secrets activada`,"Variable provisioning enabled":`Configuración de Variables activada`,"Issue workflows enabled":`Flujos de issues activados`,"Credential health enabled":`Comprobación de credenciales activada`,"Initial tag or credential-health check enabled":`Tag inicial o comprobación de credenciales activados`,"Pull-request approval enabled":`Aprobación de pull requests activada`,"Guarded pull-request approval enabled":`Aprobación protegida de pull requests activada`,"Release, hotfix, or guarded approval enabled":`Release, hotfix o aprobación protegida activados`,"Temporary health workflow required":`Hace falta un workflow temporal de comprobación`,"Organization Secret storage selected":`Se eligió guardar Secrets en la organización`,"Organization Variable storage selected":`Se eligió guardar Variables en la organización`,"Issue type automation enabled":`Automatización de tipos de issue activada`,"Organization Projects selected":`Se seleccionaron Projects de la organización`},yl={"Optional runner discovery selected":`Consultation facultative des runners sélectionnée`,"Optional organization runner discovery selected":`Consultation facultative des runners de l’organisation sélectionnée`,"List existing repository self-hosted runners without changing access.":`Consulter les runners auto-hébergés existants du dépôt sans modifier leurs accès.`,"List existing eligible runner groups and their runners; manual routing remains available without this grant.":`Consulter les groupes accessibles et leurs runners ; la configuration manuelle reste possible sans ce droit.`,"Create the reviewed installation commit and installer-owned branch.":`Créer le commit d’installation validé et la branche de l’installateur.`,"Include reviewed workflow files in the installation PR.":`Inclure les workflows validés dans la PR d’installation.`,"Create the reviewed installation PR without merging it.":`Créer la PR d’installation validée sans la fusionner.`,"Add only the reviewed repository access to an existing selected resource.":`Ajouter uniquement l’accès validé du dépôt à une ressource existante de visibilité sélectionnée.`,"Inspect reusable organization configuration without changing its values.":`Lire la configuration réutilisable de l’organisation sans modifier ses valeurs.`,"Inspect effective repository overrides.":`Lire les réglages effectifs du dépôt.`,"Inspect existing Secret names without reading their values.":`Lire les noms des Secrets existants sans accéder à leurs valeurs.`,"Inspect inherited Secret access without replacing existing bindings.":`Vérifier l’accès aux Secrets hérités sans remplacer les liaisons existantes.`,"Inspect existing trusted credential-health evidence.":`Lire les preuves fiables existantes de vérification des identifiants.`,"Resolve repository identity and visibility.":`Vérifier l’identité et la visibilité du dépôt.`,"Inspect installed workflows and repository files.":`Examiner les workflows installés et les fichiers du dépôt.`,"Inspect and provision selected GitHub Actions Secrets.":`Examiner et configurer les Secrets GitHub Actions choisis.`,"Inspect and provision selected GitHub Actions Variables.":`Examiner et configurer les Variables GitHub Actions choisies.`,"Provision labels and issue resources.":`Créer des étiquettes et des ressources pour les tickets.`,"Inspect and dispatch credential-health workflows.":`Examiner et lancer les workflows de vérification des identifiants.`,"Inspect CI workflow runs and jobs for exact producer identities.":`Examiner les exécutions et jobs CI pour identifier exactement leurs producteurs.`,"Discover exact CI check and producer identities for guarded approval.":`Identifier précisément les vérifications CI et leurs producteurs pour l’approbation encadrée.`,"Inspect branch protection and rulesets.":`Examiner la protection des branches et les ensembles de règles.`,"Bootstrap a missing credential-health workflow.":`Installer provisoirement le workflow de vérification des identifiants manquant.`,"Inspect and provision organization Actions Secrets.":`Examiner et configurer les Secrets Actions de l’organisation.`,"Inspect and provision organization Actions Variables.":`Examiner et configurer les Variables Actions de l’organisation.`,"Provision and assign configured issue types.":`Créer et attribuer les types de ticket configurés.`,"Inspect selected Projects and their Status options; setup does not edit Project items.":`Consulter les Projects sélectionnés et leurs options Status ; la configuration ne modifie aucun élément de Project.`,"Create the initial repository tag when no version tag exists.":`Créer le tag initial si le dépôt ne possède encore aucun tag de version.`,"Create an isolated branch for the Actions permission check.":`Créer une branche isolée pour vérifier l’autorisation Actions.`,"Create the initial tag and an isolated branch for the Actions permission check.":`Créer le tag initial et une branche isolée pour vérifier l’autorisation Actions.`,"Create the initial tag or an isolated branch for the Actions permission check.":`Créer le tag initial ou une branche isolée pour vérifier l’autorisation Actions.`,"Inspect and provision selected repository Actions Secrets.":`Examiner et configurer les Secrets Actions choisis dans le dépôt.`,"Inspect and provision selected repository Actions Variables.":`Examiner et configurer les Variables Actions choisies dans le dépôt.`,"Provision labels for the selected issue workflows.":`Créer les étiquettes des workflows de ticket choisis.`,"Dispatch credential-health checks for existing Secrets.":`Lancer des vérifications d’identifiants pour les Secrets existants.`,"Prepare and clean isolated Actions checks for the bot PAT and any existing credentials.":`Préparer et nettoyer les tests Actions isolés du PAT du bot et des identifiants existants.`,"Prepare a verified no-job workflow for the bot Actions check.":`Préparer un workflow vérifié aux jobs désactivés pour tester Actions avec le PAT du bot.`,"Inspect CI workflow runs and jobs for approval evidence.":`Examiner les exécutions et jobs CI comme preuve pour l’approbation.`,"Temporarily install credential health when its workflow is not confirmed installed.":`Installer provisoirement la vérification des identifiants si son workflow n’est pas confirmé.`,"Inspect branch protection and effective rulesets.":`Examiner la protection des branches et les règles applicables.`,"Inspect and provision selected organization Actions Secrets.":`Examiner et configurer les Secrets Actions choisis dans l’organisation.`,"Inspect and provision selected organization Actions Variables.":`Examiner et configurer les Variables Actions choisies dans l’organisation.`,"Provision native issue types for the selected workflows.":`Créer des types de ticket natifs pour les workflows choisis.`,"Resolve repository and collaborator metadata.":`Consulter les métadonnées du dépôt et de ses collaborateurs.`,"Read repository branches, commits, and files for enabled runtime routes.":`Lire les branches, commits et fichiers du dépôt pour les parcours d’exécution activés.`,"Dispatch selected release or hotfix workflows and check previous runs.":`Lancer les workflows de version ou correctif urgent choisis et vérifier les exécutions précédentes.`,"Check previous workflow runs before executing an enabled route.":`Vérifier les exécutions précédentes avant de lancer un parcours activé.`,"Create managed branches, edit files, or merge selected release/hotfix changes.":`Créer des branches gérées, modifier des fichiers ou fusionner les changements de version et correctif.`,"Manage selected issue lifecycles, comments, and progress.":`Gérer le cycle de vie, les commentaires et la progression des tickets choisis.`,"Manage selected pull request workflows, reviews, or autofix.":`Gérer les workflows de pull request, les revues ou les corrections automatiques.`,"Verify current-head required checks and producer identities.":`Vérifier les contrôles requis et leurs producteurs pour le commit courant.`,"Load the PR approval assessment policy.":`Lire la politique d’évaluation de l’approbation des PR.`,"Select or authorize organization members for enabled workflows.":`Sélectionner ou autoriser des membres de l’organisation pour les workflows activés.`,"Assign configured organization issue types.":`Attribuer les types de ticket configurés dans l’organisation.`,"Update selected organization Projects.":`Mettre à jour les projets de l’organisation choisis.`,"Load the organization-scoped approval policy.":`Lire la politique d’approbation stockée dans l’organisation.`,"Secret provisioning enabled":`Configuration des Secrets activée`,"Variable provisioning enabled":`Configuration des Variables activée`,"Issue workflows enabled":`Workflows de ticket activés`,"Credential health enabled":`Vérification des identifiants activée`,"Initial tag or credential-health check enabled":`Tag initial ou vérification des identifiants activés`,"Pull-request approval enabled":`Approbation des pull requests activée`,"Guarded pull-request approval enabled":`Approbation encadrée des pull requests activée`,"Release, hotfix, or guarded approval enabled":`Version, correctif urgent ou approbation encadrée activés`,"Temporary health workflow required":`Workflow temporaire de vérification requis`,"Organization Secret storage selected":`Stockage des Secrets dans l’organisation choisi`,"Organization Variable storage selected":`Stockage des Variables dans l’organisation choisi`,"Issue type automation enabled":`Automatisation des types de ticket activée`,"Organization Projects selected":`Projets de l’organisation choisis`},bl={"Optional runner discovery selected":`Consulta opcional de runners selecionada`,"Optional organization runner discovery selected":`Consulta opcional de runners da organização selecionada`,"List existing repository self-hosted runners without changing access.":`Consultar os runners self-hosted existentes do repositório sem alterar o acesso.`,"List existing eligible runner groups and their runners; manual routing remains available without this grant.":`Consultar os grupos acessíveis e os seus runners; a configuração manual continua disponível sem esta permissão.`,"Create the reviewed installation commit and installer-owned branch.":`Criar o commit de instalação revisto e o ramo do instalador.`,"Include reviewed workflow files in the installation PR.":`Incluir os workflows revistos na PR de instalação.`,"Create the reviewed installation PR without merging it.":`Criar a PR de instalação revista sem a integrar.`,"Add only the reviewed repository access to an existing selected resource.":`Adicionar apenas o acesso revisto do repositório a um recurso existente de visibilidade selecionada.`,"Inspect reusable organization configuration without changing its values.":`Consultar a configuração reutilizável da organização sem alterar os seus valores.`,"Inspect effective repository overrides.":`Consultar os ajustes efetivos do repositório.`,"Inspect existing Secret names without reading their values.":`Consultar os nomes dos Secrets existentes sem ler os seus valores.`,"Inspect inherited Secret access without replacing existing bindings.":`Consultar o acesso aos Secrets herdados sem substituir as ligações existentes.`,"Inspect existing trusted credential-health evidence.":`Consultar as provas fiáveis existentes da verificação das credenciais.`,"Resolve repository identity and visibility.":`Verificar a identidade e visibilidade do repositório.`,"Inspect installed workflows and repository files.":`Inspecionar os fluxos instalados e os ficheiros do repositório.`,"Inspect and provision selected GitHub Actions Secrets.":`Inspecionar e configurar os Secrets do GitHub Actions selecionados.`,"Inspect and provision selected GitHub Actions Variables.":`Inspecionar e configurar as Variables do GitHub Actions selecionadas.`,"Provision labels and issue resources.":`Criar etiquetas e recursos para questões.`,"Inspect and dispatch credential-health workflows.":`Inspecionar e executar os fluxos de verificação de credenciais.`,"Inspect CI workflow runs and jobs for exact producer identities.":`Inspecionar execuções e jobs CI para identificar exatamente os seus produtores.`,"Discover exact CI check and producer identities for guarded approval.":`Identificar as verificações CI e os seus produtores exatos para a aprovação protegida.`,"Inspect branch protection and rulesets.":`Inspecionar a proteção de ramos e os conjuntos de regras.`,"Bootstrap a missing credential-health workflow.":`Instalar temporariamente o fluxo de verificação de credenciais em falta.`,"Inspect and provision organization Actions Secrets.":`Inspecionar e configurar os Secrets de Actions da organização.`,"Inspect and provision organization Actions Variables.":`Inspecionar e configurar as Variables de Actions da organização.`,"Provision and assign configured issue types.":`Criar e atribuir os tipos de questão configurados.`,"Inspect selected Projects and their Status options; setup does not edit Project items.":`Consultar os Projects selecionados e as suas opções de Status; a configuração não altera os itens dos Projects.`,"Create the initial repository tag when no version tag exists.":`Criar a etiqueta inicial se o repositório ainda não tiver etiquetas de versão.`,"Create an isolated branch for the Actions permission check.":`Criar um ramo isolado para verificar a permissão de Actions.`,"Create the initial tag and an isolated branch for the Actions permission check.":`Criar a etiqueta inicial e um ramo isolado para verificar a permissão de Actions.`,"Create the initial tag or an isolated branch for the Actions permission check.":`Criar a etiqueta inicial ou um ramo isolado para verificar a permissão de Actions.`,"Inspect and provision selected repository Actions Secrets.":`Inspecionar e configurar os Secrets de Actions selecionados no repositório.`,"Inspect and provision selected repository Actions Variables.":`Inspecionar e configurar as Variables de Actions selecionadas no repositório.`,"Provision labels for the selected issue workflows.":`Criar etiquetas para os fluxos de questões selecionados.`,"Dispatch credential-health checks for existing Secrets.":`Executar verificações de credenciais para os Secrets existentes.`,"Prepare and clean isolated Actions checks for the bot PAT and any existing credentials.":`Preparar e limpar os testes isolados de Actions para o PAT do bot e as credenciais existentes.`,"Prepare a verified no-job workflow for the bot Actions check.":`Preparar um workflow verificado com os jobs desativados para testar Actions com o PAT do bot.`,"Inspect CI workflow runs and jobs for approval evidence.":`Inspecionar execuções e jobs CI como prova para aprovação.`,"Temporarily install credential health when its workflow is not confirmed installed.":`Instalar temporariamente a verificação de credenciais se o fluxo não estiver confirmado.`,"Inspect branch protection and effective rulesets.":`Inspecionar a proteção de ramos e as regras aplicáveis.`,"Inspect and provision selected organization Actions Secrets.":`Inspecionar e configurar os Secrets de Actions selecionados na organização.`,"Inspect and provision selected organization Actions Variables.":`Inspecionar e configurar as Variables de Actions selecionadas na organização.`,"Provision native issue types for the selected workflows.":`Criar tipos de questão nativos para os fluxos selecionados.`,"Resolve repository and collaborator metadata.":`Consultar os metadados do repositório e dos colaboradores.`,"Read repository branches, commits, and files for enabled runtime routes.":`Ler branches, commits e arquivos do repositório para os fluxos de execução habilitados.`,"Dispatch selected release or hotfix workflows and check previous runs.":`Executar os fluxos de release ou hotfix selecionados e verificar execuções anteriores.`,"Check previous workflow runs before executing an enabled route.":`Verificar execuções anteriores antes de iniciar um percurso ativo.`,"Create managed branches, edit files, or merge selected release/hotfix changes.":`Criar ramos geridos, editar ficheiros ou integrar alterações de release e hotfix.`,"Manage selected issue lifecycles, comments, and progress.":`Gerir o ciclo de vida, os comentários e o progresso das questões selecionadas.`,"Manage selected pull request workflows, reviews, or autofix.":`Gerir fluxos de pull requests, revisões ou correções automáticas.`,"Verify current-head required checks and producer identities.":`Verificar as verificações obrigatórias e os produtores do commit atual.`,"Load the PR approval assessment policy.":`Ler a política de avaliação de aprovação de PRs.`,"Select or authorize organization members for enabled workflows.":`Selecionar ou autorizar membros da organização para os fluxos ativos.`,"Assign configured organization issue types.":`Atribuir os tipos de questão configurados na organização.`,"Update selected organization Projects.":`Atualizar os Projetos selecionados da organização.`,"Load the organization-scoped approval policy.":`Ler a política de aprovação guardada na organização.`,"Secret provisioning enabled":`Configuração de Secrets ativa`,"Variable provisioning enabled":`Configuração de Variables ativa`,"Issue workflows enabled":`Fluxos de questões ativos`,"Credential health enabled":`Verificação de credenciais ativa`,"Initial tag or credential-health check enabled":`Etiqueta inicial ou verificação de credenciais ativas`,"Pull-request approval enabled":`Aprovação de pull requests ativa`,"Guarded pull-request approval enabled":`Aprovação protegida de pull requests ativa`,"Release, hotfix, or guarded approval enabled":`Release, hotfix ou aprovação protegida ativos`,"Temporary health workflow required":`É necessário um fluxo temporário de verificação`,"Organization Secret storage selected":`Armazenamento dos Secrets na organização selecionado`,"Organization Variable storage selected":`Armazenamento das Variables na organização selecionado`,"Issue type automation enabled":`Automatização de tipos de questão ativa`,"Organization Projects selected":`Projetos da organização selecionados`},xl=new Set(_l),Sl={es:vl,fr:yl,pt:bl};function Cl(e,t){return e===`en`?t:xl.has(t)?Sl[e][t]:Z(`permissionUnknown`,e)}var wl={en:{"contents-write":`Actions was not tested because its temporary branch could not be created. Check repository Contents Write, repository selection and organization authorization.`,"contents-workflows-write":`Actions was not tested because its temporary workflow could not be written. Check repository Contents and Workflows Write, repository selection and organization authorization. Unverifiable does not mean Actions is missing.`,"dispatch-workflow":`Actions was not tested because no active workflow_dispatch workflow was found on the default branch. Install an eligible workflow before retrying.`},es:{"contents-write":`No se comprobó Actions porque no se pudo crear su rama temporal. Revisa Contents Write del repositorio, la selección del repositorio y la autorización de la organización.`,"contents-workflows-write":`No se comprobó Actions porque no se pudo escribir su workflow temporal. Revisa Contents y Workflows Write del repositorio, la selección del repositorio y la autorización de la organización. No verificable no significa que falte Actions.`,"dispatch-workflow":`No se comprobó Actions porque no se encontró un workflow activo con workflow_dispatch en la rama predeterminada. Instala uno antes de reintentar.`},fr:{"contents-write":`Actions n’a pas été testé car sa branche temporaire n’a pas pu être créée. Vérifiez Contents Write du dépôt, la sélection du dépôt et l’autorisation de l’organisation.`,"contents-workflows-write":`Actions n’a pas été testé car son workflow temporaire n’a pas pu être écrit. Vérifiez Contents et Workflows Write du dépôt, la sélection du dépôt et l’autorisation de l’organisation. Non vérifiable ne signifie pas qu’Actions manque.`,"dispatch-workflow":`Actions n’a pas été testé car aucun workflow actif avec workflow_dispatch n’a été trouvé sur la branche par défaut. Installez-en un avant de réessayer.`},pt:{"contents-write":`Actions não foi testado porque não foi possível criar a sua branch temporária. Verifique Contents Write do repositório, a seleção do repositório e a autorização da organização.`,"contents-workflows-write":`Actions não foi testado porque não foi possível escrever o seu workflow temporário. Verifique Contents e Workflows Write do repositório, a seleção do repositório e a autorização da organização. Não verificável não significa que falte Actions.`,"dispatch-workflow":`Actions não foi testado porque não foi encontrado um workflow ativo com workflow_dispatch na branch predefinida. Instale um antes de tentar novamente.`}};function Tl(e,t){if(e===`contents-write`||e===`contents-workflows-write`||e===`dispatch-workflow`)return wl[t][e]}function El(e,t){if(e.status===`unverifiable`&&e.permission===`Actions`&&e.level===`write`){let n=Tl(e.prerequisite,t);if(n)return n}return e.status===`verified`?Z(e.level===`write`?`permissionEvidenceVerifiedWrite`:e.scope===`organization`&&e.permission===`Projects`&&e.level===`read`?`permissionEvidencePrivateProject`:`permissionEvidenceVerified`,t):e.status===`missing`?Z(`permissionEvidenceMissing`,t):e.status===`available`?Z(e.publicReadEvidence===`public-organization-projects`?`permissionEvidencePublicProjects`:`permissionEvidencePublic`,t):e.level===`write`?Z(`permissionEvidenceWrite`,t):e.publicReadEvidence===`public-organization-projects`?Z(`permissionEvidencePublicProjects`,t):e.publicReadEvidence===`public-repository`?Z(`permissionEvidencePublic`,t):Z(`permissionEvidenceUnknownRead`,t)}var Dl=H(` `),Ol=H(` `),kl=H(`
                                                                                              • `),Al=H(`

                                                                                                  `),jl=H(`

                                                                                                  `),Ml=H(``);function Nl(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`view`,8);ji();var o=Ml(),s=P(o),c=L(P(s)),l=I(c,!0),u=L(c),d=I(u,!0),f=L(u),p=I(P(f),!0);D(f),D(s);var m=L(s,2),h=e=>{var t=Al(),r=L(P(t)),i=I(r),o=L(r),s=I(o,!0),c=L(o,2);q(c,5,()=>(V(a()),B(()=>a().permissions.report?.checks??a().permissions.requirements??[])),K,(e,t)=>{var r=kl(),i=P(r),a=P(i,!0),o=L(a),s=e=>{var n=Dl(),r=I(P(n));D(n),R(()=>W(r,`GitHub · ${z(t),B(()=>z(t).permission)??``}`)),U(e,n)},c=gt(()=>(n(),V(ac),z(t),B(()=>n()!==`en`&&ac(n(),z(t).permission)!==z(t).permission)));G(o,e=>{z(c)&&e(s)});var l=L(o),u=I(l),d=L(l),f=I(d,!0),p=L(d),m=e=>{var r=Ol(),i=I(r,!0);R(e=>W(i,e),[()=>(V(Cl),n(),z(t),B(()=>Cl(n(),z(t).condition)))]),U(e,r)};G(p,e=>{z(t),B(()=>z(t).condition)&&e(m)});var h=L(p),g=e=>{var r=Ol(),i=I(r,!0);R(e=>W(i,e),[()=>(V(El),z(t),n(),B(()=>El(z(t),n())))]),U(e,r)};G(h,e=>{`status`in z(t)&&e(g)}),D(i);var _=L(i),v=P(_,!0),y=L(v),b=e=>{var r=Ol(),i=I(r,!0);R(e=>W(i,e),[()=>(V(oc),n(),z(t),B(()=>oc(n(),z(t).status)))]),U(e,r)},x=gt(()=>(z(t),V(oc),n(),B(()=>`status`in z(t)&&oc(n(),z(t).status))));G(y,e=>{z(x)&&e(b)}),D(_),D(r),R((e,t,n,r,i)=>{W(a,e),W(u,`${t??``} · ${n??``}`),W(f,r),W(v,i)},[()=>(V(ac),n(),z(t),B(()=>ac(n(),z(t).permission))),()=>(V(ic),n(),z(t),B(()=>ic(n(),z(t).scope))),()=>(V(ic),n(),z(t),B(()=>ic(n(),z(t).applicability))),()=>(V(Cl),n(),z(t),B(()=>Cl(n(),z(t).reason))),()=>(V(ic),n(),z(t),B(()=>ic(n(),z(t).level)))]),U(e,r)}),D(c);var l=I(L(c,2),!0);D(t),R((e,t,n,r)=>{W(i,`${e??``} ${t??``}`),W(s,n),W(l,r)},[()=>(V(a()),V(Z),n(),B(()=>a().permissions.role===`setup`?Z(`setupPat`,n()):Z(`botPat`,n()))),()=>(V(Z),n(),B(()=>Z(`access`,n()))),()=>(V(a()),V(Z),n(),B(()=>a().permissions.report?Z(`readOnlyCheck`,n()):Z(`provisionalGrants`,n()))),()=>(V(Z),n(),B(()=>Z(`conditionalGrants`,n())))]),U(e,t)},g=e=>{var t=jl(),r=L(P(t)),i=I(r,!0),a=I(L(r),!0);D(t),R((e,t)=>{W(i,e),W(a,t)},[()=>(V(Z),n(),B(()=>Z(`permissionsFollow`,n()))),()=>(V(Z),n(),B(()=>Z(`permissionsFollowBody`,n())))]),U(e,t)};G(m,e=>{V(a()),B(()=>a().permissions)?e(h):e(g,-1)}),D(o),R((e,t,n)=>{J(o,`aria-label`,e),W(l,t),W(d,n),W(p,(V(a()),B(()=>a().batch?.organization??a().repository)))},[()=>(V(Z),n(),B(()=>Z(`setup`,n()))),()=>(V(Z),V(a()),n(),B(()=>Z(a().batch?`batchFocusTitle`:`repoFocus`,n()))),()=>(V(a()),V(Z),n(),B(()=>a().batch?Z(`batchFocusBody`,n(),{count:String(a().batch.targets.length)}):Z(`repoFocusBody`,n())))]),U(e,o),k(),i()}function Pl(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`report`,8,void 0);ji();var o=Pr(),s=F(o),c=e=>{{let t=A(()=>(V(Z),n(),B(()=>Z(`permissionSecretCollision`,n())))),r=A(()=>(V(Z),n(),B(()=>Z(`permissionSecretCollisionAction`,n()))));to(e,{tone:`warning`,get title(){return z(t)},get message(){return z(r)}})}},l=gt(()=>(V(a()),B(()=>a()?.checks.some(e=>e.incident===`secret-collision`)))),u=e=>{{let t=A(()=>(V(Z),n(),B(()=>Z(`permissionProbeCleanupPending`,n())))),r=A(()=>(V(Z),n(),B(()=>Z(`permissionProbeCleanupAction`,n()))));to(e,{tone:`warning`,get title(){return z(t)},get message(){return z(r)}})}},d=gt(()=>(V(a()),B(()=>a()?.checks.some(e=>e.cleanupPending))));G(s,e=>{z(l)?e(c):z(d)&&e(u,1)}),U(e,o),k(),i()}var Fl=H(`
                                                                                                • `),Il=H(`

                                                                                                    `);function Ll(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`effects`,8),o={files:`receiptFiles`,secrets:`receiptSecrets`,labels:`receiptLabels`,"issue-types":`receiptIssueTypes`,variables:`receiptVariables`,"initial-tag":`receiptInitialTag`},s={completed:`effectCompleted`,skipped:`effectSkipped`,"needs-inspection":`effectInspect`,"not-started":`effectNotStarted`,"in-progress":`effectInProgress`},c={local:`scopeLocal`,repository:`scopeRepository`,organization:`scopeOrganization`,mixed:`scopeMixed`};ji();var l=Il(),u=P(l),d=I(u,!0),f=L(u,2);q(f,5,a,e=>e.id,(e,t)=>{var r=Fl(),i=P(r),a=I(i,!0),l=L(i),u=L(l),d=e=>{var r=Nr();R(e=>W(r,`· ${e??``}`),[()=>(V(Z),z(t),n(),B(()=>Z(c[z(t).scope],n())))]),U(e,r)};G(u,e=>{z(t),B(()=>z(t).scope)&&e(d)}),D(r),R((e,t)=>{W(a,e),W(l,` — ${t??``}`)},[()=>(z(t),V(Z),n(),B(()=>o[z(t).id]?Z(o[z(t).id],n()):z(t).id)),()=>(V(Z),z(t),n(),B(()=>Z(s[z(t).state],n())))]),U(e,r)}),D(f),D(l),R(e=>W(d,e),[()=>(V(Z),n(),B(()=>Z(`resourceReceipt`,n())))]),U(e,l),k(),i()}var Rl=H(`
                                                                                                  • `),zl=H(`

                                                                                                      `,1),Bl=H(`

                                                                                                      `);function Vl(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`correction`,8);ji();var o=Bl(),s=P(o),c=I(s,!0),l=L(s,2),u=I(l,!0),d=L(l,2),f=e=>{var t=zl(),r=F(t),i=I(P(r));D(r);var o=L(r,2);q(o,5,()=>(V(a()),B(()=>a().addedGrants)),K,(e,t)=>{var n=Rl(),r=I(P(n),!0);D(n),R(()=>W(r,z(t))),U(e,n)}),D(o),R(e=>W(i,`${e??``}:`),[()=>(V(Z),n(),B(()=>Z(`updatedSetupPatGrants`,n())))]),U(e,t)};G(d,e=>{V(a()),B(()=>a().stage===`final`&&a().addedGrants.length)&&e(f)});var p=L(d,2),m=I(p);D(o),R((e,t,n,r)=>{J(o,`aria-label`,e),W(c,t),W(u,n),J(p,`href`,(V(a()),B(()=>a().url))),W(m,`${r??``} ↗`)},[()=>(V(Z),n(),B(()=>Z(`updatedSetupPatTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`updatedSetupPatTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`updatedSetupPatBody`,n()))),()=>(V(Z),n(),B(()=>Z(`updatedSetupPatLink`,n())))]),U(e,o),k(),i()}var Hl=H(`

                                                                                                      `,1);function Ul(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi();ji();var a=Hl(),o=F(a),s=I(o,!0),c=L(o,2),l=P(c),u=L(l),d=I(u);D(c);var f=L(c,2),p=P(f),m=L(p),h=I(m);D(f),R((e,t,n,r,i)=>{W(s,e),W(l,`${t??``} `),J(u,`href`,Ba.verification),W(d,`${n??``} ↗`),W(p,`${r??``} `),J(m,`href`,Ba.firstWorkflow),W(h,`${i??``} ↗`)},[()=>Z(`botRenewal`,n()),()=>Ha(`result`,n()),()=>Ha(`guide`,n()),()=>Z(`setupNextWorkflow`,n()),()=>Z(`firstWorkflowGuide`,n())]),U(e,a),k(),i()}var Wl=H(`

                                                                                                      `),Gl=H(`

                                                                                                      `),Kl=H(`

                                                                                                      `),ql=H(` `),Jl=H(`

                                                                                                      `),Yl=H(`
                                                                                                    • `),Xl=H(`
                                                                                                        `),Zl=H(`

                                                                                                        `),Ql=H(`
                                                                                                        `),$l=H(`copilot doctor --read-only`),eu=H(`

                                                                                                        `);function tu(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=M(),s=M(),c=M(),l=M(),u=M(),d=M(),f=M(),p=M(),m=X(t,`management`,8,!1),h=X(t,`batch`,8,!1),g=X(t,`outcome`,8),_=X(t,`controller`,8),v=X(t,`onClose`,8),y=X(t,`onDoctor`,8,async()=>void 0),b=X(t,`doctor`,8,void 0),x=X(t,`detail`,8,void 0),S=X(t,`permissionReport`,8,void 0),C=X(t,`setupPatCorrection`,8,void 0),w={permissions:[`reasonPermissions`,`nextPermissions`],storage:[`reasonStorage`,`nextStorage`],configuration:[`reasonConfiguration`,`nextConfiguration`],"session-expired":[`reasonExpired`,`nextExpired`],cancelled:[`reasonCancelled`,`nextCancelled`],provider:[`reasonProvider`,`nextProvider`],"rate-limit":[`reasonRateLimit`,`nextRateLimit`],unknown:[`reasonUnknown`,`nextUnknown`]};Tn(()=>V(x()),()=>{N(a,x()?.effects?.some(e=>e.state===`completed`)===!0)}),Tn(()=>(V(h()),n(),V(m()),V(g()),z(a)),()=>{N(o,h()?Z(`batchNextActions`,n()):m()?ta(n())[g()===`complete`&&z(a)?`finished`:g()===`partial`?`inspectAdjustment`:g()===`complete`?`inspectionFinished`:`inspectionStopped`]:g()===`complete`?Z(`resultApplied`,n()):g()===`dry-run`?Z(`resultNoChanges`,n()):g()===`cancelled`||g()===`blocked`?Z(`resultStopped`,n()):Z(`resultPartial`,n()))}),Tn(()=>(V(h()),n(),V(m()),V(g()),z(a)),()=>{N(s,h()?Z(`batchResultBody`,n()):m()?ta(n())[g()===`complete`&&z(a)?`finishedBody`:g()===`partial`?`partial`:`inspectionBody`]:g()===`complete`?Z(`resultCompleteBody`,n()):g()===`partial`?Z(`resultPartialBody`,n()):Z(`resultNoChangesBody`,n()))}),Tn(()=>(V(g()),V(x()),V(S())),()=>{N(c,(g()===`blocked`||g()===`partial`)&&x()?.reasonCode===`permissions`?S():void 0)}),Tn(()=>z(c),()=>{N(l,z(c)?.checks.some(e=>e.cleanupPending===!0)===!0)}),Tn(()=>z(c),()=>{N(u,z(c)?.checks.some(e=>e.incident===`secret-collision`)===!0)}),Tn(()=>(z(c),V(x())),()=>{N(d,z(c)?.role===`workflow`?`reasonWorkflowPermissions`:w[x()?.reasonCode??`unknown`][0])}),Tn(()=>(V(g()),V(h()),V(x()),z(l),z(u),V(C())),()=>{N(f,(g()===`blocked`||h()&&g()===`partial`)&&x()?.reasonCode===`permissions`&&(h()||x().mutationStarted===!1)&&!z(l)&&!z(u)&&C())}),Tn(()=>z(c),()=>{N(p,z(c)?z(c).checks.filter(e=>e.applicability===`required`&&e.status!==`verified`&&e.status!==`available`):[])}),En(),ji();var ee=eu(),te=P(ee),ne=I(te,!0),re=L(te),ie=I(re,!0),ae=L(re,2),oe=e=>{var t=Kl(),r=P(t),i=P(r),a=I(i),o=L(i);D(r);var s=L(r,2),c=e=>{var t=Wl(),r=P(t),i=I(r),a=L(r);D(t),R((e,t)=>{W(i,`${e??``}:`),W(a,` ${t??``}`)},[()=>(V(Z),n(),B(()=>Z(`progress`,n()))),()=>(V(Zi),V(x()),n(),B(()=>Zi(x().stoppedStage,n())))]),U(e,t)};G(s,e=>{V(x()),B(()=>x()?.stoppedStage)&&e(c)});var f=L(s,2),p=P(f),m=I(p),h=L(p);D(f);var _=L(f,2),v=P(_),y=I(v),b=L(v);D(_);var S=L(_,2),C=e=>{var t=Gl(),r=P(t),i=I(r),a=I(L(r,2),!0);D(t),R(e=>{W(i,`${e??``}:`),W(a,(V(x()),B(()=>x().diagnosticRef)))},[()=>(V(Z),n(),B(()=>Z(`diagnosticReference`,n())))]),U(e,t)};G(S,e=>{V(x()),B(()=>x()?.diagnosticRef)&&e(C)}),D(t),R((e,t,n,r,i,s)=>{W(a,`${e??``}:`),W(o,` ${t??``}`),W(m,`${n??``}:`),W(h,` ${r??``}`),W(y,`${i??``}:`),W(b,` ${s??``}`)},[()=>(V(Z),n(),B(()=>Z(`whatHappened`,n()))),()=>(V(Z),z(d),n(),B(()=>Z(z(d),n()))),()=>(V(Z),n(),B(()=>Z(`alreadyChanged`,n()))),()=>(z(u),V(Z),n(),z(l),V(x()),V(g()),B(()=>z(u)?Z(`permissionSecretCollision`,n()):z(l)?Z(`permissionProbeCleanupPending`,n()):x()?.mutationStarted||g()===`partial`?Z(`inspectPartial`,n()):Z(`noChanges`,n()))),()=>(V(Z),n(),B(()=>Z(`nextAction`,n()))),()=>(z(u),V(Z),n(),z(l),V(g()),V(x()),B(()=>z(u)?Z(`permissionSecretCollisionAction`,n()):z(l)?Z(`permissionProbeCleanupAction`,n()):g()===`partial`?`${Z(`inspectPartial`,n())} ${Z(w[x()?.reasonCode??`unknown`][1],n())}`:Z(w[x()?.reasonCode??`unknown`][1],n())))]),U(e,t)};G(ae,e=>{(g()===`blocked`||g()===`cancelled`||g()===`partial`)&&e(oe)});var se=L(ae,2),ce=e=>{var t=Zl(),r=P(t),i=I(r,!0),a=L(r,2),o=I(a,!0),s=L(a,2),l=P(s),u=I(l),d=L(l);D(s);var f=L(s,2),m=e=>{var t=Xl();q(t,5,()=>z(p),K,(e,t)=>{var r=Yl(),i=P(r),a=I(i,!0),o=L(i),s=e=>{var n=ql(),r=I(P(n));D(n),R(()=>W(r,`GitHub · ${z(t),B(()=>z(t).permission)??``}`)),U(e,n)},l=gt(()=>(n(),V(ac),z(t),B(()=>n()!==`en`&&ac(n(),z(t).permission)!==z(t).permission)));G(o,e=>{z(l)&&e(s)});var u=L(o),d=L(u),f=I(d,!0),p=L(d),m=e=>{var r=Jl(),i=I(r,!0);R(e=>W(i,e),[()=>(V(El),z(t),n(),B(()=>El(z(t),n())))]),U(e,r)};G(p,e=>{z(c),B(()=>z(c).identityStatus===`valid`)&&e(m)}),D(r),R((e,t,n,r)=>{W(a,e),W(u,` — ${t??``} · ${n??``} · `),W(f,r)},[()=>(V(ac),n(),z(t),B(()=>ac(n(),z(t).permission))),()=>(V(ic),n(),z(t),B(()=>ic(n(),z(t).scope))),()=>(V(ic),n(),z(t),B(()=>ic(n(),z(t).level))),()=>(z(c),V(ic),n(),z(t),V(Z),B(()=>z(c).identityStatus===`valid`?ic(n(),z(t).status):Z(`permissionGrantNotChecked`,n())))]),U(e,r)}),D(t),U(e,t)},h=e=>{var t=Jl(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`permissionReportNoFailedGrant`,n())))]),U(e,t)};G(f,e=>{z(p),B(()=>z(p).length)?e(m):(z(c),B(()=>z(c).identityStatus===`valid`)&&e(h,1))}),D(t),R((e,n,r,a,s)=>{J(t,`aria-label`,e),W(i,n),W(o,r),W(u,`${a??``}:`),W(d,` ${s??``}`)},[()=>(V(Z),n(),B(()=>Z(`permissionReportTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`permissionReportTitle`,n()))),()=>(V(Z),n(),B(()=>Z(`permissionReportLead`,n()))),()=>(V(Z),n(),B(()=>Z(`permissionIdentity`,n()))),()=>(V(Z),z(c),n(),B(()=>Z(z(c).identityStatus===`valid`?`permissionIdentityValid`:z(c).identityStatus===`invalid`?`permissionIdentityInvalid`:`permissionIdentityUnknown`,n())))]),U(e,t)};G(se,e=>{z(c)&&e(ce)});var le=L(se,2),ue=e=>{Ll(e,{get effects(){return V(x()),B(()=>x().effects)}})};G(le,e=>{V(x()),B(()=>x()?.effects?.length)&&e(ue)});var de=L(le,2),fe=e=>{Vl(e,{get correction(){return C()}})};G(de,e=>{z(f)&&C()&&e(fe)});var pe=L(de,2),me=I(pe,!0),he=L(pe,2),ge=e=>{var t=Jl(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`batchCleanup`,n())))]),U(e,t)};G(he,e=>{h()&&e(ge)});var _e=L(he,2),ve=e=>{Ul(e,{})};G(_e,e=>{g()===`complete`&&!m()&&!h()&&e(ve)});var ye=L(_e,2),be=e=>{var t=Jl(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`doctorHelp`,n())))]),U(e,t)};G(ye,e=>{!m()&&!h()&&e(be)});var xe=L(ye,2),Se=e=>{var t=Ql(),r=P(t),i=e=>{var t=Jl(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`doctorRunning`,n())))]),U(e,t)},a=e=>{var t=Jl(),r=I(t);R((e,t,n)=>W(r,`${e??``} ${t??``} ${n??``}`),[()=>(V(Z),V(b()),n(),B(()=>Z(b().healthy?`doctorPassed`:`doctorWarnings`,n()))),()=>(V(Z),n(),V(b()),B(()=>Z(`doctorCounts`,n(),{pass:String(b().pass??0),warn:String(b().warn??0),fail:String(b().fail??0),skipped:String(b().skipped??0)}))),()=>(V(Z),n(),B(()=>Z(`doctorSecretLimit`,n())))]),U(e,t)},o=e=>{var t=Jl(),r=I(t,!0);R(e=>W(r,e),[()=>(V(Z),n(),B(()=>Z(`doctorFailed`,n())))]),U(e,t)};G(r,e=>{V(b()),B(()=>b()?.status===`running`)?e(i):(V(b()),B(()=>b()?.status===`complete`)?e(a,1):(V(b()),B(()=>b()?.status===`failed`)&&e(o,2)))});var s=L(r,2),c=e=>{{let t=A(()=>(V(Z),n(),B(()=>Z(`doctorRun`,n()))));Qa(e,{get label(){return z(t)},variant:`secondary`,get onClick(){return y()}})}};G(s,e=>{V(_()),V(b()),B(()=>_()&&b()?.status!==`running`&&b()?.status!==`complete`)&&e(c)}),D(t),U(e,t)};G(xe,e=>{g()===`complete`&&!m()&&!h()&&e(Se)});var Ce=L(xe,2),we=P(Ce),T=I(we,!0),Te=L(we),E=e=>{U(e,$l())};G(Te,e=>{h()||e(E)}),D(Ce);var Ee=L(Ce),De=e=>{{let t=A(()=>(V(Z),n(),B(()=>Z(`closeSession`,n()))));Qa(e,{get label(){return z(t)},get onClick(){return v()}})}};G(Ee,e=>{_()&&e(De)}),D(ee),ii(ee,(e,t)=>fl?.(e,t),()=>1),R((e,t)=>{W(ne,g()===`complete`?`✓`:`!`),W(ie,z(o)),W(me,e),W(T,t)},[()=>(z(u),V(Z),n(),z(l),z(s),B(()=>z(u)?Z(`permissionSecretCollision`,n()):z(l)?Z(`permissionProbeCleanupPending`,n()):z(s))),()=>(V(Z),n(),B(()=>Z(`patSettings`,n())))]),U(e,ee),k(),i()}var nu=H(`

                                                                                                        `);function ru(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`effects`,8,void 0);ji();var o=nu(),s=L(P(o)),c=I(s,!0),l=L(s),u=I(l,!0),d=L(l),f=e=>{Ll(e,{get effects(){return a()}})};G(d,e=>{V(a()),B(()=>a()?.length)&&e(f)}),D(o),R((e,t)=>{W(c,e),W(u,t)},[()=>(V(Z),n(),B(()=>Z(`working`,n()))),()=>(V(Z),n(),B(()=>Z(`workingBody`,n())))]),U(e,o),k(),i()}var iu={en:{title:`Checking PAT access`,lead:`Each permission is checked separately. Temporary test resources are removed after verification.`,pending:`Waiting`,checking:`Checking read access`,creating:`Creating temporary resource`,reading:`Reading temporary resource`,deleting:`Removing temporary resource`,verified:`Verified`,failed:`Needs attention`,skipped:`Checked after plan approval if required`},es:{title:`Comprobando el acceso del PAT`,lead:`Cada permiso se comprueba por separado. Los recursos temporales se eliminan tras verificarlos.`,pending:`Pendiente`,checking:`Comprobando lectura`,creating:`Creando recurso temporal`,reading:`Leyendo recurso temporal`,deleting:`Eliminando recurso temporal`,verified:`Verificado`,failed:`Requiere atención`,skipped:`Se comprobará tras aprobar el plan si es necesario`},fr:{title:`Vérification des accès du PAT`,lead:`Chaque permission est vérifiée séparément. Les ressources temporaires sont supprimées après vérification.`,pending:`En attente`,checking:`Vérification de la lecture`,creating:`Création d’une ressource temporaire`,reading:`Lecture de la ressource temporaire`,deleting:`Suppression de la ressource temporaire`,verified:`Vérifié`,failed:`Intervention nécessaire`,skipped:`Vérifiée après approbation du plan si nécessaire`},pt:{title:`A verificar o acesso do PAT`,lead:`Cada permissão é verificada separadamente. Os recursos temporários são removidos após a verificação.`,pending:`Pendente`,checking:`A verificar a leitura`,creating:`A criar recurso temporário`,reading:`A ler recurso temporário`,deleting:`A remover recurso temporário`,verified:`Verificado`,failed:`Requer atenção`,skipped:`Verificada após a aprovação do plano se necessário`}};function au(e,t){return iu[e][t]}var ou={en:{unavailable:`The check did not complete. Review the terminal result.`,"cleanup-pending":`Cleanup is unresolved; recovery is required before retrying.`,"secret-collision":`GitHub reported an existing Secret at the random test name. Setup stopped; inspect the GitHub Secret audit trail.`,unsupported:`No isolated probe exists for this permission yet.`},es:{unavailable:`La comprobación no terminó. Revisa el resultado en el terminal.`,"cleanup-pending":`La limpieza está pendiente; hay que recuperarla antes de reintentar.`,"secret-collision":`GitHub encontró un Secret existente con el nombre aleatorio de prueba. El setup se detuvo; revisa el historial del Secret.`,unsupported:`Aún no hay una prueba aislada para este permiso.`},fr:{unavailable:`La vérification n’a pas abouti. Consultez le résultat dans le terminal.`,"cleanup-pending":`Le nettoyage reste à terminer avant de réessayer.`,"secret-collision":`GitHub a trouvé un Secret existant sous le nom de test aléatoire. La configuration s’est arrêtée ; consultez l’historique du Secret.`,unsupported:`Aucun test isolé n’existe encore pour cette permission.`},pt:{unavailable:`A verificação não terminou. Consulte o resultado no terminal.`,"cleanup-pending":`A limpeza está pendente; é necessária recuperação antes de tentar novamente.`,"secret-collision":`O GitHub encontrou um Secret existente com o nome aleatório de teste. A configuração parou; consulte o histórico do Secret.`,unsupported:`Ainda não existe um teste isolado para esta permissão.`}},su={en:{closed:e=>`Temporary Issue #${e} was closed but could not be deleted. Remove it in GitHub before retrying.`,unresolved:e=>`Temporary Issue #${e} could not be deleted or confirmed closed. Inspect it in GitHub before retrying.`},es:{closed:e=>`El Issue temporal #${e} se cerró, pero no se pudo borrar. Elimínalo en GitHub antes de reintentar.`,unresolved:e=>`No se pudo borrar ni confirmar el cierre del Issue temporal #${e}. Revísalo en GitHub antes de reintentar.`},fr:{closed:e=>`L’Issue temporaire n° ${e} a été fermée mais n’a pas pu être supprimée. Supprimez-la dans GitHub avant de réessayer.`,unresolved:e=>`La suppression et la fermeture de l’Issue temporaire n° ${e} n’ont pas pu être confirmées. Vérifiez-la dans GitHub avant de réessayer.`},pt:{closed:e=>`A Issue temporária n.º ${e} foi fechada, mas não pôde ser eliminada. Elimine-a no GitHub antes de tentar novamente.`,unresolved:e=>`Não foi possível eliminar nem confirmar o fecho da Issue temporária n.º ${e}. Verifique-a no GitHub antes de tentar novamente.`}},cu={en:e=>`GitHub HTTP ${e}`,es:e=>`Error HTTP ${e} de GitHub`,fr:e=>`Erreur HTTP ${e} de GitHub`,pt:e=>`Erro HTTP ${e} do GitHub`};function lu(e,t){let n=Tl(t,e);if(n)return n;let r=/^issue-(closed|unresolved)-([1-9][0-9]*)$/u.exec(t);return r?su[e][r[1]](r[2]):/^http-[1-5][0-9]{2}$/u.test(t)?cu[e](t.slice(5)):t===`unavailable`||t===`cleanup-pending`||t===`secret-collision`||t===`unsupported`?ou[e][t]:ou[e].unavailable}var uu=H(` `),du=H(`
                                                                                                      • `),fu=H(`

                                                                                                          `);function pu(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=M(),o=X(t,`permissions`,8);function s(e){return o().progress?.filter(t=>t.requirementId===e).at(-1)}Tn(()=>V(o()),()=>{N(a,o().progress?.at(-1))}),En(),ji();var c=fu(),l=P(c),u=I(l,!0),d=L(l,2),f=I(d,!0),p=L(d,2),m=P(p),h=e=>{var t=Nr();R((e,n)=>W(t,`${e??``}: ${n??``}`),[()=>(V(ac),n(),V(o()),z(a),B(()=>ac(n(),o().requirements?.find(e=>e.id===z(a).requirementId)?.permission??z(a).requirementId))),()=>(V(au),n(),z(a),B(()=>au(n(),z(a).phase)))]),U(e,t)};G(m,e=>{z(a)&&e(h)}),D(p);var g=L(p,2);q(g,5,()=>(V(o()),B(()=>o().requirements??[])),e=>e.id,(e,t)=>{let r=A(()=>(z(t),B(()=>s(z(t).id))));var i=du();let a;var o=P(i),c=I(o,!0),l=L(o,2),u=P(l),d=I(u,!0),f=L(u),p=I(f),m=L(f),h=e=>{var t=uu(),i=I(t,!0);R(e=>W(i,e),[()=>(V(lu),n(),V(z(r)),B(()=>lu(n(),z(r).detail)))]),U(e,t)};G(m,e=>{V(z(r)),B(()=>z(r)?.phase===`failed`&&z(r).detail)&&e(h)}),D(l);var g=I(L(l,2),!0);D(i),R((e,t,n,o)=>{a=ui(i,1,``,null,a,{"permission-progress-done":z(r)?.phase===`verified`,"permission-progress-failed":z(r)?.phase===`failed`}),W(c,(V(z(r)),B(()=>z(r)?.phase===`verified`?`✓`:z(r)?.phase===`failed`?`!`:z(r)?`◌`:`·`))),W(d,e),W(p,`${t??``} · ${n??``}`),W(g,o)},[()=>(V(ac),n(),z(t),B(()=>ac(n(),z(t).permission))),()=>(V(ic),n(),z(t),B(()=>ic(n(),z(t).scope))),()=>(V(ic),n(),z(t),B(()=>ic(n(),z(t).level))),()=>(V(au),n(),V(z(r)),B(()=>au(n(),z(r)?.phase??`pending`)))]),U(e,i)}),D(g),D(c),R((e,t)=>{W(u,e),W(f,t)},[()=>(V(au),n(),B(()=>au(n(),`title`))),()=>(V(au),n(),B(()=>au(n(),`lead`)))]),U(e,c),k(),i()}function mu(e,t){return!t&&/^[A-Fa-f0-9]{16}$/u.test(e.trim())}var hu=H(`

                                                                                                          `);function gu(e,t){O(t,!1);let n=()=>Y(Q,`$setupLocale`,r),[r,i]=zi(),a=X(t,`busy`,8),o=X(t,`onPair`,8),s=X(t,`mode`,8,`pair`),c=M(``),l=M();async function u(){if(!mu(z(c),a()))return;let e=z(c).trim();N(c,``),await o()(e),await hr(),z(l)?.isConnected&&!z(l).disabled&&z(l).focus()}ji();var d=hu(),f=P(d),p=I(P(f),!0);D(f);var m=L(f,2),h=I(P(m),!0);D(m);var g=L(m,2),_=I(g,!0),v=L(g,2),y=P(v),b=I(y,!0),x=L(y,2);xi(x),Ai(x,e=>N(l,e),()=>z(l));var S=L(x,2),C=I(S,!0),w=L(S,2),ee=P(w);{let e=A(()=>(V(Z),V(s()),n(),B(()=>Z(s()===`pair`?`pairButton`:`takeOver`,n())))),t=A(()=>(V(mu),z(c),V(a()),B(()=>!mu(z(c),a()))));Qa(ee,{get label(){return z(e)},arrow:!0,onClick:u,get disabled(){return z(t)}})}D(w),D(v),D(d),R((e,t,n,r,i,o,s)=>{J(d,`aria-label`,e),W(p,t),W(h,n),W(_,r),W(b,i),x.disabled=a(),J(x,`placeholder`,o),W(C,s)},[()=>(V(Z),V(s()),n(),B(()=>Z(s()===`pair`?`pairTitle`:`takeOver`,n()))),()=>(V(Z),n(),B(()=>Z(`privateSession`,n()))),()=>(V(Z),V(s()),n(),B(()=>Z(s()===`pair`?`pairTitle`:`takeOver`,n()))),()=>(V(Z),V(s()),n(),B(()=>Z(s()===`pair`?`pairBody`:`readOnlyBody`,n()))),()=>(V(Z),n(),B(()=>Z(`pairLabel`,n()))),()=>(V(Z),n(),B(()=>Z(`pairPlaceholder`,n()))),()=>(V(Z),n(),B(()=>Z(`pairHelp`,n())))]),Cr(`submit`,v,e=>{e.preventDefault(),u()}),Ei(x,()=>z(c),e=>N(c,e)),U(e,d),k(),i()}var _u={"Could not close the local session. Check the terminal before trying again.":`The local session could not be confirmed closed. The result is retained. Check the terminal before trying again.`,"The local setup session is unavailable.":`The local setup session is unavailable. Check the terminal; you may need to restart setup.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Connection lost. The CLI may have stopped. Check the terminal before trying again.`,"Could not join this local session.":`Could not join this local session. Check the terminal and pair again.`,"Could not connect to the local setup session. Check the terminal and pair again.":`Could not connect to the local setup session. Check the terminal and pair again.`,"Pairing was rejected.":`Pairing was rejected. Check the code in the launching terminal.`,"Invalid local pairing response.":`The local pairing response was invalid. Restart setup from the terminal.`,"Could not pair this browser.":`Could not pair this browser. Check the terminal and try again.`,"The request was rejected.":`The local request was rejected. Refresh the page and check the terminal.`,"Could not submit this answer.":`Could not submit this answer. Refresh the page and try again.`,"Cancellation failed.":`Cancellation failed. Check whether setup has already started applying before closing.`,"Takeover failed.":`Could not take control. Re-enter the pairing code from the launching terminal.`,"Invalid local host or request context.":`The local request context was rejected. Open the exact URL printed in the terminal.`,"Invalid request origin.":`The request came from another origin. Open the exact local URL printed in the terminal.`,"JSON required.":`The local request format was invalid. Refresh the page and try again.`,"Too many pairing attempts. Restart setup.":`Too many incorrect pairing attempts. Restart setup from the terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Too many incorrect pairing attempts. Wait 30 seconds and try the code again; terminal setup remains available.`,"Incorrect pairing code. Check the terminal.":`Incorrect pairing code. Check the launching terminal.`,"Incorrect pairing code. Check the launching output.":`Incorrect pairing code. Check the launching output.`,"Pair this browser using the code printed by the CLI.":`Pair this browser using the code printed by the CLI.`,"This tab is read-only.":`This tab is read-only. Enter the pairing code again to take control.`,"Invalid answer.":`The answer was invalid. Review the current question and try again.`,"Control moved to another tab.":`Control moved to another tab. This tab is now read-only.`,"This question changed. Refresh the current state.":`This question changed. Refresh the page before answering again.`,"This setup has already started applying or ended.":`Setup has already started applying or ended. Inspect the current result before retrying.`,"Only the controller can close a finished session.":`Only the controlling tab can close this finished session.`,"Method not allowed.":`This local request is not allowed. Refresh the page.`,"Not found.":`The requested local page was not found. Open the URL printed in the terminal.`,"Invalid local request.":`The local request was invalid. Refresh the page and try again.`,"Body too large.":`The submitted answer is too large. Shorten it and try again.`,"JSON object required.":`The local request format was invalid. Refresh the page and try again.`,"Could not retry discovery.":`Could not refresh the GitHub suggestions. Retry or use verified manual entry.`,"Could not return to the previous question.":`Could not return to the previous question. Refresh the page and try again.`,"Invalid question revision.":`The question changed. Refresh the page before going back.`,"No earlier question is available here.":`There is no earlier question in this stage. Continue or return to the plan review.`,"Read-only verification failed.":`Read-only verification failed. Check the terminal and retry once.`,"Read-only verification failed. Check the terminal.":`Read-only verification failed. Check the terminal and retry once.`,"Read-only verification is unavailable or already running.":`Read-only verification is unavailable or already running. Check the current result before retrying.`},vu={en:_u,es:{"Could not close the local session. Check the terminal before trying again.":`No se ha podido confirmar el cierre de la sesión local. El resultado se conserva. Consulta la terminal antes de volver a intentarlo.`,"The local setup session is unavailable.":`La sesión local no está disponible. Revisa la terminal; quizá debas reiniciar la configuración.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Se perdió la conexión. Es posible que el CLI se haya detenido. Revisa la terminal antes de reintentar.`,"Could not join this local session.":`No se pudo acceder a esta sesión local. Revisa la terminal y vuelve a vincular el navegador.`,"Could not connect to the local setup session. Check the terminal and pair again.":`No se pudo conectar con la sesión local. Revisa la terminal y vuelve a vincular el navegador.`,"Pairing was rejected.":`Se rechazó la vinculación. Comprueba el código en la terminal que inició el proceso.`,"Invalid local pairing response.":`La respuesta de vinculación local no es válida. Reinicia la configuración desde la terminal.`,"Could not pair this browser.":`No se pudo vincular este navegador. Revisa la terminal y vuelve a intentarlo.`,"The request was rejected.":`Se rechazó la petición local. Actualiza la página y revisa la terminal.`,"Could not submit this answer.":`No se pudo enviar la respuesta. Actualiza la página y vuelve a intentarlo.`,"Cancellation failed.":`No se pudo cancelar. Comprueba si ya se han empezado a aplicar cambios antes de cerrar.`,"Takeover failed.":`No se pudo tomar el control. Vuelve a introducir el código de la terminal inicial.`,"Invalid local host or request context.":`Se rechazó el contexto de la petición local. Abre la URL exacta que aparece en la terminal.`,"Invalid request origin.":`La petición llegó desde otro origen. Abre la URL local exacta de la terminal.`,"JSON required.":`El formato de la petición local no es válido. Actualiza la página y reinténtalo.`,"Too many pairing attempts. Restart setup.":`Demasiados intentos de vinculación fallidos. Reinicia la configuración desde la terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Demasiados intentos de vinculación fallidos. Espera 30 segundos y vuelve a probar el código; puedes seguir con el setup en la terminal.`,"Incorrect pairing code. Check the terminal.":`Código de vinculación incorrecto. Comprueba la terminal inicial.`,"Incorrect pairing code. Check the launching output.":`Código de vinculación incorrecto. Comprueba la salida de inicio.`,"Pair this browser using the code printed by the CLI.":`Vincula este navegador con el código mostrado por el CLI.`,"This tab is read-only.":`Esta pestaña es de solo lectura. Introduce otra vez el código para tomar el control.`,"Invalid answer.":`La respuesta no es válida. Revisa la pregunta actual e inténtalo de nuevo.`,"Control moved to another tab.":`El control pasó a otra pestaña. Esta ahora es de solo lectura.`,"This question changed. Refresh the current state.":`La pregunta cambió. Actualiza la página antes de volver a responder.`,"This setup has already started applying or ended.":`La configuración ya empezó a aplicarse o terminó. Revisa el resultado antes de reintentar.`,"Only the controller can close a finished session.":`Solo la pestaña que tiene el control puede cerrar esta sesión finalizada.`,"Method not allowed.":`Esta petición local no está permitida. Actualiza la página.`,"Not found.":`No se encontró la página local solicitada. Abre la URL de la terminal.`,"Invalid local request.":`La petición local no es válida. Actualiza la página y reinténtalo.`,"Body too large.":`La respuesta enviada es demasiado larga. Acórtala y reinténtalo.`,"JSON object required.":`El formato de la petición local no es válido. Actualiza la página y reinténtalo.`,"Could not retry discovery.":`No se pudieron actualizar las sugerencias de GitHub. Reinténtalo o introduce datos verificados manualmente.`,"Could not return to the previous question.":`No se pudo volver a la pregunta anterior. Actualiza la página y reinténtalo.`,"Invalid question revision.":`La pregunta cambió. Actualiza la página antes de volver atrás.`,"No earlier question is available here.":`No hay una pregunta anterior en esta etapa. Continúa o vuelve a revisar el plan.`,"Read-only verification failed.":`Falló la comprobación de solo lectura. Revisa la terminal y vuelve a intentarlo una vez.`,"Read-only verification failed. Check the terminal.":`Falló la comprobación de solo lectura. Revisa la terminal y vuelve a intentarlo una vez.`,"Read-only verification is unavailable or already running.":`La comprobación de solo lectura no está disponible o ya se está ejecutando. Revisa el resultado antes de reintentar.`},fr:{"Could not close the local session. Check the terminal before trying again.":`La fermeture de la session locale n’a pas pu être confirmée. Le résultat est conservé. Consultez le terminal avant de réessayer.`,"The local setup session is unavailable.":`La session locale est indisponible. Vérifiez le terminal ; vous devrez peut-être relancer la configuration.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Connexion perdue. Le CLI s’est peut-être arrêté. Vérifiez le terminal avant de réessayer.`,"Could not join this local session.":`Impossible de rejoindre cette session locale. Vérifiez le terminal et associez de nouveau le navigateur.`,"Could not connect to the local setup session. Check the terminal and pair again.":`Impossible de se connecter à la session locale. Vérifiez le terminal et associez de nouveau le navigateur.`,"Pairing was rejected.":`L’association a été refusée. Vérifiez le code dans le terminal de lancement.`,"Invalid local pairing response.":`La réponse d’association locale est invalide. Relancez la configuration depuis le terminal.`,"Could not pair this browser.":`Impossible d’associer ce navigateur. Vérifiez le terminal et réessayez.`,"The request was rejected.":`La demande locale a été refusée. Actualisez la page et vérifiez le terminal.`,"Could not submit this answer.":`Impossible d’envoyer cette réponse. Actualisez la page et réessayez.`,"Cancellation failed.":`Annulation impossible. Vérifiez si des changements ont déjà commencé avant de fermer.`,"Takeover failed.":`Impossible de prendre le contrôle. Ressaisissez le code du terminal de lancement.`,"Invalid local host or request context.":`Le contexte de la demande locale a été refusé. Ouvrez l’URL exacte affichée dans le terminal.`,"Invalid request origin.":`La demande vient d’une autre origine. Ouvrez l’URL locale exacte du terminal.`,"JSON required.":`Le format de la demande locale est invalide. Actualisez la page et réessayez.`,"Too many pairing attempts. Restart setup.":`Trop de tentatives d’association incorrectes. Relancez la configuration depuis le terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Trop de tentatives d’association incorrectes. Attendez 30 secondes puis ressaisissez le code ; la configuration par terminal reste disponible.`,"Incorrect pairing code. Check the terminal.":`Code d’association incorrect. Vérifiez le terminal de lancement.`,"Incorrect pairing code. Check the launching output.":`Code d’association incorrect. Vérifiez la sortie de lancement.`,"Pair this browser using the code printed by the CLI.":`Associez ce navigateur avec le code affiché par le CLI.`,"This tab is read-only.":`Cet onglet est en lecture seule. Ressaisissez le code pour prendre le contrôle.`,"Invalid answer.":`La réponse est invalide. Revoyez la question actuelle et réessayez.`,"Control moved to another tab.":`Le contrôle est passé à un autre onglet. Celui-ci est maintenant en lecture seule.`,"This question changed. Refresh the current state.":`La question a changé. Actualisez la page avant de répondre de nouveau.`,"This setup has already started applying or ended.":`La configuration est déjà en cours d’application ou terminée. Inspectez le résultat avant de réessayer.`,"Only the controller can close a finished session.":`Seul l’onglet qui détient le contrôle peut fermer cette session terminée.`,"Method not allowed.":`Cette demande locale n’est pas autorisée. Actualisez la page.`,"Not found.":`La page locale demandée est introuvable. Ouvrez l’URL affichée dans le terminal.`,"Invalid local request.":`La demande locale est invalide. Actualisez la page et réessayez.`,"Body too large.":`La réponse envoyée est trop longue. Raccourcissez-la et réessayez.`,"JSON object required.":`Le format de la demande locale est invalide. Actualisez la page et réessayez.`,"Could not retry discovery.":`Impossible d’actualiser les suggestions GitHub. Réessayez ou saisissez des données vérifiées manuellement.`,"Could not return to the previous question.":`Impossible de revenir à la question précédente. Actualisez la page et réessayez.`,"Invalid question revision.":`La question a changé. Actualisez la page avant de revenir en arrière.`,"No earlier question is available here.":`Il n’y a pas de question précédente à cette étape. Continuez ou revenez à la révision du plan.`,"Read-only verification failed.":`La vérification en lecture seule a échoué. Consultez le terminal et réessayez une fois.`,"Read-only verification failed. Check the terminal.":`La vérification en lecture seule a échoué. Consultez le terminal et réessayez une fois.`,"Read-only verification is unavailable or already running.":`La vérification en lecture seule est indisponible ou déjà en cours. Consultez le résultat avant de réessayer.`},pt:{"Could not close the local session. Check the terminal before trying again.":`Não foi possível confirmar o encerramento da sessão local. O resultado foi preservado. Consulte o terminal antes de tentar novamente.`,"The local setup session is unavailable.":`A sessão local não está disponível. Verifique o terminal; poderá ter de reiniciar a configuração.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Ligação perdida. O CLI pode ter parado. Verifique o terminal antes de tentar novamente.`,"Could not join this local session.":`Não foi possível entrar nesta sessão local. Verifique o terminal e volte a emparelhar o navegador.`,"Could not connect to the local setup session. Check the terminal and pair again.":`Não foi possível ligar à sessão local. Verifique o terminal e volte a emparelhar o navegador.`,"Pairing was rejected.":`O emparelhamento foi recusado. Confirme o código no terminal de lançamento.`,"Invalid local pairing response.":`A resposta de emparelhamento local é inválida. Reinicie a configuração a partir do terminal.`,"Could not pair this browser.":`Não foi possível emparelhar este navegador. Verifique o terminal e tente novamente.`,"The request was rejected.":`O pedido local foi recusado. Atualize a página e verifique o terminal.`,"Could not submit this answer.":`Não foi possível enviar a resposta. Atualize a página e tente novamente.`,"Cancellation failed.":`Não foi possível cancelar. Confirme se a aplicação das alterações já começou antes de fechar.`,"Takeover failed.":`Não foi possível assumir o controlo. Volte a introduzir o código do terminal de lançamento.`,"Invalid local host or request context.":`O contexto do pedido local foi recusado. Abra o URL exato apresentado no terminal.`,"Invalid request origin.":`O pedido veio de outra origem. Abra o URL local exato do terminal.`,"JSON required.":`O formato do pedido local é inválido. Atualize a página e tente novamente.`,"Too many pairing attempts. Restart setup.":`Demasiadas tentativas incorretas de emparelhamento. Reinicie a configuração no terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Demasiadas tentativas incorretas de emparelhamento. Aguarde 30 segundos e volte a introduzir o código; a configuração no terminal continua disponível.`,"Incorrect pairing code. Check the terminal.":`Código de emparelhamento incorreto. Verifique o terminal de lançamento.`,"Incorrect pairing code. Check the launching output.":`Código de emparelhamento incorreto. Verifique a saída de lançamento.`,"Pair this browser using the code printed by the CLI.":`Emparelhe este navegador com o código apresentado pelo CLI.`,"This tab is read-only.":`Este separador é apenas de leitura. Reintroduza o código para assumir o controlo.`,"Invalid answer.":`A resposta é inválida. Reveja a pergunta atual e tente novamente.`,"Control moved to another tab.":`O controlo passou para outro separador. Este é agora apenas de leitura.`,"This question changed. Refresh the current state.":`A pergunta mudou. Atualize a página antes de voltar a responder.`,"This setup has already started applying or ended.":`A configuração já começou a ser aplicada ou terminou. Inspecione o resultado antes de tentar novamente.`,"Only the controller can close a finished session.":`Só o separador que detém o controlo pode fechar esta sessão terminada.`,"Method not allowed.":`Este pedido local não é permitido. Atualize a página.`,"Not found.":`A página local pedida não foi encontrada. Abra o URL apresentado no terminal.`,"Invalid local request.":`O pedido local é inválido. Atualize a página e tente novamente.`,"Body too large.":`A resposta enviada é demasiado longa. Encurte-a e tente novamente.`,"JSON object required.":`O formato do pedido local é inválido. Atualize a página e tente novamente.`,"Could not retry discovery.":`Não foi possível atualizar as sugestões do GitHub. Tente novamente ou introduza dados verificados manualmente.`,"Could not return to the previous question.":`Não foi possível voltar à pergunta anterior. Atualize a página e tente novamente.`,"Invalid question revision.":`A pergunta mudou. Atualize a página antes de voltar atrás.`,"No earlier question is available here.":`Não há uma pergunta anterior nesta etapa. Continue ou volte à revisão do plano.`,"Read-only verification failed.":`A verificação só de leitura falhou. Consulte o terminal e tente mais uma vez.`,"Read-only verification failed. Check the terminal.":`A verificação só de leitura falhou. Consulte o terminal e tente mais uma vez.`,"Read-only verification is unavailable or already running.":`A verificação só de leitura não está disponível ou já está em curso. Consulte o resultado antes de tentar novamente.`}};function yu(e,t){let n=vu[t]??_u;return Object.prototype.hasOwnProperty.call(n,e)?n[e]:Z(`unknownLocalError`,t)}var bu=H(`
                                                                                                          `),xu=H(`
                                                                                                          `),Su=H(` `,1),Cu=H(``),wu=H(`
                                                                                                          `,1),Tu=H(`
                                                                                                          `);function Eu(e,t){O(t,!1);let n=()=>Y(o,`$session`,i),r=()=>Y(Q,`$setupLocale`,i),[i,a]=zi(),o=Hi();Kr(()=>{let e=Q.subscribe(e=>{document.documentElement.lang=e,document.documentElement.dir=`ltr`,document.title=`Copilot · ${Z(`studio`,e)}`}),t=window.setInterval(()=>{n().paired&&!n().closed&&!n().view?.outcome&&o.poll()},900);return()=>{window.clearInterval(t),e()}});async function s(){window.confirm(Z(n().view?.batch?.phase===`applying`?`batchStopConfirm`:`cancelConfirm`,r()))&&await o.cancel()}async function c(e){let t=n().view?.promptRevision;t!==void 0&&await o.submit(t,e)}async function l(){let e=n().view?.promptRevision;e!==void 0&&await o.retryDiscovery(e)}async function u(){let e=n().view?.promptRevision;e!==void 0&&await o.back(e)}ji();var d=Tu(),f=P(d);{let e=A(()=>n().view?.journey),t=A(()=>n().view?.surface===`management`);la(f,{get journey(){return z(e)},get management(){return z(t)}})}var p=L(f,2),m=P(p);{let e=A(()=>n().view?.repository),t=A(()=>n().closed===!0);_a(m,{get repository(){return z(e)},get closed(){return z(t)}})}var h=L(m,2),g=P(h);Wa(g,{});var _=L(g,2),v=e=>{{let t=A(()=>Z(`translationPreviewTitle`,r())),n=A(()=>Z(`translationPreviewBody`,r()));to(e,{tone:`warning`,get title(){return z(t)},get message(){return z(n)}})}};G(_,e=>{r()!==`en`&&e(v)});var y=L(_,2),b=e=>{za(e,{get view(){return n().view}})};G(y,e=>{n().paired&&n().view?.surface!==`management`&&e(b)});var x=L(y,2),S=e=>{var t=bu(),i=L(P(t));D(t),R(e=>W(i,` ${e??``}`),[()=>Z(`reviewPass`,r(),{pass:String(n().view.journey.choiceReviewPass)})]),U(e,t)};G(x,e=>{n().view?.journey?.choiceReviewPass&&n().view.journey.choiceReviewPass>1&&!n().view.outcome&&e(S)});var C=L(x,2),w=e=>{var t=xu(),n=P(t);{let e=A(()=>Z(`sessionClosed`,r())),t=A(()=>Z(`sessionClosedBody`,r()));to(n,{tone:`success`,get title(){return z(e)},get message(){return z(t)}})}D(t),ii(t,(e,t)=>fl?.(e,t),()=>1),R(e=>J(t,`aria-label`,e),[()=>Z(`sessionClosed`,r())]),U(e,t)};G(C,e=>{n().closed&&e(w)});var ee=L(C,2),te=e=>{var t=Su(),i=F(t);{let e=A(()=>Z(`readOnly`,r())),t=A(()=>Z(`readOnlyBody`,r()));to(i,{tone:`warning`,get title(){return z(e)},get message(){return z(t)}})}gu(L(i,2),{mode:`takeover`,get busy(){return n().busy},get onPair(){return o.takeOver}}),U(e,t)};G(ee,e=>{!n().closed&&!n().controller&&n().view&&e(te)});var ne=L(ee,2),re=e=>{{let t=A(()=>Z(`attention`,r())),i=A(()=>yu(n().error,r()));to(e,{tone:`error`,get title(){return z(t)},get message(){return z(i)}})}};G(ne,e=>{n().error&&e(re)});var ie=L(ne,2),ae=e=>{{let t=A(()=>Z(n().view.message.tone===`success`?`checked`:n().view.message.tone===`warning`?`pleaseNote`:n().view.message.tone===`error`?`attention`:`progressUpdate`,r())),i=A(()=>Na(n().view.message,r()));to(e,{get tone(){return n().view.message.tone},get title(){return z(t)},get message(){return z(i)},get link(){return n().view.message.link}})}};G(ie,e=>{n().view?.message&&!n().view.outcome&&e(ae)});var oe=L(ie,2),se=e=>{{let t=A(()=>n().view.permissions?.report);Pl(e,{get report(){return z(t)}})}};G(oe,e=>{n().view?.batch&&e(se)});var ce=L(oe,2),le=e=>{gu(e,{get busy(){return n().busy},get onPair(){return o.pair}})},ue=e=>{var t=Su(),r=F(t),i=e=>{Qc(e,{get batch(){return n().view.batch},mode:`closed`,get controller(){return n().controller},get busy(){return n().busy}})};G(r,e=>{n().view.batch&&e(i)});var a=L(r,2);{let e=A(()=>!!n().view.batch),t=A(()=>n().view.surface===`management`),r=A(()=>n().view.permissions?.report);tu(a,{get batch(){return z(e)},get management(){return z(t)},get outcome(){return n().view.outcome},get detail(){return n().view.resultDetail},get permissionReport(){return z(r)},get setupPatCorrection(){return n().view.setupPatCorrection},get doctor(){return n().view.doctor},get controller(){return n().controller},get onDoctor(){return o.runDoctor},get onClose(){return o.close}})}U(e,t)},de=e=>{var t=wu(),i=F(t),a=P(i);gl(a,{get prompt(){return n().view.prompt},get revision(){return n().view.revision},get promptRevision(){return n().view.promptRevision},get controller(){return n().controller},get busy(){return n().busy},onSubmit:c,onRetryDiscovery:l,onBack:u}),Nl(L(a,2),{get view(){return n().view}}),D(i);var o=L(i,2),d=e=>{var t=Cu(),i=I(t,!0);R(e=>{t.disabled=n().busy,W(i,e)},[()=>Z(`cancelSetup`,r())]),wr(`click`,t,s),U(e,t)};G(o,e=>{n().controller&&n().view.journey?.current!==`Apply`&&e(d)}),U(e,t)},fe=e=>{var t=Su(),r=F(t);Qc(r,{get batch(){return n().view.batch},mode:`progress`,get controller(){return n().controller},get busy(){return n().busy},onStop:s});var i=L(r,2),a=e=>{pu(e,{get permissions(){return n().view.permissions}})};G(i,e=>{n().view.permissions?.progress?.length&&!n().view.permissions.report&&e(a)}),U(e,t)},pe=e=>{pu(e,{get permissions(){return n().view.permissions}})},me=e=>{{let t=A(()=>n().view?.resultDetail?.effects);ru(e,{get effects(){return z(t)}})}};G(ce,e=>{n().paired?n().view?.outcome?e(ue,1):n().view?.prompt?e(de,2):n().view?.batch?e(fe,3):n().view?.permissions?.progress?.length&&!n().view.permissions.report?e(pe,4):e(me,-1):e(le)});var he=L(ce,2),ge=P(he),_e=L(ge,2),ve=L(_e,2);D(he),D(h),D(p),D(d),R((e,t,n)=>{W(ge,`${e??``} `),W(_e,` ${t??``} `),W(ve,` ${n??``}`)},[()=>Z(`footerLocal`,r()),()=>Z(`footerCloud`,r()),()=>Z(`footerGithub`,r())]),U(e,d),k(),a()}Tr([`click`]),Vr(Eu,{target:document.getElementById(`app`)}); \ No newline at end of file diff --git a/build/web/index.html b/build/web/index.html index 7d5c8d4cc..99f0e1f78 100644 --- a/build/web/index.html +++ b/build/web/index.html @@ -5,7 +5,7 @@ Copilot · Setup studio - + diff --git a/docs/agents/repository-collaboration.mdx b/docs/agents/repository-collaboration.mdx index 540dc108a..7e8cd5a42 100644 --- a/docs/agents/repository-collaboration.mdx +++ b/docs/agents/repository-collaboration.mdx @@ -15,6 +15,13 @@ Repository collaborator agents use the same public controls as human contributor - `.copilot/setup-manifest.json`: generator version, profile digest, artifact roles, and SHA-256 hashes. - an optional marker-bounded pointer in root `AGENTS.md`. +Manifest hashes use LF-normalized content. For the `AGENTS.md` entry with +`role: "pointer"`, the hash covers only the managed block, including both marker +comments. It excludes repository-authored text outside the block and any newline +after the end marker. A whole-file `shasum -a 256 AGENTS.md` can therefore differ +from the manifest without indicating drift. See [pointer hash verification](/agents/repository-guidance-troubleshooting#agentsmd-pointer-hash-scope) +for a check using the same scope as setup and doctor. + The profile contains only enabled kinds, effective forms and labels, required fields, branch roles, relevant release/hotfix workflow names, PR linkage, and deployment boundaries. It contains no token, Secret, arbitrary action input, executable command, or provider response. The generated guide links to the shared documentation in `vypdev/copilot` through absolute HTTPS URLs. These links follow the source repository's `master` documentation, so destination repositories do not need a copied documentation tree. Links to installed artifacts, such as `repository-profile.json`, remain relative to the generated guide. diff --git a/docs/agents/repository-guidance-troubleshooting.mdx b/docs/agents/repository-guidance-troubleshooting.mdx index 197719df4..e226fe6f8 100644 --- a/docs/agents/repository-guidance-troubleshooting.mdx +++ b/docs/agents/repository-guidance-troubleshooting.mdx @@ -28,3 +28,50 @@ Setup writes each generated artifact atomically and the manifest last. Approved Older generated guides may link to `../docs/agents/` files that were never installed in the destination repository. Update Copilot and rerun setup with the same configuration to replace an unchanged, setup-owned guide with absolute links to the shared documentation. The previous guide is backed up. If the guide was edited or is not setup-owned, preserve those edits and follow the normal conflict recovery above. Do not repair drift by editing `.copilot/repository-profile.json` or its hashes. Change the setup configuration and rerun setup so forms, Variables, workflows, guide, skill, and manifest converge from one plan. + +## AGENTS.md pointer hash scope + +In `.copilot/setup-manifest.json`, the `AGENTS.md` record has `role: "pointer"`. +Its SHA-256 covers only the block from `` +through ``, including both markers. Hashing +normalizes CRLF to LF. Text outside that block, including a trailing newline +after the end marker, is excluded so repository-authored instructions remain +outside setup ownership. + +Comparing this record with `shasum -a 256 AGENTS.md` hashes different content. +Even a freshly generated pointer-only file ends with a newline outside the +managed block, so a different whole-file hash is expected. This alone is not +generated-file corruption or drift. + +Use `copilot doctor --config copilot.setup.yml` to inspect the installation, or +run this read-only check from the repository root with Node.js: + +```bash +node <<'NODE' +const fs = require('node:fs'); +const { createHash } = require('node:crypto'); +const manifest = JSON.parse(fs.readFileSync('.copilot/setup-manifest.json', 'utf8')); +const record = manifest.artifacts['AGENTS.md']; +if (record?.role !== 'pointer') throw new Error('No managed AGENTS.md pointer record.'); +const content = fs.readFileSync('AGENTS.md', 'utf8').replace(/\r\n/g, '\n'); +const start = ''; +const end = ''; +const from = content.indexOf(start); +const to = content.indexOf(end); +if (content.split(start).length !== 2 || content.split(end).length !== 2 || to < from) { + throw new Error('Missing, duplicate, or malformed pointer markers; inspect with doctor.'); +} +const block = content.slice(from, to + end.length); +const actual = createHash('sha256').update(block, 'utf8').digest('hex'); +console.log({ expected: record.sha256, actual, matches: actual === record.sha256 }); +process.exitCode = actual === record.sha256 ? 0 : 1; +NODE +``` + +If this scoped check differs, inspect changes inside the markers and follow the +normal drift recovery above. Preserve surrounding instructions and review the +managed block before reconciling; do not replace its manifest hash with a +whole-file digest. + +For workflow linter errors about `concurrency.queue`, see +[validating `queue: max`](/issues/deployment-orchestration#validating-queue-max). diff --git a/docs/bugbot/failure-scenarios.mdx b/docs/bugbot/failure-scenarios.mdx index 0264b84cd..14e2c3734 100644 --- a/docs/bugbot/failure-scenarios.mdx +++ b/docs/bugbot/failure-scenarios.mdx @@ -30,6 +30,22 @@ description: Diagnose terminal failures across detection, publication, autofix, Use the canonical **Bugbot status** card and `Copilot / Review` Check for the aggregate state. Run `/copilot recheck` to repair the generated status block; the historical snapshot text is intentionally retained. + + A uniquely matched finding keeps its original finding ID and native thread + link, even when its current title or location changes. Upgrade the Action + and run one `/copilot recheck` on the current PR head to refresh this evidence. + Unknown rows include their exact finding IDs for investigation. If two + retained records could match, inspect both threads and compare the causal + defect and required fix. Keep an ambiguous record unresolved; use the + documented evidence-based dismissal only for a verified duplicate or false + positive. Never resolve an unknown merely because a later scan omits it. + + A candidate whose publication failed has no durable native finding marker. + Its unknown row describes that failed attempt; a later scan can produce a + different candidate set. Disappearance from the later aggregate does not + prove a fix or a dismissal. Preserve the failed run's finding IDs and inspect + those concerns against the exact head before relying on the later review. + Do not treat the review as complete. Open **Incomplete coverage**, review every named source, and manually inspect omitted items. Prompt-sized PR diffs are partitioned exhaustively, so `diff` partial now indicates a provider enumeration limit rather than the old single-prompt packing omission. Split a PR that exceeds the provider scope; for comment/history/rule caps, reduce the relevant scope when practical or restore provider access before rerunning. The context limits are fixed safety boundaries, not configuration knobs. Retained evidence may produce findings, but Bugbot cannot declare the whole PR clean or resolve omitted history. Even with zero observed findings, the Review Check remains neutral, `state:ready` is removed, and lifecycle becomes `state:blocked` plus `state:awaiting-maintainer`. Repeating `/copilot recheck` against the same capped provider evidence cannot improve coverage. A provider or permission error is `unavailable` and aborts before analysis; correct access or wait for the rate limit before retrying. Every final-read surface is tracked independently, so an empty verified result is not confused with a failed read. A previously observed non-clean finding that disappears remains visible as `unknown`; only fully resolved findings may be omitted safely. @@ -51,6 +67,13 @@ description: Diagnose terminal failures across detection, publication, autofix, Bugbot updates historical review blocks in sequential batches of 20, up to 100 per run. If more remain, or a batch fails, the status card and Check report the exact unattempted count and the Action uses `workflow.presentation-pending` for a budget remainder. This does not mean the provider is unavailable or that the diff was only partly analyzed. Re-run `/copilot recheck` after inspecting any separate write failure; successful updates are kept and already-current blocks are skipped. The canonical status card remains the aggregate view throughout. + + Successful publication can precede a later failed marker/thread mutation. The recovery details identify the publication or resolution stage, exact operation, affected finding (plus batch count), HTTP status and provider request reference when available. Missing provider metadata is explicitly unavailable. Existing reviews, comments and durable dismissal intent are retained; a zero completed-publication count on a failed run does not prove that no native review exists. + + Correct permanent credential/access or contract failures before retrying. For a transient outage or rate limit, restore provider availability first, then run `/copilot recheck` on the same PR. The normal fresh provider read reconciles existing comments and threads rather than recreating completed effects. Do not delete a review or install an application dependency merely to clear an unrelated finding-publication failure. + + **Incomplete coverage** remains separate. `human-conversation` lists retained, omitted and truncated counts plus `truncated-source-ids` for exact retained records, such as `issue:6311517518` (a general issue/PR comment ID) or `review:PRRC_50` (an inline comment node ID). Inspect that source from the linked PR/issue, preserve its substantive decisions and reduce only redundant text before rechecking. Source IDs contain no comment text. A mutation retry never upgrades incomplete conversation evidence to complete. + See [Verification commands](/bugbot/verification-commands) and [Security & Operations](/security-operations). diff --git a/docs/bugbot/finding-publication.mdx b/docs/bugbot/finding-publication.mdx index de78b7b3c..89c55ec18 100644 --- a/docs/bugbot/finding-publication.mdx +++ b/docs/bugbot/finding-publication.mdx @@ -30,4 +30,14 @@ When the agent supplies an exact replacement, Bugbot renders a native GitHub sug Finding markers carry both a location fingerprint and a location-independent semantic fingerprint based on category plus an exact code snippet, symbol, or title fallback. An explicit provider id is reused only when its local identity is compatible; matching then falls back to location and, only when unambiguous, semantics. This keeps one thread across nearby line movement, rebases, and file renames without allowing a similar but unrelated finding to hijack or silently resolve it. Markers are loaded only when both the authenticated bot identity and comment author are known and match. Manual thread resolution becomes a durable dismissal and is not undone by a model response. +When a current report uniquely matches a retained finding, its original finding +ID remains in the marker while the title, location and explanation are refreshed +on the same linked thread. Analysis, comment limits, publication and final counts +use that same ID, so a changed model ID cannot leave an extra unknown record. +Multiple current reports of that uniquely matched identity consume one comment +slot. Ambiguous location or semantic matches retain separate evidence; Bugbot +does not select the first provider result or resolve a suspected duplicate. +An unrelated report that reuses another finding's ID receives a short local +collision-free ID so both concerns retain separate evidence and threads. + Publication MUST complete before a finding is marked resolved. Within each reopen or resolution transition the marker is updated before the native thread, making retries convergent. After mutation, Bugbot MUST re-read provider state; invalid responses, unsafe paths, malformed identifiers, missing expected publications, or publication failures are terminal for that finding and MUST NOT produce a false resolved state. diff --git a/docs/bugbot/quality-observability.mdx b/docs/bugbot/quality-observability.mdx index 016f64400..084f63ec6 100644 --- a/docs/bugbot/quality-observability.mdx +++ b/docs/bugbot/quality-observability.mdx @@ -5,7 +5,16 @@ description: Measure Bugbot accuracy, latency, outcomes, feedback, and regressio # Bugbot quality and observability -Bugbot separates deterministic evaluator checks from optional, cost-bearing model benchmarks. The versioned corpus at `quality/bugbot/corpus.v1.json` contains 30 positive and negative synthetic cases across TypeScript/TSX, Python, Go, SQL, Java, Rust, YAML workflows, shell, Terraform, C#, Kotlin, and Markdown. Ground truth is never included in the model prompt. +Bugbot separates deterministic evaluator checks from optional, cost-bearing model benchmarks. The versioned corpus at `quality/bugbot/corpus.v1.json` contains 38 positive and negative synthetic cases across TypeScript/TSX, Python, Go, SQL, Java, Rust, YAML workflows, shell, Terraform, C#, Kotlin, and Markdown. Ground truth is never included in the model prompt. + +The #655 cases cover branch coverage enabled through repository configuration, +inherited HTTP/1.0 connection behavior, correct arithmetic, short-circuit guards, +validation through helpers, and mutually exclusive render paths. Positive +controls still require detection of an unsafe guard order and simultaneous +duplicate IDs. The reviewer is instructed to check effective settings, defaults, +call paths and counterevidence before reporting a defect. Passing the checked-in +predictions proves the evaluator contract; measuring a model's improvement still +requires running the real-agent benchmark and inspecting its predictions. ## Quality gates diff --git a/docs/configuration-checklist.mdx b/docs/configuration-checklist.mdx index f1f0f5d08..027b117e0 100644 --- a/docs/configuration-checklist.mdx +++ b/docs/configuration-checklist.mdx @@ -4,6 +4,10 @@ description: Required checks before enabling Copilot automation. --- # Configuration checklist +For compact comment callbacks, verify runner 2.336.0+, platform support and the +Actions policy for Copilot's reusable coordinator. Review the retained runner and +any custom bootstrap migration using the [upgrade guide](/security-operations/operations/upgrade-rollback#upgrade-an-existing-copilot-repository). + Before enabling repository verification or automated fixes, provision required project runtimes in **each** executing job and add the reviewed [runtime declaration](/security-operations/operations/verification#repository-verification-prerequisites). diff --git a/docs/configuration.mdx b/docs/configuration.mdx index 555c142eb..57924342c 100644 --- a/docs/configuration.mdx +++ b/docs/configuration.mdx @@ -5,6 +5,13 @@ description: Detailed configuration options for Copilot # Configuration Options +The generated comment callbacks delegate their whole job to +`vypdev/copilot/.github/workflows/copilot_comment_runtime.yml@v3`. The coordinator +reads this repository's existing Variables and explicitly forwarded Secrets; +project setup remains isolated from provider/PAT inputs. Setup stores the reviewed +runner route as JSON in the call's `with.runs-on`, including label arrays and group +objects. See [verification and coordinator configuration](/security-operations/operations/verification#repository-owned-setup). + For a new installation, use [web setup](/setup-web). To configure a specific outcome, start with the [goal guides](/guides); they connect setup choices, runtime configuration and verification. This page is the input and scope reference. Copilot provides extensive configuration options to customize your workflow. Use the tabs below to jump to the category you need. @@ -63,6 +70,7 @@ PR bot approval uses the versioned `pullRequestApproval` setup object and `PR_AP ## Branch Management - `issue-managed-branches`: Create and verify a linked branch after `in-progress` (default: "true") + - `verification-setup`: Run the trusted main-branch composite action before each configured verification command in generated GitHub Actions callbacks (default: "false"). Setup's terminal/web question maps `repository.verificationSetup` to `VERIFICATION_SETUP` using the existing storage/reuse precedence. Setup creates `.github/actions/copilot-verification-setup/action.yml` only if missing and preserves an existing action and its assets. Customize the failing starter and review it onto `MAIN_BRANCH` before enabling; generation and activation do not prove readiness. See [repository-owned setup](/security-operations/operations/verification#repository-owned-setup) and [upgrade/rollback](/security-operations/operations/upgrade-rollback#upgrade-an-existing-copilot-repository). - `pre-branch-sdd`: Require a validated SDD before implementation for eligible issues (default: "false") - `branch-management-emoji`: Emoji for branched issues (default: "🧑‍💻") @@ -326,6 +334,14 @@ When updating the configuration (for example, after a push or label change), Cop The hidden block is owned by Copilot. Do not add third-party or manually managed keys to it; they are outside the contract and will be removed on the next write. +An invalid stored block fails with `configuration.invalid` and is not retryable +without correction. Its diagnostic identifies the issue/PR, distinguishes a +missing schema from an unsupported version or malformed state, and states the +required version. An absent block remains distinct from invalid stored state. +Follow [stored-configuration recovery](/security-operations/operations/troubleshooting#unsupported-stored-configuration) +before editing or removing a block; never add a version number merely to bypass +validation. No automatic migration or reset is performed. + ### Persistence failures If GitHub cannot read or update the issue description, the run fails closed after diff --git a/docs/development/architecture.mdx b/docs/development/architecture.mdx index bc828dca3..1407ee2db 100644 --- a/docs/development/architecture.mdx +++ b/docs/development/architecture.mdx @@ -4,6 +4,28 @@ description: Clean Architecture boundaries for agent execution and workflow auto --- # Architecture +Issue/review comment callbacks are compact entrypoints into the Copilot-owned +`copilot_comment_runtime.yml` reusable workflow. One job owns the existing native +worker, project composite setup, continuations and reverse post cleanup. Internal +`uses: $/` references bind all runtime phases to the called workflow commit. The +pure known-workflow/runner contract lives in `copilot_comment_workflow.ts`; existing +setup adapters retain YAML/filesystem inspection, preview/Apply and migration. +Safe Variable/default bindings are shared by the workflow generator and maintenance +reader. See the [coordinator SDD](https://github.com/vypdev/copilot/blob/develop/specs/copilot-comment-workflow-coordinator.md) +and [operational contract](/security-operations/operations/verification#repository-owned-setup). + +Verification setup onboarding uses the shared repository questionnaire and the +existing `repository.verificationSetup` boolean. The package supplies a native +composite starter under `setup/actions/`; the filesystem adapter inspects only +the fixed consumer path and creates it exclusively when absent. Existing action +contents and auxiliaries are outside generator overwrite and retirement ownership. +Installation review records create/preserve/blocked, activation and trusted main +as semantic facts shared by terminal, web and batch PR presentation. Batch Git +inventory permits the exact entrypoint and rejects unsafe parent/file modes or +case collisions before rendering. See [the onboarding +SDD](https://github.com/vypdev/copilot/blob/develop/specs/verification-setup-onboarding.md) +and the [verification guide](/security-operations/operations/verification#repository-owned-setup). + ### Setup runner profiles and installation parity `setup_runner_policy` owns pure registry validation, precedence, fixed job roles, @@ -633,3 +655,40 @@ The trusted credential health adapter is GET-only and pins packaged workflow content, default SHA, run identity, freshness and unchanged Secret metadata. It never inherits the legacy bootstrap or dispatch adapter. Architecture/cycle, SDK contract, replay, drift and presentation tests enforce these boundaries. + +## Repository verification setup + +The optional [repository-owned composite action](/security-operations/operations/verification#repository-owned-setup) +is captured with all reviewed auxiliary files at comment-route composition from +an immutable trusted main commit. Acquisition errors remain deferred. Existing +actor, fork, native-head and workspace gates decide whether verification is reached. + +Branch synchronization and shared automated commit preflight request the same +`untrusted + verifyRuntimePrerequisites` port intent. The Git adapter creates a +fresh private HOME. Its infrastructure pauses the admitted same-job worker exactly +before preflight, stages the trusted action in local Git metadata and lets GitHub Actions execute the +native YAML. Continuation matches the operation/request/run/job, validates the unchanged candidate identity and bounded runtime directories, then +resolves executables against the private runtime PATH and runs the existing probes +and verifier. Staging survives native post steps; trusted Copilot post phases +use the initially pinned absolute Git executable to reload pinned Git objects and verify their original digest before native post +execution, then the initial Action post step cleans staging and profiles. The agent and publication are not replayed. + +Pure policy owns limits, schemas and sanitized errors. Snapshot, staging, protocol, +profile and controller adapters own Git/filesystem/process details; application +use cases retain mutation policy. Native action post steps can use dependency-only +profiles until the original Action's final post cleanup removes them. They are +never reused by later commands. Native step failure/cancellation blocks publication +and triggers existing recovery. A final cleanup guard stops a leftover worker. + +Source callbacks first copy the Action manifest and runtime outside the mutable +workspace, so rebuilding a candidate cannot replace continuation or post code. +Remote installed Actions already use the runner action cache. Only native callback +phases register active Copilot post behavior. + +The workflow generator emits twenty conditional setup/continuation slots and a +completion step in each actual mutation callback. Structural validation compares +the complete native contract, including timeout and runtime-only setup environment. +All six configuration callbacks forward the opt-in, while only issue/review-comment +mutation compositions execute it. Push analysis does not become a verifier. +Native platform acceptance runs real `uses`/`run` on Linux, Windows and macOS; +local real-Git integration covers exact managed-ref push and abort behavior. diff --git a/docs/development/release-process.mdx b/docs/development/release-process.mdx index c13dc9b4d..b2660e44b 100644 --- a/docs/development/release-process.mdx +++ b/docs/development/release-process.mdx @@ -36,7 +36,8 @@ prepare release -> production PR -> accepted production SHA For unattended completion, enable repository auto-merge and active required validation on both production and development targets. This repository requires -GitHub Actions `CI Check` on `master` and `develop`; RepoWise is advisory. +GitHub Actions `CI Check` on `master` and `develop`; RepoWise is optional and +runs only through manual dispatch. Default `auto` mode enables native auto-merge while a managed PR must wait. When GitHub already reports the PR ready, Copilot requests a normal merge pinned to its verified head SHA. This also handles pending advisory checks, without diff --git a/docs/development/testing.mdx b/docs/development/testing.mdx index 157088acf..2c05ee01a 100644 --- a/docs/development/testing.mdx +++ b/docs/development/testing.mdx @@ -104,20 +104,48 @@ local topology before an architecture review with Graphify, and use the RepoWise index-only health/dead-code reports to distinguish current complexity from history-based churn signals: -The required `RepoWise code health` workflow publishes its index and health -reports. Its dead-code and history-security scans have separate time and memory limits; -the Job Summary and artifact status identify an incomplete advisory scan -instead of claiming that it passed. -For PRs, pushes and merge groups, history-security scans cover the native event -base through the checked-out HEAD, including commits that introduced and then -removed a finding. The base must be a valid commit and an ancestor of HEAD; -missing or unrelated evidence produces an incomplete advisory result. The -artifact records both immutable bounds. Manual dispatch scans the complete -reachable history within the same limits; a successful event-range scan is -not evidence of a complete historical audit. -Repository-owned PRs, pushes and merge groups run RepoWise and `CI Check` on -self-hosted Ubuntu `codex` runners. Fork PRs use GitHub-hosted Ubuntu for -these checks. The automatic setup fixture matrix remains hosted on three +`RepoWise Code Health` is an optional manual workflow. PRs, pushes and merge +groups do not launch it, and it must not be a required branch check. To run an +analysis, open **Actions → RepoWise Code Health → Run workflow**, select a +reviewed repository branch, and launch it. The CLI equivalent for development is +`gh workflow run repowise.yml --ref develop`. The workflow already exists on the +default branch, as required for [manual dispatch](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/manually-run-a-workflow). + +Open the run's Job Summary for the analyzed commit, phase status, elapsed time +and peak RSS. Download `repowise-code-health` (14 days) for health Markdown/JSON, +safe-only dead-code JSON, the security JSON aggregate, index/phase logs, +`revision.txt`, `scope.json`, `timings.json` and `history-resources.json`. + +The pinned RepoWise 0.58.0 builds one fresh standard index and exports its stored +health/dead-code results. Index git analytics retain a 500-commit limit; security +separately covers **all reachable history**, including removed secrets and generated +bundles, using RepoWise's supported source extensions, secret patterns and +allowlists. Two spawned workers read one blob at a time each, with at most two +tasks/results in flight and results consumed in upstream order. Worker failures +propagate. The adapter avoids +computing code-smell findings discarded by history mode. This remains an advisory +signal scanner; an aggregate with no findings is not proof that no secrets exist. + +Indexing has a 900-second/4 GiB virtual-memory cap. Each health export and dead-code +has a 60-second/2 GiB cap; security has a 1200-second/2 GiB coordinator cap and +a 1 GiB cap per worker, inside the +40-minute job. Limits apply per process; reported peak RSS is the largest process, +not aggregate simultaneous memory. These budgets accommodate the roughly 9 GB of +historical JavaScript without retaining all of it in memory. Two available CPU +cores are recommended for the bounded parallel history scan. + +An interrupted scan, Git error, stale/failed index or invalid report marks analysis +incomplete and fails this optional run. Completed reports and diagnostics still +upload; invalid JSON is removed. Inspect the named phase log, fix the cause, then +rerun. A newer manual run for the same ref cancels the older one; cancellation or +runner loss can prevent publication. No manual run blocks automatic CI. Upgrading +the pin requires the Python compatibility fixtures, which run before every manual +analysis. They compare secret detection with upstream and verify deleted secrets, +other refs, bounded reads and failures. + +Manual RepoWise runs use self-hosted Ubuntu `codex` runners. `CI Check` uses +that pool for repository-owned PRs and pushes; fork PRs and all merge groups +use disposable GitHub-hosted Ubuntu runners. The automatic setup fixture matrix remains hosted on three operating systems, with service-runner fixtures available by manual dispatch. Runner routing is contract-checked, but actual runner availability and remote results require evidence from the corresponding Actions runs. @@ -184,6 +212,23 @@ or model-only `READY` response cannot certify real tool execution. See [tool smoke evidence](/security-operations/operations/smoke-tests). +## Permission journal integration budget + +`setup_permission_operator_actions.test.ts` uses a real temporary directory and +journal, including file writes, `fsync`, atomic replacement, recovery and cleanup. +Its tests and hooks have a bounded 30-second Jest budget. A rejected dispatch +alone flushes six journal versions, so the generic five-second unit-test deadline +can expire during slow filesystem operations under hosted Windows coverage. + +For issue #577, adding 900 ms to each real journal flush reproduced the original +five-second timeout. With the 30-second integration budget, all eight cases +completed, including the two-transaction recovery case. This demonstrates the +budget mismatch; historical CI logs do not identify the underlying host storage +or scheduling delay. Keep real persistence and every authority/cleanup assertion. +Fake timers cover Actions polling; recovery switches back to real timers before +starting its next journal transaction. Other suites retain their existing budgets. +Hosted Windows full coverage remains the platform verification gate. + ## Semantic component rendering The component suites use a real Vite/Svelte SSR renderer isolated from Jest. @@ -219,6 +264,11 @@ budgets and contract validators. Native macOS self-hosted acceptance remains pending until the operator restores the Apple Intel runners and macOS row; hosted macOS results cannot substitute for that evidence. +Hosted Windows has a 30-minute job limit; hosted Ubuntu and macOS retain +20 minutes. This includes native setup, package checks, isolated fixtures and +the full coverage suite. A timeout is missing evidence and must be corrected +or rerun before merging; it never substitutes for successful verification. + `upload_windows_coverage` defaults to `false`. Coverage export is a separate explicit opt-in, never a prerequisite for hosted fixture validation. Set `windows_startup_probe=true` with coverage export disabled for the isolated diff --git a/docs/features.mdx b/docs/features.mdx index 9f950a751..e66982ccc 100644 --- a/docs/features.mdx +++ b/docs/features.mdx @@ -166,10 +166,10 @@ decorative media or expose configuration for it. ## Workflow concurrency and sequential execution - **Two coordination policies:** durable mutation workflows preserve every admitted event in a workflow-local queue. Commit and Pull Request each have a separate repository/branch latest-revision lane, so paired events cannot cancel one another. + **Coordination policies:** issue and comment mutation workflows preserve admitted events in a workflow-local queue. Deployment mutations use a shared issue-scoped native queue. Commit and Pull Request each have a separate repository/branch latest-revision lane, so paired events cannot cancel one another. -GitHub's native [concurrency](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency) can cancel in-progress runs when a newer one starts and can retain only one pending run. The replaceable branch jobs therefore use event-specific keys: Commit uses `copilot-push-${{ github.repository }}-${{ github.ref_name }}`; Pull Request code/lifecycle analysis uses the branch key with an `analysis` suffix; and the dedicated review-state workflow uses the same branch key with a `review-state` suffix. Each lane cancels only its own obsolete revision. Commit still synchronizes issue progress, then Bugbot performs a read-only exact-head lookup because a `push` payload does not contain PR identity. A validated open same-repository PR makes the push stop before review-context loading or agent invocation; the PR `synchronize` event exclusively owns review for that head. This prevents duplicate reviews without letting a push or review-state event cancel useful PR analysis. Branches without an open PR retain push-time Bugbot. Metadata-only `pull_request: edited` events are not subscribed because Copilot changes the PR body itself; excluding them prevents self-generated run cascades and preserves human metadata edits. Application-level head guards prevent an older run from updating a newer PR, and the next code/lifecycle run repairs any durable half-transition discovered after cancellation. Fixed workflow/job names expose analysis and review-state checks without leaking an unevaluated expression when GitHub skips bot-authored events. A separate merge-group workflow avoids a skipped duplicate on normal PRs while deliberately preserving the exact `Copilot - Pull Request` required-check context for branch-protection compatibility. +GitHub's native [concurrency](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency) can cancel in-progress runs when a newer one starts. Its default `queue: single` retains only one pending run; `queue: max` allows up to 100 pending jobs or workflow runs when `cancel-in-progress` is `false` or omitted. The replaceable branch jobs therefore use event-specific keys: Commit uses `copilot-push-${{ github.repository }}-${{ github.ref_name }}`; Pull Request code/lifecycle analysis uses the branch key with an `analysis` suffix; and the dedicated review-state workflow uses the same branch key with a `review-state` suffix. Each lane cancels only its own obsolete revision. Commit still synchronizes issue progress, then Bugbot performs a read-only exact-head lookup because a `push` payload does not contain PR identity. A validated open same-repository PR makes the push stop before review-context loading or agent invocation; the PR `synchronize` event exclusively owns review for that head. This prevents duplicate reviews without letting a push or review-state event cancel useful PR analysis. Branches without an open PR retain push-time Bugbot. Metadata-only `pull_request: edited` events are not subscribed because Copilot changes the PR body itself; excluding them prevents self-generated run cascades and preserves human metadata edits. Application-level head guards prevent an older run from updating a newer PR, and the next code/lifecycle run repairs any durable half-transition discovered after cancellation. Fixed workflow/job names expose analysis and review-state checks without leaking an unevaluated expression when GitHub skips bot-authored events. A separate merge-group workflow avoids a skipped duplicate on normal PRs while deliberately preserving the exact `Copilot - Pull Request` required-check context for branch-protection compatibility. For non-replaceable issue and comment mutations, Copilot adds an application-level queue per workflow: every started run waits for earlier active runs of that same workflow, so intermediate events are not discarded by a native concurrency group. Runs triggered by the PAT owner that would only re-trigger the normal pipeline complete before entering this queue. @@ -221,7 +221,7 @@ jobs: project-ids: '2,3' ``` -Durable mutation workflows deliberately do not use a GitHub Actions `concurrency` block: native cancellation retains only one pending run and can discard intermediate issue, comment, or release mutations. The Commit and Pull Request templates are the deliberate exception for their own replaceable branch revisions, but they use distinct groups and cannot cancel one another. Native concurrency also remains appropriate for replaceable read-only workflows such as CI and RepoWise. +Issue and comment mutation workflows use the application-level queue above to preserve intermediate events. Release, hotfix, and managed-PR deployment mutations use native `concurrency` with `queue: max` and `cancel-in-progress: false`, which preserves pending deployment runs and is valid GitHub Actions syntax. Without `queue: max`, native concurrency retains only one pending run and can discard intermediate mutations. See [deployment concurrency validation](/issues/deployment-orchestration#validating-queue-max) before changing generated workflows in response to a linter error. Commit and Pull Request use separate native groups with cancellation for their own replaceable branch revisions, so they cannot cancel one another. Native concurrency also remains appropriate for replaceable read-only workflows such as CI and the optional, manually dispatched RepoWise analysis. --- diff --git a/docs/issues/comment-commands.mdx b/docs/issues/comment-commands.mdx index cc42960d2..4e1c285ef 100644 --- a/docs/issues/comment-commands.mdx +++ b/docs/issues/comment-commands.mdx @@ -5,6 +5,12 @@ description: Use @vypbot from issues and pull requests for help, analysis, plann # Comment commands +Generated comment workflows call one Copilot-owned coordinator. The command, +project dependency setup, verification and cleanup still run in the same job; +inspect the comment run's nested `Copilot` job for preparation/continuation logs. +Command permissions and result cards retain their existing behavior. See +[repository setup and verification](/security-operations/operations/verification#repository-owned-setup). + Branchless help requests stay on the read-only answer route even when natural language classification suggests a repository task. File changes require an authoritative branch from a supported surface, such as a PR review comment; diff --git a/docs/issues/deployment-orchestration.mdx b/docs/issues/deployment-orchestration.mdx index ba7f71e26..085ea171d 100644 --- a/docs/issues/deployment-orchestration.mdx +++ b/docs/issues/deployment-orchestration.mdx @@ -58,7 +58,7 @@ Complete this once before starting the first production-first operation: ancestry relationship; - activate required validation on every promotion/reconciliation target. This project requires GitHub Actions `CI Check` on both `master` and `develop`; - RepoWise remains advisory; + RepoWise is optional and runs only through manual dispatch; - enable repository auto-merge if selecting `auto-merge`, or configure every required check for `merge_group` if the target requires a merge queue, and add an exact attestation only for a producer Copilot cannot inspect; @@ -146,8 +146,10 @@ provider mutation. Start a new deployment from valid current configuration. ## Serialization, durable revisions, and safe retries All release, hotfix, and managed-PR mutation routes for the same launcher issue -share one repository-and-issue concurrency group. The workflows retain every -waiting run and never cancel an in-progress deployment owner. A validation job +share one repository-and-issue concurrency group with `queue: max` and +`cancel-in-progress: false`. GitHub allows up to 100 pending jobs or workflow +runs in that group; additional arrivals are canceled when the queue is full. +The workflows never cancel an in-progress deployment owner. A validation job with `permissions: {}` rejects an invalid issue, mode, version, operation ID, title, or changelog before a job receives write permission. It uses the runtime bundled with `actions/github-script@v9` and its automatic token, without a PAT or @@ -155,6 +157,36 @@ configured secret. Leave `github-token` unspecified: an empty override prevents the Action from starting. No host-installed Node executable is required by this validation step. +### Validating `queue: max` + +`queue: max` is valid at both workflow and job level. GitHub added larger +concurrency queues on [May 7, 2026](https://github.blog/changelog/2026-05-07-github-actions-concurrency-groups-now-allow-larger-queues/). +The [official concurrency documentation](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency) +defines `single` (the default) and `max`; `max` requires `cancel-in-progress` to +be `false` or omitted. Combining it with `cancel-in-progress: true` is invalid. + +The generated release and hotfix workflows use: + +```yaml +concurrency: + group: copilot-deployment-${{ github.repository_id }}-${{ inputs.issue }} + cancel-in-progress: false + queue: max +``` + +The deployment continuation uses the same queue settings on its mutation job, +with the issue resolved by its read-only predecessor. A diagnostic such as +`unexpected key "queue" for "concurrency" section` from `actionlint` 1.7.12 is a +false positive against this supported syntax. Use a validator that supports +`queue: max`. Keep the generated queue setting: removing it restores the default +single pending slot, where a new pending run replaces the previous one. + +Queue order is not deployment authority. If the queue reaches capacity, use +**Retry current deployment phase** from the launcher dashboard; the retry +reloads durable state before continuing. + +### Durable revisions + The launcher issue stores only deployment state version 1. The first snapshot is revision 1; every accepted state change increments it by exactly one and saves against the previously read operation ID, phase, and revision. A stale delivery @@ -297,8 +329,10 @@ branch roles and orchestration choices are snapshotted; changing those Variables does not rewrite an in-flight deployment. Merge-queue attestations are the exception: they are live repository policy and are reread with effective target rules at every readiness decision. Both publishing workflows and the managed-PR -continuation workflow pass `MERGE_QUEUE_CHECK_ATTESTATIONS`, so a multi-target -operation does not fall back to stale or empty trust policy between events. +continuation workflow pass `MERGE_QUEUE_CHECK_ATTESTATIONS` (with `[]` only as +the absent-variable fallback). Normal publication callbacks and reconciliation-only +resume both receive this live value in consumer and source workflows, so a +multi-target operation does not fall back to stale or empty trust policy between events. A recommended non-interactive fragment is: diff --git a/docs/issues/pre-branch-sdds.mdx b/docs/issues/pre-branch-sdds.mdx index f2a2cfb77..ffb335860 100644 --- a/docs/issues/pre-branch-sdds.mdx +++ b/docs/issues/pre-branch-sdds.mdx @@ -20,6 +20,49 @@ and fenced examples do not prove a budget. Existing positive numeric prose remains supported. A malformed existing owner needs contributor review; regenerating a proposed appendix cannot repair that retained contract. +Newly generated drafts and appendices also need a checkable inventory. They use +these visible tables, with the English column names retained in localized prose: + +| Section | Columns | What publication verifies | +|---|---|---| +| 4 | `Requirement`, `Behavior` | Every declared goal has one stable ID | +| 14 | `Area`, `Minimum distinct cases`, `Behaviors/risks covered` | Every area and the total match its distinct cases | +| 14 | `Case ID`, `Area`, `Requirements`, `Scenario` | Fully qualified, unique IDs, exact areas and comma-separated requirement IDs | +| 15 | `Path`, `Change` | `update` and `reference` files exist at the immutable base; `create` explicitly proposes an absent file | +| 17 | `Requirement`, `Cases` | Every requirement names defined cases and the reverse links match | + +Tables inside a code fence cannot establish this inventory. A closing fence +must use the same marker with at least the opening length, at most three leading +spaces, and only spaces or tabs after it. A marker followed by text keeps the +example fenced until a valid close or the end of the document. HTML comment +syntax inside the code block is literal and cannot turn that line into a close. + +Use a separate case namespace for each proposed change, such as +`identity-development-C01`. Copilot reserves identifiers across **every** SDD +registered to the selected owner, including legacy shorthand inventories. A +new case cannot redefine a baseline case. Use full IDs in references; shorthand +and ranges do not establish new cases. Each case belongs to one budget area. +Equal grand totals cannot hide an over-allocation in one area and a shortage in +another. Generic documentation checks cannot replace defined acceptance cases. + +Cite repository files with full repository-relative paths in backticks or +relative Markdown file links. Existing paths are checked against the selected +Git commit, including files outside the catalog evidence arrays. Relative links +may include a URL query and fragment; publication checks their file pathname. +A file present +only in the current checkout does not count. Declare intended new files in the +section 15 table with `create`; ordinary documentation updates must identify +the real existing document. Symlinks, submodules and paths below them cannot +establish file evidence. Source paths remain language and layout neutral. +The selected SDD must appear in this table too: use `create` for a new or +companion SDD, and `update` for an existing one. A self-link or a `reference` +row cannot replace that declaration. + +The new tables apply to generated candidates. Existing owner documents remain +verbatim and do not require a table migration to receive an appendix. These +checks establish internal consistency for draft publication. Product, +architecture, security, operator review and runtime acceptance remain separate. + `pre-branch-sdd: true` enables a specification gate for admitted **feature** issues and issues marked `contract-change`. It requires `issue-managed-branches: true` and an agent configuration that can return structured responses. The default is `false`. The repository must already contain a valid `specs/catalog.json`, `specs/README.md`, and `specs/_template.md`. The catalog identifies the owning SDD. The Action can update that SDD, add a companion SDD to its capability, or create a new proposed capability when the catalog evidence and referenced paths are valid. Drafting receives the selected owner's verified source, test and documentation paths at the immutable base, the canonical issue link and retained authorized answers. A new companion identifies the existing owner; its own new path is proposed evidence. It does not generate PRDs or ADRs in this flow. @@ -118,6 +161,22 @@ Opening a PR replaces GitHub's direct issue-to-branch connection with its issue- Automatic updates retain the owning SDD from its original Git commit, including when Windows converts checkout line endings. +### Ownership analysis recovery + +If the analysis proposes an unknown companion owner or a path already registered +in the catalog, Copilot blocks before drafting and publishes an editable **SDD +work status: analysis blocked** card. The card identifies a closed failure +category without exposing the model's proposed values or raw response. + +Clarify the existing capability ID and intended SDD path in the same issue, then +rerun the original workflow. Updates use a path registered to that owner; +companions use an existing owner and a new path; new capabilities use a new ID +and path. Each invocation makes one analysis attempt with no automatic repair. +Existing answers, SDDs, branches and commits remain intact. A later valid analysis +updates the diagnostic; normal publication checks still determine readiness. +The diagnostic is separate from the validated question/publication record and +cannot authorize a branch or `branched` label. + ### Draft validation recovery Drafting aims for a complete compact document: about 6,000 characters for an @@ -131,6 +190,15 @@ Copilot limits proposed update appendices to 18,000 characters and complete new or companion specifications to 70,000. If a generated draft exceeds its limit, it tries one concise regeneration for the same owner and answers. Missing required sections or a numeric test budget can use that same single attempt. +Case identity, per-area case budgets, requirement mappings and repository paths +share that attempt too. A repeated failure gives a specific recovery message: +choose distinct full IDs, reconcile each area's cases, repair both directions +of the mappings, or correct the paths and explicitly proposed files. No further +generation or publication occurs in that run. Review the named contract and +retry the same issue workflow; answered questions and historical commits remain. +Proposed files must also be compatible with one another: a file cannot be the +parent directory of another proposed file, in either declaration order or at +any nesting depth. Sibling files and distinct pathname prefixes remain valid. All validation and freshness checks still apply. If the second draft still fails, no draft is published; existing answers and SDDs are retained. Retry with a proportional change or an approved companion specification. diff --git a/docs/security-operations/operations/error-reference.mdx b/docs/security-operations/operations/error-reference.mdx index 110dd972f..fb122c06a 100644 --- a/docs/security-operations/operations/error-reference.mdx +++ b/docs/security-operations/operations/error-reference.mdx @@ -41,6 +41,16 @@ Retryability is determined by the code. A specific operation can make a normally retryable failure terminal, but presentation never turns a terminal code into a retry recommendation. +For stored issue/PR state, `configuration.invalid` includes the affected number, +the expected schema version, and a missing-schema, unsupported-version or +malformed-content diagnosis in the failure annotation and Job Summary. It +remains nonretryable until corrected; the same correlation reference survives +to the final Action failure. The read does not rewrite the body. Use +[stored-configuration recovery](/security-operations/operations/troubleshooting#unsupported-stored-configuration): +only a verified obsolete unmanaged block may be removed after preserving a +copy. Potentially valuable managed state requires maintainer review and verified +restoration. Provider/authentication failures are not schema failures. + Some partial operations add a closed recovery variant, for example to name a retained managed branch or a closed issue whose final explanation was not published. These variants use reviewed catalog templates and only bounded, diff --git a/docs/security-operations/operations/troubleshooting.mdx b/docs/security-operations/operations/troubleshooting.mdx index 737179f10..f21ba8a50 100644 --- a/docs/security-operations/operations/troubleshooting.mdx +++ b/docs/security-operations/operations/troubleshooting.mdx @@ -548,3 +548,72 @@ When current-repository organization reuse reports configuration/access changed after review, inspect the credential-health workflow too. Its installation or removal changes required bootstrap permissions. Prepare and approve a fresh plan instead of applying a previously audited permission set. + +## Unsupported stored configuration + +An issue or PR with an invalid stored Copilot block stops with +`configuration.invalid` and **Retryable: No**. The annotation and Job Summary +identify its number, the missing/unsupported/malformed state, the required +schema version (currently `3`), and the same reference. Retrying unchanged state +will fail again. The failed read does not change the body or stored state. + +| Stored content | Meaning | Next action | +|---|---|---| +| No Copilot block | No previous state to restore | An unlinked PR can follow its normal PR workflow. | +| Missing schema, unsupported version, malformed JSON/value or incomplete delimiters | Stored state cannot be trusted | A maintainer must review it before retrying. | +| Valid current-schema block | Supported state | Continue through normal validation; this is not a reset instruction. | + +An ordinary inline mention or closed code example containing only an opening or +closing marker is not stored state and does not cause a configuration error. +Complete legacy blocks inside code fences still undergo strict validation; +avoid reproducing complete live delimiter pairs in examples. Multiple complete +blocks or potential state behind an unclosed fence require maintainer review, +so Copilot never silently discards one record or chooses between conflicting +records. Reads and updates preserve the human description around the owned block. + +Recovery is manual and depends on what the block owns: + +1. Preserve the original body using GitHub history or a copy before editing. +2. If a maintainer verifies that the issue/PR is unmanaged and the block is + only an obsolete marker with no branch, release, hotfix or orchestration + state to retain, remove **only that block**, preserve the human description, + and rerun the failed workflow. An obsolete reproduction example can instead + show its JSON without live Copilot comment delimiters: the current reader + also recognizes those delimiters inside fenced issue/PR examples. +3. If managed state may exist or ownership is unclear, stop. Ask a maintainer + to inspect linked branches and operations and restore verified supported + state through the supported workflow before rerunning. Do not discard + unknown state. + +Never repair this by merely adding `schemaVersion: 3`, changing a version number, +automatically migrating/resetting state, or turning the failed check into a +successful skip. A version field alone does not prove that the stored branch or +operation facts are valid. Authorization and temporary GitHub read failures +retain their own error categories; follow their permission/provider recovery +instead of deleting configuration. + +## Repository setup blocks verification + +`Repository setup blocked verification` means preparation did not establish a safe +command environment. Verification and commit/push are withheld; branch sync uses +its existing merge abort. Inspect the native setup step and closed cause in the +run, then repair the reviewed action on `main-branch`. + +| Cause | Recovery | +| --- | --- | +| `source-unavailable` | Make the trusted origin ref available in the full checkout. | +| `helper-invalid` | Review the fixed native composite and regular auxiliary files; respect file/step bounds and avoid nested local `uses`. | +| `native-workflow-required` | Update generated callbacks and use their normal directory-based Git checkout in GitHub Actions. The local CLI cannot execute composite actions. | +| `workspace-changed` / `candidate-changed` | Keep setup dependency-only; do not change publishable source, index, branch or lockfiles. Retry from a fresh candidate. | +| `process-failed` | Inspect the native action's logs and fix its reviewed dependency installation. | +| `timeout` | Fit each native setup within five minutes; no limit override or automatic retry exists. | +| `output-limit` | A Copilot worker log line/output exceeded its framing bound; native setup logs use normal Actions limits. | +| `cancelled` | Retry the authorized operation after cancellation is resolved. | +| `handoff-invalid` | Rerun through updated generated callbacks; never reuse a session from another run/job or request. | +| `result-invalid` | Export only supported, existing PATH/JAVA_HOME directories under the candidate, private HOME or trusted tool cache. | + +The consumer file is `.github/actions/copilot-verification-setup/action.yml`. +Candidate edits do not replace the trusted snapshot. Enabling without a reviewed +action blocks verification; the disabled default preserves existing behavior. +See [repository-owned setup](/security-operations/operations/verification#repository-owned-setup) +for native Python/pnpm examples, profile lifetime, trust boundaries and migration. diff --git a/docs/security-operations/operations/upgrade-rollback.mdx b/docs/security-operations/operations/upgrade-rollback.mdx index 1df6e15e9..c2076e69f 100644 --- a/docs/security-operations/operations/upgrade-rollback.mdx +++ b/docs/security-operations/operations/upgrade-rollback.mdx @@ -36,6 +36,119 @@ copilot --version Use `@latest` only when the latest published release is intentionally selected. Keep explicit versions for reproducible rollback procedures. +## Upgrade an existing Copilot repository + +Copilot has three separate versioned layers: + +| Layer | What changes it | What still needs review | +|---|---|---| +| Installed CLI | `copilot upgrade` or an explicit npm/pnpm package version | The CLI prepares local files; it does not rewrite committed workflows merely by upgrading | +| Remote Copilot reference | Action and reusable-workflow `uses` references in committed workflows | `@v3` follows the published major tag; an exact version or commit SHA stays pinned until explicitly changed | +| Generated workflow files | An approved `copilot setup --update-workflows` run | New jobs, inputs and coordinator calls must be committed, reviewed and merged | + +Moving a tag does not add steps to an old YAML file. Upgrading the CLI does not +change the Action references in Git. A merge into `develop` is not a package or +Action release: first select a [published release](https://github.com/vypdev/copilot/releases) +that contains the required setup and native verification support. + +For verification setup adoption: + +**1. Record the existing installation.** + +Start with a clean branch, record the currently reviewed workflow references, +and keep `VERIFICATION_SETUP=false` during preparation. Inspect the effective +repository/organization value; a repository Variable overrides an inherited +organization value. + +**2. Upgrade the CLI and preview.** + +Upgrade the CLI and confirm `copilot --version`. Preview the installation: + +```bash +copilot upgrade +copilot --version +copilot setup --web --dry-run +``` + +**3. Regenerate and review workflows.** + +Before upgrading the comment callbacks, update self-hosted GitHub Actions runners +to **2.336.0+**. The centralized coordinator uses GitHub.com's self-repository +references to keep its internal Action on the exact selected workflow commit. +Verify platform support before adopting this format on other GitHub deployments. +Check that the repository/organization Actions policy permits the published +`vypdev/copilot/.github/workflows/copilot_comment_runtime.yml` reusable workflow +at your selected ref, as well as the existing Copilot Action. +If the existing comment jobs have custom dependency/bootstrap steps, migrate them +into the reviewed repository setup action before replacing those jobs; setup +blocks silently dropping them. Keep the prior reviewed callbacks until this is +ready. See [repository-owned setup](/security-operations/operations/verification#repository-owned-setup). + +Apply a reviewed workflow upgrade: + +```bash +copilot setup --web --update-workflows +``` + +The shared assistant also works in the terminal without `--web`. Keep the +verification setup question disabled for this preparation pass. Review the +displayed create/preserve result and changes before approval. The installer +creates `.github/actions/copilot-verification-setup/action.yml` only if absent; +existing action bytes and auxiliary files are preserved through upgrades. +Generated comment callbacks use +`vypdev/copilot/.github/workflows/copilot_comment_runtime.yml@v3`; other generated +callbacks continue using `vypdev/copilot@v3`. The coordinator owns setup, +continuations and cleanup in one job, keeping consumer YAML compact. If your +repository pins versions or SHAs, update the reusable-workflow and remaining +Action references to the chosen compatible published release. You do not edit +the internal `uses: $/` references: GitHub pins them to the called workflow commit. +The reviewed runner route is retained in the comment call's `with.runs-on` JSON. +Workflow backups are retained under `.copilot/setup-backups/`. + +**4. Customize and merge on trusted main.** + +Replace the starter's failing placeholder with reviewed project-specific +dependency preparation. Commit the action, its auxiliary files and the updated +workflows. Review and merge them onto the configured trusted `MAIN_BRANCH`; +the installer PR's default target may differ from this trusted branch. Follow +the repository's branch/promotion process until both contain the reviewed +changes. Creating or merging an installer PR alone does not verify the runtime. + +**5. Activate verification setup.** + +Re-run the assistant and enable **Prepare dependencies with the repository +verification setup action?**, or use: + +```yaml +repository: + verificationSetup: true +``` + +Setup writes `VERIFICATION_SETUP` only when Variable management is enabled +and follows the reviewed storage/reuse policy. With `--skip-variables`, update +the effective Variable manually. Confirm that generated workflows pass the +`VERIFICATION_SETUP` Variable through the coordinator (or the direct Action's +`verification-setup` input), and that the trusted action has been customized. +Choose **Customize** when changing an existing repository Variable; **Reuse** +keeps existing values. If an organization value must differ for this project, +select `VERIFICATION_SETUP` in the repository Variable overrides and review the +scope before Apply. + +**6. Verify actual execution.** + +Run `copilot doctor --read-only`, then an authorized write/sync operation that +actually executes the configured verification commands. Inspect the native +action and verifier results; a doctor pass, dry run or already-aligned sync +does not prove dependency preparation. + +To roll back adoption, first set the effective `VERIFICATION_SETUP=false` (or +answer No with Variable management enabled). This stops the optional hook and +retains the existing verification commands. Restore the previous reviewed +workflow files and Action refs together if necessary, and install the prior CLI +version explicitly. Consumer action files are retained; restore any owner changes +through Git review instead of asking setup to overwrite or delete them. Inspect +partial setup receipts and GitHub resources before retrying a failed upgrade. + ## Rollback 1. Restore the last known-good version variable. diff --git a/docs/security-operations/operations/verification.mdx b/docs/security-operations/operations/verification.mdx index 394eafca2..0537cd75d 100644 --- a/docs/security-operations/operations/verification.mdx +++ b/docs/security-operations/operations/verification.mdx @@ -32,8 +32,10 @@ The source workflow validator accepts the setup's literal `runs-on: {group: vypd The setup's runner profile chooses **where** a job runs. It does not install a consumer project's language runtimes or dependencies. A passing application CI job does not prepare the separate `issue_comment`, PR-comment or automated-fix -job. Each job that runs `bugbot-fix-verify-commands` must prepare its own tools -before Copilot, including for `/copilot sync-branch --no-agent`. +job. Each job that runs `bugbot-fix-verify-commands` must prepare its own tools, +including for `/copilot sync-branch --no-agent`. Use the [repository-owned setup +action](#repository-owned-setup) to prepare the candidate without editing generated +workflows, or retain your reviewed same-job bootstrap. For a Kotlin/JVM project, commit a reviewed `.copilot/verification-prerequisites.json`: @@ -117,6 +119,241 @@ commit or push; automated fixes also withhold their commit and push. Correct the declaration or bootstrap, then retry the original operation. Dry runs and already-aligned branches do not execute verification or prove runtime readiness. +## Repository-owned setup + +Each repository can prepare its dependencies in a native composite action, without +editing generated Copilot workflows. GitHub Actions executes the YAML's `uses` and +`run` steps in the same job where Copilot verifies the candidate. + +The generated issue-comment and PR-review-comment workflows call +`vypdev/copilot/.github/workflows/copilot_comment_runtime.yml@v3`. This reusable +workflow keeps the complete job inside Copilot: checkout, the admitted operation, +project setup, verification continuations and native cleanup. Consumer callbacks +contain one call; they do not copy the twenty possible continuation slots. +Your dependency action stays in your own repository. + +The coordinator reads the caller repository's existing Variables and receives +only the named Secrets forwarded by the generated callback. Provider credentials +remain scoped to the initial Copilot step. The project setup action receives the +existing private runtime environment. Setup retains the selected runner in the +call's `with.runs-on` JSON string, including self-hosted labels and runner groups. + +GitHub Actions runner **2.336.0 or newer** is required: the coordinator's `uses: $/` +references load Copilot from the exact reusable-workflow commit, including a +consumer's pinned SHA, outside the mutable project checkout. This is supported on +GitHub.com; verify equivalent platform support before adopting it elsewhere. +See [GitHub's self-repository reference announcement](https://github.blog/changelog/2026-07-30-reference-same-repository-actions-with-self-repository-syntax/). +The existing five-minute setup limit and 120-minute job budget remain in force. + +```mermaid +flowchart LR + A[Copilot prepares changes] --> B[Repository composite installs dependencies] + B --> C[Runtime preflight and verification] + C --> D[Existing publication guards] +``` + +Text equivalent: prepare the candidate, install its dependencies, verify it, then +apply the existing publication guards. A separate CI job does not prepare this job. + +1. Run `copilot setup` or `copilot setup --web` with a published CLI version that + includes this onboarding support. The plan shows **Create the starter only if + missing** or **Preserve the existing project action** at + `.github/actions/copilot-verification-setup/action.yml`, plus the activation + state and configured trusted main branch. Setup creates this file even when + activation is disabled. It never overwrites an existing regular action, + changes its auxiliary files or retires it when you disable the option. +2. Leave **Prepare dependencies with the repository verification setup action?** + disabled while preparing the action. The generated native composite contains + a failing placeholder with customization instructions. Replace that step with + your project's reviewed runtime and dependency setup; no language, version or + install command is inferred, and setup does not execute the action. +3. Update the generated comment workflows with `copilot setup --update-workflows` + and review the complete diff. They need the reusable coordinator call; an older + callback without native support cannot execute YAML. Review the action, auxiliary + scripts and workflows onto the configured `main-branch` (`MAIN_BRANCH`, normally + production). Candidate or model changes cannot replace the trusted action. +4. Enable the same question in the terminal/web assistant, or set non-secret + configuration `repository: { verificationSetup: true }`. With Variable + management enabled, setup plans `VERIFICATION_SETUP=true` using the selected + storage/reuse policy. Existing configured values are shown; the default is + `false`. If Variable management is skipped, set the effective GitHub Actions + Variable yourself. The corresponding boolean Action input is + `verification-setup`. + Choose **Customize** to change an existing repository Variable; **Reuse** + retains existing effective values. To override an inherited organization value + just for this repository, select `VERIFICATION_SETUP` under repository Variable + overrides and review its scope. +5. Retry an authorized modification or `/copilot sync-branch --no-agent` that + actually needs configured verification. Inspect the native setup and verifier + results. A dry run, no-op sync, read-only doctor result, generated file or + installer PR does not establish runtime readiness. + +The starter deliberately fails until customized. Enabling the flag before the +reviewed action is available on trusted main blocks verification and publication; +it does not bypass the placeholder. Batch setup uses the same create/preserve +rule and includes a missing starter in its installation PR. An existing action +stays outside generator ownership and out of the update diff. Unsafe parent +links, non-regular action paths and collisions block setup; inspect the path and +review a fresh plan. If a file appears after review, setup preserves it and stops +the stale creation. Dry-run, cancellation and declined approval create no starter. + +For an existing installation, follow the [three-layer upgrade and rollback +procedure](/security-operations/operations/upgrade-rollback#upgrade-an-existing-copilot-repository). +This repository's `setup_platform_smoke.yml` is internal CI and is not installed +in consumer projects. + +If your old comment job contains custom bootstrap steps, keep that reviewed +workflow until you move those steps into the trusted project setup action and +review its activation. A job that calls a reusable workflow cannot also declare +its own steps. Setup blocks that migration rather than silently removing custom +preparation; it also blocks malformed runner JSON or dependent runner expressions +that require separate workflow review. Plain generated callbacks and previously +upgraded callbacks retain their static runner selection automatically. + +Copilot captures the complete action directory from an immutable trusted Git SHA +before candidate changes. The trusted origin ref must be available locally; +generated comment workflows use a full checkout. The runner executes that snapshot +**after merge/fix changes and before each configured verifier**, reading the actual +candidate manifests. The admitted operation continues once; the agent is not rerun. +Copilot stages the reviewed snapshot in reserved local Git metadata at +`.git/copilot-verification-setup`; the consumer's candidate files stay unchanged. +The normal directory-based `.git` checkout from generated workflows is required. +Staging remains available for native post steps. Trusted Copilot post steps reload +the pinned Git objects and verify their original content digest before those +phases with the initially pinned Git executable, so later candidate edits cannot +supply post code. Source workflows also snapshot Copilot itself outside the +mutable workspace; normal remote Action installations already use a separate +runner cache. + +For Python, the consumer file can contain: + +```yaml +name: Prepare project verification +runs: + using: composite + steps: + - uses: actions/setup-python@v6 + id: python + with: + update-environment: false + python-version: '3.12' + - name: Install the candidate's test dependencies + run: | + "$PYTHON_EXECUTABLE" - <<'PYTHON' + import os, pathlib, subprocess, venv + home = pathlib.Path(os.environ['HOME']) / 'venv' + venv.create(home, with_pip=True) + tools = home / ('Scripts' if os.name == 'nt' else 'bin') + python = tools / ('python.exe' if os.name == 'nt' else 'python') + subprocess.check_call([str(python), '-m', 'pip', 'install', + '--no-cache-dir', '--require-hashes', '-r', 'requirements-test.lock']) + with open(os.environ['GITHUB_PATH'], 'a') as paths: + print(tools, file=paths) + PYTHON + shell: bash + env: + PYTHON_EXECUTABLE: ${{ steps.python.outputs.python-path }} +``` + +Keep pytest and all transitive dependencies pinned with hashes in the candidate's +`requirements-test.lock`. The verifier can remain `python -m pytest`. Adapt runtime +versions and dependency commands to your project; these examples do not infer them. +The example disables pip's cache so platform-specific cache discovery cannot create +publishable files in the candidate. To use a cache, set its path explicitly under +the private HOME or an ignored dependency directory. + +For Node/pnpm: + +```yaml +name: Prepare project verification +runs: + using: composite + steps: + - uses: actions/setup-node@v7 + with: + node-version: '24.x' + package-manager-cache: false + - uses: pnpm/action-setup@v5 + with: + version: 10.12.4 + dest: ${{ env.HOME }}/pnpm + standalone: false + - run: pnpm install --frozen-lockfile --ignore-scripts + shell: bash +``` + +The action may include reviewed auxiliary scripts, referenced through +`${{ github.action_path }}`. Use native external `uses` actions and `run` steps; +nested local `uses: ./...` actions are rejected because their deferred post steps +could otherwise load candidate code outside trusted staging. Review external action versions as +part of the executable setup. The composite inherits the job's operating system; +its metadata cannot declare jobs, runners or a matrix. + +Each command gets a **fresh private HOME**. These dependency-only profiles stay +private until native post-job actions finish, then Copilot's final post cleanup +removes them. They are never reused by another command. Keep dependencies that +must survive native post steps under the private HOME, an ignored candidate directory +or the trusted runner tool cache, rather than inside the reserved action staging folder. + +Native setup exports tools through normal Actions mechanisms such as `GITHUB_PATH` +and `JAVA_HOME`; no custom JSON helper protocol is required. Copilot accepts up to +eight new unique absolute PATH directories, each at most 2,048 characters, and +JAVA_HOME. They must exist inside the candidate workspace, its private HOME or the +captured `RUNNER_TOOL_CACHE`; unsafe links, traversal and escaping paths are rejected. +The internal closed runtime result is bounded to 16 KiB. Other `GITHUB_ENV` values +are not forwarded to verification. Use complete executable paths or supported +runtime directories when a tool needs additional environment configuration. + +Copilot's PAT, provider/model inputs, agent auth stores and evidence token are not +passed to the consumer action or verifier. The native runner and external actions +retain normal GitHub Actions facilities and the job's scoped `GITHUB_TOKEN` context. +This is the existing trusted-runner boundary, not an OS sandbox against malicious +maintainer code or service-level credentials. Review setup as executable code and +avoid printing secrets. Agent credential profiles close before verification. + +A native setup step has a fixed **five-minute timeout**; the worker also rejects +readiness after 300 seconds. There are at most twenty setup boundaries per operation, +one for each configured command. No automatic setup retry or limit override exists. +The action directory is bounded to 32 regular files, 64 KiB each and 256 KiB total; +its metadata must be `action.yml`, with `runs.using: composite` and 1–32 steps. +Use portable ASCII asset paths (letters, digits, `_`, `.`, `-` and `/`), at most +200 characters; parent/empty segments and Windows reserved filenames are rejected. +Native setup logs are visible in the run; there is no 64-KiB helper-output ceiling. +Copilot's own error/result comments contain only a closed cause, fixed path and +pinned trusted SHA, never copied raw setup output. + +Setup must install dependencies without changing publishable code or lockfiles. +Copilot compares HEAD, branch, index, tracked edits and publishable untracked file +contents, types and executable modes before allowing the verifier to continue. Executable lookup uses that verifier's +validated PATH, so its private Python/pnpm takes precedence over the worker tools. Observations are bounded to +16 MiB, 256 untracked files and 16 MiB aggregate untracked contents. Ignore dependency +caches and keep source changes within these bounds. Failure, changed candidate, +invalid runtime output, timeout or cancellation withholds verification and push; +branch synchronization follows its existing abort/recovery. + +Read-only questions/status, dry runs, already-aligned branches and empty command +lists execute no setup. Snapshot failures remain deferred until verification. +Setup/install/update preserves this consumer-owned directory and all its assets. + +If a runner crash leaves an unknown reserved staging directory, preparation fails +closed rather than overwriting it. Confirm the prior job has stopped, inspect its +run, and remove only that stale `.git/copilot-verification-setup` directory before +retrying. Normal completion/cancellation uses the Action post cleanup. +Invalid session handoffs fail closed. An invocation removes only the setup request +it created after validating the session; rejection before that point leaves +preexisting request files untouched. + +Native composite execution is available in the generated **GitHub Actions** +callbacks. The local CLI cannot execute `uses` steps: opted-in local verification +fails with `native-workflow-required`. Run the authorized operation in Actions, +or keep the opt-in disabled and provision your local dependencies normally. +Direct custom callers must implement the documented generated native callback +structure; setting the flag on an old single Action step is insufficient. + +To roll back, set `VERIFICATION_SETUP=false` and provision dependencies before +Copilot in the same job. The unreleased `.copilot/verification-setup.mjs` prototype +is superseded; it is not executed or installed by this contract. + ## Reused credential evidence The reuse journey performs GET-only inspection of trusted installed health diff --git a/docs/security-operations/security/self-hosted-runners.mdx b/docs/security-operations/security/self-hosted-runners.mdx index f2925d0e4..a5b54e990 100644 --- a/docs/security-operations/security/self-hosted-runners.mdx +++ b/docs/security-operations/security/self-hosted-runners.mdx @@ -14,6 +14,12 @@ A self-hosted runner that can access agent credentials MUST be dedicated or isol - audit runner labels and permissions; - keep local session files outside repository workspaces. +The compact Copilot comment callbacks require GitHub Actions runner **2.336.0+** +and platform support for self-repository references. Their reusable coordinator +keeps the Action on the called workflow's exact commit. Setup retains self-hosted +labels and groups in the call's `with.runs-on` JSON; it does not change group +access or prove capacity. See [comment workflow upgrades](/security-operations/operations/upgrade-rollback#upgrade-an-existing-copilot-repository). + A shared persistent runner is not equivalent to an ephemeral trusted runner. The self-hosted platform smoke uses the local pnpm store without exporting a @@ -22,9 +28,8 @@ package-manager caching. This keeps a successful full validation from timing out in the post-job archive step; hosted fixture caching is retained. See the [setup-node cache inputs](https://github.com/actions/setup-node#usage). -This repository runs `CI Check` and `RepoWise code health` on self-hosted -Ubuntu `codex` runners for its own PRs and pushes. Fork PRs and all merge -groups keep the same quality checks on disposable GitHub-hosted Ubuntu +This repository runs `CI Check` on self-hosted Ubuntu `codex` runners for its +own PRs and pushes. Fork PRs and all merge groups run CI on disposable GitHub-hosted Ubuntu runners. A merge group can contain fork code without exposing its origin to the runner selector; never route it to a persistent service runner. The trusted-default-branch PR approval observer also runs on a self-hosted Ubuntu `codex` runner. The @@ -47,8 +52,16 @@ Publishing currently requires a hosted runner. Their other jobs continue on self-hosted runners. RepoWise obtains a complete Python 3.12 distribution via `actions/setup-python`, creates its virtual environment and reports in run-specific temporary directories, and removes them after artifact upload. -Its runner needs a writable Actions tool cache; the workflow does not install -Ubuntu system packages. +Its runner needs a writable Actions tool cache and GNU `/usr/bin/time` for phase +RSS evidence. The isolated Python suite verifies the pinned history adapter before +analysis; phase time/virtual-memory caps and a 40-minute job bound the run. +The workflow does not install +Ubuntu system packages. RepoWise runs only through manual dispatch on +`[self-hosted, codex, Linux]`, using the reviewed repository ref selected by the +maintainer. It is optional and must not be required by branch protections or +rulesets. It no longer consumes this pool on every PR or push. See +[testing and manual analysis](/development/testing) for launch instructions, +revision evidence, scan limits, artifacts, and retry behavior. The `[self-hosted, codex]` pool routes agent jobs to macOS and Ubuntu. Windows services MUST omit `codex` on registration; recreate existing registrations to diff --git a/docs/setup-web.mdx b/docs/setup-web.mdx index b3a421d61..75db6586b 100644 --- a/docs/setup-web.mdx +++ b/docs/setup-web.mdx @@ -5,6 +5,11 @@ description: Install Copilot with the local browser assistant, then verify a rea This is the recommended interactive installation path. The assistant runs on your computer and prepares the selected workflows and GitHub resources. You review the plan before permission checks or installation changes begin. +Comment callbacks call Copilot's reusable coordinator, keeping dependency setup, +verification and cleanup in one job. Existing runner labels/groups remain visible +in review. Check runner/platform prerequisites and migrate custom bootstrap before +adopting this format; follow the [existing repository upgrade guide](/security-operations/operations/upgrade-rollback#upgrade-an-existing-copilot-repository). + The assistant keeps tutorial, first-workflow and troubleshooting links available throughout the session. They open in another tab and retain your answers. Each question also links to its own reference and has a **Why this matters** explanation. See [Use the documentation](/using-the-docs) for version selection and offline help. ## Before you start @@ -53,6 +58,18 @@ Choose **This repository** for your first installation. A new checkout offers ** Choose **Basic guided setup** unless you need every advanced setting. Basic still asks for permission, branch, runner, Project, approval and storage decisions. **Customize every setting** exposes the advanced configuration. Use **Previous question** or the plan's **Change** controls to revise answers without losing the others. +Both modes ask **Prepare dependencies with the repository verification setup +action?** The default is disabled; configured and reused values remain visible. +The plan shows whether `.github/actions/copilot-verification-setup/action.yml` +will be created or preserved, the activation state and the configured trusted main +branch. Apply creates a failing starter only when missing and preserves existing +project actions and auxiliary files. Customize and review the action on +`MAIN_BRANCH` before enabling `VERIFICATION_SETUP`, then exercise a real verifier. +No dependency installation runs during setup. Follow the [upgrade and rollback +guide](/security-operations/operations/upgrade-rollback#upgrade-an-existing-copilot-repository) +for an existing installation; creating an installer PR does not establish runtime +readiness. + The six milestones are: ```text diff --git a/docs/single-actions/workflow-and-cli.mdx b/docs/single-actions/workflow-and-cli.mdx index 84dcb6c27..846da64ae 100644 --- a/docs/single-actions/workflow-and-cli.mdx +++ b/docs/single-actions/workflow-and-cli.mdx @@ -217,6 +217,16 @@ copilot setup Run it from the target repository root. Existing setup files are not overwritten unless you approve the update prompt or pass `--update-workflows`. The interactive flow installs the selected workflows/templates, asks for agent routing and operational settings, inspects the repository's effective Actions resources, and asks separately where Secrets and Variables should live. Organization scope requires an organization-owned repository and the corresponding organization permissions on the setup PAT. Existing repository resources take precedence over organization resources; setup preserves an inherited organization resource unless you explicitly request a repository override. +Setup also creates `.github/actions/copilot-verification-setup/action.yml` only +if missing. This project-owned action and its auxiliaries are preserved even +with `--update-workflows`; they are never retired on deselection. The shared +terminal/web repository question controls the existing boolean +`repository.verificationSetup` / `VERIFICATION_SETUP`, disabled by default. +Customize the generated failing placeholder and review it on configured +`MAIN_BRANCH` before activation. Preview/cancel/decline creates no starter; +setup does not infer or install dependencies. See the [ordered upgrade +procedure](/security-operations/operations/upgrade-rollback#upgrade-an-existing-copilot-repository). + The questionnaire is forward-only and immutable. Its stable stages are capabilities, issue workflow multi-select, agent runtime, model defaults, optional role overrides, repository, deployment, Bugbot, optional Projects, provisioning, storage, review, and confirmation. The issue workflow selector uses the usual `Space` to toggle and `Enter` to confirm; `All` is selected by default. `Ctrl-C` or end-of-input closes the prompt once, exits 130, and writes nothing. Declining the final plan exits 0 and also writes nothing; rerun setup or edit the config file to change earlier answers. The wizard covers these features: `issues`, `pullRequests`, `commits`, `issueComments`, `pullRequestComments`, `release`, `hotfix`, `agentProvisioning`, `credentialHealth`, `inactiveIssueClosure`, `issueTemplates`, and `pullRequestTemplate`. It also asks whether to generate repository agent guidance; this is enabled by default. The agent tasks are `planner`, `findings`, `reviewer`, `fixer`, and `tester`; each can use any of the three supported runtimes independently. Model provider, model, effort, branch strategy, locales, AI ignore patterns, project columns, Bugbot policy, and initial-tag creation are also configurable. Cursor is available as an experimental runtime and is called out in the review plan with its extra credential/checksum requirements. diff --git a/package.json b/package.json index b52c34bf5..c4ff15a8c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@vypdev/copilot", - "version": "3.9.3", + "version": "3.10.0", "packageManager": "pnpm@10.12.4", "pnpm": { "overrides": { @@ -40,6 +40,7 @@ "build/api/index.js", "build/api/src/", "setup/ISSUE_TEMPLATE/", + "setup/actions/", "setup/workflows/", "setup/source-workflows/", "setup/pull_request_template.md", diff --git a/quality/bugbot/corpus.v1.json b/quality/bugbot/corpus.v1.json index bef9c316c..8129bbf62 100644 --- a/quality/bugbot/corpus.v1.json +++ b/quality/bugbot/corpus.v1.json @@ -300,6 +300,14 @@ "startLine": 57, "diff": "+val bytes = withContext(Dispatchers.IO) { Files.readAllBytes(reportPath) }", "expected": [] - } + }, + {"id": "py-coverage-config-branch", "language": "python", "category": "negative", "description": "A coverage job runs python -m coverage run -m unittest discover from the repository root using the supplied TOML settings, with TOML support and no config overrides.", "file": "pyproject.toml", "startLine": 1, "diff": "+[tool.coverage.run]\n+branch = true\n+[tool.coverage.report]\n+fail_under = 85\n+# From this repository root, with TOML support installed and no other config/overrides:\n+# python -m coverage run -m unittest discover -s tests -q", "expected": []}, + {"id": "py-http10-reconnect", "language": "python", "category": "negative", "description": "A callback handler sends 404 before an HTTPConnection client makes its next request.", "file": "tools/callback.py", "startLine": 1, "diff": "+from http.server import BaseHTTPRequestHandler\n+from http.client import HTTPConnection\n+class Handler(BaseHTTPRequestHandler):\n+ def do_GET(self):\n+ self.send_response(404)\n+ self.end_headers()\n+def two_requests(port):\n+ client = HTTPConnection(\"127.0.0.1\", port)\n+ client.request(\"GET\", \"/missing\")\n+ first = client.getresponse()\n+ client.request(\"GET\", \"/callback\")\n+ return first.status, client.getresponse().status", "expected": []}, + {"id": "docs-correct-regression-total", "language": "markdown", "category": "negative", "description": "A regression report lists the stated total and the per-area case counts.", "file": "docs/regressions.md", "startLine": 1, "diff": "+Regression total: 34\n+Cases by area: 6 + 8 + 3 + 1 + 4 + 1 + 4 + 2 + 1 + 3 + 1 = 34.", "expected": []}, + {"id": "py-short-circuit-unhashable", "language": "python", "category": "negative", "description": "A checkpoint validator checks issue steps supplied as arbitrary persisted JSON values.", "file": "src/checkpoint.py", "startLine": 1, "diff": "+def valid_steps(issue_steps, writable_ids):\n+ if any(not isinstance(step, str) or step not in writable_ids for step in issue_steps):\n+ return False\n+ return set(issue_steps) <= writable_ids", "expected": []}, + {"id": "py-helper-retry-validation", "language": "python", "category": "negative", "description": "A copy entrypoint loads persisted retry_attempts through a validation helper before constructing provider work.", "file": "src/copy.py", "startLine": 1, "diff": "+def parse_progress(raw):\n+ value = raw[\"retry_attempts\"]\n+ if isinstance(value, bool) or not isinstance(value, int) or value < 0:\n+ raise ValueError(\"invalid_copy_checkpoint\")\n+ return value\n+\n+def run_copy(raw, provider):\n+ attempts = parse_progress(raw)\n+ return provider.create(attempts)", "expected": []}, + {"id": "ts-exclusive-render-branches", "language": "typescript", "category": "negative", "description": "A selected UI section is rendered through a map of view functions.", "file": "ui/views.ts", "startLine": 1, "diff": "+const unavailableAction = () => html`Unavailable`;\n+const overview = () => html`

                                                                                                          Overview

                                                                                                          `;\n+const copy = () => html`
                                                                                                          ${unavailableAction()}
                                                                                                          `;\n+const library = () => html`
                                                                                                          ${unavailableAction()}
                                                                                                          `;\n+const viewFor = (section: \"overview\" | \"copy\" | \"library\") => ({ overview, copy, library })[section]();\n+const render = (section: \"overview\" | \"copy\" | \"library\") => html`${viewFor(section)}`;", "expected": []}, + {"id": "py-short-circuit-unsafe-order", "language": "python", "category": "correctness", "description": "A checkpoint validator checks issue steps supplied as arbitrary persisted JSON values.", "file": "src/checkpoint.py", "startLine": 1, "diff": "+def valid_steps(issue_steps, writable_ids):\n+ return all(step in writable_ids and isinstance(step, str) for step in issue_steps)", "expected": [{"id": "unhashable-membership", "title": "Unhashable steps reach set membership before validation", "file": "src/checkpoint.py", "line": 2, "severity": "low", "category": "correctness", "symbol": "valid_steps", "codeSnippet": "step in writable_ids"}]}, + {"id": "ts-composed-duplicate-ids", "language": "typescript", "category": "correctness", "description": "A UI helper supplies a reason label to actions composed in one overview.", "file": "ui/views.ts", "startLine": 1, "diff": "+const unavailableAction = () => html`Unavailable`;\n+const overview = () => html`
                                                                                                          ${unavailableAction()}${unavailableAction()}
                                                                                                          `;", "expected": [{"id": "composed-duplicate-id", "title": "Composed actions render duplicate reason IDs", "file": "ui/views.ts", "line": 2, "severity": "low", "category": "correctness", "symbol": "overview", "codeSnippet": "${unavailableAction()}${unavailableAction()}"}]} ] } diff --git a/quality/bugbot/reference-predictions.v1.json b/quality/bugbot/reference-predictions.v1.json index b9f640bab..7405a095f 100644 --- a/quality/bugbot/reference-predictions.v1.json +++ b/quality/bugbot/reference-predictions.v1.json @@ -30,6 +30,14 @@ "csharp-path-traversal": [{ "id": "download-traversal", "title": "Request filename can escape the upload root", "file": "Controllers/DownloadController.cs", "line": 58, "severity": "high", "category": "security", "confidence": 0.97, "symbol": "Download", "codeSnippet": "Path.Combine(uploadRoot, request.FileName)" }], "csharp-contained-path": [], "kotlin-blocking-coroutine": [{ "id": "blocking-request-thread", "title": "Blocking file read runs on the request dispatcher", "file": "src/ReportController.kt", "line": 49, "severity": "medium", "category": "performance", "confidence": 0.88, "symbol": "report", "codeSnippet": "Files.readAllBytes(reportPath)" }], - "kotlin-io-dispatcher": [] + "kotlin-io-dispatcher": [], + "py-coverage-config-branch": [], + "py-http10-reconnect": [], + "docs-correct-regression-total": [], + "py-short-circuit-unhashable": [], + "py-helper-retry-validation": [], + "ts-exclusive-render-branches": [], + "py-short-circuit-unsafe-order": [{"id": "unhashable-membership", "title": "Unhashable steps reach set membership before validation", "file": "src/checkpoint.py", "line": 2, "severity": "low", "category": "correctness", "symbol": "valid_steps", "codeSnippet": "step in writable_ids", "confidence": 0.98}], + "ts-composed-duplicate-ids": [{"id": "composed-duplicate-id", "title": "Composed actions render duplicate reason IDs", "file": "ui/views.ts", "line": 2, "severity": "low", "category": "correctness", "symbol": "overview", "codeSnippet": "${unavailableAction()}${unavailableAction()}", "confidence": 0.98}] } } diff --git a/scripts/coverage-budgets.json b/scripts/coverage-budgets.json index 4336d03af..5daac8b1e 100644 --- a/scripts/coverage-budgets.json +++ b/scripts/coverage-budgets.json @@ -900,6 +900,81 @@ } ], "successMessage": "approval evidence diagnostics coverage: PASS (95% lines/statements, 90% branches/functions)" + }, + { + "name": "Verification setup", + "missingEntryLabel": "verification setup", + "rules": [ + { + "files": [ + "src/application/policies/verification_setup_policy.ts" + ], + "mode": "each", + "thresholdProfile": "default" + }, + { + "files": [ + "src/infrastructure/verification_setup_snapshot.ts", + "src/infrastructure/verification_setup_result.ts", + "src/infrastructure/verification_setup_runner.ts", + "src/infrastructure/native_verification_protocol.ts", + "src/infrastructure/native_verification_candidate.ts", + "src/infrastructure/native_verification_staging.ts", + "src/infrastructure/native_verification_controller.ts", + "src/infrastructure/native_verification_profiles.ts", + "src/infrastructure/native_verification_redaction.ts", + "src/infrastructure/verification_executable.ts", + "src/infrastructure/native_verification_source_runtime.ts" + ], + "mode": "aggregate", + "thresholdProfile": "default" + } + ], + "successMessage": "verification setup coverage: PASS (95% lines/statements, 90% branches/functions)" + }, + { + "name": "Verification setup onboarding", + "missingEntryLabel": "verification setup onboarding", + "rules": [ + { + "files": [ + "src/application/policies/setup_verification_action_summary_policy.ts" + ], + "mode": "each", + "thresholdProfile": "exhaustive" + }, + { + "files": [ + "src/infrastructure/setup_verification_action.ts" + ], + "mode": "each", + "thresholdProfile": "default" + } + ], + "successMessage": "verification setup onboarding coverage: PASS (summary decisions 100%; safe file adapter 95% lines/statements, 90% branches/functions)" + }, + { + "name": "Finding identity continuity", + "missingEntryLabel": "finding identity continuity", + "rules": [ + { + "files": [ + "src/domain/bugbot/finding.ts" + ], + "mode": "each", + "thresholdProfile": "exhaustive" + }, + { + "files": [ + "src/application/usecases/steps/commit/bugbot/analyze_bugbot_revision_use_case.ts", + "src/application/usecases/steps/commit/bugbot/publish_findings_use_case.ts", + "src/application/usecases/steps/commit/bugbot/reconcile_bugbot_review_state_use_case.ts" + ], + "mode": "aggregate", + "thresholdProfile": "default" + } + ], + "successMessage": "finding identity continuity coverage: PASS (pure matching 100%; changed path 95% lines/statements, 90% branches/functions)" } ] } diff --git a/scripts/generate-native-verification-workflows.cjs b/scripts/generate-native-verification-workflows.cjs new file mode 100644 index 000000000..d47081f62 --- /dev/null +++ b/scripts/generate-native-verification-workflows.cjs @@ -0,0 +1,103 @@ +const fs = require('node:fs'); +const path = require('node:path'); +const yaml = require('js-yaml'); + +const MAX_REQUESTS = 20; +const ACTION = './.git/copilot-verification-setup'; +const { SOURCE_ACTION } = require('./prepare-native-source-action.cjs'); +const CALLBACKS = ['copilot_issue_comment.yml', 'copilot_pull_request_comment.yml']; +const { COPILOT_COMMENT_RUNTIME: RUNTIME, COPILOT_COMMENT_REMOTE_WORKFLOW: REMOTE_WORKFLOW, COPILOT_COMMENT_SELF_WORKFLOW: SELF_WORKFLOW } = require('../src/domain/copilot_comment_workflow.ts'); +const SELF_ACTION = '$/'; +const SECRET_NAMES = ['PAT', 'OPENCODE_API_KEY', 'OPENAI_API_KEY', 'ANTHROPIC_API_KEY', 'GOOGLE_API_KEY', 'OPENROUTER_API_KEY', 'CURSOR_API_KEY', 'CODEX_API_KEY']; +const BINDINGS = require('../src/infrastructure/copilot_comment_inputs.json'); +const expr = value => '${{ ' + value + ' }}'; + +function phaseSteps(action, inputAlias = 'copilot-inputs', id = 'copilot') { + const steps = []; + let previous = id; + for (let count = 1; count <= MAX_REQUESTS; count++) { + const setup = `verification_setup_${count}`; + const continuation = `verification_continue_${count}`; + const pending = `steps.${previous}.outputs.verification-setup-pending == 'true'`; + const output = key => `\${{ steps.${previous}.outputs.verification-${key} }}`; + steps.push({ name: `Prepare repository verification ${count}`, id: setup, + if: `\${{ !cancelled() && steps.${previous}.outcome == 'success' && ${pending} }}`, uses: ACTION, 'timeout-minutes': 5, + env: Object.fromEntries(['HOME', 'USERPROFILE', 'APPDATA', 'LOCALAPPDATA', 'PATH', 'JAVA_HOME', 'TMP', 'TEMP', 'TMPDIR'].map(key => [key, output(key.toLowerCase())])) }); + steps.push({ name: `Continue repository verification ${count}`, id: continuation, + if: `\${{ always() && ${pending} }}`, uses: action, with: { alias: inputAlias }, + env: { COPILOT_NATIVE_PHASE: 'continue', COPILOT_NATIVE_SOURCE: `\${{ steps.${id}.outputs.verification-source }}`, COPILOT_NATIVE_DIGEST: `\${{ steps.${id}.outputs.verification-digest }}`, COPILOT_NATIVE_GIT: `\${{ steps.${id}.outputs.verification-git }}`, COPILOT_NATIVE_TICKET: `\${{ steps.${id}.outputs.verification-ticket }}`, + COPILOT_NATIVE_REQUEST: `\${{ steps.${previous}.outputs.verification-request }}`, + COPILOT_NATIVE_OUTCOME: `\${{ steps.${setup}.outcome }}` } }); + previous = continuation; + } + steps.push({ name: 'Complete repository verification', id: 'verification_complete', + if: `\${{ always() && steps.${id}.outputs.verification-ticket != '' }}`, uses: action, with: { alias: inputAlias }, + env: { COPILOT_NATIVE_PHASE: 'finish', COPILOT_NATIVE_SOURCE: `\${{ steps.${id}.outputs.verification-source }}`, COPILOT_NATIVE_DIGEST: `\${{ steps.${id}.outputs.verification-digest }}`, COPILOT_NATIVE_GIT: `\${{ steps.${id}.outputs.verification-git }}`, COPILOT_NATIVE_TICKET: `\${{ steps.${id}.outputs.verification-ticket }}` } }); + return steps; +} + +function renderSteps(action, alias = 'copilot-inputs', id = 'copilot') { + return yaml.dump(phaseSteps(action, alias, id), { lineWidth: -1, noRefs: true, quotingType: '"' }) + .replace(/with:\n alias: ([^\n]+)/g, 'with: *$1') + .split('\n').map(line => line ? ` ${line}` : '').join('\n'); +} + +function commentWorkflow(file, source = false) { + const pr = path.basename(file) === CALLBACKS[1]; + return { + name: `Copilot - ${pr ? 'Pull Request' : 'Issue'} Comment`, + on: { [pr ? 'pull_request_review_comment' : 'issue_comment']: { types: ['created', 'edited'] } }, + jobs: { [pr ? 'copilot-pull-requests' : 'copilot-issues']: { + if: expr(pr ? "(vars.COPILOT_BOT_LOGIN == '' || github.actor != vars.COPILOT_BOT_LOGIN) && github.event.pull_request.head.repo.full_name == github.repository" : "vars.COPILOT_BOT_LOGIN == '' || github.actor != vars.COPILOT_BOT_LOGIN"), + uses: source ? SELF_WORKFLOW : REMOTE_WORKFLOW, + permissions: { checks: 'write', contents: 'read' }, + with: { 'runs-on': JSON.stringify(source ? ['self-hosted', 'codex', 'Linux'] : 'ubuntu-latest'), + ...(source ? { 'issue-managed-branches': 'true', 'pre-branch-sdd': 'true', 'ai-ignore-files': 'build/*,specs/CATALOG.md', 'prepare-source-verification': true } : {}) }, + secrets: Object.fromEntries(SECRET_NAMES.map(name => [name, expr(`secrets.${name}`)])), + } }, + }; +} + +function runtimeWorkflow() { + const inputs = { ...BINDINGS, token: expr('secrets.PAT') }; + for (const key of ['issue-managed-branches', 'pre-branch-sdd', 'ai-ignore-files']) { + inputs[key] = BINDINGS[key].replace('${{ ', '${{ inputs.' + key + ' || '); + } + const initial = { name: 'Run Copilot', id: 'copilot', uses: SELF_ACTION, with: inputs, + env: { COPILOT_NATIVE_PHASE: 'prepare', + ...Object.fromEntries(['PROVIDER', 'MODEL_PROVIDER', 'MODEL', 'EFFORT', 'EXECUTABLE'].map(name => ['AGENT_' + name, expr('vars.AGENT_' + name + (name === 'PROVIDER' ? " || 'codex'" : name === 'MODEL_PROVIDER' ? " || 'openai'" : ''))])), + AGENT_ALLOWED_MODEL_PROVIDERS: expr("vars.AGENT_ALLOWED_MODEL_PROVIDERS || 'openai'"), + AGENT_ALLOWED_MODELS: expr("vars.AGENT_ALLOWED_MODELS || 'openai/gpt-6-luna'"), + ...Object.fromEntries(SECRET_NAMES.filter(name => name !== 'PAT').map(name => [name, expr('secrets.' + name)])), + COPILOT_EVIDENCE_TOKEN: expr('github.token') } }; + initial.env.CURSOR_API_KEY = expr("(vars.AGENT_PROVIDER == 'cursor' || vars.FINDINGS_PROVIDER == 'cursor' || vars.FIXER_PROVIDER == 'cursor' || vars.PLANNER_PROVIDER == 'cursor' || vars.REVIEWER_PROVIDER == 'cursor' || vars.TESTER_PROVIDER == 'cursor') && secrets.CURSOR_API_KEY || ''"); + const preparation = "env.COPILOT_PREPARE_VERIFICATION == 'true'"; + const steps = [ + { name: 'Checkout Repository', uses: 'actions/checkout@v5', with: { 'persist-credentials': false, 'fetch-depth': 0 } }, + { name: 'Prepare repository pnpm', if: preparation, uses: 'pnpm/action-setup@v5', with: { version: '10.12.4', standalone: false, dest: expr('runner.temp') + '/setup-pnpm-' + expr('github.run_id') + '-' + expr('github.run_attempt') + '-' + expr('github.job') } }, + { name: 'Prepare repository Node', if: preparation, uses: 'actions/setup-node@v7', with: { 'node-version': '24.x' } }, + { name: 'Install repository verification dependencies', if: preparation, run: 'pnpm install --frozen-lockfile --ignore-scripts', shell: 'bash' }, + initial, + ...phaseSteps(SELF_ACTION).map(step => ({ ...step, ...(step.with ? { with: inputs } : {}) })), + ]; + return { name: 'Copilot - Comment Runtime', on: { workflow_call: { + inputs: { 'runs-on': { description: 'JSON runner labels or group retained by setup.', type: 'string', default: '"ubuntu-latest"' }, + ...Object.fromEntries(['issue-managed-branches', 'pre-branch-sdd', 'ai-ignore-files'].map(key => [key, { description: `Optional ${key} override; otherwise use the caller repository Variable.`, type: 'string', default: '' }])), + 'prepare-source-verification': { description: 'Retain Copilot source-repository verification prerequisites; ignored in consumer repositories.', type: 'boolean', default: false } }, + secrets: Object.fromEntries(SECRET_NAMES.map(name => [name, { required: false }])) } }, + jobs: { copilot: { name: 'Copilot', + if: expr("(vars.COPILOT_BOT_LOGIN == '' || github.actor != vars.COPILOT_BOT_LOGIN) && (github.event_name == 'issue_comment' || (github.event_name == 'pull_request_review_comment' && github.event.pull_request.head.repo.full_name == github.repository))"), + 'runs-on': expr("fromJSON(inputs.runs-on)"), 'timeout-minutes': 120, + permissions: { checks: 'write', contents: 'read' }, + env: { COPILOT_PREPARE_VERIFICATION: expr("github.repository == 'vypdev/copilot' && inputs.prepare-source-verification && vars.BUGBOT_AUTOFIX_VERIFY_COMMANDS != '' && ((contains(github.event.comment.body, '/copilot') && ((contains(github.event.comment.body, 'sync-branch') && !contains(github.event.comment.body, '--dry-run')) || contains(github.event.comment.body, 'implement') || contains(github.event.comment.body, 'fix') || contains(github.event.comment.body, 'remember'))) || (vars.COPILOT_BOT_LOGIN != '' && contains(github.event.comment.body, format('@{0}', vars.COPILOT_BOT_LOGIN)) && !contains(github.event.comment.body, '--dry-run')))" ) }, steps } } }; +} + +function generate() { + for (const directory of ['.github/workflows', 'setup/workflows']) for (const file of CALLBACKS) { + fs.writeFileSync(path.join(directory, file), '# Generated by scripts/generate-native-verification-workflows.cjs\n# Project runtimes: .copilot/verification-prerequisites.json\n# Dependencies: .github/actions/copilot-verification-setup/action.yml\n# https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-verification-prerequisites\n' + yaml.dump(commentWorkflow(file, directory.startsWith('.github')), { lineWidth: -1, noRefs: true })); + } + fs.writeFileSync(path.join('.github/workflows', RUNTIME), '# Generated by scripts/generate-native-verification-workflows.cjs\n' + yaml.dump(runtimeWorkflow(), { lineWidth: -1 })); +} + +if (require.main === module) generate(); +module.exports = { MAX_REQUESTS, ACTION, SOURCE_ACTION, CALLBACKS, RUNTIME, SELF_ACTION, REMOTE_WORKFLOW, SELF_WORKFLOW, SECRET_NAMES, BINDINGS, phaseSteps, renderSteps, commentWorkflow, runtimeWorkflow, generate }; diff --git a/scripts/prepare-native-source-action.cjs b/scripts/prepare-native-source-action.cjs new file mode 100644 index 000000000..8863d6c79 --- /dev/null +++ b/scripts/prepare-native-source-action.cjs @@ -0,0 +1,42 @@ +const fs = require('node:fs'); +const path = require('node:path'); +const crypto = require('node:crypto'); + +const SOURCE_ACTION = './../.copilot-native-runtime'; +const FIXTURE_ACTION = './../.copilot-native-fixture-runtime'; +const RECEIPT = '.copilot-runtime-snapshot.json'; + +function prepareNativeSourceAction(workspace, fixture = false) { + workspace = fs.realpathSync(workspace); + const target = path.resolve(workspace, fixture ? FIXTURE_ACTION : SOURCE_ACTION); + const receipt = path.join(target, RECEIPT); + if (fs.existsSync(target)) { + const stat = fs.lstatSync(target); + if (!stat.isDirectory() || stat.isSymbolicLink()) throw new Error('Native runtime snapshot path is not an owned directory.'); + let previous; + try { previous = JSON.parse(fs.readFileSync(receipt, 'utf8')); } catch { throw new Error('Native runtime snapshot directory is not owned by Copilot.'); } + if (previous?.kind !== 'copilot-native-runtime' || previous.workspace !== workspace) throw new Error('Native runtime snapshot ownership does not match.'); + fs.rmSync(target, { recursive: true, force: true }); + } + fs.mkdirSync(target, { mode: 0o700 }); + const source = fixture ? path.join(workspace, '.github/actions/copilot-native-fixture') : workspace; + const files = fixture ? ['action.yml', 'dist/index.js'] : ['action.yml', 'build/github_action/index.js']; + const hashes = {}; + for (const file of files) { + const from = path.join(source, file); + if (!fs.lstatSync(from).isFile() || fs.lstatSync(from).isSymbolicLink()) throw new Error('Native runtime source must be a regular file.'); + const data = fs.readFileSync(from); + fs.mkdirSync(path.dirname(path.join(target, file)), { recursive: true, mode: 0o700 }); + fs.writeFileSync(path.join(target, file), data, { mode: 0o600, flag: 'wx' }); + hashes[file] = crypto.createHash('sha256').update(data).digest('hex'); + } + if (!fixture && fs.existsSync(path.join(workspace, 'setup'))) fs.cpSync(path.join(workspace, 'setup'), path.join(target, 'setup'), { recursive: true, dereference: false }); + fs.writeFileSync(receipt, JSON.stringify({ kind: 'copilot-native-runtime', workspace, hashes }), { mode: 0o600, flag: 'wx' }); + return target; +} + +if (require.main === module) { + const target = prepareNativeSourceAction(process.cwd(), process.argv.includes('--fixture')); + if (process.env.GITHUB_OUTPUT) fs.appendFileSync(process.env.GITHUB_OUTPUT, `path=${target}\n`); +} +module.exports = { prepareNativeSourceAction, SOURCE_ACTION, FIXTURE_ACTION }; diff --git a/scripts/repowise_history.py b/scripts/repowise_history.py new file mode 100644 index 000000000..9fb0007af --- /dev/null +++ b/scripts/repowise_history.py @@ -0,0 +1,248 @@ +"""Bounded full-history adapter for the explicitly pinned RepoWise version. + +Keep RepoWise's traversal, provenance, allowlists, deduplication and detectors. +Replace only its eager blob dictionary and work discarded by secrets-only mode. +Private interfaces are deliberate: upgrades require the compatibility fixtures. +""" + +from __future__ import annotations + +import atexit +from collections import deque +from concurrent.futures import ProcessPoolExecutor +from importlib.metadata import version +import multiprocessing +from pathlib import Path +import subprocess + +REPOWISE_VERSION = "0.58.0" +HISTORY_WORKERS = 2 + + +class BlobReader: + """One request/response at a time; never retain previous blob contents.""" + + def __init__(self, repo: Path): + self.process = subprocess.Popen( + ["git", "-C", str(repo), "cat-file", "--batch"], + stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, + ) + self.count = 0 + self.bytes_read = 0 + self.largest_blob = 0 + atexit.register(self.close) + + def get(self, sha: str, default: str = "") -> str: + # Object names come from Git, never accept a batch protocol injection. + if len(sha) not in (40, 64) or any(c not in "0123456789abcdef" for c in sha): + raise ValueError("Invalid blob object name") + self.process.stdin.write((sha + "\n").encode("ascii")) + self.process.stdin.flush() + header = self.process.stdout.readline(256).split() + if len(header) != 3 or header[0].decode("ascii") != sha or header[1] != b"blob": + raise RuntimeError("Missing or malformed Git blob response") + size = int(header[2]) + if size < 0: + raise RuntimeError("Negative Git blob size") + content = self.process.stdout.read(size) + if len(content) != size or self.process.stdout.read(1) != b"\n": + raise RuntimeError("Truncated Git blob response") + self.count += 1 + self.bytes_read += size + self.largest_blob = max(self.largest_blob, size) + if self.count % 1000 == 0: + import sys + print(f"History: {self.count} source blobs, {self.bytes_read} bytes read", file=sys.stderr, flush=True) + return content.decode("utf-8", errors="replace") + + def close(self): + if self.process.poll() is None: + self.process.terminate() + try: + self.process.wait(timeout=2) + except subprocess.TimeoutExpired: + self.process.kill() + self.process.wait() + for stream in (self.process.stdin, self.process.stdout): + if stream: + stream.close() + + +class SecretPrefilter: + # Necessary literals in every line-oriented SECRET_KINDS regex in 0.58.0. + # False positives are allowed; authoritative matching stays in RepoWise. + # PEM is a separate spanning pass and deliberately never gated here. + literals = ( + "password", "apikey", "api_key", "secret", "token", "accesskey", "access_key", + "akia", "asia", "gho_", "ghp_", "ghr_", "ghs_", "ghu_", "github_pat_", + "xox", "aiza", "sk_", "rk_", "glpat-", "gldt-", "glrt-", "glptt-", + "gloas-", "glimt-", "glcbt-", "gr1348941", "azdo", "://", + ) + + def search(self, text): + # Python IGNORECASE also accepts dotless i, long s and dotted I. + lowered = text.lower().replace("ı", "i").replace("ſ", "s").replace("\u0307", "") + return any(literal in lowered for literal in self.literals) + + +def configure_secret_scan(): + from repowise.core.analysis.security import scanner + from repowise.core.analysis.security.patterns import SECRET_KINDS + + scanner._PATTERNS = [p for p in scanner._PATTERNS if p[1] in SECRET_KINDS] + scanner._SPANNING_PATTERNS = [p for p in scanner._SPANNING_PATTERNS if p[1] in SECRET_KINDS] + scanner._ANY_PATTERN = SecretPrefilter() + # History's secrets_only=True discards all call findings; don't compute them. + scanner._call_findings = lambda *args: [] + + +def initialize_worker(repo): + import resource + import sys + from multiprocessing.util import Finalize + + # Two workers have a deliberately smaller cap than the coordinating CLI. + if sys.platform == "linux": + resource.setrlimit(resource.RLIMIT_AS, (1024 * 1024**2,) * 2) + configure_secret_scan() + global worker_reader + worker_reader = BlobReader(Path(repo)) + Finalize(None, worker_reader.close, exitpriority=10) + + +def scan_blob(sha, path): + from repowise.core.analysis.security.scanner import scan_source + + before = worker_reader.bytes_read + content = worker_reader.get(sha) + findings = scan_source(path, content) + # Upstream only needs source again for findings' fingerprints/material. + # Negative results carry no large source string across the process pipe. + return findings, content if findings else "", worker_reader.bytes_read - before + + +class PrefetchedBlobs: + """At most two tasks/results resident; consume in upstream history order.""" + + def __init__(self, repo, shas, paths): + self.pool = ProcessPoolExecutor( + max_workers=HISTORY_WORKERS, mp_context=multiprocessing.get_context("spawn"), + initializer=initialize_worker, initargs=(str(repo),), + ) + self.remaining = iter(shas) + self.paths = paths + self.pending = deque() + self.findings = [] + self.count = self.bytes_read = self.largest_blob = 0 + for _ in range(HISTORY_WORKERS): + self.enqueue() + + def enqueue(self): + sha = next(self.remaining, None) + if sha: + self.pending.append((sha, self.pool.submit(scan_blob, sha, self.paths[sha]))) + + def get(self, sha, default=""): + expected, future = self.pending.popleft() + if expected != sha: + raise RuntimeError("History traversal order changed; adapter compatibility failure") + self.findings, content, size = future.result() + self.count += 1 + self.bytes_read += size + self.largest_blob = max(self.largest_blob, size) + self.enqueue() + if self.count % 1000 == 0: + import sys + print(f"History: {self.count} source blobs, {self.bytes_read} bytes scanned", file=sys.stderr, flush=True) + return content + + def close(self): + self.pool.shutdown(wait=True, cancel_futures=True) + + +class PrefetchedScanner: + def __init__(self, reader, delegate): + self.reader = reader + self.delegate = delegate + + async def scan_file(self, path, content, symbols): + return self.reader.findings + + async def persist(self, *args, **kwargs): + return await self.delegate.persist(*args, **kwargs) + + +def bounded_scanner_class(original, readers): + class BoundedHistoryScanner(original): + def _unique_blobs(self, *args): + self.blob_paths = super()._unique_blobs(*args) + return self.blob_paths + + def _read_blobs_batch(self, repo_path, blob_shas): + reader = PrefetchedBlobs(repo_path, blob_shas, self.blob_paths) + readers.append(reader) + self._scanner = PrefetchedScanner(reader, self._scanner) + return reader + + return BoundedHistoryScanner + + +def strict_git(repo_path, args, *, timeout=30.0): + # Upstream's best-effort helper returns an empty string on Git failures, + # which could otherwise turn a failed history enumeration into a clean scan. + return subprocess.run( + ["git", "-C", str(repo_path), *args], check=True, timeout=timeout, + capture_output=True, text=True, encoding="utf-8", errors="replace", + ).stdout + + +def fail_on_persistence_error(): + import logging + + class PersistenceFailure(logging.Handler): + def emit(self, record): + if record.getMessage().startswith("security_finding_persist_failed"): + raise RuntimeError("History finding persistence failed") + + logger = logging.getLogger("repowise.core.analysis.security_scan") + # Override the CLI's ancestor ERROR level: upstream logs swallowed writes + # at WARNING. This handler raises before a diagnostic can pollute JSON. + logger.setLevel(logging.WARNING) + handler = PersistenceFailure() + logger.addHandler(handler) + return handler + + +def main(): + import json + import os + + if version("repowise") != REPOWISE_VERSION: + raise RuntimeError("Unsupported RepoWise version; rerun compatibility fixtures before upgrading") + from repowise.core.analysis import history_scan + from repowise.cli.main import cli + + readers = [] + fail_on_persistence_error() + history_scan._run_git = strict_git + history_scan.HistorySecurityScanner = bounded_scanner_class(history_scan.HistorySecurityScanner, readers) + try: + cli(["security", "scan", "--history", "--path", ".", "--format", "json"]) + finally: + for reader in readers: + reader.close() + metrics = os.environ.get("REPOWISE_HISTORY_METRICS") + if metrics: + Path(metrics).write_text(json.dumps({ + "blobs_read": sum(r.count for r in readers), + "bytes_read": sum(r.bytes_read for r in readers), + "largest_blob_bytes": max((r.largest_blob for r in readers), default=0), + "reader_cache_blobs": 0, + "max_blob_requests_in_flight": HISTORY_WORKERS, + "workers": HISTORY_WORKERS, + "worker_virtual_memory_mib": 1024, + }) + "\n") + + +if __name__ == "__main__": + main() diff --git a/scripts/repowise_reports.py b/scripts/repowise_reports.py new file mode 100644 index 000000000..e3cb0c8e8 --- /dev/null +++ b/scripts/repowise_reports.py @@ -0,0 +1,172 @@ +"""Manual RepoWise orchestration. Stdlib only; no application/runtime dependency.""" + +from __future__ import annotations + +import argparse +import json +import os +from pathlib import Path +import resource +import signal +import subprocess +import sys +import time + +from repowise_history import REPOWISE_VERSION + +# Maximum wall seconds and virtual MiB per process. Sum fits the 40-minute job, +# leaving setup, tests, publication and cleanup time. No caller-controlled flags. +BUDGETS = {"index": (900, 4096), "health-md": (60, 2048), + "health-json": (60, 2048), "dead-code": (60, 2048), "security": (1200, 2048)} + + +def validate_index(path): + events = [json.loads(line) for line in path.read_text().splitlines() if line.strip()] + summaries = [e for e in events if e.get("event") == "summary"] + dead = [e for e in events if e.get("phase") == "dead_code" and e.get("state") == "done"] + health = [e for e in events if e.get("phase") == "health" and e.get("state") == "done"] + if not summaries or summaries[-1].get("status") != "ready" or not dead or not health: + raise ValueError("Index did not confirm ready status and completed dead-code analysis") + if any(e.get("state") in ("failed", "error") for e in events): + raise ValueError("Index contains an incomplete phase") + state = json.loads(Path(".repowise/state.json").read_text()) + head = subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip() + if state.get("last_sync_commit") != head: + raise ValueError("Index revision does not match HEAD") + + +def validate_json(path, kind): + value = json.loads(path.read_text()) + if kind == "dead-code": + if not isinstance(value, list) or not all(isinstance(f, dict) and "kind" in f for f in value): + raise ValueError("Invalid dead-code report") + if "Read from the index" not in (path.parent / "dead-code.stderr.log").read_text(): + raise ValueError("Dead-code did not reuse the index") + return value + if not isinstance(value, dict): + raise ValueError("Expected a JSON object") + required = {"health-json": ("targets", "refactoring_plans"), + "security": ("commits_scanned", "files_scanned", "blobs_scanned", "by_kind", "by_severity")}[kind] + if not all(k in value for k in required): + raise ValueError("Incomplete report schema") + if kind == "health-json" and value.get("source") != "index": + raise ValueError("Health report did not reuse the index") + if kind == "health-json": + head = subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip() + if value.get("analyzed_commit") != head: + raise ValueError("Stored health revision does not match HEAD") + if kind == "security" and (value["commits_scanned"] <= 0 or value["files_scanned"] <= 0): + raise ValueError("History scan did not cover any commits or source blobs") + if kind == "security": + expected = int(subprocess.check_output(["git", "rev-list", "--all", "--count"], text=True)) + measured = json.loads((path.parent / "history-resources.json").read_text()) + if value["commits_scanned"] != expected or measured["blobs_read"] != value["files_scanned"]: + raise ValueError("History coverage does not match reachable commits and requested source blobs") + return value + + +def run_stage(name, command, output, report_dir, validator=None): + seconds, memory_mib = BUDGETS[name] + started = time.monotonic() + measurement = report_dir / (name + ".resources.txt") + result = {"status": "incomplete", "timeout_seconds": seconds, "virtual_memory_mib": memory_mib} + + def limits(): + resource.setrlimit(resource.RLIMIT_AS, (memory_mib * 1024**2,) * 2) + + try: + with output.open("w") as out, (report_dir / (name + ".stderr.log")).open("w") as err: + process = subprocess.Popen( + ["/usr/bin/time", "-f", "%e %M", "-o", str(measurement), *command], + stdout=out, stderr=err, start_new_session=True, preexec_fn=limits, + ) + try: + code = process.wait(timeout=seconds) + except subprocess.TimeoutExpired: + os.killpg(process.pid, signal.SIGKILL) + process.wait() + raise RuntimeError(f"Timed out after {seconds}s") + if code: + raise RuntimeError(f"Command exited {code}; inspect {name}.stderr.log") + if validator: + validator(output) + elif not output.stat().st_size: + raise ValueError("Empty report") + result["status"] = "complete" + except Exception as error: + result["error"] = str(error) + # Keep diagnostic/index logs; never publish malformed JSON as a report. + if output.suffix == ".json": + output.unlink(missing_ok=True) + print(f"::warning::RepoWise {name} incomplete: {error}", flush=True) + finally: + result["wall_seconds"] = round(time.monotonic() - started, 3) + if measurement.exists(): + fields = (measurement.read_text().splitlines() or [""])[-1].split() + if len(fields) == 2 and fields[1].isdigit(): + result["peak_rss_kib"] = int(fields[1]) + print(f"RepoWise {name}: {result['status']} ({result['wall_seconds']}s)", flush=True) + return result + + +def write_summary(report_dir, sha, results): + lines = ["## RepoWise code health", "", f"Analyzed revision: `{sha}`", "", + "Security scope: full reachable history, RepoWise secret patterns; generated bundles included.", + "Health and safe-only dead-code: stored results from this revision's completed index.", "", + "| Phase | Status | Seconds | Peak RSS (MiB) |", "|---|---|---:|---:|"] + for name, result in results.items(): + rss = result.get("peak_rss_kib") + lines.append(f"| {name} | {result['status']} | {result.get('wall_seconds', '—')} | {round(rss / 1024, 1) if rss is not None else '—'} |") + incomplete = any(r["status"] != "complete" for r in results.values()) + lines += ["", ("Analysis incomplete. Inspect phase logs in the artifact, fix the cause, then rerun." + if incomplete else "Analysis complete. Findings are advisory; download the reports to review them."), + "Artifact: `repowise-code-health` (14 days), including scope, timings, logs and completed reports.", ""] + text = "\n".join(lines) + (report_dir / "summary.md").write_text(text) + (report_dir / "timings.json").write_text(json.dumps(results, indent=2) + "\n") + (report_dir / "advisory-status.txt").write_text("\n".join(f"{n}: {r['status']}" for n, r in results.items()) + "\n") + if os.environ.get("GITHUB_STEP_SUMMARY"): + with open(os.environ["GITHUB_STEP_SUMMARY"], "a") as summary: + summary.write(text) + return incomplete + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--report-dir", required=True, type=Path) + args = parser.parse_args() + report_dir = args.report_dir.resolve() + report_dir.mkdir(parents=True, exist_ok=True) + sha = subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip() + (report_dir / "revision.txt").write_text(sha + "\n") + refs = subprocess.check_output(["git", "for-each-ref", "--format=%(objectname) %(refname)"], text=True).splitlines() + (report_dir / "scope.json").write_text(json.dumps({ + "revision": sha, "refs": refs, "repowise_version": REPOWISE_VERSION, + "security": "full reachable history (--all), RepoWise source extensions and secret patterns; upstream allowlists apply", + "health": "all indexed origins, cached refactoring targets", "dead_code": "cached safe-only findings", + "index_commit_limit": 500, "history_commit_limit": None, "logical_cpus": os.cpu_count(), + }, indent=2) + "\n") + os.environ.update(OPENBLAS_NUM_THREADS="1", OMP_NUM_THREADS="1", REPOWISE_SKIP_EDITOR_SETUP="1", REPOWISE_NO_SAVE_KEY="1", + REPOWISE_HISTORY_METRICS=str(report_dir / "history-resources.json")) + binary = str(Path(sys.executable).with_name("repowise")) + commands = { + "index": ([binary, "init", "--no-prose", "--no-claude-md", "--no-codex", "--no-editor-setup", + "--no-onboarding", "--no-distill-hook", "--no-workspace", "--no-seed", "--no-save-key", + "--commit-limit", "500", "--progress", "json", "."], "index.log", validate_index), + "health-md": ([binary, "health", "--no-workspace", "--refactoring-targets", "--scope", "all", "--format", "md", "."], "health.md", None), + "health-json": ([binary, "health", "--no-workspace", "--refactoring-targets", "--scope", "all", "--format", "json", "."], "health.json", lambda p: validate_json(p, "health-json")), + "dead-code": ([binary, "dead-code", "--safe-only", "--no-workspace", "--format", "json", "."], "dead-code.json", lambda p: validate_json(p, "dead-code")), + "security": ([sys.executable, str(Path(__file__).with_name("repowise_history.py"))], "security.json", lambda p: validate_json(p, "security")), + } + results = {} + for name, (command, filename, validator) in commands.items(): + # Exporting cached empty data after a failed index would be misleading. + if name != "security" and name != "index" and results["index"]["status"] != "complete": + results[name] = {"status": "incomplete", "error": "Index did not complete"} + continue + results[name] = run_stage(name, command, report_dir / filename, report_dir, validator) + return int(write_summary(report_dir, sha, results)) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/smoke-test-npm-package.cjs b/scripts/smoke-test-npm-package.cjs index a411d8920..496bac85f 100644 --- a/scripts/smoke-test-npm-package.cjs +++ b/scripts/smoke-test-npm-package.cjs @@ -45,6 +45,11 @@ try { const help = execFileSync(process.execPath, [cliPath, '--help'], { encoding: 'utf8' }); const bugbotApi = require(bugbotApiPath); const cliBundle = fs.readFileSync(cliPath, 'utf8'); + const verificationStarter = fs.readFileSync(path.join(packageRoot, 'setup/actions/copilot-verification-setup/action.yml'), 'utf8'); + if (!verificationStarter.includes('using: composite') || !verificationStarter.includes('exit 1') + || !verificationStarter.includes('MAIN_BRANCH') || !cliBundle.includes('setup/actions/copilot-verification-setup/action.yml')) { + throw new Error('Packaged setup must resolve the fail-closed consumer verification starter.'); + } for (const runtime of ['github_action', 'api']) { const bundle = fs.readFileSync(path.join(packageRoot, 'build', runtime, 'index.js'), 'utf8'); if (bundle.includes('Local setup web assets are incomplete') || bundle.includes('Control moved to another tab.')) { diff --git a/scripts/tests/test_repowise.py b/scripts/tests/test_repowise.py new file mode 100644 index 000000000..a41a400ff --- /dev/null +++ b/scripts/tests/test_repowise.py @@ -0,0 +1,355 @@ +"""Pinned-package compatibility and resource/failure regressions for manual CI.""" + +import asyncio +from contextlib import contextmanager +from importlib.metadata import version +import io +import json +from pathlib import Path +import subprocess +import sys +import tempfile +import unittest +from unittest.mock import Mock, patch + +sys.path.insert(0, str(Path(__file__).resolve().parents[1])) +import repowise_history as history +import repowise_reports as reports +from repowise.core.analysis import history_scan +from repowise.core.analysis.security import scanner +from repowise.core.analysis.security.patterns import SECRET_KINDS + + +@contextmanager +def optimized(): + names = ("_PATTERNS", "_SPANNING_PATTERNS", "_ANY_PATTERN", "_call_findings") + saved = {name: getattr(scanner, name) for name in names} + try: + history.configure_secret_scan() + yield + finally: + for name, value in saved.items(): + setattr(scanner, name, value) + + +class SecretCompatibility(unittest.TestCase): + def compare(self, kind, text): + expected = [f for f in scanner.scan_source("src/code.ts", text) if f["kind"] in SECRET_KINDS] + self.assertIn(kind, {f["kind"] for f in expected}) + with optimized(): + self.assertEqual(expected, scanner.scan_source("src/code.ts", text)) + + def test_pin(self): + self.assertEqual(history.REPOWISE_VERSION, version("repowise")) + + def test_password(self): + self.compare("hardcoded_password", 'password = "Q9vLm2rX7pNs4kT8"') + + def test_secret(self): + self.compare("hardcoded_secret", 'API_KEY = "V8mK2qZ9fT4nY7jP"') + + def test_unicode_case(self): + self.compare("hardcoded_secret", 'APı_KEY = "V8mK2qZ9fT4nY7jP"') + + def test_aws(self): + self.compare("aws_access_key", 'const x = "AK' + 'IA' + 'QWERTYUIOPASDFGH"') + + def test_github(self): + self.compare("github_token", 'const x = "gh' + 'p_' + 'Q2wE3rT4yU5iO6pA7sD8fG9hJ0kL1zX2cV3b' + '"') + + def test_slack(self): + self.compare("slack_token", 'const x = "xo' + 'xb-' + '123456789012-987654321012-A7bC9dE2fG4hI6jK"') + + def test_google(self): + self.compare("google_api_key", 'const x = "AI' + 'za' + 'Q2wE3rT4yU5iO6pA7sD8fG9hJ0kL1zX2cV3"') + + def test_stripe(self): + self.compare("stripe_key", 'const x = "sk_' + 'live_' + 'Q2wE3rT4yU5iO6pA7sD8fG9h"') + + def test_gitlab(self): + self.compare("gitlab_token", 'const x = "gl' + 'pat-' + 'Q2wE3rT4yU5iO6pA7sD8fG9h"') + + def test_azure(self): + self.compare("azure_devops_pat", 'const x = "' + ('Q2wE3rT4yU5iO6pA7sD8fG9hJ0kL1zX2cV3bN4m' * 3)[:76] + 'AZDOq7W2"') + + def test_git_url(self): + self.compare("git_url_credentials", 'const x = "https://user:Q9vLm2rX7pNs4kT8@github.com/org/repo.git"') + + def test_multiline_pem(self): + self.compare("private_key_pem", '-----BEGIN PRIVATE KEY-----\n' + 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASC' * 3 + '\n-----END PRIVATE KEY-----') + + def test_placeholders_and_suppression(self): + text = 'api_key = "example"; eval("code");\n// repowise:ignore\npassword = "${ENV}"' + expected = [f for f in scanner.scan_source("tests/a.ts", text) if f["kind"] in SECRET_KINDS] + with optimized(): + self.assertEqual(expected, scanner.scan_source("tests/a.ts", text)) + + +class BlobProtocol(unittest.TestCase): + def reader(self, response): + process = Mock(stdin=io.BytesIO(), stdout=io.BytesIO(response)) + process.poll.return_value = 0 + with patch.object(history.subprocess, "Popen", return_value=process), patch.object(history.atexit, "register"): + return history.BlobReader(Path(".")) + + def test_sequential_blobs_no_cache(self): + sha = "a" * 40 + reader = self.reader(f"{sha} blob 3\none\n{sha} blob 3\ntwo\n".encode()) + self.assertEqual("one", reader.get(sha)) + self.assertEqual("two", reader.get(sha)) + self.assertEqual((2, 6, 3), (reader.count, reader.bytes_read, reader.largest_blob)) + self.assertNotIn("contents", reader.__dict__) + + def test_missing_blob_fails(self): + reader = self.reader(b"a missing\n") + with self.assertRaises(RuntimeError): + reader.get("a" * 40) + + def test_truncated_blob_fails(self): + reader = self.reader(("a" * 40 + " blob 100\nshort").encode()) + with self.assertRaises(RuntimeError): + reader.get("a" * 40) + + def test_protocol_injection_rejected(self): + with self.assertRaises(ValueError): + self.reader(b"").get("HEAD\nHEAD") + + def test_git_error_is_not_empty_history(self): + with tempfile.TemporaryDirectory() as directory: + with self.assertRaises(subprocess.CalledProcessError): + history.strict_git(Path(directory), ["rev-list", "--all"]) + + +class HistoryIntegration(unittest.TestCase): + def test_deleted_and_other_ref_secrets_preserve_upstream_provenance(self): + with tempfile.TemporaryDirectory() as directory: + root = Path(directory) + def git(*args): + return subprocess.check_output(["git", "-C", directory, *args], stderr=subprocess.DEVNULL, text=True).strip() + git("init", "-b", "main") + git("config", "user.name", "Fixture") + git("config", "user.email", "fixture@example.invalid") + (root / "deleted.ts").write_text('password = "Q9vLm2rX7pNs4kT8"') + git("add", ".") + git("-c", "core.hooksPath=/dev/null", "commit", "-qm", "introduce") + introduction = git("rev-parse", "HEAD") + git("rm", "deleted.ts") + git("-c", "core.hooksPath=/dev/null", "commit", "-qm", "remove") + git("checkout", "-b", "other") + (root / "other.ts").write_text('secret = "J4fT8nP2qW6rY9kZ"') + git("add", ".") + git("-c", "core.hooksPath=/dev/null", "commit", "-qm", "other branch") + git("checkout", "main") + + class Sink: + def __init__(self): self.saved = [] + async def scan_file(self, path, content, symbols): return scanner.scan_source(path, content, symbols) + async def persist(self, path, findings, **provenance): + self.saved.append((path, findings, provenance)) + return len(findings) + + async def scan(bounded): + readers = [] + cls = history.bounded_scanner_class(history_scan.HistorySecurityScanner, readers) if bounded else history_scan.HistorySecurityScanner + instance = cls(None, "fixture") + sink = Sink() + instance._scanner = sink + try: + with patch.object(history_scan, "_run_git", history.strict_git): + summary = await instance.scan_history(root) + return summary, sink.saved + finally: + for reader in readers: reader.close() + + expected = asyncio.run(scan(False)) + with optimized(): actual = asyncio.run(scan(True)) + self.assertEqual(expected, actual) + self.assertEqual(3, actual[0].commits_scanned) + self.assertEqual(2, actual[0].findings_inserted) + deleted = next(f for f in actual[1] if f[0] == "deleted.ts") + self.assertEqual(introduction, deleted[2]["commit_sha"]) + + +class BoundedPrefetch(unittest.TestCase): + def reader(self, count=5): + pool = Mock() + def submit(function, sha, path): + future = Mock() + future.result.return_value = ([], "", 3) + return future + pool.submit.side_effect = submit + with patch.object(history, "ProcessPoolExecutor", return_value=pool): + reader = history.PrefetchedBlobs(Path("."), [str(i) for i in range(count)], {str(i): "a.ts" for i in range(count)}) + return reader, pool + + def test_queue_has_fixed_width(self): + reader, pool = self.reader() + self.assertEqual(2, pool.submit.call_count) + for i in range(5): + reader.get(str(i)) + self.assertLessEqual(len(reader.pending), 2) + self.assertEqual((5, 15), (reader.count, reader.bytes_read)) + reader.close() + pool.shutdown.assert_called_once_with(wait=True, cancel_futures=True) + + def test_traversal_order_mismatch_fails(self): + reader, _ = self.reader() + with self.assertRaises(RuntimeError): reader.get("other") + + def test_worker_failure_propagates(self): + reader, _ = self.reader() + reader.pending[0][1].result.side_effect = RuntimeError("worker failed") + with self.assertRaisesRegex(RuntimeError, "worker failed"): reader.get("0") + self.assertEqual(0, reader.count) + + def test_prefetched_results_preserve_delegate_persistence(self): + from unittest.mock import AsyncMock + reader = Mock(findings=[{"kind": "hardcoded_secret"}]) + delegate = Mock(); delegate.persist = AsyncMock(return_value=1) + instance = history.PrefetchedScanner(reader, delegate) + self.assertEqual(reader.findings, asyncio.run(instance.scan_file("a.ts", "", []))) + self.assertEqual(1, asyncio.run(instance.persist("a.ts", reader.findings, commit_sha="abc"))) + delegate.persist.assert_awaited_once_with("a.ts", reader.findings, commit_sha="abc") + + +class ReportFailures(unittest.TestCase): + def setUp(self): + # Failure fixtures must not publish fake warnings or a synthetic partial + # Job Summary when this suite runs inside the real manual workflow. + output = patch("sys.stdout", new_callable=io.StringIO) + output.start() + self.addCleanup(output.stop) + environment = patch.dict(reports.os.environ, {"GITHUB_STEP_SUMMARY": ""}) + environment.start() + self.addCleanup(environment.stop) + + def test_swallowed_persistence_failure_becomes_fatal(self): + from repowise.core.analysis.security.store import SecurityScanner, logger + from unittest.mock import AsyncMock + previous = logger.level + handler = history.fail_on_persistence_error() + session = Mock(); session.execute = AsyncMock(side_effect=RuntimeError("broken database")) + try: + instance = SecurityScanner(session, "fixture") + with self.assertRaisesRegex(RuntimeError, "persistence failed"): + asyncio.run(instance.persist("a.ts", [{"kind": "hardcoded_secret", "severity": "high"}])) + finally: + logger.removeHandler(handler) + logger.setLevel(previous) + + def test_budgets_fit_job_with_publication_margin(self): + self.assertLessEqual(sum(v[0] for v in reports.BUDGETS.values()), 38 * 60) + self.assertEqual((1200, 2048), reports.BUDGETS["security"]) + self.assertEqual((60, 2048), reports.BUDGETS["dead-code"]) + + def test_success_measures_rss_and_publishes_valid_json(self): + with tempfile.TemporaryDirectory() as directory: + root = Path(directory); p = root / "dead-code.json" + def start(command, **kwargs): + kwargs["stdout"].write("[]") + kwargs["stdout"].flush() + kwargs["stderr"].write("Read from the index") + kwargs["stderr"].flush() + (root / "dead-code.resources.txt").write_text("1.2 2048\n") + process = Mock(); process.wait.return_value = 0 + return process + with patch.object(reports.subprocess, "Popen", side_effect=start): + result = reports.run_stage("dead-code", ["fixture"], p, root, lambda p: reports.validate_json(p, "dead-code")) + self.assertEqual("complete", result["status"]) + self.assertEqual(2048, result["peak_rss_kib"]) + self.assertTrue(p.exists()) + + def test_dead_code_live_fallback_rejected(self): + with tempfile.TemporaryDirectory() as directory: + root = Path(directory); p = root / "dead-code.json" + p.write_text('[]'); (root / "dead-code.stderr.log").write_text("Computing live") + with self.assertRaisesRegex(ValueError, "reuse the index"): + reports.validate_json(p, "dead-code") + + def test_stale_health_revision_rejected(self): + with tempfile.TemporaryDirectory() as directory: + p = Path(directory) / "health.json" + p.write_text('{"targets":[],"refactoring_plans":[],"source":"index","analyzed_commit":"old"}') + with patch.object(reports.subprocess, "check_output", return_value="current"): + with self.assertRaisesRegex(ValueError, "revision"): + reports.validate_json(p, "health-json") + + def test_command_failure_is_incomplete(self): + with tempfile.TemporaryDirectory() as directory: + root = Path(directory); process = Mock(); process.wait.return_value = 1 + with patch.object(reports.subprocess, "Popen", return_value=process): + result = reports.run_stage("security", ["fixture"], root / "security.json", root) + self.assertEqual("incomplete", result["status"]) + self.assertIn("exited 1", result["error"]) + + def test_security_coverage_mismatch_rejected(self): + with tempfile.TemporaryDirectory() as directory: + root = Path(directory); p = root / "security.json" + p.write_text(json.dumps(dict(commits_scanned=3, files_scanned=2, blobs_scanned=3, by_kind={}, by_severity={}))) + (root / "history-resources.json").write_text('{"blobs_read":1}') + with patch.object(reports.subprocess, "check_output", return_value="3"): + with self.assertRaises(ValueError): reports.validate_json(p, "security") + + def test_live_health_report_rejected(self): + with tempfile.TemporaryDirectory() as directory: + p = Path(directory) / "health.json" + p.write_text('{"targets":[],"refactoring_plans":[],"source":"live"}') + with self.assertRaises(ValueError): reports.validate_json(p, "health-json") + + def test_dead_code_report_schema_rejected(self): + with tempfile.TemporaryDirectory() as directory: + p = Path(directory) / "dead-code.json"; p.write_text('{}') + with self.assertRaises(ValueError): reports.validate_json(p, "dead-code") + + def test_index_requires_completed_dead_code(self): + with tempfile.TemporaryDirectory() as directory: + p = Path(directory) / "index.log" + p.write_text(json.dumps({"event": "summary", "status": "ready"}) + "\n") + with self.assertRaises(ValueError): reports.validate_index(p) + + def test_index_rejects_degraded(self): + with tempfile.TemporaryDirectory() as directory: + p = Path(directory) / "index.log" + p.write_text('{"phase":"dead_code","state":"done"}\n{"event":"summary","status":"partial"}\n') + with self.assertRaises(ValueError): reports.validate_index(p) + + def test_malformed_json_deleted_and_failure_reported(self): + with tempfile.TemporaryDirectory() as directory: + root = Path(directory); p = root / "security.json" + process = Mock(pid=1234); process.wait.return_value = 0 + with patch.object(reports.subprocess, "Popen", return_value=process): + result = reports.run_stage("security", ["fixture"], p, root, lambda p: reports.validate_json(p, "security")) + self.assertEqual("incomplete", result["status"]) + self.assertFalse(p.exists()) + + def test_timeout_kills_process_group(self): + with tempfile.TemporaryDirectory() as directory: + root = Path(directory); process = Mock(pid=1234) + process.wait.side_effect = [subprocess.TimeoutExpired("fixture", 1), 0] + with patch.object(reports.subprocess, "Popen", return_value=process), patch.object(reports.os, "killpg") as kill: + result = reports.run_stage("dead-code", ["fixture"], root / "dead-code.json", root) + kill.assert_called_once_with(1234, reports.signal.SIGKILL) + self.assertEqual("incomplete", result["status"]) + + def test_empty_security_coverage_rejected(self): + with tempfile.TemporaryDirectory() as directory: + p = Path(directory) / "security.json" + p.write_text(json.dumps(dict(commits_scanned=0, files_scanned=0, blobs_scanned=0, by_kind={}, by_severity={}))) + with self.assertRaises(ValueError): reports.validate_json(p, "security") + + def test_partial_summary_retains_complete_phases(self): + with tempfile.TemporaryDirectory() as directory: + root = Path(directory) + incomplete = reports.write_summary(root, "a" * 40, { + "health-md": {"status": "complete", "wall_seconds": 1, "peak_rss_kib": 1024}, + "security": {"status": "incomplete", "wall_seconds": 1200}, + }) + self.assertTrue(incomplete) + text = (root / "summary.md").read_text() + self.assertIn("Analysis incomplete", text) + self.assertIn("| health-md | complete |", text) + self.assertIn("full reachable history", text) + + +if __name__ == "__main__": + unittest.main() diff --git a/scripts/validate-comment-workflows.cjs b/scripts/validate-comment-workflows.cjs new file mode 100644 index 000000000..e40c8dfd5 --- /dev/null +++ b/scripts/validate-comment-workflows.cjs @@ -0,0 +1,33 @@ +const path = require('node:path'); +const { isDeepStrictEqual } = require('node:util'); +const contract = require('./generate-native-verification-workflows.cjs'); +const { copilotCommentRunner, isCopilotCommentRunner } = require('../src/domain/copilot_comment_workflow.ts'); + +function assertCommentWorkflowCaller(file, workflow) { + const source = !file.replaceAll(path.sep, '/').includes('/setup/workflows/'); + const expected = contract.commentWorkflow(path.basename(file), source); + const expectedJob = Object.values(expected.jobs)[0]; + const actualJob = Object.values(workflow.jobs ?? {})[0]; + let route; + try { route = copilotCommentRunner(actualJob); } catch { /* Fixed contract error below. */ } + if (!isCopilotCommentRunner(route)) throw new Error(`${file} native comment runner must be reviewed literal JSON.`); + if (source) { + const labels = typeof route === 'string' || Array.isArray(route) ? route : route.labels; + if (!Array.isArray(labels) || !['self-hosted', 'codex'].every(label => labels.includes(label))) throw new Error(`${file} native source comment caller must retain its self-hosted codex role.`); + } + expectedJob.with['runs-on'] = actualJob.with['runs-on']; + if (actualJob?.if !== expectedJob.if) { + throw new Error(`${file} native comment caller must keep its required bot actor and same-repository PR gate.`); + } + if (!isDeepStrictEqual(workflow, expected)) { + throw new Error(`${file} must pass consistent policy to the native comment coordinator, retaining only its event, bot/fork gate, reviewed runner, scoped Secrets and least-privilege permissions.`); + } +} + +function assertCommentWorkflowRuntime(file, workflow) { + if (!isDeepStrictEqual(workflow, contract.runtimeWorkflow())) { + throw new Error(`${file} must retain the canonical native comment runtime: same-commit Action, input bindings, isolated setup/continue/finish steps, timeout and cleanup.`); + } +} + +module.exports = { assertCommentWorkflowCaller, assertCommentWorkflowRuntime }; diff --git a/scripts/validate-npm-package.cjs b/scripts/validate-npm-package.cjs index 5ec818f86..ca5c35c79 100644 --- a/scripts/validate-npm-package.cjs +++ b/scripts/validate-npm-package.cjs @@ -39,6 +39,7 @@ const requiredPackageFiles = [ 'build/api/index.js', 'build/api/src/', 'setup/ISSUE_TEMPLATE/', + 'setup/actions/', 'setup/workflows/', 'setup/pull_request_template.md', 'scripts/install-git-hooks.cjs', @@ -58,6 +59,7 @@ const requiredRepositoryFiles = [ 'build/api/index.js', 'build/api/src/api.d.ts', 'setup/workflows/copilot_issue.yml', + 'setup/actions/copilot-verification-setup/action.yml', 'setup/ISSUE_TEMPLATE/config.yml', 'setup/ISSUE_TEMPLATE/feature_request.yml', 'setup/ISSUE_TEMPLATE/bug_report.yml', diff --git a/scripts/validate-workflow-contract.cjs b/scripts/validate-workflow-contract.cjs index 096a9f50e..8bcae2918 100644 --- a/scripts/validate-workflow-contract.cjs +++ b/scripts/validate-workflow-contract.cjs @@ -3,6 +3,8 @@ const { readFileSync, readdirSync } = require('node:fs'); const path = require('node:path'); const yaml = require('js-yaml'); +const commentContract = require('./generate-native-verification-workflows.cjs'); +const { assertCommentWorkflowCaller, assertCommentWorkflowRuntime } = require('./validate-comment-workflows.cjs'); const repositoryRoot = path.resolve(__dirname, '..'); const workflowDirectories = [ @@ -113,6 +115,7 @@ const AGENT_ROLE_INPUTS = Object.freeze(Object.fromEntries( ]]), )); const WORKFLOW_AGENT_ROLES = Object.freeze({ + 'copilot_comment_runtime.yml': ['findings', 'fixer', 'planner', 'reviewer', 'tester'], 'copilot_issue.yml': ['planner'], 'copilot_pull_request.yml': ['planner', 'reviewer'], 'copilot_pull_request_review_state.yml': ['planner', 'reviewer'], @@ -144,9 +147,16 @@ function relativeWorkflow(file) { return path.relative(repositoryRoot, file).replaceAll(path.sep, '/'); } +function expectedCopilotAction(relativeFile) { + if (path.basename(relativeFile) === commentContract.RUNTIME) return commentContract.SELF_ACTION; + if (relativeFile.startsWith('setup/workflows/')) return DISTRIBUTED_COPILOT_ACTION; + const native = require('./generate-native-verification-workflows.cjs'); + return native.CALLBACKS.includes(path.basename(relativeFile)) ? native.SOURCE_ACTION : './'; +} + function isCopilotAction(step) { return typeof step?.uses === 'string' - && (step.uses === './' || /(?:^|\/)copilot@/.test(step.uses)); + && (step.uses === '$/' || step.uses === './' || step.uses === './../.copilot-native-runtime' || /(?:^|\/)copilot@/.test(step.uses)); } function shouldPersistCheckoutCredentials(relativeFile, jobId) { @@ -165,7 +175,7 @@ function assertMajorActionReferences(file, workflow) { .filter(value => typeof value === 'string'); for (const uses of actionUses) { if (isCopilotAction({ uses })) { - const expected = relativeFile.startsWith('setup/workflows/') ? DISTRIBUTED_COPILOT_ACTION : './'; + const expected = expectedCopilotAction(relativeFile); if (uses !== expected) { throw new Error(`${relativeFile} job ${jobId} must invoke Copilot with ${expected}.`); } @@ -177,7 +187,7 @@ function assertMajorActionReferences(file, workflow) { } continue; } - if (uses.startsWith('./') || uses.startsWith('docker://')) continue; + if (uses.startsWith('./') || uses.startsWith('$/') || uses.startsWith('docker://')) continue; if (!MAJOR_ACTION_REFERENCE.test(uses)) { throw new Error(`${relativeFile} job ${jobId} action ${uses} must use a major version tag such as owner/action@v1.`); } @@ -259,15 +269,34 @@ function assertRepoWiseTemporaryCleanup(relativeFile, job) { throw new Error(`${relativeFile} must select complete Python, isolate RepoWise files, and remove them after artifact upload.`); } const reports = (job.steps ?? []).find(step => step?.name === 'Generate RepoWise reports'); - if (job.env?.REPOWISE_BASE_SHA !== "${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before || '' }}" - || job.env?.REPOWISE_EVENT_NAME !== '${{ github.event_name }}' - || !reports?.run?.includes('[[ "$REPOWISE_BASE_SHA" =~ ^[0-9a-f]{40}$ ]]') - || !reports.run.includes('git cat-file -e "$REPOWISE_BASE_SHA^{commit}"') - || !reports.run.includes('git merge-base --is-ancestor "$REPOWISE_BASE_SHA" HEAD') - || !reports.run.includes('--since "$REPOWISE_BASE_SHA" --to HEAD') - || !reports.run.includes('[ "$REPOWISE_EVENT_NAME" = workflow_dispatch ]') - || !reports.run.includes('security: incomplete (event base unavailable or not an ancestor)')) { - throw new Error(`${relativeFile} must verify and report event-scoped security history; only manual dispatch may scan full history.`); + const install = (job.steps ?? []).find(step => step?.name === 'Install RepoWise'); + if (!install?.run?.includes("'repowise==0.58.0'") + || !reports?.run?.includes('"$python_bin" scripts/repowise_reports.py --report-dir "$report_dir"') + || !reports.run.includes('"$python_bin" -m unittest discover -s scripts/tests -p \'test_repowise*.py\' -v') + || !reports.run.includes('trap cleanup EXIT') + || reports.run.replace('rmdir .vscode 2>/dev/null || true', '').includes('|| true') + || upload.if !== '${{ always() }}' + || upload.with?.['retention-days'] !== 14) { + throw new Error(`${relativeFile} must preserve pinned bounded reports, compatibility tests, cleanup and unconditional artifacts.`); + } +} + +function assertManualRepoWiseWorkflow(file, workflow) { + const relativeFile = relativeWorkflow(file); + if (relativeFile !== '.github/workflows/repowise.yml') return; + if (Object.keys(workflow.on ?? {}).join(',') !== 'workflow_dispatch') { + throw new Error(`${relativeFile} must run only through workflow_dispatch.`); + } + const job = workflow.jobs?.['code-health']; + const checkout = (job?.steps ?? []).find(step => step?.uses === CHECKOUT_ACTION); + if (job?.['timeout-minutes'] !== 40 + || JSON.stringify(workflow.permissions) !== JSON.stringify({ contents: 'read' }) + || job.permissions !== undefined + || checkout?.with?.['fetch-depth'] !== 0 + || checkout.with?.ref !== undefined + || workflow.concurrency?.group !== 'repowise-${{ github.ref }}' + || workflow.concurrency?.['cancel-in-progress'] !== true) { + throw new Error(`${relativeFile} must retain its manual job budget, read-only permissions, selected revision and per-ref concurrency.`); } } @@ -315,6 +344,8 @@ function assertPlatformHistoryCheckout(relativeFile, job) { function assertRunner(file, workflow) { const relativeFile = relativeWorkflow(file); + if (path.basename(file) === commentContract.RUNTIME) return assertCommentWorkflowRuntime(file, workflow); + if (commentContract.CALLBACKS.includes(path.basename(file))) return assertCommentWorkflowCaller(file, workflow); if (relativeFile === '.github/workflows/setup_platform_smoke.yml') { const jobIds = Object.keys(workflow.jobs ?? {}).sort(); if (JSON.stringify(jobIds) !== JSON.stringify(['setup-platform-smoke', 'setup-self-hosted-codex-smoke', 'upload-windows-coverage', 'windows-startup-probe'])) { @@ -451,8 +482,9 @@ function assertRunner(file, workflow) { } else if (relativeFile === '.github/workflows/copilot_runner_diagnostics.yml') { if (jobId !== 'linux') throw new Error(`${relativeFile} contains an unsupported Codex diagnostic job.`); expected = ['self-hosted', 'codex', 'Linux']; - } else if (relativeFile === '.github/workflows/ci_check.yml' - || relativeFile === '.github/workflows/repowise.yml') { + } else if (relativeFile === '.github/workflows/repowise.yml') { + expected = ['self-hosted', 'codex', 'Linux']; + } else if (relativeFile === '.github/workflows/ci_check.yml') { expected = [QUALITY_RUNNER_BY_TRUST]; } const labels = runnerLabels(job['runs-on']); @@ -539,7 +571,7 @@ function assertAgentInstallationPrerequisites(file, workflow) { for (const [jobId, job] of Object.entries(workflow.jobs ?? {})) { const steps = job.steps ?? []; for (const step of steps) { - const repositoryVerificationStep = ['.github/workflows/copilot_issue_comment.yml', '.github/workflows/copilot_pull_request_comment.yml'].includes(relativeFile) + const repositoryVerificationStep = ['.github/workflows/copilot_issue_comment.yml', '.github/workflows/copilot_pull_request_comment.yml', '.github/workflows/copilot_comment_runtime.yml'].includes(relativeFile) && step.if === "env.COPILOT_PREPARE_VERIFICATION == 'true'" && ((step.name === 'Prepare repository Node' && step.uses === 'actions/setup-node@v7' && step.with?.['node-version'] === '24.x') || (step.name === 'Prepare repository pnpm' && step.uses === 'pnpm/action-setup@v5' && step.with?.version === '10.12.4') @@ -570,7 +602,7 @@ function assertAgentWorkflowPermissions(file, workflow) { const relativeFile = relativeWorkflow(file); if (!WORKFLOW_AGENT_ROLES[path.basename(file)]) return; const reviewEvidenceWorkflow = ['copilot_pull_request.yml', 'copilot_pull_request_review_state.yml', - 'copilot_issue_comment.yml', 'copilot_pull_request_comment.yml'].includes(path.basename(file)); + 'copilot_issue_comment.yml', 'copilot_pull_request_comment.yml', 'copilot_comment_runtime.yml'].includes(path.basename(file)); const expectedPermissions = reviewEvidenceWorkflow ? { checks: 'write', contents: 'read' } : { contents: 'read' }; @@ -583,6 +615,10 @@ function assertAgentWorkflowPermissions(file, workflow) { || expectedKeys.some(key => permissions[key] !== expectedPermissions[key])) { throw new Error(`${relativeFile} job ${jobId} must grant GITHUB_TOKEN exactly ${expectedKeys.map(key => `${key}: ${expectedPermissions[key]}`).join(', ')}; mutations use the explicit PAT.`); } + if (commentContract.CALLBACKS.includes(path.basename(file)) && job.uses) { + assertCommentWorkflowCaller(file, workflow); + continue; + } if (reviewEvidenceWorkflow && !(job.steps ?? []).some(step => isCopilotAction(step) && step?.env?.COPILOT_EVIDENCE_TOKEN === '${{ github.token }}')) { throw new Error(`${relativeFile} job ${jobId} must scope COPILOT_EVIDENCE_TOKEN to the Action step for exact-head review Checks.`); @@ -1125,6 +1161,10 @@ function assertPhaseConditions(relativeFile, jobs, finalJob) { if (publishedActions.length !== 2) { throw new Error(`${relativeFile} must project publication through published_deployment_action.`); } + if ([...preparationActions, ...publishedActions].some(step => + step.with?.['merge-queue-check-attestations'] !== "${{ vars.MERGE_QUEUE_CHECK_ATTESTATIONS || '[]' }}")) { + throw new Error(`${relativeFile} must pass live merge-queue attestations on every preparation and reconciliation entrypoint.`); + } const trustedContinuations = Object.values(jobs).flatMap(job => job.steps ?? []) .filter(step => isCopilotAction(step) && [ 'create_tag', @@ -1233,7 +1273,6 @@ function assertMergeQueueWorkflowSupport(file, workflow) { const relativeFile = relativeWorkflow(file); const required = new Set([ '.github/workflows/ci_check.yml', - '.github/workflows/repowise.yml', '.github/workflows/copilot_pull_request_merge_queue.yml', 'setup/workflows/copilot_pull_request_merge_queue.yml', ]); @@ -1277,6 +1316,7 @@ function assertQueueWorkflow(file, workflow) { if (BOT_GATED_WORKFLOW_FILES.has(manifest.file) && queueJob.if !== expectedBotGate) { throw new Error(`${relativeFile} queue job ${manifest.jobId} must use the required bot actor${FORK_GATED_WORKFLOW_FILES.has(manifest.file) ? ' and same-repository PR' : ''} gate.`); } + if (commentContract.CALLBACKS.includes(manifest.file)) return assertCommentWorkflowCaller(file, workflow); if (typeof queueJob['timeout-minutes'] !== 'number' || queueJob['timeout-minutes'] < MIN_QUEUE_JOB_TIMEOUT_MINUTES) { throw new Error(`${relativeFile} queue job ${manifest.jobId} must have timeout-minutes >= ${MIN_QUEUE_JOB_TIMEOUT_MINUTES}.`); @@ -1346,7 +1386,7 @@ function assertSequentialMutationWorkflow(file, workflow) { function assertIssueWorkflowProfileInput(file, workflow) { if (!ISSUE_WORKFLOW_PROFILE_FILES.has(path.basename(file))) return; const relativeFile = relativeWorkflow(file); - const expectedAction = relativeFile.startsWith('setup/workflows/') ? DISTRIBUTED_COPILOT_ACTION : './'; + const expectedAction = expectedCopilotAction(relativeFile); const actionSteps = Object.values(workflow.jobs ?? {}).flatMap(job => job?.steps ?? []) .filter(step => step?.uses === expectedAction); if (actionSteps.length === 0 || actionSteps.some(step => @@ -1357,6 +1397,7 @@ function assertIssueWorkflowProfileInput(file, workflow) { function assertIssueBranchConfigurationInputs(file, workflow) { if (!WORKFLOW_AGENT_ROLES[path.basename(file)]) return; + if (commentContract.CALLBACKS.includes(path.basename(file))) return assertCommentWorkflowCaller(file, workflow); const relativeFile = relativeWorkflow(file); const distributed = relativeFile.startsWith('setup/workflows/'); const branches = JSON.parse(readFileSync(path.join(repositoryRoot, '.copilot/repository-profile.json'), 'utf8')).branches; @@ -1364,21 +1405,46 @@ function assertIssueBranchConfigurationInputs(file, workflow) { ? { 'issue-managed-branches': "${{ vars.ISSUE_MANAGED_BRANCHES || 'true' }}", 'pre-branch-sdd': "${{ vars.PRE_BRANCH_SDD || 'false' }}", + 'verification-setup': "${{ vars.VERIFICATION_SETUP || 'false' }}", } : { 'issue-managed-branches': branches.issueManagedBranches, 'pre-branch-sdd': branches.preBranchSdd, + 'verification-setup': "${{ vars.VERIFICATION_SETUP || 'false' }}", }; const actionSteps = Object.values(workflow.jobs ?? {}).flatMap(job => job?.steps ?? []) .filter(isCopilotAction); if (actionSteps.length === 0 || actionSteps.some(step => Object.entries(expected).some(([input, value]) => step.with?.[input] !== value))) { - throw new Error(`${relativeFile} must pass consistent issue-managed-branches and pre-branch-sdd inputs to every Copilot callback.`); + throw new Error(`${relativeFile} must pass consistent issue-managed-branches, pre-branch-sdd and verification-setup inputs to every Copilot callback.`); } } +function assertNativeVerificationWorkflow(file, workflow) { + const contract = require('./generate-native-verification-workflows.cjs'); + if (path.basename(file) === contract.RUNTIME) return assertCommentWorkflowRuntime(file, workflow); + if (contract.CALLBACKS.includes(path.basename(file))) return assertCommentWorkflowCaller(file, workflow); + +} + function validateWorkflow(file, workflow) { if (!workflow || typeof workflow !== 'object') throw new Error('workflow document is empty.'); + if (commentContract.CALLBACKS.includes(path.basename(file))) { + assertCommentWorkflowCaller(file, workflow); + assertDirectEventTriggers(file, workflow); + return; + } + if (path.basename(file) === commentContract.RUNTIME) { + assertCommentWorkflowRuntime(file, workflow); + assertCopilotActionInputs(file, workflow); + assertNoJobLevelSecrets(file, workflow); + assertAgentWorkflowPermissions(file, workflow); + assertAgentInputs(file, workflow); + assertRepositoryLocaleInputs(file, workflow); + return; + } + assertNativeVerificationWorkflow(file, workflow); + assertManualRepoWiseWorkflow(file, workflow); assertDirectEventTriggers(file, workflow); assertApprovalObserverWorkflow(file, workflow); assertPullRequestMergeQueueWorkflow(file, workflow); @@ -1423,6 +1489,7 @@ function main() { if (require.main === module) main(); module.exports = { + assertNativeVerificationWorkflow, QUEUE_WAIT_MINUTES, MIN_QUEUE_JOB_TIMEOUT_MINUTES, DEPLOYMENT_VALIDATION_TIMEOUT_MINUTES, diff --git a/scripts/web-setup-runner-review-fixtures.cjs b/scripts/web-setup-runner-review-fixtures.cjs index 2c118c247..8b9575a12 100644 --- a/scripts/web-setup-runner-review-fixtures.cjs +++ b/scripts/web-setup-runner-review-fixtures.cjs @@ -62,6 +62,7 @@ const runnerDiscoveryPresentation = { }; /** Credential-free presentation evidence; no provider or mutation adapters. */ const installationReview = { + verificationSetup: { action: 'create', enabled: false, mainBranch: 'main' }, blockers: [], jobs: [ { file: 'copilot_issue.yml', job: 'copilot-issues', role: 'agent', runsOn: { group: 'vypdev', labels: ['self-hosted', 'codex', 'Linux'] }, status: 'pending-capacity', retained: false }, diff --git a/setup/actions/copilot-verification-setup/action.yml b/setup/actions/copilot-verification-setup/action.yml new file mode 100644 index 000000000..354055158 --- /dev/null +++ b/setup/actions/copilot-verification-setup/action.yml @@ -0,0 +1,13 @@ +# Created once by Copilot setup. This action and its assets belong to your project. +# Replace the placeholder with reviewed runtime/dependency setup, then merge onto MAIN_BRANCH. +name: Prepare project verification +description: Configure project dependencies before enabling VERIFICATION_SETUP. +runs: + using: composite + steps: + - name: Configure project verification dependencies + shell: bash + run: | + printf '%s\n' 'Configure .github/actions/copilot-verification-setup/action.yml with your project dependencies before enabling VERIFICATION_SETUP.' + printf '%s\n' 'Replace this failing placeholder, review and merge it onto the configured MAIN_BRANCH, then run a real verification.' + exit 1 diff --git a/setup/workflows/copilot_commit.yml b/setup/workflows/copilot_commit.yml index e289a0932..c5421cf99 100644 --- a/setup/workflows/copilot_commit.yml +++ b/setup/workflows/copilot_commit.yml @@ -43,6 +43,7 @@ jobs: # Before Copilot, provision project runtimes/dependencies in this same job when # repository verification is configured. A separate CI job does not prepare it. # Declare reviewed versions in .copilot/verification-prerequisites.json. + # Optional trusted-main setup: VERIFICATION_SETUP=true and .github/actions/copilot-verification-setup/action.yml. # https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-verification-prerequisites - uses: vypdev/copilot@v3 with: @@ -62,6 +63,7 @@ jobs: chore-tree: ${{ vars.CHORE_TREE || 'chore' }} issue-managed-branches: ${{ vars.ISSUE_MANAGED_BRANCHES || 'true' }} pre-branch-sdd: ${{ vars.PRE_BRANCH_SDD || 'false' }} + verification-setup: ${{ vars.VERIFICATION_SETUP || 'false' }} reopen-issue-on-push: ${{ vars.REOPEN_ISSUE_ON_PUSH || 'true' }} desired-assignees-count: ${{ vars.DESIRED_ASSIGNEES_COUNT || '1' }} desired-reviewers-count: ${{ vars.DESIRED_REVIEWERS_COUNT || '1' }} diff --git a/setup/workflows/copilot_issue.yml b/setup/workflows/copilot_issue.yml index 6955abe07..05ce55b50 100644 --- a/setup/workflows/copilot_issue.yml +++ b/setup/workflows/copilot_issue.yml @@ -21,6 +21,7 @@ jobs: # Before Copilot, provision project runtimes/dependencies in this same job when # repository verification is configured. A separate CI job does not prepare it. # Declare reviewed versions in .copilot/verification-prerequisites.json. + # Optional trusted-main setup: VERIFICATION_SETUP=true and .github/actions/copilot-verification-setup/action.yml. # https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-verification-prerequisites - uses: vypdev/copilot@v3 with: @@ -39,6 +40,7 @@ jobs: chore-tree: ${{ vars.CHORE_TREE || 'chore' }} issue-managed-branches: ${{ vars.ISSUE_MANAGED_BRANCHES || 'true' }} pre-branch-sdd: ${{ vars.PRE_BRANCH_SDD || 'false' }} + verification-setup: ${{ vars.VERIFICATION_SETUP || 'false' }} issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }} reopen-issue-on-push: ${{ vars.REOPEN_ISSUE_ON_PUSH || 'true' }} desired-assignees-count: ${{ vars.DESIRED_ASSIGNEES_COUNT || '1' }} diff --git a/setup/workflows/copilot_issue_comment.yml b/setup/workflows/copilot_issue_comment.yml index d977a5eba..dd360d03e 100644 --- a/setup/workflows/copilot_issue_comment.yml +++ b/setup/workflows/copilot_issue_comment.yml @@ -1,114 +1,28 @@ +# Generated by scripts/generate-native-verification-workflows.cjs +# Project runtimes: .copilot/verification-prerequisites.json +# Dependencies: .github/actions/copilot-verification-setup/action.yml +# https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-verification-prerequisites name: Copilot - Issue Comment - -on: +'on': issue_comment: - types: [created, edited] - + types: + - created + - edited jobs: copilot-issues: if: ${{ vars.COPILOT_BOT_LOGIN == '' || github.actor != vars.COPILOT_BOT_LOGIN }} - name: Copilot - Issue Comment - runs-on: ubuntu-latest - timeout-minutes: 120 + uses: vypdev/copilot/.github/workflows/copilot_comment_runtime.yml@v3 permissions: checks: write contents: read - steps: - - name: Checkout Repository - uses: actions/checkout@v5 - with: - persist-credentials: false - fetch-depth: 0 - - # Before Copilot, provision project runtimes/dependencies in this same job when - # repository verification is configured. A separate CI job does not prepare it. - # Declare reviewed versions in .copilot/verification-prerequisites.json. - # https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-verification-prerequisites - - uses: vypdev/copilot@v3 - with: - repository-locale: ${{ vars.REPOSITORY_LOCALE || 'en-US' }} - issues-locale: ${{ vars.ISSUES_LOCALE || '' }} - pull-requests-locale: ${{ vars.PULL_REQUESTS_LOCALE || '' }} - ai-ignore-files: ${{ vars.AI_IGNORE_FILES || 'build/*' }} - debug: ${{ vars.DEBUG }} - main-branch: ${{ vars.MAIN_BRANCH || 'master' }} - development-branch: ${{ vars.DEVELOPMENT_BRANCH || 'develop' }} - feature-tree: ${{ vars.FEATURE_TREE || 'feature' }} - bugfix-tree: ${{ vars.BUGFIX_TREE || 'bugfix' }} - hotfix-tree: ${{ vars.HOTFIX_TREE || 'hotfix' }} - release-tree: ${{ vars.RELEASE_TREE || 'release' }} - docs-tree: ${{ vars.DOCS_TREE || 'docs' }} - chore-tree: ${{ vars.CHORE_TREE || 'chore' }} - issue-managed-branches: ${{ vars.ISSUE_MANAGED_BRANCHES || 'true' }} - pre-branch-sdd: ${{ vars.PRE_BRANCH_SDD || 'false' }} - issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }} - reopen-issue-on-push: ${{ vars.REOPEN_ISSUE_ON_PUSH || 'true' }} - desired-assignees-count: ${{ vars.DESIRED_ASSIGNEES_COUNT || '1' }} - desired-reviewers-count: ${{ vars.DESIRED_REVIEWERS_COUNT || '1' }} - commit-prefix-transforms: ${{ vars.COMMIT_PREFIX_TRANSFORMS || 'replace-slash' }} - ai-pull-request-description-mode: ${{ vars.AI_PULL_REQUEST_DESCRIPTION_MODE || 'replace' }} - ai-members-only: ${{ vars.AI_MEMBERS_ONLY || 'false' }} - ai-include-reasoning: ${{ vars.AI_INCLUDE_REASONING || 'false' }} - bugbot-severity: ${{ vars.BUGBOT_SEVERITY || 'low' }} - bugbot-comment-limit: ${{ vars.BUGBOT_COMMENT_LIMIT || '20' }} - bugbot-fix-verify-commands: ${{ vars.BUGBOT_AUTOFIX_VERIFY_COMMANDS }} - bugbot-dry-run: ${{ vars.BUGBOT_DRY_RUN || 'false' }} - bugbot-effort: ${{ vars.BUGBOT_EFFORT || 'smart' }} - bugbot-review-drafts: ${{ vars.BUGBOT_REVIEW_DRAFTS || 'false' }} - bugbot-trace-rules: ${{ vars.BUGBOT_TRACE_RULES || 'false' }} - bugbot-suggested-changes: ${{ vars.BUGBOT_SUGGESTED_CHANGES || 'true' }} - bugbot-telemetry: ${{ vars.BUGBOT_TELEMETRY || 'true' }} - bugbot-fail-on-unresolved: ${{ vars.BUGBOT_FAIL_ON_UNRESOLVED || 'false' }} - bugbot-organization-rules: ${{ vars.BUGBOT_ORGANIZATION_RULES }} - project-column-issue-created: ${{ vars.PROJECT_COLUMN_ISSUE_CREATED || 'Todo' }} - project-column-pull-request-created: ${{ vars.PROJECT_COLUMN_PULL_REQUEST_CREATED || 'In Progress' }} - project-column-issue-in-progress: ${{ vars.PROJECT_COLUMN_ISSUE_IN_PROGRESS || 'In Progress' }} - project-column-pull-request-in-progress: ${{ vars.PROJECT_COLUMN_PULL_REQUEST_IN_PROGRESS || 'In Progress' }} - agent-provider: ${{ vars.AGENT_PROVIDER || 'codex' }} - agent-model-provider: ${{ vars.AGENT_MODEL_PROVIDER || 'openai' }} - agent-model: ${{ vars.AGENT_MODEL || 'gpt-6-luna' }} - agent-effort: ${{ vars.AGENT_EFFORT }} - agent-executable: ${{ vars.AGENT_EXECUTABLE }} - findings-provider: ${{ vars.FINDINGS_PROVIDER }} - findings-model-provider: ${{ vars.FINDINGS_MODEL_PROVIDER }} - findings-model: ${{ vars.FINDINGS_MODEL }} - findings-effort: ${{ vars.FINDINGS_EFFORT }} - findings-executable: ${{ vars.FINDINGS_EXECUTABLE }} - fixer-provider: ${{ vars.FIXER_PROVIDER }} - fixer-model-provider: ${{ vars.FIXER_MODEL_PROVIDER }} - fixer-model: ${{ vars.FIXER_MODEL }} - fixer-effort: ${{ vars.FIXER_EFFORT }} - fixer-executable: ${{ vars.FIXER_EXECUTABLE }} - planner-provider: ${{ vars.PLANNER_PROVIDER }} - planner-model-provider: ${{ vars.PLANNER_MODEL_PROVIDER }} - planner-model: ${{ vars.PLANNER_MODEL }} - planner-effort: ${{ vars.PLANNER_EFFORT }} - planner-executable: ${{ vars.PLANNER_EXECUTABLE }} - reviewer-provider: ${{ vars.REVIEWER_PROVIDER }} - reviewer-model-provider: ${{ vars.REVIEWER_MODEL_PROVIDER }} - reviewer-model: ${{ vars.REVIEWER_MODEL }} - reviewer-effort: ${{ vars.REVIEWER_EFFORT }} - reviewer-executable: ${{ vars.REVIEWER_EXECUTABLE }} - tester-provider: ${{ vars.TESTER_PROVIDER }} - tester-model-provider: ${{ vars.TESTER_MODEL_PROVIDER }} - tester-model: ${{ vars.TESTER_MODEL }} - tester-effort: ${{ vars.TESTER_EFFORT }} - tester-executable: ${{ vars.TESTER_EXECUTABLE }} - project-ids: ${{ vars.PROJECT_IDS }} - token: ${{ secrets.PAT }} - env: - AGENT_PROVIDER: ${{ vars.AGENT_PROVIDER || 'codex' }} - AGENT_MODEL_PROVIDER: ${{ vars.AGENT_MODEL_PROVIDER || 'openai' }} - AGENT_MODEL: ${{ vars.AGENT_MODEL }} - AGENT_EFFORT: ${{ vars.AGENT_EFFORT }} - AGENT_ALLOWED_MODEL_PROVIDERS: ${{ vars.AGENT_ALLOWED_MODEL_PROVIDERS || 'openai' }} - AGENT_ALLOWED_MODELS: ${{ vars.AGENT_ALLOWED_MODELS || 'openai/gpt-6-luna' }} - AGENT_EXECUTABLE: ${{ vars.AGENT_EXECUTABLE }} - OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} - GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} - OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} - CURSOR_API_KEY: ${{ (vars.AGENT_PROVIDER == 'cursor' || vars.FINDINGS_PROVIDER == 'cursor' || vars.FIXER_PROVIDER == 'cursor' || vars.PLANNER_PROVIDER == 'cursor' || vars.REVIEWER_PROVIDER == 'cursor' || vars.TESTER_PROVIDER == 'cursor') && secrets.CURSOR_API_KEY || '' }} - CODEX_API_KEY: ${{ secrets.CODEX_API_KEY }} - COPILOT_EVIDENCE_TOKEN: ${{ github.token }} + with: + runs-on: '"ubuntu-latest"' + secrets: + PAT: ${{ secrets.PAT }} + OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} + OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} + CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} + CODEX_API_KEY: ${{ secrets.CODEX_API_KEY }} diff --git a/setup/workflows/copilot_pull_request.yml b/setup/workflows/copilot_pull_request.yml index f6dd20108..1127ec283 100644 --- a/setup/workflows/copilot_pull_request.yml +++ b/setup/workflows/copilot_pull_request.yml @@ -39,6 +39,7 @@ jobs: # Before Copilot, provision project runtimes/dependencies in this same job when # repository verification is configured. A separate CI job does not prepare it. # Declare reviewed versions in .copilot/verification-prerequisites.json. + # Optional trusted-main setup: VERIFICATION_SETUP=true and .github/actions/copilot-verification-setup/action.yml. # https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-verification-prerequisites - uses: vypdev/copilot@v3 with: @@ -58,6 +59,7 @@ jobs: chore-tree: ${{ vars.CHORE_TREE || 'chore' }} issue-managed-branches: ${{ vars.ISSUE_MANAGED_BRANCHES || 'true' }} pre-branch-sdd: ${{ vars.PRE_BRANCH_SDD || 'false' }} + verification-setup: ${{ vars.VERIFICATION_SETUP || 'false' }} reopen-issue-on-push: ${{ vars.REOPEN_ISSUE_ON_PUSH || 'true' }} desired-assignees-count: ${{ vars.DESIRED_ASSIGNEES_COUNT || '1' }} desired-reviewers-count: ${{ vars.DESIRED_REVIEWERS_COUNT || '1' }} diff --git a/setup/workflows/copilot_pull_request_comment.yml b/setup/workflows/copilot_pull_request_comment.yml index b9e2bae5b..455fa34a6 100644 --- a/setup/workflows/copilot_pull_request_comment.yml +++ b/setup/workflows/copilot_pull_request_comment.yml @@ -1,114 +1,28 @@ +# Generated by scripts/generate-native-verification-workflows.cjs +# Project runtimes: .copilot/verification-prerequisites.json +# Dependencies: .github/actions/copilot-verification-setup/action.yml +# https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-verification-prerequisites name: Copilot - Pull Request Comment - -on: +'on': pull_request_review_comment: - types: [created, edited] - + types: + - created + - edited jobs: copilot-pull-requests: if: ${{ (vars.COPILOT_BOT_LOGIN == '' || github.actor != vars.COPILOT_BOT_LOGIN) && github.event.pull_request.head.repo.full_name == github.repository }} - name: Copilot - Pull Request Comment - runs-on: ubuntu-latest - timeout-minutes: 120 + uses: vypdev/copilot/.github/workflows/copilot_comment_runtime.yml@v3 permissions: checks: write contents: read - steps: - - name: Checkout Repository - uses: actions/checkout@v5 - with: - persist-credentials: false - fetch-depth: 0 - - # Before Copilot, provision project runtimes/dependencies in this same job when - # repository verification is configured. A separate CI job does not prepare it. - # Declare reviewed versions in .copilot/verification-prerequisites.json. - # https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-verification-prerequisites - - uses: vypdev/copilot@v3 - with: - repository-locale: ${{ vars.REPOSITORY_LOCALE || 'en-US' }} - issues-locale: ${{ vars.ISSUES_LOCALE || '' }} - pull-requests-locale: ${{ vars.PULL_REQUESTS_LOCALE || '' }} - issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }} - ai-ignore-files: ${{ vars.AI_IGNORE_FILES || 'build/*' }} - debug: ${{ vars.DEBUG }} - main-branch: ${{ vars.MAIN_BRANCH || 'master' }} - development-branch: ${{ vars.DEVELOPMENT_BRANCH || 'develop' }} - feature-tree: ${{ vars.FEATURE_TREE || 'feature' }} - bugfix-tree: ${{ vars.BUGFIX_TREE || 'bugfix' }} - hotfix-tree: ${{ vars.HOTFIX_TREE || 'hotfix' }} - release-tree: ${{ vars.RELEASE_TREE || 'release' }} - docs-tree: ${{ vars.DOCS_TREE || 'docs' }} - chore-tree: ${{ vars.CHORE_TREE || 'chore' }} - issue-managed-branches: ${{ vars.ISSUE_MANAGED_BRANCHES || 'true' }} - pre-branch-sdd: ${{ vars.PRE_BRANCH_SDD || 'false' }} - reopen-issue-on-push: ${{ vars.REOPEN_ISSUE_ON_PUSH || 'true' }} - desired-assignees-count: ${{ vars.DESIRED_ASSIGNEES_COUNT || '1' }} - desired-reviewers-count: ${{ vars.DESIRED_REVIEWERS_COUNT || '1' }} - commit-prefix-transforms: ${{ vars.COMMIT_PREFIX_TRANSFORMS || 'replace-slash' }} - ai-pull-request-description-mode: ${{ vars.AI_PULL_REQUEST_DESCRIPTION_MODE || 'replace' }} - ai-members-only: ${{ vars.AI_MEMBERS_ONLY || 'false' }} - ai-include-reasoning: ${{ vars.AI_INCLUDE_REASONING || 'false' }} - bugbot-severity: ${{ vars.BUGBOT_SEVERITY || 'low' }} - bugbot-comment-limit: ${{ vars.BUGBOT_COMMENT_LIMIT || '20' }} - bugbot-fix-verify-commands: ${{ vars.BUGBOT_AUTOFIX_VERIFY_COMMANDS }} - bugbot-dry-run: ${{ vars.BUGBOT_DRY_RUN || 'false' }} - bugbot-effort: ${{ vars.BUGBOT_EFFORT || 'smart' }} - bugbot-review-drafts: ${{ vars.BUGBOT_REVIEW_DRAFTS || 'false' }} - bugbot-trace-rules: ${{ vars.BUGBOT_TRACE_RULES || 'false' }} - bugbot-suggested-changes: ${{ vars.BUGBOT_SUGGESTED_CHANGES || 'true' }} - bugbot-telemetry: ${{ vars.BUGBOT_TELEMETRY || 'true' }} - bugbot-fail-on-unresolved: ${{ vars.BUGBOT_FAIL_ON_UNRESOLVED || 'false' }} - bugbot-organization-rules: ${{ vars.BUGBOT_ORGANIZATION_RULES }} - project-column-issue-created: ${{ vars.PROJECT_COLUMN_ISSUE_CREATED || 'Todo' }} - project-column-pull-request-created: ${{ vars.PROJECT_COLUMN_PULL_REQUEST_CREATED || 'In Progress' }} - project-column-issue-in-progress: ${{ vars.PROJECT_COLUMN_ISSUE_IN_PROGRESS || 'In Progress' }} - project-column-pull-request-in-progress: ${{ vars.PROJECT_COLUMN_PULL_REQUEST_IN_PROGRESS || 'In Progress' }} - agent-provider: ${{ vars.AGENT_PROVIDER || 'codex' }} - agent-model-provider: ${{ vars.AGENT_MODEL_PROVIDER || 'openai' }} - agent-model: ${{ vars.AGENT_MODEL || 'gpt-6-luna' }} - agent-effort: ${{ vars.AGENT_EFFORT }} - agent-executable: ${{ vars.AGENT_EXECUTABLE }} - findings-provider: ${{ vars.FINDINGS_PROVIDER }} - findings-model-provider: ${{ vars.FINDINGS_MODEL_PROVIDER }} - findings-model: ${{ vars.FINDINGS_MODEL }} - findings-effort: ${{ vars.FINDINGS_EFFORT }} - findings-executable: ${{ vars.FINDINGS_EXECUTABLE }} - fixer-provider: ${{ vars.FIXER_PROVIDER }} - fixer-model-provider: ${{ vars.FIXER_MODEL_PROVIDER }} - fixer-model: ${{ vars.FIXER_MODEL }} - fixer-effort: ${{ vars.FIXER_EFFORT }} - fixer-executable: ${{ vars.FIXER_EXECUTABLE }} - reviewer-provider: ${{ vars.REVIEWER_PROVIDER }} - reviewer-model-provider: ${{ vars.REVIEWER_MODEL_PROVIDER }} - reviewer-model: ${{ vars.REVIEWER_MODEL }} - reviewer-effort: ${{ vars.REVIEWER_EFFORT }} - reviewer-executable: ${{ vars.REVIEWER_EXECUTABLE }} - planner-provider: ${{ vars.PLANNER_PROVIDER }} - planner-model-provider: ${{ vars.PLANNER_MODEL_PROVIDER }} - planner-model: ${{ vars.PLANNER_MODEL }} - planner-effort: ${{ vars.PLANNER_EFFORT }} - planner-executable: ${{ vars.PLANNER_EXECUTABLE }} - tester-provider: ${{ vars.TESTER_PROVIDER }} - tester-model-provider: ${{ vars.TESTER_MODEL_PROVIDER }} - tester-model: ${{ vars.TESTER_MODEL }} - tester-effort: ${{ vars.TESTER_EFFORT }} - tester-executable: ${{ vars.TESTER_EXECUTABLE }} - project-ids: ${{ vars.PROJECT_IDS }} - token: ${{ secrets.PAT }} - env: - AGENT_PROVIDER: ${{ vars.AGENT_PROVIDER || 'codex' }} - AGENT_MODEL_PROVIDER: ${{ vars.AGENT_MODEL_PROVIDER || 'openai' }} - AGENT_MODEL: ${{ vars.AGENT_MODEL }} - AGENT_EFFORT: ${{ vars.AGENT_EFFORT }} - AGENT_ALLOWED_MODEL_PROVIDERS: ${{ vars.AGENT_ALLOWED_MODEL_PROVIDERS || 'openai' }} - AGENT_ALLOWED_MODELS: ${{ vars.AGENT_ALLOWED_MODELS || 'openai/gpt-6-luna' }} - AGENT_EXECUTABLE: ${{ vars.AGENT_EXECUTABLE }} - OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} - GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} - OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} - CURSOR_API_KEY: ${{ (vars.AGENT_PROVIDER == 'cursor' || vars.FINDINGS_PROVIDER == 'cursor' || vars.FIXER_PROVIDER == 'cursor' || vars.PLANNER_PROVIDER == 'cursor' || vars.REVIEWER_PROVIDER == 'cursor' || vars.TESTER_PROVIDER == 'cursor') && secrets.CURSOR_API_KEY || '' }} - CODEX_API_KEY: ${{ secrets.CODEX_API_KEY }} - COPILOT_EVIDENCE_TOKEN: ${{ github.token }} + with: + runs-on: '"ubuntu-latest"' + secrets: + PAT: ${{ secrets.PAT }} + OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} + OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} + CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} + CODEX_API_KEY: ${{ secrets.CODEX_API_KEY }} diff --git a/setup/workflows/copilot_pull_request_review_state.yml b/setup/workflows/copilot_pull_request_review_state.yml index ab7cfce09..8942d1d7f 100644 --- a/setup/workflows/copilot_pull_request_review_state.yml +++ b/setup/workflows/copilot_pull_request_review_state.yml @@ -27,6 +27,7 @@ jobs: # Before Copilot, provision project runtimes/dependencies in this same job when # repository verification is configured. A separate CI job does not prepare it. # Declare reviewed versions in .copilot/verification-prerequisites.json. + # Optional trusted-main setup: VERIFICATION_SETUP=true and .github/actions/copilot-verification-setup/action.yml. # https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-verification-prerequisites - uses: vypdev/copilot@v3 with: @@ -46,6 +47,7 @@ jobs: chore-tree: ${{ vars.CHORE_TREE || 'chore' }} issue-managed-branches: ${{ vars.ISSUE_MANAGED_BRANCHES || 'true' }} pre-branch-sdd: ${{ vars.PRE_BRANCH_SDD || 'false' }} + verification-setup: ${{ vars.VERIFICATION_SETUP || 'false' }} reopen-issue-on-push: ${{ vars.REOPEN_ISSUE_ON_PUSH || 'true' }} desired-assignees-count: ${{ vars.DESIRED_ASSIGNEES_COUNT || '1' }} desired-reviewers-count: ${{ vars.DESIRED_REVIEWERS_COUNT || '1' }} diff --git a/setup/workflows/hotfix_workflow.yml b/setup/workflows/hotfix_workflow.yml index bcd718bcf..10efa7cd1 100644 --- a/setup/workflows/hotfix_workflow.yml +++ b/setup/workflows/hotfix_workflow.yml @@ -179,6 +179,7 @@ jobs: uses: vypdev/copilot@v3 with: single-action: published_deployment_action + merge-queue-check-attestations: ${{ vars.MERGE_QUEUE_CHECK_ATTESTATIONS || '[]' }} single-action-issue: ${{ inputs.issue }} issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }} single-action-operation-id: ${{ inputs.operation-id }} diff --git a/setup/workflows/release_workflow.yml b/setup/workflows/release_workflow.yml index 63b340a85..b5300c717 100644 --- a/setup/workflows/release_workflow.yml +++ b/setup/workflows/release_workflow.yml @@ -179,6 +179,7 @@ jobs: uses: vypdev/copilot@v3 with: single-action: published_deployment_action + merge-queue-check-attestations: ${{ vars.MERGE_QUEUE_CHECK_ATTESTATIONS || '[]' }} single-action-issue: ${{ inputs.issue }} issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }} single-action-operation-id: ${{ inputs.operation-id }} diff --git a/specs/CATALOG.md b/specs/CATALOG.md index b5608fbec..5526a0369 100644 --- a/specs/CATALOG.md +++ b/specs/CATALOG.md @@ -12,19 +12,19 @@ debt or convert unknown historic intent into a design decision. |---|---|---|---|---| | `github-communication-experience` | Implemented | English-default, localized, semantic, bounded, and idempotent product messages across GitHub and repository-aware operator surfaces | [Semantic GitHub communication and repository localization](./semantic-github-publication-and-notification.md) + 3 companion | 277 paths · 2026-10-20 | | `release-orchestration` | Implemented | Release and hotfix promotion, publication, bounded merge readiness recovery, and receipt-verified reconciliation without republication | [Configurable production-first release orchestration](./configurable-release-orchestration.md) + 2 companion | 59 paths · 2026-10-16 | -| `merge-queue-readiness` | Implemented | Fail-closed validation of required checks and merge-group workflow support | [Merge queue readiness and effective target rules](./merge-queue-readiness.md) | 24 paths · 2026-10-15 | -| `bugbot-review-state-reconciliation` | Implemented | Reconcile review snapshots, findings, threads, comments, and check conclusions | [Bugbot review-state reconciliation](./bugbot-review-state-reconciliation.md) | 59 paths · 2026-10-11 | -| `execution-lifecycle` | Implemented | Shared GitHub Action lifecycle from event admission through durable user-facing results | [Execution admission, queueing, routing, and result publication](./execution-admission-queue-and-publication.md) + 3 companion | 97 paths · 2026-10-14 | +| `merge-queue-readiness` | Implemented | Fail-closed validation of required checks and merge-group workflow support; optional manual-only RepoWise analysis with independent CI and verified required-check migration; cached RepoWise exports and bounded full-history secret processing with truthful completeness and resource evidence | [Merge queue readiness and effective target rules](./merge-queue-readiness.md) | 29 paths · 2026-10-21 | +| `bugbot-review-state-reconciliation` | Implemented | Reconcile review snapshots, findings, threads, comments, and check conclusions | [Bugbot review-state reconciliation](./bugbot-review-state-reconciliation.md) | 70 paths · 2026-10-21 | +| `execution-lifecycle` | Implemented | Shared GitHub Action lifecycle from event admission through durable user-facing results | [Execution admission, queueing, routing, and result publication](./execution-admission-queue-and-publication.md) + 3 companion | 105 paths · 2026-10-21 | | `architecture-quality-hardening` | Implemented | Close verified concurrency, error-contract, context-coupling, fan-out, setup/doctor, and provider-policy risks in dependency order | [Architecture quality and scalability hardening](./architecture-quality-and-scalability-hardening.md) + 1 companion | 72 paths · 2026-10-13 | -| `setup-and-doctor` | Implemented | Plan, validate, provision, and audit a repository installation without exposing credentials | [Setup, configuration, credentials, and doctor](./setup-configuration-credentials-and-doctor.md) + 5 companion | 326 paths · 2026-10-20 | -| `local-web-setup-assistant` | Proposed | Offer a packaged, loopback-only Svelte setup interface over the existing engine with four-language guidance, English CLI help, basic/custom first-run paths, editable question and plan review, source-labelled GitHub facts, assisted CI and Project evidence, role-separated PATs, and truthful itemized outcomes; inspect existing configuration and apply independent, scope-aware runtime adjustments with permission, drift and read-back verification | [Local web setup assistant](./local-web-setup-assistant.md) + 1 companion | 238 paths · 2026-10-20 | +| `setup-and-doctor` | Implemented | Plan, validate, provision, and audit a repository installation without exposing credentials | [Setup, configuration, credentials, and doctor](./setup-configuration-credentials-and-doctor.md) + 6 companion | 331 paths · 2026-10-20 | +| `local-web-setup-assistant` | Proposed | Offer a packaged, loopback-only Svelte setup interface over the existing engine with four-language guidance, English CLI help, basic/custom first-run paths, editable question and plan review, source-labelled GitHub facts, assisted CI and Project evidence, role-separated PATs, and truthful itemized outcomes; inspect existing configuration and apply independent, scope-aware runtime adjustments with permission, drift and read-back verification | [Local web setup assistant](./local-web-setup-assistant.md) + 2 companion | 247 paths · 2026-10-21 | | `guided-bot-pat-onboarding` | Proposed | Guide creation of the persistent workflow PAT, verify bot identity and grants, recover explicitly from wrong-account input within the session, and install the approved Actions Secret | [Guided bot PAT onboarding](./guided-bot-pat-onboarding.md) | 39 paths · 2026-10-07 | | `temporary-setup-operator-authorization` | Proposed | Guide creation of the one-run operator PAT through GitHub's official form, verify final setup access, and report user-owned deletion accurately | [Assisted setup PAT creation](./temporary-setup-operator-authorization.md) | 36 paths · 2026-10-18 | -| `issue-start-and-sdd-readiness` | Implemented | Start every admitted issue with one explicit signal and publish a validated SDD before eligible Action-managed branch work; inspect verified SDD status and bounded structural publication comparisons | [Uniform issue start and pre-branch SDD readiness](./issue-start-and-branch-readiness.md) + 3 companion | 116 paths · 2026-10-19 | +| `issue-start-and-sdd-readiness` | Implemented | Start every admitted issue with one explicit signal and publish a validated SDD before eligible Action-managed branch work; inspect verified SDD status and bounded structural publication comparisons | [Uniform issue start and pre-branch SDD readiness](./issue-start-and-branch-readiness.md) + 3 companion | 119 paths · 2026-10-21 | | `managed-issue-lifecycle` | As-built baseline | Convert typed issues into traceable work branches, project state, and lifecycle state | [Managed issue and branch lifecycle](./managed-issue-and-branch-lifecycle.md) | 71 paths · 2026-10-20 | | `comment-automation` | Implemented | Admit only explicit commands or exact mentions, then route them while protecting repository mutations | [Comment automation and authorization](./comment-automation-and-authorization.md) | 79 paths · 2026-10-11 | -| `bugbot-analysis-and-autofix` | Implemented | Select one canonical PR, exhaustively analyze its bounded diff partitions, publish stable findings atomically, and apply authorized verified fixes | [Bugbot analysis, finding publication, and autofix](./bugbot-analysis-publication-and-autofix.md) + 2 companion | 109 paths · 2026-10-13 | -| `branch-synchronization` | Implemented | Observe parent drift with one localized status card and transition-only notifications, then safely merge a parent branch into a linked working branch | [Branch synchronization and conflict recovery](./branch-synchronization-and-conflict-recovery.md) + 1 companion | 90 paths · 2026-10-20 | +| `bugbot-analysis-and-autofix` | Implemented | Select one canonical PR, exhaustively analyze its bounded diff partitions, publish stable findings atomically, and apply authorized verified fixes | [Bugbot analysis, finding publication, and autofix](./bugbot-analysis-publication-and-autofix.md) + 2 companion | 115 paths · 2026-10-21 | +| `branch-synchronization` | Implemented | Observe parent drift with one localized status card and transition-only notifications, then safely merge a parent branch into a linked working branch | [Branch synchronization and conflict recovery](./branch-synchronization-and-conflict-recovery.md) + 2 companion | 126 paths · 2026-10-22 | | `pull-request-lifecycle` | Implemented | Enrich linked and unlinked pull requests with safe issue linkage, projects, metadata, reviewers, concise descriptions, and distinct workflow evidence | [Pull request lifecycle and enrichment](./pull-request-lifecycle-and-enrichment.md) | 77 paths · 2026-10-20 | | `agent-runtime` | Implemented | Resolve, provision, authenticate, authorize, and execute only the agent roles reachable by a run | [Agent runtime, provider, model, and role routing](./agent-runtime-provider-and-model-routing.md) + 1 companion | 99 paths · 2026-10-17 | | `cli-and-single-actions` | As-built baseline | Expose bounded local commands and workflow-dispatched operations through the shared application core | [CLI and single-action execution](./cli-and-single-action-execution.md) | 44 paths · 2026-10-19 | @@ -59,35 +59,35 @@ debt or convert unknown historic intent into a design decision. ### `merge-queue-readiness` — Merge queue readiness and effective target rules - Owner: Copilot maintainers -- Last verified: 2026-10-15 +- Last verified: 2026-10-21 - Specifications: [`specs/merge-queue-readiness.md`](./merge-queue-readiness.md) - Workflows: [`.github/workflows/ci_check.yml`](../.github/workflows/ci_check.yml) · [`.github/workflows/repowise.yml`](../.github/workflows/repowise.yml) · [`.github/workflows/copilot_pull_request_merge_queue.yml`](../.github/workflows/copilot_pull_request_merge_queue.yml) · [`setup/workflows/copilot_pull_request_merge_queue.yml`](../setup/workflows/copilot_pull_request_merge_queue.yml) · [`.github/workflows/copilot_deployment_orchestration.yml`](../.github/workflows/copilot_deployment_orchestration.yml) - Entrypoints: [`src/application/usecases/setup/merge_queue_readiness_use_case.ts`](../src/application/usecases/setup/merge_queue_readiness_use_case.ts) -- Core code: [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`src/domain/merge_queue_readiness.ts`](../src/domain/merge_queue_readiness.ts) · [`src/application/policies/merge_queue_message_catalog.ts`](../src/application/policies/merge_queue_message_catalog.ts) · [`src/application/policies/deployment_message_catalog.ts`](../src/application/policies/deployment_message_catalog.ts) · [`src/application/policies/deployment_plan_policy.ts`](../src/application/policies/deployment_plan_policy.ts) · [`src/application/policies/setup_doctor_message_catalog.ts`](../src/application/policies/setup_doctor_message_catalog.ts) · [`src/application/usecases/setup/merge_queue_readiness_use_case.ts`](../src/application/usecases/setup/merge_queue_readiness_use_case.ts) · [`src/data/repository/deployment/github_target_merge_capabilities_inspector.ts`](../src/data/repository/deployment/github_target_merge_capabilities_inspector.ts) · [`src/infrastructure/github/octokit_checks_adapters.ts`](../src/infrastructure/github/octokit_checks_adapters.ts) · [`scripts/validate-workflow-contract.cjs`](../scripts/validate-workflow-contract.cjs) -- Tests: [`src/domain/__tests__/merge_queue_readiness.test.ts`](../src/domain/__tests__/merge_queue_readiness.test.ts) · [`src/application/policies/__tests__/deployment_plan_policy.test.ts`](../src/application/policies/__tests__/deployment_plan_policy.test.ts) · [`src/application/policies/__tests__/setup_doctor_message_catalog.test.ts`](../src/application/policies/__tests__/setup_doctor_message_catalog.test.ts) · [`src/application/usecases/setup/__tests__/merge_queue_readiness_use_case.test.ts`](../src/application/usecases/setup/__tests__/merge_queue_readiness_use_case.test.ts) · [`src/data/repository/deployment/__tests__/github_deployment_adapters.test.ts`](../src/data/repository/deployment/__tests__/github_deployment_adapters.test.ts) · [`src/tooling/__tests__/validate_workflow_contract.test.ts`](../src/tooling/__tests__/validate_workflow_contract.test.ts) -- User documentation: [`docs/issues/deployment-orchestration.mdx`](../docs/issues/deployment-orchestration.mdx) · [`docs/security-operations/operations/verification.mdx`](../docs/security-operations/operations/verification.mdx) +- Core code: [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`src/domain/merge_queue_readiness.ts`](../src/domain/merge_queue_readiness.ts) · [`src/application/policies/merge_queue_message_catalog.ts`](../src/application/policies/merge_queue_message_catalog.ts) · [`src/application/policies/deployment_message_catalog.ts`](../src/application/policies/deployment_message_catalog.ts) · [`src/application/policies/deployment_plan_policy.ts`](../src/application/policies/deployment_plan_policy.ts) · [`src/application/policies/setup_doctor_message_catalog.ts`](../src/application/policies/setup_doctor_message_catalog.ts) · [`src/application/usecases/setup/merge_queue_readiness_use_case.ts`](../src/application/usecases/setup/merge_queue_readiness_use_case.ts) · [`src/data/repository/deployment/github_target_merge_capabilities_inspector.ts`](../src/data/repository/deployment/github_target_merge_capabilities_inspector.ts) · [`src/infrastructure/github/octokit_checks_adapters.ts`](../src/infrastructure/github/octokit_checks_adapters.ts) · [`scripts/validate-workflow-contract.cjs`](../scripts/validate-workflow-contract.cjs) · [`scripts/repowise_history.py`](../scripts/repowise_history.py) · [`scripts/repowise_reports.py`](../scripts/repowise_reports.py) +- Tests: [`src/domain/__tests__/merge_queue_readiness.test.ts`](../src/domain/__tests__/merge_queue_readiness.test.ts) · [`src/application/policies/__tests__/deployment_plan_policy.test.ts`](../src/application/policies/__tests__/deployment_plan_policy.test.ts) · [`src/application/policies/__tests__/setup_doctor_message_catalog.test.ts`](../src/application/policies/__tests__/setup_doctor_message_catalog.test.ts) · [`src/application/usecases/setup/__tests__/merge_queue_readiness_use_case.test.ts`](../src/application/usecases/setup/__tests__/merge_queue_readiness_use_case.test.ts) · [`src/data/repository/deployment/__tests__/github_deployment_adapters.test.ts`](../src/data/repository/deployment/__tests__/github_deployment_adapters.test.ts) · [`src/tooling/__tests__/validate_workflow_contract.test.ts`](../src/tooling/__tests__/validate_workflow_contract.test.ts) · [`scripts/tests/test_repowise.py`](../scripts/tests/test_repowise.py) +- User documentation: [`docs/issues/deployment-orchestration.mdx`](../docs/issues/deployment-orchestration.mdx) · [`docs/security-operations/operations/verification.mdx`](../docs/security-operations/operations/verification.mdx) · [`docs/development/testing.mdx`](../docs/development/testing.mdx) · [`docs/security-operations/security/self-hosted-runners.mdx`](../docs/security-operations/security/self-hosted-runners.mdx) ### `bugbot-review-state-reconciliation` — Bugbot review-state reconciliation - Owner: Copilot maintainers -- Last verified: 2026-10-11 +- Last verified: 2026-10-21 - Specifications: [`specs/bugbot-review-state-reconciliation.md`](./bugbot-review-state-reconciliation.md) - Workflows: [`.github/workflows/copilot_commit.yml`](../.github/workflows/copilot_commit.yml) · [`.github/workflows/copilot_pull_request.yml`](../.github/workflows/copilot_pull_request.yml) · [`.github/workflows/copilot_pull_request_comment.yml`](../.github/workflows/copilot_pull_request_comment.yml) - Entrypoints: [`src/application/usecases/steps/commit/detect_potential_problems_workflow.ts`](../src/application/usecases/steps/commit/detect_potential_problems_workflow.ts) · [`src/application/usecases/steps/commit/bugbot/reconcile_bugbot_review_state_use_case.ts`](../src/application/usecases/steps/commit/bugbot/reconcile_bugbot_review_state_use_case.ts) · [`src/actions/github_action_completion.ts`](../src/actions/github_action_completion.ts) · [`src/api.ts`](../src/api.ts) -- Core code: [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`src/domain/bugbot/review_state.ts`](../src/domain/bugbot/review_state.ts) · [`src/domain/bugbot/review_projection.ts`](../src/domain/bugbot/review_projection.ts) · [`src/application/policies/bugbot_reconciliation_policy.ts`](../src/application/policies/bugbot_reconciliation_policy.ts) · [`src/application/policies/bugbot_event_ownership_policy.ts`](../src/application/policies/bugbot_event_ownership_policy.ts) · [`src/application/policies/bugbot_result_finding_state_projection_policy.ts`](../src/application/policies/bugbot_result_finding_state_projection_policy.ts) · [`src/application/policies/bugbot_telemetry_projection_policy.ts`](../src/application/policies/bugbot_telemetry_projection_policy.ts) · [`src/application/policies/bugbot_message_catalog.ts`](../src/application/policies/bugbot_message_catalog.ts) · [`src/application/policies/bugbot_finding_marker_policy.ts`](../src/application/policies/bugbot_finding_marker_policy.ts) · [`src/application/policies/bugbot_review_presentation_policy.ts`](../src/application/policies/bugbot_review_presentation_policy.ts) · [`src/application/policies/action_summary_policy.ts`](../src/application/policies/action_summary_policy.ts) · [`src/application/policies/copilot_evidence_policy.ts`](../src/application/policies/copilot_evidence_policy.ts) · [`src/application/policies/lifecycle_state_policy.ts`](../src/application/policies/lifecycle_state_policy.ts) · [`src/application/policies/status_command_policy.ts`](../src/application/policies/status_command_policy.ts) · [`src/application/usecases/steps/common/publish_resume_workflow.ts`](../src/application/usecases/steps/common/publish_resume_workflow.ts) · [`src/application/usecases/steps/commit/bugbot/load_bugbot_context_use_case.ts`](../src/application/usecases/steps/commit/bugbot/load_bugbot_context_use_case.ts) · [`src/application/usecases/steps/commit/bugbot/schema.ts`](../src/application/usecases/steps/commit/bugbot/schema.ts) · [`src/application/usecases/steps/commit/bugbot/prepare_bugbot_findings_policy.ts`](../src/application/usecases/steps/commit/bugbot/prepare_bugbot_findings_policy.ts) · [`src/application/usecases/steps/commit/bugbot/publish_pr_review_comments.ts`](../src/application/usecases/steps/commit/bugbot/publish_pr_review_comments.ts) · [`src/application/usecases/steps/commit/bugbot/synchronize_bugbot_review_presentation_use_case.ts`](../src/application/usecases/steps/commit/bugbot/synchronize_bugbot_review_presentation_use_case.ts) · [`src/application/policies/bugbot_status_count_marker_policy.ts`](../src/application/policies/bugbot_status_count_marker_policy.ts) -- Tests: [`src/domain/bugbot/__tests__/review_state.test.ts`](../src/domain/bugbot/__tests__/review_state.test.ts) · [`src/domain/bugbot/__tests__/review_projection.test.ts`](../src/domain/bugbot/__tests__/review_projection.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/schema.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/schema.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/prepare_bugbot_findings.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/prepare_bugbot_findings.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/reconcile_bugbot_review_state_integration.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/reconcile_bugbot_review_state_integration.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/synchronize_bugbot_review_presentation_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/synchronize_bugbot_review_presentation_use_case.test.ts) · [`src/application/policies/__tests__/bugbot_result_finding_state_projection_policy.test.ts`](../src/application/policies/__tests__/bugbot_result_finding_state_projection_policy.test.ts) · [`src/application/policies/__tests__/bugbot_event_ownership_policy.test.ts`](../src/application/policies/__tests__/bugbot_event_ownership_policy.test.ts) · [`src/application/policies/__tests__/bugbot_telemetry_projection_policy.test.ts`](../src/application/policies/__tests__/bugbot_telemetry_projection_policy.test.ts) · [`src/application/policies/__tests__/bugbot_message_catalog.test.ts`](../src/application/policies/__tests__/bugbot_message_catalog.test.ts) · [`src/application/policies/__tests__/bugbot_finding_marker_policy.test.ts`](../src/application/policies/__tests__/bugbot_finding_marker_policy.test.ts) · [`src/application/policies/__tests__/bugbot_review_presentation_policy.test.ts`](../src/application/policies/__tests__/bugbot_review_presentation_policy.test.ts) · [`src/application/policies/__tests__/action_summary_policy.test.ts`](../src/application/policies/__tests__/action_summary_policy.test.ts) · [`src/application/policies/__tests__/copilot_evidence_policy.test.ts`](../src/application/policies/__tests__/copilot_evidence_policy.test.ts) · [`src/application/policies/__tests__/lifecycle_state_policy.test.ts`](../src/application/policies/__tests__/lifecycle_state_policy.test.ts) · [`src/application/policies/__tests__/status_command_policy.test.ts`](../src/application/policies/__tests__/status_command_policy.test.ts) · [`src/actions/__tests__/github_action_completion.test.ts`](../src/actions/__tests__/github_action_completion.test.ts) · [`src/application/usecases/steps/common/__tests__/publish_resume_use_case.test.ts`](../src/application/usecases/steps/common/__tests__/publish_resume_use_case.test.ts) · [`src/application/usecases/actions/__tests__/synchronize_lifecycle_state_use_case.test.ts`](../src/application/usecases/actions/__tests__/synchronize_lifecycle_state_use_case.test.ts) · [`src/application/usecases/steps/commit/__tests__/detect_potential_problems_use_case.test.ts`](../src/application/usecases/steps/commit/__tests__/detect_potential_problems_use_case.test.ts) · [`src/infrastructure/composition/__tests__/pull_request_use_case_composition_root.test.ts`](../src/infrastructure/composition/__tests__/pull_request_use_case_composition_root.test.ts) · [`src/tooling/__tests__/validate_workflow_contract.test.ts`](../src/tooling/__tests__/validate_workflow_contract.test.ts) +- Core code: [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`src/domain/bugbot/review_state.ts`](../src/domain/bugbot/review_state.ts) · [`src/domain/bugbot/review_projection.ts`](../src/domain/bugbot/review_projection.ts) · [`src/application/policies/bugbot_reconciliation_policy.ts`](../src/application/policies/bugbot_reconciliation_policy.ts) · [`src/application/policies/bugbot_event_ownership_policy.ts`](../src/application/policies/bugbot_event_ownership_policy.ts) · [`src/application/policies/bugbot_result_finding_state_projection_policy.ts`](../src/application/policies/bugbot_result_finding_state_projection_policy.ts) · [`src/application/policies/bugbot_telemetry_projection_policy.ts`](../src/application/policies/bugbot_telemetry_projection_policy.ts) · [`src/application/policies/bugbot_message_catalog.ts`](../src/application/policies/bugbot_message_catalog.ts) · [`src/application/policies/bugbot_finding_marker_policy.ts`](../src/application/policies/bugbot_finding_marker_policy.ts) · [`src/application/policies/bugbot_review_presentation_policy.ts`](../src/application/policies/bugbot_review_presentation_policy.ts) · [`src/application/policies/action_summary_policy.ts`](../src/application/policies/action_summary_policy.ts) · [`src/application/policies/copilot_evidence_policy.ts`](../src/application/policies/copilot_evidence_policy.ts) · [`src/application/policies/lifecycle_state_policy.ts`](../src/application/policies/lifecycle_state_policy.ts) · [`src/application/policies/status_command_policy.ts`](../src/application/policies/status_command_policy.ts) · [`src/application/usecases/steps/common/publish_resume_workflow.ts`](../src/application/usecases/steps/common/publish_resume_workflow.ts) · [`src/application/usecases/steps/commit/bugbot/load_bugbot_context_use_case.ts`](../src/application/usecases/steps/commit/bugbot/load_bugbot_context_use_case.ts) · [`src/application/usecases/steps/commit/bugbot/schema.ts`](../src/application/usecases/steps/commit/bugbot/schema.ts) · [`src/application/usecases/steps/commit/bugbot/prepare_bugbot_findings_policy.ts`](../src/application/usecases/steps/commit/bugbot/prepare_bugbot_findings_policy.ts) · [`src/application/usecases/steps/commit/bugbot/publish_pr_review_comments.ts`](../src/application/usecases/steps/commit/bugbot/publish_pr_review_comments.ts) · [`src/application/usecases/steps/commit/bugbot/synchronize_bugbot_review_presentation_use_case.ts`](../src/application/usecases/steps/commit/bugbot/synchronize_bugbot_review_presentation_use_case.ts) · [`src/application/policies/bugbot_status_count_marker_policy.ts`](../src/application/policies/bugbot_status_count_marker_policy.ts) · [`src/application/errors/bugbot_mutation_error.ts`](../src/application/errors/bugbot_mutation_error.ts) · [`src/data/repository/pull_request/pull_request_review_error_metadata.ts`](../src/data/repository/pull_request/pull_request_review_error_metadata.ts) · [`src/domain/bugbot/finding.ts`](../src/domain/bugbot/finding.ts) · [`src/application/usecases/steps/commit/bugbot/analyze_bugbot_revision_use_case.ts`](../src/application/usecases/steps/commit/bugbot/analyze_bugbot_revision_use_case.ts) · [`src/application/usecases/steps/commit/bugbot/publish_findings_use_case.ts`](../src/application/usecases/steps/commit/bugbot/publish_findings_use_case.ts) +- Tests: [`src/domain/bugbot/__tests__/review_state.test.ts`](../src/domain/bugbot/__tests__/review_state.test.ts) · [`src/domain/bugbot/__tests__/review_projection.test.ts`](../src/domain/bugbot/__tests__/review_projection.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/schema.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/schema.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/prepare_bugbot_findings.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/prepare_bugbot_findings.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/reconcile_bugbot_review_state_integration.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/reconcile_bugbot_review_state_integration.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/synchronize_bugbot_review_presentation_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/synchronize_bugbot_review_presentation_use_case.test.ts) · [`src/application/policies/__tests__/bugbot_result_finding_state_projection_policy.test.ts`](../src/application/policies/__tests__/bugbot_result_finding_state_projection_policy.test.ts) · [`src/application/policies/__tests__/bugbot_event_ownership_policy.test.ts`](../src/application/policies/__tests__/bugbot_event_ownership_policy.test.ts) · [`src/application/policies/__tests__/bugbot_telemetry_projection_policy.test.ts`](../src/application/policies/__tests__/bugbot_telemetry_projection_policy.test.ts) · [`src/application/policies/__tests__/bugbot_message_catalog.test.ts`](../src/application/policies/__tests__/bugbot_message_catalog.test.ts) · [`src/application/policies/__tests__/bugbot_finding_marker_policy.test.ts`](../src/application/policies/__tests__/bugbot_finding_marker_policy.test.ts) · [`src/application/policies/__tests__/bugbot_review_presentation_policy.test.ts`](../src/application/policies/__tests__/bugbot_review_presentation_policy.test.ts) · [`src/application/policies/__tests__/action_summary_policy.test.ts`](../src/application/policies/__tests__/action_summary_policy.test.ts) · [`src/application/policies/__tests__/copilot_evidence_policy.test.ts`](../src/application/policies/__tests__/copilot_evidence_policy.test.ts) · [`src/application/policies/__tests__/lifecycle_state_policy.test.ts`](../src/application/policies/__tests__/lifecycle_state_policy.test.ts) · [`src/application/policies/__tests__/status_command_policy.test.ts`](../src/application/policies/__tests__/status_command_policy.test.ts) · [`src/actions/__tests__/github_action_completion.test.ts`](../src/actions/__tests__/github_action_completion.test.ts) · [`src/application/usecases/steps/common/__tests__/publish_resume_use_case.test.ts`](../src/application/usecases/steps/common/__tests__/publish_resume_use_case.test.ts) · [`src/application/usecases/actions/__tests__/synchronize_lifecycle_state_use_case.test.ts`](../src/application/usecases/actions/__tests__/synchronize_lifecycle_state_use_case.test.ts) · [`src/application/usecases/steps/commit/__tests__/detect_potential_problems_use_case.test.ts`](../src/application/usecases/steps/commit/__tests__/detect_potential_problems_use_case.test.ts) · [`src/infrastructure/composition/__tests__/pull_request_use_case_composition_root.test.ts`](../src/infrastructure/composition/__tests__/pull_request_use_case_composition_root.test.ts) · [`src/tooling/__tests__/validate_workflow_contract.test.ts`](../src/tooling/__tests__/validate_workflow_contract.test.ts) · [`src/application/errors/__tests__/bugbot_mutation_error.test.ts`](../src/application/errors/__tests__/bugbot_mutation_error.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/finding_mutation_recovery.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/finding_mutation_recovery.test.ts) · [`src/domain/bugbot/__tests__/finding.test.ts`](../src/domain/bugbot/__tests__/finding.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/finding_identity_replay.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/finding_identity_replay.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/analyze_bugbot_revision_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/analyze_bugbot_revision_use_case.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/publish_findings_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/publish_findings_use_case.test.ts) - User documentation: [`docs/bugbot/detection.mdx`](../docs/bugbot/detection.mdx) · [`docs/bugbot/finding-publication.mdx`](../docs/bugbot/finding-publication.mdx) · [`docs/bugbot/quality-observability.mdx`](../docs/bugbot/quality-observability.mdx) · [`docs/bugbot/failure-scenarios.mdx`](../docs/bugbot/failure-scenarios.mdx) · [`docs/bugbot/configuration.mdx`](../docs/bugbot/configuration.mdx) · [`docs/bugbot/how-it-works.mdx`](../docs/bugbot/how-it-works.mdx) · [`docs/bugbot/programmatic-api.mdx`](../docs/bugbot/programmatic-api.mdx) · [`docs/pull-requests/workflow-setup.mdx`](../docs/pull-requests/workflow-setup.mdx) · [`docs/issues/comment-commands.mdx`](../docs/issues/comment-commands.mdx) ### `execution-lifecycle` — Execution admission, queueing, routing, and result publication - Owner: Copilot maintainers -- Last verified: 2026-10-14 +- Last verified: 2026-10-21 - Specifications: [`specs/execution-admission-queue-and-publication.md`](./execution-admission-queue-and-publication.md) · [`specs/execution-error-and-context-hardening.md`](./execution-error-and-context-hardening.md) · [`specs/execution-boundary-closure-audit.md`](./execution-boundary-closure-audit.md) · [`specs/push-and-single-action-context-hardening.md`](./push-and-single-action-context-hardening.md) - Workflows: [`.github/workflows/copilot_issue.yml`](../.github/workflows/copilot_issue.yml) · [`.github/workflows/copilot_issue_comment.yml`](../.github/workflows/copilot_issue_comment.yml) · [`.github/workflows/copilot_pull_request.yml`](../.github/workflows/copilot_pull_request.yml) · [`.github/workflows/copilot_pull_request_comment.yml`](../.github/workflows/copilot_pull_request_comment.yml) · [`.github/workflows/copilot_commit.yml`](../.github/workflows/copilot_commit.yml) - Entrypoints: [`src/actions/github_action.ts`](../src/actions/github_action.ts) · [`src/actions/common_action.ts`](../src/actions/common_action.ts) -- Core code: [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`scripts/validate-coverage-budgets.cjs`](../scripts/validate-coverage-budgets.cjs) · [`src/actions/main_run_lifecycle.ts`](../src/actions/main_run_lifecycle.ts) · [`src/actions/main_run_route.ts`](../src/actions/main_run_route.ts) · [`src/actions/github_action_completion.ts`](../src/actions/github_action_completion.ts) · [`src/api.ts`](../src/api.ts) · [`src/data/model/application_error.ts`](../src/data/model/application_error.ts) · [`src/application/errors/application_error.ts`](../src/application/errors/application_error.ts) · [`src/application/errors/application_error_context.ts`](../src/application/errors/application_error_context.ts) · [`src/application/policies/application_error_message_catalog.ts`](../src/application/policies/application_error_message_catalog.ts) · [`src/application/policies/application_error_presentation_policy.ts`](../src/application/policies/application_error_presentation_policy.ts) · [`src/application/policies/bugbot_result_finding_state_projection_policy.ts`](../src/application/policies/bugbot_result_finding_state_projection_policy.ts) · [`src/application/policies/bugbot_telemetry_projection_policy.ts`](../src/application/policies/bugbot_telemetry_projection_policy.ts) · [`src/application/policies/action_summary_policy.ts`](../src/application/policies/action_summary_policy.ts) · [`src/application/policies/copilot_evidence_policy.ts`](../src/application/policies/copilot_evidence_policy.ts) · [`src/application/policies/lifecycle_state_policy.ts`](../src/application/policies/lifecycle_state_policy.ts) · [`src/application/policies/status_command_policy.ts`](../src/application/policies/status_command_policy.ts) · [`src/application/policies/github_execution_admission_policy.ts`](../src/application/policies/github_execution_admission_policy.ts) · [`src/application/policies/workflow_queue_policy.ts`](../src/application/policies/workflow_queue_policy.ts) · [`src/application/usecases/actions/lifecycle_synchronization_context.ts`](../src/application/usecases/actions/lifecycle_synchronization_context.ts) · [`src/application/usecases/actions/synchronize_lifecycle_state_use_case.ts`](../src/application/usecases/actions/synchronize_lifecycle_state_use_case.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_review_operation_context.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_review_operation_context.ts) · [`src/application/policies/semantic_result_publication_policy.ts`](../src/application/policies/semantic_result_publication_policy.ts) · [`src/application/usecases/steps/common/status_card_publication_workflow.ts`](../src/application/usecases/steps/common/status_card_publication_workflow.ts) · [`src/application/usecases/comment_automation_context.ts`](../src/application/usecases/comment_automation_context.ts) · [`src/application/usecases/issue_workflow_context.ts`](../src/application/usecases/issue_workflow_context.ts) · [`src/application/usecases/pull_request_workflow_context.ts`](../src/application/usecases/pull_request_workflow_context.ts) · [`src/application/usecases/push_single_action_contexts.ts`](../src/application/usecases/push_single_action_contexts.ts) · [`src/application/usecases/steps/common/check_permissions_workflow.ts`](../src/application/usecases/steps/common/check_permissions_workflow.ts) · [`src/application/usecases/steps/common/comment_language_translation_workflow.ts`](../src/application/usecases/steps/common/comment_language_translation_workflow.ts) · [`src/application/usecases/steps/common/think_workflow.ts`](../src/application/usecases/steps/common/think_workflow.ts) · [`src/application/usecases/steps/common/update_title_workflow.ts`](../src/application/usecases/steps/common/update_title_workflow.ts) · [`src/application/usecases/steps/common/project_content_link_workflow.ts`](../src/application/usecases/steps/common/project_content_link_workflow.ts) · [`src/application/usecases/steps/common/publish_resume_workflow.ts`](../src/application/usecases/steps/common/publish_resume_workflow.ts) · [`src/application/usecases/steps/common/store_configuration_use_case.ts`](../src/application/usecases/steps/common/store_configuration_use_case.ts) · [`src/infrastructure/composition/shared_capability_port_binding.ts`](../src/infrastructure/composition/shared_capability_port_binding.ts) · [`src/infrastructure/composition/lifecycle_capability_port_binding.ts`](../src/infrastructure/composition/lifecycle_capability_port_binding.ts) · [`src/infrastructure/composition/lifecycle_state_composition_root.ts`](../src/infrastructure/composition/lifecycle_state_composition_root.ts) · [`src/infrastructure/composition/push_single_action_capability_port_binding.ts`](../src/infrastructure/composition/push_single_action_capability_port_binding.ts) · [`src/infrastructure/composition/main_run_route_composition_root.ts`](../src/infrastructure/composition/main_run_route_composition_root.ts) · [`src/application/policies/configuration_persistence_policy.ts`](../src/application/policies/configuration_persistence_policy.ts) · [`src/application/ports/project_board_query_ports.ts`](../src/application/ports/project_board_query_ports.ts) · [`src/application/usecases/steps/commit/check_changes_issue_size_use_case.ts`](../src/application/usecases/steps/commit/check_changes_issue_size_use_case.ts) · [`src/application/usecases/steps/commit/check_changes_issue_size_workflow.ts`](../src/application/usecases/steps/commit/check_changes_issue_size_workflow.ts) · [`src/application/usecases/steps/commit/update_change_size_labels.ts`](../src/application/usecases/steps/commit/update_change_size_labels.ts) · [`src/data/repository/project/project_board_item_query.ts`](../src/data/repository/project/project_board_item_query.ts) · [`src/infrastructure/composition/change_size_project_membership_composition_root.ts`](../src/infrastructure/composition/change_size_project_membership_composition_root.ts) -- Tests: [`src/tooling/__tests__/coverage_budget_validator.test.ts`](../src/tooling/__tests__/coverage_budget_validator.test.ts) · [`src/__tests__/api.test.ts`](../src/__tests__/api.test.ts) · [`src/actions/__tests__/github_action.test.ts`](../src/actions/__tests__/github_action.test.ts) · [`src/actions/__tests__/github_action_completion.test.ts`](../src/actions/__tests__/github_action_completion.test.ts) · [`src/application/errors/__tests__/application_error.test.ts`](../src/application/errors/__tests__/application_error.test.ts) · [`src/application/policies/__tests__/application_error_message_catalog.test.ts`](../src/application/policies/__tests__/application_error_message_catalog.test.ts) · [`src/application/policies/__tests__/application_error_presentation_policy.test.ts`](../src/application/policies/__tests__/application_error_presentation_policy.test.ts) · [`src/application/policies/__tests__/bugbot_result_finding_state_projection_policy.test.ts`](../src/application/policies/__tests__/bugbot_result_finding_state_projection_policy.test.ts) · [`src/application/policies/__tests__/bugbot_telemetry_projection_policy.test.ts`](../src/application/policies/__tests__/bugbot_telemetry_projection_policy.test.ts) · [`src/application/policies/__tests__/action_summary_policy.test.ts`](../src/application/policies/__tests__/action_summary_policy.test.ts) · [`src/application/policies/__tests__/copilot_evidence_policy.test.ts`](../src/application/policies/__tests__/copilot_evidence_policy.test.ts) · [`src/application/policies/__tests__/lifecycle_state_policy.test.ts`](../src/application/policies/__tests__/lifecycle_state_policy.test.ts) · [`src/application/policies/__tests__/status_command_policy.test.ts`](../src/application/policies/__tests__/status_command_policy.test.ts) · [`src/application/usecases/actions/__tests__/lifecycle_synchronization_context.test.ts`](../src/application/usecases/actions/__tests__/lifecycle_synchronization_context.test.ts) · [`src/application/usecases/actions/__tests__/synchronize_lifecycle_state_use_case.test.ts`](../src/application/usecases/actions/__tests__/synchronize_lifecycle_state_use_case.test.ts) · [`src/application/usecases/actions/__tests__/lifecycle_event_replay.integration.test.ts`](../src/application/usecases/actions/__tests__/lifecycle_event_replay.integration.test.ts) · [`src/architecture/__tests__/execution_import_ratchet.test.ts`](../src/architecture/__tests__/execution_import_ratchet.test.ts) · [`src/architecture/__tests__/raw_error_logging_boundaries.test.ts`](../src/architecture/__tests__/raw_error_logging_boundaries.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/bugbot_review_operation_context.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/bugbot_review_operation_context.test.ts) · [`src/application/usecases/steps/common/__tests__/shared_capability_context_projection.test.ts`](../src/application/usecases/steps/common/__tests__/shared_capability_context_projection.test.ts) · [`src/application/usecases/steps/common/__tests__/publish_resume_use_case.test.ts`](../src/application/usecases/steps/common/__tests__/publish_resume_use_case.test.ts) · [`src/infrastructure/composition/__tests__/shared_capability_port_binding.test.ts`](../src/infrastructure/composition/__tests__/shared_capability_port_binding.test.ts) · [`src/application/usecases/__tests__/issue_pull_request_context_projection.test.ts`](../src/application/usecases/__tests__/issue_pull_request_context_projection.test.ts) · [`src/infrastructure/composition/__tests__/lifecycle_capability_port_binding.test.ts`](../src/infrastructure/composition/__tests__/lifecycle_capability_port_binding.test.ts) · [`src/infrastructure/composition/__tests__/lifecycle_state_composition_root.test.ts`](../src/infrastructure/composition/__tests__/lifecycle_state_composition_root.test.ts) · [`src/application/usecases/__tests__/push_single_action_contexts.test.ts`](../src/application/usecases/__tests__/push_single_action_contexts.test.ts) · [`src/application/usecases/__tests__/single_action_workflow.test.ts`](../src/application/usecases/__tests__/single_action_workflow.test.ts) · [`src/infrastructure/composition/__tests__/push_single_action_capability_port_binding.test.ts`](../src/infrastructure/composition/__tests__/push_single_action_capability_port_binding.test.ts) · [`src/application/usecases/execution/__tests__/resolve_github_execution_admission_use_case.test.ts`](../src/application/usecases/execution/__tests__/resolve_github_execution_admission_use_case.test.ts) · [`src/application/usecases/workflow/__tests__/wait_for_previous_workflow_runs_use_case.test.ts`](../src/application/usecases/workflow/__tests__/wait_for_previous_workflow_runs_use_case.test.ts) · [`src/application/policies/__tests__/configuration_persistence_policy.test.ts`](../src/application/policies/__tests__/configuration_persistence_policy.test.ts) · [`src/application/usecases/steps/commit/__tests__/check_changes_issue_size_use_case.test.ts`](../src/application/usecases/steps/commit/__tests__/check_changes_issue_size_use_case.test.ts) · [`src/application/usecases/steps/commit/__tests__/update_change_size_labels.test.ts`](../src/application/usecases/steps/commit/__tests__/update_change_size_labels.test.ts) · [`src/data/repository/project/__tests__/project_board_visibility_recovery.test.ts`](../src/data/repository/project/__tests__/project_board_visibility_recovery.test.ts) · [`src/infrastructure/composition/__tests__/change_size_project_membership_composition_root.test.ts`](../src/infrastructure/composition/__tests__/change_size_project_membership_composition_root.test.ts) -- User documentation: [`docs/overview.mdx`](../docs/overview.mdx) · [`docs/bugbot/programmatic-api.mdx`](../docs/bugbot/programmatic-api.mdx) · [`docs/security-operations/operations/error-reference.mdx`](../docs/security-operations/operations/error-reference.mdx) · [`docs/security-operations/operations/troubleshooting.mdx`](../docs/security-operations/operations/troubleshooting.mdx) · [`docs/bugbot/quality-observability.mdx`](../docs/bugbot/quality-observability.mdx) · [`docs/bugbot/failure-scenarios.mdx`](../docs/bugbot/failure-scenarios.mdx) · [`docs/development/architecture.mdx`](../docs/development/architecture.mdx) · [`docs/issues/assignees-and-projects.mdx`](../docs/issues/assignees-and-projects.mdx) +- Core code: [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`scripts/validate-coverage-budgets.cjs`](../scripts/validate-coverage-budgets.cjs) · [`src/actions/main_run_lifecycle.ts`](../src/actions/main_run_lifecycle.ts) · [`src/actions/main_run_route.ts`](../src/actions/main_run_route.ts) · [`src/actions/github_action_completion.ts`](../src/actions/github_action_completion.ts) · [`src/api.ts`](../src/api.ts) · [`src/data/model/application_error.ts`](../src/data/model/application_error.ts) · [`src/application/errors/application_error.ts`](../src/application/errors/application_error.ts) · [`src/application/errors/application_error_context.ts`](../src/application/errors/application_error_context.ts) · [`src/application/policies/application_error_message_catalog.ts`](../src/application/policies/application_error_message_catalog.ts) · [`src/application/policies/application_error_presentation_policy.ts`](../src/application/policies/application_error_presentation_policy.ts) · [`src/application/policies/bugbot_result_finding_state_projection_policy.ts`](../src/application/policies/bugbot_result_finding_state_projection_policy.ts) · [`src/application/policies/bugbot_telemetry_projection_policy.ts`](../src/application/policies/bugbot_telemetry_projection_policy.ts) · [`src/application/policies/action_summary_policy.ts`](../src/application/policies/action_summary_policy.ts) · [`src/application/policies/copilot_evidence_policy.ts`](../src/application/policies/copilot_evidence_policy.ts) · [`src/application/policies/lifecycle_state_policy.ts`](../src/application/policies/lifecycle_state_policy.ts) · [`src/application/policies/status_command_policy.ts`](../src/application/policies/status_command_policy.ts) · [`src/application/policies/github_execution_admission_policy.ts`](../src/application/policies/github_execution_admission_policy.ts) · [`src/application/policies/workflow_queue_policy.ts`](../src/application/policies/workflow_queue_policy.ts) · [`src/application/usecases/actions/lifecycle_synchronization_context.ts`](../src/application/usecases/actions/lifecycle_synchronization_context.ts) · [`src/application/usecases/actions/synchronize_lifecycle_state_use_case.ts`](../src/application/usecases/actions/synchronize_lifecycle_state_use_case.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_review_operation_context.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_review_operation_context.ts) · [`src/application/policies/semantic_result_publication_policy.ts`](../src/application/policies/semantic_result_publication_policy.ts) · [`src/application/usecases/steps/common/status_card_publication_workflow.ts`](../src/application/usecases/steps/common/status_card_publication_workflow.ts) · [`src/application/usecases/comment_automation_context.ts`](../src/application/usecases/comment_automation_context.ts) · [`src/application/usecases/issue_workflow_context.ts`](../src/application/usecases/issue_workflow_context.ts) · [`src/application/usecases/pull_request_workflow_context.ts`](../src/application/usecases/pull_request_workflow_context.ts) · [`src/application/usecases/push_single_action_contexts.ts`](../src/application/usecases/push_single_action_contexts.ts) · [`src/application/usecases/steps/common/check_permissions_workflow.ts`](../src/application/usecases/steps/common/check_permissions_workflow.ts) · [`src/application/usecases/steps/common/comment_language_translation_workflow.ts`](../src/application/usecases/steps/common/comment_language_translation_workflow.ts) · [`src/application/usecases/steps/common/think_workflow.ts`](../src/application/usecases/steps/common/think_workflow.ts) · [`src/application/usecases/steps/common/update_title_workflow.ts`](../src/application/usecases/steps/common/update_title_workflow.ts) · [`src/application/usecases/steps/common/project_content_link_workflow.ts`](../src/application/usecases/steps/common/project_content_link_workflow.ts) · [`src/application/usecases/steps/common/publish_resume_workflow.ts`](../src/application/usecases/steps/common/publish_resume_workflow.ts) · [`src/application/usecases/steps/common/store_configuration_use_case.ts`](../src/application/usecases/steps/common/store_configuration_use_case.ts) · [`src/infrastructure/composition/shared_capability_port_binding.ts`](../src/infrastructure/composition/shared_capability_port_binding.ts) · [`src/infrastructure/composition/lifecycle_capability_port_binding.ts`](../src/infrastructure/composition/lifecycle_capability_port_binding.ts) · [`src/infrastructure/composition/lifecycle_state_composition_root.ts`](../src/infrastructure/composition/lifecycle_state_composition_root.ts) · [`src/infrastructure/composition/push_single_action_capability_port_binding.ts`](../src/infrastructure/composition/push_single_action_capability_port_binding.ts) · [`src/infrastructure/composition/main_run_route_composition_root.ts`](../src/infrastructure/composition/main_run_route_composition_root.ts) · [`src/application/policies/configuration_persistence_policy.ts`](../src/application/policies/configuration_persistence_policy.ts) · [`src/application/ports/project_board_query_ports.ts`](../src/application/ports/project_board_query_ports.ts) · [`src/application/usecases/steps/commit/check_changes_issue_size_use_case.ts`](../src/application/usecases/steps/commit/check_changes_issue_size_use_case.ts) · [`src/application/usecases/steps/commit/check_changes_issue_size_workflow.ts`](../src/application/usecases/steps/commit/check_changes_issue_size_workflow.ts) · [`src/application/usecases/steps/commit/update_change_size_labels.ts`](../src/application/usecases/steps/commit/update_change_size_labels.ts) · [`src/data/repository/project/project_board_item_query.ts`](../src/data/repository/project/project_board_item_query.ts) · [`src/infrastructure/composition/change_size_project_membership_composition_root.ts`](../src/infrastructure/composition/change_size_project_membership_composition_root.ts) · [`src/manager/description/configuration_handler.ts`](../src/manager/description/configuration_handler.ts) · [`src/manager/description/configuration_markers.ts`](../src/manager/description/configuration_markers.ts) · [`src/data/repository/issue/issue_content_repository.ts`](../src/data/repository/issue/issue_content_repository.ts) · [`src/data/repository/github/github_error_policy.ts`](../src/data/repository/github/github_error_policy.ts) +- Tests: [`src/tooling/__tests__/coverage_budget_validator.test.ts`](../src/tooling/__tests__/coverage_budget_validator.test.ts) · [`src/__tests__/api.test.ts`](../src/__tests__/api.test.ts) · [`src/actions/__tests__/github_action.test.ts`](../src/actions/__tests__/github_action.test.ts) · [`src/actions/__tests__/github_action_completion.test.ts`](../src/actions/__tests__/github_action_completion.test.ts) · [`src/application/errors/__tests__/application_error.test.ts`](../src/application/errors/__tests__/application_error.test.ts) · [`src/application/policies/__tests__/application_error_message_catalog.test.ts`](../src/application/policies/__tests__/application_error_message_catalog.test.ts) · [`src/application/policies/__tests__/application_error_presentation_policy.test.ts`](../src/application/policies/__tests__/application_error_presentation_policy.test.ts) · [`src/application/policies/__tests__/bugbot_result_finding_state_projection_policy.test.ts`](../src/application/policies/__tests__/bugbot_result_finding_state_projection_policy.test.ts) · [`src/application/policies/__tests__/bugbot_telemetry_projection_policy.test.ts`](../src/application/policies/__tests__/bugbot_telemetry_projection_policy.test.ts) · [`src/application/policies/__tests__/action_summary_policy.test.ts`](../src/application/policies/__tests__/action_summary_policy.test.ts) · [`src/application/policies/__tests__/copilot_evidence_policy.test.ts`](../src/application/policies/__tests__/copilot_evidence_policy.test.ts) · [`src/application/policies/__tests__/lifecycle_state_policy.test.ts`](../src/application/policies/__tests__/lifecycle_state_policy.test.ts) · [`src/application/policies/__tests__/status_command_policy.test.ts`](../src/application/policies/__tests__/status_command_policy.test.ts) · [`src/application/usecases/actions/__tests__/lifecycle_synchronization_context.test.ts`](../src/application/usecases/actions/__tests__/lifecycle_synchronization_context.test.ts) · [`src/application/usecases/actions/__tests__/synchronize_lifecycle_state_use_case.test.ts`](../src/application/usecases/actions/__tests__/synchronize_lifecycle_state_use_case.test.ts) · [`src/application/usecases/actions/__tests__/lifecycle_event_replay.integration.test.ts`](../src/application/usecases/actions/__tests__/lifecycle_event_replay.integration.test.ts) · [`src/architecture/__tests__/execution_import_ratchet.test.ts`](../src/architecture/__tests__/execution_import_ratchet.test.ts) · [`src/architecture/__tests__/raw_error_logging_boundaries.test.ts`](../src/architecture/__tests__/raw_error_logging_boundaries.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/bugbot_review_operation_context.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/bugbot_review_operation_context.test.ts) · [`src/application/usecases/steps/common/__tests__/shared_capability_context_projection.test.ts`](../src/application/usecases/steps/common/__tests__/shared_capability_context_projection.test.ts) · [`src/application/usecases/steps/common/__tests__/publish_resume_use_case.test.ts`](../src/application/usecases/steps/common/__tests__/publish_resume_use_case.test.ts) · [`src/infrastructure/composition/__tests__/shared_capability_port_binding.test.ts`](../src/infrastructure/composition/__tests__/shared_capability_port_binding.test.ts) · [`src/application/usecases/__tests__/issue_pull_request_context_projection.test.ts`](../src/application/usecases/__tests__/issue_pull_request_context_projection.test.ts) · [`src/infrastructure/composition/__tests__/lifecycle_capability_port_binding.test.ts`](../src/infrastructure/composition/__tests__/lifecycle_capability_port_binding.test.ts) · [`src/infrastructure/composition/__tests__/lifecycle_state_composition_root.test.ts`](../src/infrastructure/composition/__tests__/lifecycle_state_composition_root.test.ts) · [`src/application/usecases/__tests__/push_single_action_contexts.test.ts`](../src/application/usecases/__tests__/push_single_action_contexts.test.ts) · [`src/application/usecases/__tests__/single_action_workflow.test.ts`](../src/application/usecases/__tests__/single_action_workflow.test.ts) · [`src/infrastructure/composition/__tests__/push_single_action_capability_port_binding.test.ts`](../src/infrastructure/composition/__tests__/push_single_action_capability_port_binding.test.ts) · [`src/application/usecases/execution/__tests__/resolve_github_execution_admission_use_case.test.ts`](../src/application/usecases/execution/__tests__/resolve_github_execution_admission_use_case.test.ts) · [`src/application/usecases/workflow/__tests__/wait_for_previous_workflow_runs_use_case.test.ts`](../src/application/usecases/workflow/__tests__/wait_for_previous_workflow_runs_use_case.test.ts) · [`src/application/policies/__tests__/configuration_persistence_policy.test.ts`](../src/application/policies/__tests__/configuration_persistence_policy.test.ts) · [`src/application/usecases/steps/commit/__tests__/check_changes_issue_size_use_case.test.ts`](../src/application/usecases/steps/commit/__tests__/check_changes_issue_size_use_case.test.ts) · [`src/application/usecases/steps/commit/__tests__/update_change_size_labels.test.ts`](../src/application/usecases/steps/commit/__tests__/update_change_size_labels.test.ts) · [`src/data/repository/project/__tests__/project_board_visibility_recovery.test.ts`](../src/data/repository/project/__tests__/project_board_visibility_recovery.test.ts) · [`src/infrastructure/composition/__tests__/change_size_project_membership_composition_root.test.ts`](../src/infrastructure/composition/__tests__/change_size_project_membership_composition_root.test.ts) · [`src/manager/description/__tests__/configuration_recovery.test.ts`](../src/manager/description/__tests__/configuration_recovery.test.ts) · [`src/manager/description/__tests__/configuration_handler.test.ts`](../src/manager/description/__tests__/configuration_handler.test.ts) · [`src/data/repository/issue/__tests__/issue_content_repository.test.ts`](../src/data/repository/issue/__tests__/issue_content_repository.test.ts) +- User documentation: [`docs/overview.mdx`](../docs/overview.mdx) · [`docs/bugbot/programmatic-api.mdx`](../docs/bugbot/programmatic-api.mdx) · [`docs/security-operations/operations/error-reference.mdx`](../docs/security-operations/operations/error-reference.mdx) · [`docs/security-operations/operations/troubleshooting.mdx`](../docs/security-operations/operations/troubleshooting.mdx) · [`docs/bugbot/quality-observability.mdx`](../docs/bugbot/quality-observability.mdx) · [`docs/bugbot/failure-scenarios.mdx`](../docs/bugbot/failure-scenarios.mdx) · [`docs/development/architecture.mdx`](../docs/development/architecture.mdx) · [`docs/issues/assignees-and-projects.mdx`](../docs/issues/assignees-and-projects.mdx) · [`docs/configuration.mdx`](../docs/configuration.mdx) ### `architecture-quality-hardening` — Architecture quality and scalability hardening @@ -104,23 +104,23 @@ debt or convert unknown historic intent into a design decision. - Owner: Copilot maintainers - Last verified: 2026-10-20 -- Specifications: [`specs/setup-configuration-credentials-and-doctor.md`](./setup-configuration-credentials-and-doctor.md) · [`specs/setup-doctor-architecture-hardening.md`](./setup-doctor-architecture-hardening.md) · [`specs/setup-pat-permission-guidance-and-verification.md`](./setup-pat-permission-guidance-and-verification.md) · [`specs/github-runtime-doctor-command.md`](./github-runtime-doctor-command.md) · [`specs/organization-configuration-reuse-and-batch-setup.md`](./organization-configuration-reuse-and-batch-setup.md) · [`specs/setup-runner-profiles-and-installation-parity.md`](./setup-runner-profiles-and-installation-parity.md) +- Specifications: [`specs/setup-configuration-credentials-and-doctor.md`](./setup-configuration-credentials-and-doctor.md) · [`specs/setup-doctor-architecture-hardening.md`](./setup-doctor-architecture-hardening.md) · [`specs/setup-pat-permission-guidance-and-verification.md`](./setup-pat-permission-guidance-and-verification.md) · [`specs/github-runtime-doctor-command.md`](./github-runtime-doctor-command.md) · [`specs/organization-configuration-reuse-and-batch-setup.md`](./organization-configuration-reuse-and-batch-setup.md) · [`specs/setup-runner-profiles-and-installation-parity.md`](./setup-runner-profiles-and-installation-parity.md) · [`specs/copilot-comment-workflow-coordinator.md`](./copilot-comment-workflow-coordinator.md) - Workflows: [`setup/workflows/agent-cli-provisioning.yml`](../setup/workflows/agent-cli-provisioning.yml) · [`setup/workflows/copilot_credential_health.yml`](../setup/workflows/copilot_credential_health.yml) · [`.github/workflows/copilot_issue_comment.yml`](../.github/workflows/copilot_issue_comment.yml) · [`.github/workflows/copilot_pull_request_comment.yml`](../.github/workflows/copilot_pull_request_comment.yml) · [`.github/workflows/agent-cli-provisioning.yml`](../.github/workflows/agent-cli-provisioning.yml) · [`.github/workflows/copilot_credential_health.yml`](../.github/workflows/copilot_credential_health.yml) · [`.github/workflows/copilot_commit.yml`](../.github/workflows/copilot_commit.yml) · [`.github/workflows/copilot_branch_sync.yml`](../.github/workflows/copilot_branch_sync.yml) · [`setup/workflows/copilot_commit.yml`](../setup/workflows/copilot_commit.yml) · [`setup/workflows/copilot_branch_sync.yml`](../setup/workflows/copilot_branch_sync.yml) · [`setup/workflows/copilot_issue_comment.yml`](../setup/workflows/copilot_issue_comment.yml) · [`setup/workflows/copilot_pull_request_comment.yml`](../setup/workflows/copilot_pull_request_comment.yml) - Entrypoints: [`src/cli/commands/setup.ts`](../src/cli/commands/setup.ts) · [`src/cli/commands/doctor.ts`](../src/cli/commands/doctor.ts) · [`src/application/usecases/issue_comment_use_case.ts`](../src/application/usecases/issue_comment_use_case.ts) · [`src/application/usecases/pull_request_review_comment_use_case.ts`](../src/application/usecases/pull_request_review_comment_use_case.ts) -- Core code: [`src/domain/setup.ts`](../src/domain/setup.ts) · [`src/domain/setup_questionnaire.ts`](../src/domain/setup_questionnaire.ts) · [`src/domain/setup_token_permissions.ts`](../src/domain/setup_token_permissions.ts) · [`src/application/ports/setup_terminal_ports.ts`](../src/application/ports/setup_terminal_ports.ts) · [`src/application/ports/setup_wizard_ports.ts`](../src/application/ports/setup_wizard_ports.ts) · [`src/application/ports/branch_tag_ports.ts`](../src/application/ports/branch_tag_ports.ts) · [`src/application/policies/setup_issue_workflow_policy.ts`](../src/application/policies/setup_issue_workflow_policy.ts) · [`src/data/repository/release/repository_version_tags_query_repository.ts`](../src/data/repository/release/repository_version_tags_query_repository.ts) · [`src/application/ports/setup_token_permission_ports.ts`](../src/application/ports/setup_token_permission_ports.ts) · [`src/application/policies/setup_token_permission_evidence_policy.ts`](../src/application/policies/setup_token_permission_evidence_policy.ts) · [`src/application/policies/setup_token_permission_policy.ts`](../src/application/policies/setup_token_permission_policy.ts) · [`src/application/policies/setup_questionnaire_policy.ts`](../src/application/policies/setup_questionnaire_policy.ts) · [`src/application/policies/setup_configuration_plan.ts`](../src/application/policies/setup_configuration_plan.ts) · [`src/application/policies/merge_setup_overrides_policy.ts`](../src/application/policies/merge_setup_overrides_policy.ts) · [`src/application/policies/setup_configuration_storage_policy.ts`](../src/application/policies/setup_configuration_storage_policy.ts) · [`src/application/policies/setup_doctor_message_catalog.ts`](../src/application/policies/setup_doctor_message_catalog.ts) · [`src/application/policies/setup_doctor_report_policy.ts`](../src/application/policies/setup_doctor_report_policy.ts) · [`src/application/policies/setup_journey_policy.ts`](../src/application/policies/setup_journey_policy.ts) · [`src/application/policies/setup_permission_summary_policy.ts`](../src/application/policies/setup_permission_summary_policy.ts) · [`src/application/usecases/setup/setup_wizard_use_case.ts`](../src/application/usecases/setup/setup_wizard_use_case.ts) · [`src/application/usecases/setup/setup_journey_use_case.ts`](../src/application/usecases/setup/setup_journey_use_case.ts) · [`src/application/usecases/setup/setup_session_coordinator.ts`](../src/application/usecases/setup/setup_session_coordinator.ts) · [`src/application/usecases/setup/setup_questionnaire_controller.ts`](../src/application/usecases/setup/setup_questionnaire_controller.ts) · [`src/application/usecases/setup/setup_credentials_use_case.ts`](../src/application/usecases/setup/setup_credentials_use_case.ts) · [`src/application/usecases/setup/setup_token_permissions_use_case.ts`](../src/application/usecases/setup/setup_token_permissions_use_case.ts) · [`src/application/usecases/setup/doctor_use_case.ts`](../src/application/usecases/setup/doctor_use_case.ts) · [`src/application/usecases/setup/merge_queue_readiness_use_case.ts`](../src/application/usecases/setup/merge_queue_readiness_use_case.ts) · [`src/application/usecases/actions/initial_setup_workflow.ts`](../src/application/usecases/actions/initial_setup_workflow.ts) · [`src/application/usecases/actions/setup_resource_provisioning.ts`](../src/application/usecases/actions/setup_resource_provisioning.ts) · [`src/application/ports/message_catalog_ports.ts`](../src/application/ports/message_catalog_ports.ts) · [`src/application/usecases/localization/resolve_message_catalog_use_case.ts`](../src/application/usecases/localization/resolve_message_catalog_use_case.ts) · [`src/application/policies/setup_configuration_validation.ts`](../src/application/policies/setup_configuration_validation.ts) · [`src/infrastructure/setup_workspace_adapter.ts`](../src/infrastructure/setup_workspace_adapter.ts) · [`src/data/repository/repository_variables_repository.ts`](../src/data/repository/repository_variables_repository.ts) · [`src/infrastructure/github/ports/github_repository_variables_protocol.ts`](../src/infrastructure/github/ports/github_repository_variables_protocol.ts) · [`src/infrastructure/setup_remote_credential_health_adapter.ts`](../src/infrastructure/setup_remote_credential_health_adapter.ts) · [`src/infrastructure/setup_credential_validation_adapter.ts`](../src/infrastructure/setup_credential_validation_adapter.ts) · [`src/infrastructure/setup_token_permission_query_adapter.ts`](../src/infrastructure/setup_token_permission_query_adapter.ts) · [`src/infrastructure/setup_permission_actions_probe.ts`](../src/infrastructure/setup_permission_actions_probe.ts) · [`src/infrastructure/setup_permission_issue_probe.ts`](../src/infrastructure/setup_permission_issue_probe.ts) · [`src/infrastructure/setup_permission_issue_cleanup.ts`](../src/infrastructure/setup_permission_issue_cleanup.ts) · [`src/infrastructure/setup_permission_probe_journal.ts`](../src/infrastructure/setup_permission_probe_journal.ts) · [`src/infrastructure/setup_permission_probe_transaction.ts`](../src/infrastructure/setup_permission_probe_transaction.ts) · [`src/infrastructure/setup_permission_resource_probes.ts`](../src/infrastructure/setup_permission_resource_probes.ts) · [`src/infrastructure/setup_projects_probe_page_policy.ts`](../src/infrastructure/setup_projects_probe_page_policy.ts) · [`src/cli/setup_terminal_driver.ts`](../src/cli/setup_terminal_driver.ts) · [`src/cli/setup_question_renderer.ts`](../src/cli/setup_question_renderer.ts) · [`src/cli/setup_journey_presenter.ts`](../src/cli/setup_journey_presenter.ts) · [`src/cli/setup_plan_presenter.ts`](../src/cli/setup_plan_presenter.ts) · [`src/cli/setup_doctor_presenter.ts`](../src/cli/setup_doctor_presenter.ts) · [`src/cli/setup_prompt_rendering.ts`](../src/cli/setup_prompt_rendering.ts) · [`src/cli/setup_credential_prompt_adapter.ts`](../src/cli/setup_credential_prompt_adapter.ts) · [`src/cli/setup_credential_collection.ts`](../src/cli/setup_credential_collection.ts) · [`src/cli/commands/setup_execution.ts`](../src/cli/commands/setup_execution.ts) · [`src/cli/setup_token_permission_presenter.ts`](../src/cli/setup_token_permission_presenter.ts) · [`src/infrastructure/composition/setup_credentials_composition_root.ts`](../src/infrastructure/composition/setup_credentials_composition_root.ts) · [`src/infrastructure/composition/setup_token_permissions_composition_root.ts`](../src/infrastructure/composition/setup_token_permissions_composition_root.ts) · [`src/infrastructure/composition/setup_doctor_composition_root.ts`](../src/infrastructure/composition/setup_doctor_composition_root.ts) · [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`scripts/documentation_pat_exception_policy.cjs`](../scripts/documentation_pat_exception_policy.cjs) · [`scripts/validate-documentation-contract.cjs`](../scripts/validate-documentation-contract.cjs) · [`src/infrastructure/http_deadline.ts`](../src/infrastructure/http_deadline.ts) · [`src/infrastructure/setup_permission_denial.ts`](../src/infrastructure/setup_permission_denial.ts) · [`src/infrastructure/setup_permission_read_probe.ts`](../src/infrastructure/setup_permission_read_probe.ts) · [`src/infrastructure/setup_permission_read_evidence.ts`](../src/infrastructure/setup_permission_read_evidence.ts) · [`src/infrastructure/setup_permission_read_shape.ts`](../src/infrastructure/setup_permission_read_shape.ts) · [`src/infrastructure/setup_permission_projects_read.ts`](../src/infrastructure/setup_permission_projects_read.ts) · [`src/infrastructure/setup_permission_projects_access.ts`](../src/infrastructure/setup_permission_projects_access.ts) · [`src/infrastructure/setup_permission_workflow_cleanup.ts`](../src/infrastructure/setup_permission_workflow_cleanup.ts) · [`src/infrastructure/setup_permission_project_cleanup.ts`](../src/infrastructure/setup_permission_project_cleanup.ts) · [`src/infrastructure/setup_permission_probe_http.ts`](../src/infrastructure/setup_permission_probe_http.ts) · [`src/infrastructure/setup_permission_pull_request_probe.ts`](../src/infrastructure/setup_permission_pull_request_probe.ts) · [`src/infrastructure/git_authentication_environment.ts`](../src/infrastructure/git_authentication_environment.ts) · [`src/actions/github_action_input.ts`](../src/actions/github_action_input.ts) · [`src/infrastructure/setup_github_identity_query_adapter.ts`](../src/infrastructure/setup_github_identity_query_adapter.ts) · [`src/infrastructure/github_secret_encryption.ts`](../src/infrastructure/github_secret_encryption.ts) · [`src/infrastructure/setup_permission_organization_owner.ts`](../src/infrastructure/setup_permission_organization_owner.ts) · [`src/data/repository/github/github_actions_resource_inspector.ts`](../src/data/repository/github/github_actions_resource_inspector.ts) · [`src/data/repository/github/github_actions_resource_commands.ts`](../src/data/repository/github/github_actions_resource_commands.ts) · [`src/data/repository/github/github_actions_resource_collection.ts`](../src/data/repository/github/github_actions_resource_collection.ts) · [`src/application/usecases/setup/resolve_setup_workflow_pat_conflict_use_case.ts`](../src/application/usecases/setup/resolve_setup_workflow_pat_conflict_use_case.ts) · [`src/cli/setup_workflow_pat_storage_copy.ts`](../src/cli/setup_workflow_pat_storage_copy.ts) · [`src/cli/commands/setup_policy.ts`](../src/cli/commands/setup_policy.ts) · [`src/application/usecases/execution/execution_issue_number_policy.ts`](../src/application/usecases/execution/execution_issue_number_policy.ts) · [`src/application/usecases/execution/setup_execution_workflow.ts`](../src/application/usecases/execution/setup_execution_workflow.ts) · [`src/domain/github_runtime_doctor.ts`](../src/domain/github_runtime_doctor.ts) · [`src/domain/copilot_command.ts`](../src/domain/copilot_command.ts) · [`src/application/usecases/comment_automation_command_workflow.ts`](../src/application/usecases/comment_automation_command_workflow.ts) · [`src/application/policies/copilot_interaction_policy.ts`](../src/application/policies/copilot_interaction_policy.ts) · [`src/application/policies/publication_message_catalog.ts`](../src/application/policies/publication_message_catalog.ts) · [`src/application/ports/github_runtime_doctor_ports.ts`](../src/application/ports/github_runtime_doctor_ports.ts) · [`src/application/policies/github_runtime_doctor_policy.ts`](../src/application/policies/github_runtime_doctor_policy.ts) · [`src/application/policies/doctor_workflow_condition_policy.ts`](../src/application/policies/doctor_workflow_condition_policy.ts) · [`src/application/policies/github_runtime_doctor_presentation_policy.ts`](../src/application/policies/github_runtime_doctor_presentation_policy.ts) · [`src/application/usecases/read_copilot_doctor_workflow.ts`](../src/application/usecases/read_copilot_doctor_workflow.ts) · [`src/data/repository/github/runtime_doctor_repository.ts`](../src/data/repository/github/runtime_doctor_repository.ts) · [`src/infrastructure/composition/github_runtime_doctor_composition_root.ts`](../src/infrastructure/composition/github_runtime_doctor_composition_root.ts) · [`src/application/policies/agent_activity_policy.ts`](../src/application/policies/agent_activity_policy.ts) · [`src/application/policies/doctor_workflow_matrix_policy.ts`](../src/application/policies/doctor_workflow_matrix_policy.ts) · [`src/application/contracts/setup_batch_view.ts`](../src/application/contracts/setup_batch_view.ts) · [`src/application/policies/issue_resource_input_policy.ts`](../src/application/policies/issue_resource_input_policy.ts) · [`src/application/policies/setup_batch_access_policy.ts`](../src/application/policies/setup_batch_access_policy.ts) · [`src/application/policies/setup_batch_policy.ts`](../src/application/policies/setup_batch_policy.ts) · [`src/application/policies/setup_batch_retry_policy.ts`](../src/application/policies/setup_batch_retry_policy.ts) · [`src/application/policies/setup_batch_selection_policy.ts`](../src/application/policies/setup_batch_selection_policy.ts) · [`src/application/policies/setup_batch_view_policy.ts`](../src/application/policies/setup_batch_view_policy.ts) · [`src/application/policies/setup_credential_binding_policy.ts`](../src/application/policies/setup_credential_binding_policy.ts) · [`src/application/policies/setup_organization_import_policy.ts`](../src/application/policies/setup_organization_import_policy.ts) · [`src/application/policies/setup_organization_variable_bindings.ts`](../src/application/policies/setup_organization_variable_bindings.ts) · [`src/application/policies/setup_organization_variable_reuse_policy.ts`](../src/application/policies/setup_organization_variable_reuse_policy.ts) · [`src/application/ports/setup_batch_ports.ts`](../src/application/ports/setup_batch_ports.ts) · [`src/application/usecases/setup/apply_setup_batch_use_case.ts`](../src/application/usecases/setup/apply_setup_batch_use_case.ts) · [`src/application/usecases/setup/configure_setup_batch_target_use_case.ts`](../src/application/usecases/setup/configure_setup_batch_target_use_case.ts) · [`src/application/usecases/setup/prepare_setup_batch_use_case.ts`](../src/application/usecases/setup/prepare_setup_batch_use_case.ts) · [`src/application/usecases/setup/select_setup_batch_targets_use_case.ts`](../src/application/usecases/setup/select_setup_batch_targets_use_case.ts) · [`src/application/usecases/setup/setup_batch_session_use_case.ts`](../src/application/usecases/setup/setup_batch_session_use_case.ts) · [`src/cli/setup_batch_adapter.ts`](../src/cli/setup_batch_adapter.ts) · [`src/cli/setup_source_adapter.ts`](../src/cli/setup_source_adapter.ts) · [`src/domain/setup_batch.ts`](../src/domain/setup_batch.ts) · [`src/domain/setup_credential_health.ts`](../src/domain/setup_credential_health.ts) · [`src/domain/setup_organization_reuse.ts`](../src/domain/setup_organization_reuse.ts) · [`src/infrastructure/composition/setup_batch_composition_root.ts`](../src/infrastructure/composition/setup_batch_composition_root.ts) · [`src/infrastructure/github/ports/github_setup_batch_protocol.ts`](../src/infrastructure/github/ports/github_setup_batch_protocol.ts) · [`src/infrastructure/github/ports/github_trusted_credential_health_protocol.ts`](../src/infrastructure/github/ports/github_trusted_credential_health_protocol.ts) · [`src/infrastructure/setup_batch_github_apply_adapter.ts`](../src/infrastructure/setup_batch_github_apply_adapter.ts) · [`src/infrastructure/setup_batch_github_read_adapter.ts`](../src/infrastructure/setup_batch_github_read_adapter.ts) · [`src/infrastructure/setup_batch_journal_adapter.ts`](../src/infrastructure/setup_batch_journal_adapter.ts) · [`src/infrastructure/setup_batch_workspace_adapter.ts`](../src/infrastructure/setup_batch_workspace_adapter.ts) · [`src/infrastructure/setup_trusted_credential_health_adapter.ts`](../src/infrastructure/setup_trusted_credential_health_adapter.ts) · [`src/application/policies/setup_remote_facts_policy.ts`](../src/application/policies/setup_remote_facts_policy.ts) · [`src/cli/setup_confirmation_adapter.ts`](../src/cli/setup_confirmation_adapter.ts) · [`src/cli/web_setup_adapters.ts`](../src/cli/web_setup_adapters.ts) · [`scripts/validate-agent-documentation.cjs`](../scripts/validate-agent-documentation.cjs) · [`src/utils/setup_workflow_upgrade.ts`](../src/utils/setup_workflow_upgrade.ts) · [`src/domain/setup_runner.ts`](../src/domain/setup_runner.ts) · [`src/application/policies/setup_runner_policy.ts`](../src/application/policies/setup_runner_policy.ts) · [`src/application/policies/setup_runner_question_policy.ts`](../src/application/policies/setup_runner_question_policy.ts) · [`src/application/policies/setup_runner_guidance_policy.ts`](../src/application/policies/setup_runner_guidance_policy.ts) · [`src/application/ports/setup_runner_ports.ts`](../src/application/ports/setup_runner_ports.ts) · [`src/infrastructure/setup_runner_discovery_adapter.ts`](../src/infrastructure/setup_runner_discovery_adapter.ts) · [`src/infrastructure/composition/setup_runner_composition_root.ts`](../src/infrastructure/composition/setup_runner_composition_root.ts) · [`src/utils/setup_installation_review.ts`](../src/utils/setup_installation_review.ts) · [`src/cli/setup_installation_review_presenter.ts`](../src/cli/setup_installation_review_presenter.ts) · [`src/application/policies/setup_runner_installation_summary_policy.ts`](../src/application/policies/setup_runner_installation_summary_policy.ts) · [`src/utils/setup_files.ts`](../src/utils/setup_files.ts) · [`src/domain/specification_catalog_path_policy.cjs`](../src/domain/specification_catalog_path_policy.cjs) · [`src/domain/sdd_prerequisite_policy.cjs`](../src/domain/sdd_prerequisite_policy.cjs) · [`src/application/contracts/setup_documentation.ts`](../src/application/contracts/setup_documentation.ts) · [`src/application/policies/setup_question_documentation_policy.ts`](../src/application/policies/setup_question_documentation_policy.ts) · [`web/src/components/SetupHelp.svelte`](../web/src/components/SetupHelp.svelte) · [`web/src/components/CompletedSetupHelp.svelte`](../web/src/components/CompletedSetupHelp.svelte) · [`src/application/policies/verification_runtime_policy.ts`](../src/application/policies/verification_runtime_policy.ts) · [`src/infrastructure/verification_runtime_manifest.ts`](../src/infrastructure/verification_runtime_manifest.ts) · [`src/infrastructure/verification_runtime_preflight.ts`](../src/infrastructure/verification_runtime_preflight.ts) · [`src/infrastructure/untrusted_command_environment.ts`](../src/infrastructure/untrusted_command_environment.ts) · [`src/application/ports/git_ports.ts`](../src/application/ports/git_ports.ts) · [`src/application/ports/bugbot_git_ports.ts`](../src/application/ports/bugbot_git_ports.ts) · [`src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts`](../src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts) · [`src/application/usecases/steps/commit/bugbot/verify_command_runner.ts`](../src/application/usecases/steps/commit/bugbot/verify_command_runner.ts) -- Tests: [`src/data/repository/__tests__/repository_version_tags_query_repository.test.ts`](../src/data/repository/__tests__/repository_version_tags_query_repository.test.ts) · [`src/cli/__tests__/setup_command_options.test.ts`](../src/cli/__tests__/setup_command_options.test.ts) · [`src/data/repository/__tests__/setup_variable_write_failures.test.ts`](../src/data/repository/__tests__/setup_variable_write_failures.test.ts) · [`src/infrastructure/composition/__tests__/initial_setup_composition_root.test.ts`](../src/infrastructure/composition/__tests__/initial_setup_composition_root.test.ts) · [`src/application/policies/__tests__/setup_questionnaire_policy.test.ts`](../src/application/policies/__tests__/setup_questionnaire_policy.test.ts) · [`src/application/policies/__tests__/setup_configuration_policy.test.ts`](../src/application/policies/__tests__/setup_configuration_policy.test.ts) · [`src/application/policies/__tests__/setup_token_permission_policy.test.ts`](../src/application/policies/__tests__/setup_token_permission_policy.test.ts) · [`src/application/policies/__tests__/setup_remote_facts_policy.test.ts`](../src/application/policies/__tests__/setup_remote_facts_policy.test.ts) · [`src/application/policies/__tests__/setup_doctor_message_catalog.test.ts`](../src/application/policies/__tests__/setup_doctor_message_catalog.test.ts) · [`src/application/policies/__tests__/setup_doctor_report_policy.test.ts`](../src/application/policies/__tests__/setup_doctor_report_policy.test.ts) · [`src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts`](../src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts) · [`src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts`](../src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts) · [`src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_token_permissions_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_token_permissions_use_case.test.ts) · [`src/application/usecases/setup/__tests__/doctor_use_case.test.ts`](../src/application/usecases/setup/__tests__/doctor_use_case.test.ts) · [`src/application/usecases/setup/__tests__/merge_queue_readiness_use_case.test.ts`](../src/application/usecases/setup/__tests__/merge_queue_readiness_use_case.test.ts) · [`src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts`](../src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts) · [`src/application/usecases/actions/__tests__/setup_resource_provisioning.test.ts`](../src/application/usecases/actions/__tests__/setup_resource_provisioning.test.ts) · [`src/infrastructure/__tests__/setup_workspace_adapter.test.ts`](../src/infrastructure/__tests__/setup_workspace_adapter.test.ts) · [`src/infrastructure/__tests__/setup_remote_credential_health_adapter.test.ts`](../src/infrastructure/__tests__/setup_remote_credential_health_adapter.test.ts) · [`src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts`](../src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts) · [`src/infrastructure/__tests__/setup_permission_resource_probes.test.ts`](../src/infrastructure/__tests__/setup_permission_resource_probes.test.ts) · [`src/infrastructure/__tests__/setup_projects_probe_page_policy.test.ts`](../src/infrastructure/__tests__/setup_projects_probe_page_policy.test.ts) · [`src/infrastructure/composition/__tests__/setup_token_permissions_composition_root.test.ts`](../src/infrastructure/composition/__tests__/setup_token_permissions_composition_root.test.ts) · [`src/data/repository/__tests__/repository_variables_repository.test.ts`](../src/data/repository/__tests__/repository_variables_repository.test.ts) · [`src/cli/__tests__/setup_presenters.test.ts`](../src/cli/__tests__/setup_presenters.test.ts) · [`src/cli/__tests__/setup_journey_presenter.test.ts`](../src/cli/__tests__/setup_journey_presenter.test.ts) · [`src/cli/__tests__/setup_prompt_rendering.test.ts`](../src/cli/__tests__/setup_prompt_rendering.test.ts) · [`src/cli/__tests__/setup_token_permission_presenter.test.ts`](../src/cli/__tests__/setup_token_permission_presenter.test.ts) · [`src/__tests__/cli.test.ts`](../src/__tests__/cli.test.ts) · [`src/cli/__tests__/setup_terminal_driver.test.ts`](../src/cli/__tests__/setup_terminal_driver.test.ts) · [`src/architecture/__tests__/setup_doctor_boundaries.test.ts`](../src/architecture/__tests__/setup_doctor_boundaries.test.ts) · [`src/tooling/__tests__/documentation_pat_exception_policy.test.ts`](../src/tooling/__tests__/documentation_pat_exception_policy.test.ts) · [`src/infrastructure/__tests__/setup_pat_audit.test.ts`](../src/infrastructure/__tests__/setup_pat_audit.test.ts) · [`src/infrastructure/__tests__/setup_permission_projects_access.test.ts`](../src/infrastructure/__tests__/setup_permission_projects_access.test.ts) · [`src/infrastructure/__tests__/setup_credential_validation_adapter.test.ts`](../src/infrastructure/__tests__/setup_credential_validation_adapter.test.ts) · [`src/infrastructure/__tests__/setup_github_identity_query_adapter.test.ts`](../src/infrastructure/__tests__/setup_github_identity_query_adapter.test.ts) · [`src/infrastructure/__tests__/git_commit_adapter.test.ts`](../src/infrastructure/__tests__/git_commit_adapter.test.ts) · [`src/actions/__tests__/github_action_input.test.ts`](../src/actions/__tests__/github_action_input.test.ts) · [`src/infrastructure/__tests__/setup_permission_cleanup_contract.test.ts`](../src/infrastructure/__tests__/setup_permission_cleanup_contract.test.ts) · [`src/infrastructure/__tests__/setup_permission_actions_cleanup_timing.test.ts`](../src/infrastructure/__tests__/setup_permission_actions_cleanup_timing.test.ts) · [`src/infrastructure/__tests__/setup_permission_operator_actions.test.ts`](../src/infrastructure/__tests__/setup_permission_operator_actions.test.ts) · [`src/infrastructure/__tests__/setup_permission_journal_contract.test.ts`](../src/infrastructure/__tests__/setup_permission_journal_contract.test.ts) · [`src/infrastructure/__tests__/setup_permission_audit_transactions.test.ts`](../src/infrastructure/__tests__/setup_permission_audit_transactions.test.ts) · [`src/infrastructure/__tests__/setup_permission_write_failures.test.ts`](../src/infrastructure/__tests__/setup_permission_write_failures.test.ts) · [`src/infrastructure/__tests__/setup_permission_resource_failures.test.ts`](../src/infrastructure/__tests__/setup_permission_resource_failures.test.ts) · [`src/infrastructure/__tests__/setup_permission_boundary_failures.test.ts`](../src/infrastructure/__tests__/setup_permission_boundary_failures.test.ts) · [`src/infrastructure/__tests__/github_secret_encryption.test.ts`](../src/infrastructure/__tests__/github_secret_encryption.test.ts) · [`src/infrastructure/__tests__/setup_permission_organization_owner.test.ts`](../src/infrastructure/__tests__/setup_permission_organization_owner.test.ts) · [`src/infrastructure/__tests__/setup_pat_bootstrap_transactions.test.ts`](../src/infrastructure/__tests__/setup_pat_bootstrap_transactions.test.ts) · [`src/data/repository/__tests__/repository_actions_sdk_contract.integration.test.ts`](../src/data/repository/__tests__/repository_actions_sdk_contract.integration.test.ts) · [`src/data/repository/__tests__/repository_actions_resource_edge_cases.test.ts`](../src/data/repository/__tests__/repository_actions_resource_edge_cases.test.ts) · [`src/data/repository/__tests__/repository_selected_resource_grants.test.ts`](../src/data/repository/__tests__/repository_selected_resource_grants.test.ts) · [`src/infrastructure/__tests__/setup_permission_read_contract.test.ts`](../src/infrastructure/__tests__/setup_permission_read_contract.test.ts) · [`src/application/usecases/setup/__tests__/setup_workflow_pat_conflict.test.ts`](../src/application/usecases/setup/__tests__/setup_workflow_pat_conflict.test.ts) · [`src/application/usecases/setup/__tests__/setup_workflow_pat_credential_rotation.test.ts`](../src/application/usecases/setup/__tests__/setup_workflow_pat_credential_rotation.test.ts) · [`src/data/repository/__tests__/setup_organization_pat_inventory.test.ts`](../src/data/repository/__tests__/setup_organization_pat_inventory.test.ts) · [`src/cli/__tests__/web_setup_bot_pat_scope_conflict.test.ts`](../src/cli/__tests__/web_setup_bot_pat_scope_conflict.test.ts) · [`src/actions/__tests__/local_setup_apply_contract.test.ts`](../src/actions/__tests__/local_setup_apply_contract.test.ts) · [`src/cli/commands/__tests__/setup_policy.test.ts`](../src/cli/commands/__tests__/setup_policy.test.ts) · [`src/application/usecases/execution/__tests__/execution_issue_number_policy.test.ts`](../src/application/usecases/execution/__tests__/execution_issue_number_policy.test.ts) · [`src/application/usecases/execution/__tests__/setup_execution_workflow.test.ts`](../src/application/usecases/execution/__tests__/setup_execution_workflow.test.ts) · [`src/domain/__tests__/github_runtime_doctor.test.ts`](../src/domain/__tests__/github_runtime_doctor.test.ts) · [`src/domain/__tests__/copilot_command.test.ts`](../src/domain/__tests__/copilot_command.test.ts) · [`src/application/usecases/__tests__/comment_automation_use_case.test.ts`](../src/application/usecases/__tests__/comment_automation_use_case.test.ts) · [`src/application/policies/__tests__/github_runtime_doctor_policy.test.ts`](../src/application/policies/__tests__/github_runtime_doctor_policy.test.ts) · [`src/application/policies/__tests__/doctor_workflow_condition_policy.test.ts`](../src/application/policies/__tests__/doctor_workflow_condition_policy.test.ts) · [`src/application/policies/__tests__/github_runtime_doctor_presentation_policy.test.ts`](../src/application/policies/__tests__/github_runtime_doctor_presentation_policy.test.ts) · [`src/application/usecases/__tests__/read_copilot_doctor_workflow.test.ts`](../src/application/usecases/__tests__/read_copilot_doctor_workflow.test.ts) · [`src/application/usecases/__tests__/runtime_doctor_security_integration.test.ts`](../src/application/usecases/__tests__/runtime_doctor_security_integration.test.ts) · [`src/data/repository/github/__tests__/runtime_doctor_repository.test.ts`](../src/data/repository/github/__tests__/runtime_doctor_repository.test.ts) · [`src/infrastructure/composition/__tests__/github_runtime_doctor_composition_root.test.ts`](../src/infrastructure/composition/__tests__/github_runtime_doctor_composition_root.test.ts) · [`src/application/policies/__tests__/runtime_doctor_agent_activity.test.ts`](../src/application/policies/__tests__/runtime_doctor_agent_activity.test.ts) · [`src/application/policies/__tests__/doctor_workflow_matrix_policy.test.ts`](../src/application/policies/__tests__/doctor_workflow_matrix_policy.test.ts) · [`src/application/policies/__tests__/setup_approval_operator_permissions.test.ts`](../src/application/policies/__tests__/setup_approval_operator_permissions.test.ts) · [`src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts`](../src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts) · [`src/application/policies/__tests__/setup_batch_permission_policy.test.ts`](../src/application/policies/__tests__/setup_batch_permission_policy.test.ts) · [`src/application/policies/__tests__/setup_batch_policy.test.ts`](../src/application/policies/__tests__/setup_batch_policy.test.ts) · [`src/application/policies/__tests__/setup_batch_retry_policy.test.ts`](../src/application/policies/__tests__/setup_batch_retry_policy.test.ts) · [`src/application/policies/__tests__/setup_batch_selection_policy.test.ts`](../src/application/policies/__tests__/setup_batch_selection_policy.test.ts) · [`src/application/policies/__tests__/setup_organization_approval_draft.test.ts`](../src/application/policies/__tests__/setup_organization_approval_draft.test.ts) · [`src/application/policies/__tests__/setup_organization_import_policy.test.ts`](../src/application/policies/__tests__/setup_organization_import_policy.test.ts) · [`src/application/policies/__tests__/setup_organization_import_safety.test.ts`](../src/application/policies/__tests__/setup_organization_import_safety.test.ts) · [`src/application/policies/__tests__/setup_organization_variable_reuse_policy.test.ts`](../src/application/policies/__tests__/setup_organization_variable_reuse_policy.test.ts) · [`src/application/usecases/actions/__tests__/setup_organization_reuse_provisioning.test.ts`](../src/application/usecases/actions/__tests__/setup_organization_reuse_provisioning.test.ts) · [`src/application/usecases/setup/__tests__/apply_setup_batch_use_case.test.ts`](../src/application/usecases/setup/__tests__/apply_setup_batch_use_case.test.ts) · [`src/application/usecases/setup/__tests__/select_setup_batch_targets_use_case.test.ts`](../src/application/usecases/setup/__tests__/select_setup_batch_targets_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_batch_flow.test.ts`](../src/application/usecases/setup/__tests__/setup_batch_flow.test.ts) · [`src/application/usecases/setup/__tests__/setup_organization_import_wizard.test.ts`](../src/application/usecases/setup/__tests__/setup_organization_import_wizard.test.ts) · [`src/application/usecases/setup/__tests__/setup_organization_secret_reuse.test.ts`](../src/application/usecases/setup/__tests__/setup_organization_secret_reuse.test.ts) · [`src/cli/__tests__/setup_source_adapter.test.ts`](../src/cli/__tests__/setup_source_adapter.test.ts) · [`src/cli/__tests__/web_setup_batch_components.test.ts`](../src/cli/__tests__/web_setup_batch_components.test.ts) · [`src/cli/__tests__/web_setup_batch_selection.test.ts`](../src/cli/__tests__/web_setup_batch_selection.test.ts) · [`src/infrastructure/__tests__/setup_batch_github_apply_adapter.test.ts`](../src/infrastructure/__tests__/setup_batch_github_apply_adapter.test.ts) · [`src/infrastructure/__tests__/setup_batch_github_read_adapter.test.ts`](../src/infrastructure/__tests__/setup_batch_github_read_adapter.test.ts) · [`src/infrastructure/__tests__/setup_batch_local_adapters.test.ts`](../src/infrastructure/__tests__/setup_batch_local_adapters.test.ts) · [`src/infrastructure/__tests__/setup_reuse_empty_collections.integration.test.ts`](../src/infrastructure/__tests__/setup_reuse_empty_collections.integration.test.ts) · [`src/infrastructure/__tests__/setup_trusted_credential_health_adapter.test.ts`](../src/infrastructure/__tests__/setup_trusted_credential_health_adapter.test.ts) · [`src/infrastructure/__tests__/setup_trusted_health_sdk_contract.integration.test.ts`](../src/infrastructure/__tests__/setup_trusted_health_sdk_contract.integration.test.ts) · [`src/application/policies/__tests__/setup_batch_access_and_view.test.ts`](../src/application/policies/__tests__/setup_batch_access_and_view.test.ts) · [`src/cli/__tests__/setup_batch_adapter.test.ts`](../src/cli/__tests__/setup_batch_adapter.test.ts) · [`src/infrastructure/__tests__/setup_batch_composition.test.ts`](../src/infrastructure/__tests__/setup_batch_composition.test.ts) · [`src/infrastructure/__tests__/setup_batch_guidance_compatibility.test.ts`](../src/infrastructure/__tests__/setup_batch_guidance_compatibility.test.ts) · [`src/utils/__tests__/setup_workflow_upgrade.test.ts`](../src/utils/__tests__/setup_workflow_upgrade.test.ts) · [`src/cli/__tests__/setup_pat_intent_adapter.test.ts`](../src/cli/__tests__/setup_pat_intent_adapter.test.ts) · [`src/application/usecases/__tests__/push_single_action_contexts.test.ts`](../src/application/usecases/__tests__/push_single_action_contexts.test.ts) · [`src/application/policies/__tests__/setup_runner_policy.test.ts`](../src/application/policies/__tests__/setup_runner_policy.test.ts) · [`src/application/policies/__tests__/setup_runner_question_policy.test.ts`](../src/application/policies/__tests__/setup_runner_question_policy.test.ts) · [`src/infrastructure/__tests__/setup_runner_discovery_adapter.test.ts`](../src/infrastructure/__tests__/setup_runner_discovery_adapter.test.ts) · [`src/utils/__tests__/setup_runner_installation.test.ts`](../src/utils/__tests__/setup_runner_installation.test.ts) · [`src/cli/__tests__/web_setup_runner_components.test.ts`](../src/cli/__tests__/web_setup_runner_components.test.ts) · [`src/application/policies/__tests__/setup_runner_installation_summary_policy.test.ts`](../src/application/policies/__tests__/setup_runner_installation_summary_policy.test.ts) · [`src/application/usecases/setup/__tests__/setup_runner_planning.test.ts`](../src/application/usecases/setup/__tests__/setup_runner_planning.test.ts) · [`src/cli/__tests__/setup_runner_config_file.test.ts`](../src/cli/__tests__/setup_runner_config_file.test.ts) · [`src/infrastructure/__tests__/setup_runner_composition.test.ts`](../src/infrastructure/__tests__/setup_runner_composition.test.ts) · [`src/tooling/__tests__/setup_provisioning_workflow.test.ts`](../src/tooling/__tests__/setup_provisioning_workflow.test.ts) · [`src/infrastructure/__tests__/setup_sdd_prerequisites.test.ts`](../src/infrastructure/__tests__/setup_sdd_prerequisites.test.ts) · [`src/cli/__tests__/setup_documentation_navigation.test.ts`](../src/cli/__tests__/setup_documentation_navigation.test.ts) · [`src/application/policies/__tests__/setup_question_documentation_policy.test.ts`](../src/application/policies/__tests__/setup_question_documentation_policy.test.ts) · [`src/application/policies/__tests__/verification_runtime_policy.test.ts`](../src/application/policies/__tests__/verification_runtime_policy.test.ts) · [`src/infrastructure/__tests__/verification_runtime_preflight.test.ts`](../src/infrastructure/__tests__/verification_runtime_preflight.test.ts) · [`src/infrastructure/__tests__/verification_runtime_branch_sync.test.ts`](../src/infrastructure/__tests__/verification_runtime_branch_sync.test.ts) · [`src/infrastructure/__tests__/untrusted_command_environment.test.ts`](../src/infrastructure/__tests__/untrusted_command_environment.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/verify_command_runner.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/verify_command_runner.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts) · [`src/tooling/__tests__/verification_runtime_guidance.test.ts`](../src/tooling/__tests__/verification_runtime_guidance.test.ts) +- Core code: [`src/domain/setup.ts`](../src/domain/setup.ts) · [`src/domain/setup_questionnaire.ts`](../src/domain/setup_questionnaire.ts) · [`src/domain/setup_token_permissions.ts`](../src/domain/setup_token_permissions.ts) · [`src/application/ports/setup_terminal_ports.ts`](../src/application/ports/setup_terminal_ports.ts) · [`src/application/ports/setup_wizard_ports.ts`](../src/application/ports/setup_wizard_ports.ts) · [`src/application/ports/branch_tag_ports.ts`](../src/application/ports/branch_tag_ports.ts) · [`src/application/policies/setup_issue_workflow_policy.ts`](../src/application/policies/setup_issue_workflow_policy.ts) · [`src/data/repository/release/repository_version_tags_query_repository.ts`](../src/data/repository/release/repository_version_tags_query_repository.ts) · [`src/application/ports/setup_token_permission_ports.ts`](../src/application/ports/setup_token_permission_ports.ts) · [`src/application/policies/setup_token_permission_evidence_policy.ts`](../src/application/policies/setup_token_permission_evidence_policy.ts) · [`src/application/policies/setup_token_permission_policy.ts`](../src/application/policies/setup_token_permission_policy.ts) · [`src/application/policies/setup_questionnaire_policy.ts`](../src/application/policies/setup_questionnaire_policy.ts) · [`src/application/policies/setup_configuration_plan.ts`](../src/application/policies/setup_configuration_plan.ts) · [`src/application/policies/merge_setup_overrides_policy.ts`](../src/application/policies/merge_setup_overrides_policy.ts) · [`src/application/policies/setup_configuration_storage_policy.ts`](../src/application/policies/setup_configuration_storage_policy.ts) · [`src/application/policies/setup_doctor_message_catalog.ts`](../src/application/policies/setup_doctor_message_catalog.ts) · [`src/application/policies/setup_doctor_report_policy.ts`](../src/application/policies/setup_doctor_report_policy.ts) · [`src/application/policies/setup_journey_policy.ts`](../src/application/policies/setup_journey_policy.ts) · [`src/application/policies/setup_permission_summary_policy.ts`](../src/application/policies/setup_permission_summary_policy.ts) · [`src/application/usecases/setup/setup_wizard_use_case.ts`](../src/application/usecases/setup/setup_wizard_use_case.ts) · [`src/application/usecases/setup/setup_journey_use_case.ts`](../src/application/usecases/setup/setup_journey_use_case.ts) · [`src/application/usecases/setup/setup_session_coordinator.ts`](../src/application/usecases/setup/setup_session_coordinator.ts) · [`src/application/usecases/setup/setup_questionnaire_controller.ts`](../src/application/usecases/setup/setup_questionnaire_controller.ts) · [`src/application/usecases/setup/setup_credentials_use_case.ts`](../src/application/usecases/setup/setup_credentials_use_case.ts) · [`src/application/usecases/setup/setup_token_permissions_use_case.ts`](../src/application/usecases/setup/setup_token_permissions_use_case.ts) · [`src/application/usecases/setup/doctor_use_case.ts`](../src/application/usecases/setup/doctor_use_case.ts) · [`src/application/usecases/setup/merge_queue_readiness_use_case.ts`](../src/application/usecases/setup/merge_queue_readiness_use_case.ts) · [`src/application/usecases/actions/initial_setup_workflow.ts`](../src/application/usecases/actions/initial_setup_workflow.ts) · [`src/application/usecases/actions/setup_resource_provisioning.ts`](../src/application/usecases/actions/setup_resource_provisioning.ts) · [`src/application/ports/message_catalog_ports.ts`](../src/application/ports/message_catalog_ports.ts) · [`src/application/usecases/localization/resolve_message_catalog_use_case.ts`](../src/application/usecases/localization/resolve_message_catalog_use_case.ts) · [`src/application/policies/setup_configuration_validation.ts`](../src/application/policies/setup_configuration_validation.ts) · [`src/infrastructure/setup_workspace_adapter.ts`](../src/infrastructure/setup_workspace_adapter.ts) · [`src/data/repository/repository_variables_repository.ts`](../src/data/repository/repository_variables_repository.ts) · [`src/infrastructure/github/ports/github_repository_variables_protocol.ts`](../src/infrastructure/github/ports/github_repository_variables_protocol.ts) · [`src/infrastructure/setup_remote_credential_health_adapter.ts`](../src/infrastructure/setup_remote_credential_health_adapter.ts) · [`src/infrastructure/setup_credential_validation_adapter.ts`](../src/infrastructure/setup_credential_validation_adapter.ts) · [`src/infrastructure/setup_token_permission_query_adapter.ts`](../src/infrastructure/setup_token_permission_query_adapter.ts) · [`src/infrastructure/setup_permission_actions_probe.ts`](../src/infrastructure/setup_permission_actions_probe.ts) · [`src/infrastructure/setup_permission_issue_probe.ts`](../src/infrastructure/setup_permission_issue_probe.ts) · [`src/infrastructure/setup_permission_issue_cleanup.ts`](../src/infrastructure/setup_permission_issue_cleanup.ts) · [`src/infrastructure/setup_permission_probe_journal.ts`](../src/infrastructure/setup_permission_probe_journal.ts) · [`src/infrastructure/setup_permission_probe_transaction.ts`](../src/infrastructure/setup_permission_probe_transaction.ts) · [`src/infrastructure/setup_permission_resource_probes.ts`](../src/infrastructure/setup_permission_resource_probes.ts) · [`src/infrastructure/setup_projects_probe_page_policy.ts`](../src/infrastructure/setup_projects_probe_page_policy.ts) · [`src/cli/setup_terminal_driver.ts`](../src/cli/setup_terminal_driver.ts) · [`src/cli/setup_question_renderer.ts`](../src/cli/setup_question_renderer.ts) · [`src/cli/setup_journey_presenter.ts`](../src/cli/setup_journey_presenter.ts) · [`src/cli/setup_plan_presenter.ts`](../src/cli/setup_plan_presenter.ts) · [`src/cli/setup_doctor_presenter.ts`](../src/cli/setup_doctor_presenter.ts) · [`src/cli/setup_prompt_rendering.ts`](../src/cli/setup_prompt_rendering.ts) · [`src/cli/setup_credential_prompt_adapter.ts`](../src/cli/setup_credential_prompt_adapter.ts) · [`src/cli/setup_credential_collection.ts`](../src/cli/setup_credential_collection.ts) · [`src/cli/commands/setup_execution.ts`](../src/cli/commands/setup_execution.ts) · [`src/cli/setup_token_permission_presenter.ts`](../src/cli/setup_token_permission_presenter.ts) · [`src/infrastructure/composition/setup_credentials_composition_root.ts`](../src/infrastructure/composition/setup_credentials_composition_root.ts) · [`src/infrastructure/composition/setup_token_permissions_composition_root.ts`](../src/infrastructure/composition/setup_token_permissions_composition_root.ts) · [`src/infrastructure/composition/setup_doctor_composition_root.ts`](../src/infrastructure/composition/setup_doctor_composition_root.ts) · [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`scripts/documentation_pat_exception_policy.cjs`](../scripts/documentation_pat_exception_policy.cjs) · [`scripts/validate-documentation-contract.cjs`](../scripts/validate-documentation-contract.cjs) · [`src/infrastructure/http_deadline.ts`](../src/infrastructure/http_deadline.ts) · [`src/infrastructure/setup_permission_denial.ts`](../src/infrastructure/setup_permission_denial.ts) · [`src/infrastructure/setup_permission_read_probe.ts`](../src/infrastructure/setup_permission_read_probe.ts) · [`src/infrastructure/setup_permission_read_evidence.ts`](../src/infrastructure/setup_permission_read_evidence.ts) · [`src/infrastructure/setup_permission_read_shape.ts`](../src/infrastructure/setup_permission_read_shape.ts) · [`src/infrastructure/setup_permission_projects_read.ts`](../src/infrastructure/setup_permission_projects_read.ts) · [`src/infrastructure/setup_permission_projects_access.ts`](../src/infrastructure/setup_permission_projects_access.ts) · [`src/infrastructure/setup_permission_workflow_cleanup.ts`](../src/infrastructure/setup_permission_workflow_cleanup.ts) · [`src/infrastructure/setup_permission_project_cleanup.ts`](../src/infrastructure/setup_permission_project_cleanup.ts) · [`src/infrastructure/setup_permission_probe_http.ts`](../src/infrastructure/setup_permission_probe_http.ts) · [`src/infrastructure/setup_permission_pull_request_probe.ts`](../src/infrastructure/setup_permission_pull_request_probe.ts) · [`src/infrastructure/git_authentication_environment.ts`](../src/infrastructure/git_authentication_environment.ts) · [`src/actions/github_action_input.ts`](../src/actions/github_action_input.ts) · [`src/infrastructure/setup_github_identity_query_adapter.ts`](../src/infrastructure/setup_github_identity_query_adapter.ts) · [`src/infrastructure/github_secret_encryption.ts`](../src/infrastructure/github_secret_encryption.ts) · [`src/infrastructure/setup_permission_organization_owner.ts`](../src/infrastructure/setup_permission_organization_owner.ts) · [`src/data/repository/github/github_actions_resource_inspector.ts`](../src/data/repository/github/github_actions_resource_inspector.ts) · [`src/data/repository/github/github_actions_resource_commands.ts`](../src/data/repository/github/github_actions_resource_commands.ts) · [`src/data/repository/github/github_actions_resource_collection.ts`](../src/data/repository/github/github_actions_resource_collection.ts) · [`src/application/usecases/setup/resolve_setup_workflow_pat_conflict_use_case.ts`](../src/application/usecases/setup/resolve_setup_workflow_pat_conflict_use_case.ts) · [`src/cli/setup_workflow_pat_storage_copy.ts`](../src/cli/setup_workflow_pat_storage_copy.ts) · [`src/cli/commands/setup_policy.ts`](../src/cli/commands/setup_policy.ts) · [`src/application/usecases/execution/execution_issue_number_policy.ts`](../src/application/usecases/execution/execution_issue_number_policy.ts) · [`src/application/usecases/execution/setup_execution_workflow.ts`](../src/application/usecases/execution/setup_execution_workflow.ts) · [`src/domain/github_runtime_doctor.ts`](../src/domain/github_runtime_doctor.ts) · [`src/domain/copilot_command.ts`](../src/domain/copilot_command.ts) · [`src/application/usecases/comment_automation_command_workflow.ts`](../src/application/usecases/comment_automation_command_workflow.ts) · [`src/application/policies/copilot_interaction_policy.ts`](../src/application/policies/copilot_interaction_policy.ts) · [`src/application/policies/publication_message_catalog.ts`](../src/application/policies/publication_message_catalog.ts) · [`src/application/ports/github_runtime_doctor_ports.ts`](../src/application/ports/github_runtime_doctor_ports.ts) · [`src/application/policies/github_runtime_doctor_policy.ts`](../src/application/policies/github_runtime_doctor_policy.ts) · [`src/application/policies/doctor_workflow_condition_policy.ts`](../src/application/policies/doctor_workflow_condition_policy.ts) · [`src/application/policies/github_runtime_doctor_presentation_policy.ts`](../src/application/policies/github_runtime_doctor_presentation_policy.ts) · [`src/application/usecases/read_copilot_doctor_workflow.ts`](../src/application/usecases/read_copilot_doctor_workflow.ts) · [`src/data/repository/github/runtime_doctor_repository.ts`](../src/data/repository/github/runtime_doctor_repository.ts) · [`src/infrastructure/composition/github_runtime_doctor_composition_root.ts`](../src/infrastructure/composition/github_runtime_doctor_composition_root.ts) · [`src/application/policies/agent_activity_policy.ts`](../src/application/policies/agent_activity_policy.ts) · [`src/application/policies/doctor_workflow_matrix_policy.ts`](../src/application/policies/doctor_workflow_matrix_policy.ts) · [`src/application/contracts/setup_batch_view.ts`](../src/application/contracts/setup_batch_view.ts) · [`src/application/policies/issue_resource_input_policy.ts`](../src/application/policies/issue_resource_input_policy.ts) · [`src/application/policies/setup_batch_access_policy.ts`](../src/application/policies/setup_batch_access_policy.ts) · [`src/application/policies/setup_batch_policy.ts`](../src/application/policies/setup_batch_policy.ts) · [`src/application/policies/setup_batch_retry_policy.ts`](../src/application/policies/setup_batch_retry_policy.ts) · [`src/application/policies/setup_batch_selection_policy.ts`](../src/application/policies/setup_batch_selection_policy.ts) · [`src/application/policies/setup_batch_view_policy.ts`](../src/application/policies/setup_batch_view_policy.ts) · [`src/application/policies/setup_credential_binding_policy.ts`](../src/application/policies/setup_credential_binding_policy.ts) · [`src/application/policies/setup_organization_import_policy.ts`](../src/application/policies/setup_organization_import_policy.ts) · [`src/application/policies/setup_organization_variable_bindings.ts`](../src/application/policies/setup_organization_variable_bindings.ts) · [`src/application/policies/setup_organization_variable_reuse_policy.ts`](../src/application/policies/setup_organization_variable_reuse_policy.ts) · [`src/application/ports/setup_batch_ports.ts`](../src/application/ports/setup_batch_ports.ts) · [`src/application/usecases/setup/apply_setup_batch_use_case.ts`](../src/application/usecases/setup/apply_setup_batch_use_case.ts) · [`src/application/usecases/setup/configure_setup_batch_target_use_case.ts`](../src/application/usecases/setup/configure_setup_batch_target_use_case.ts) · [`src/application/usecases/setup/prepare_setup_batch_use_case.ts`](../src/application/usecases/setup/prepare_setup_batch_use_case.ts) · [`src/application/usecases/setup/select_setup_batch_targets_use_case.ts`](../src/application/usecases/setup/select_setup_batch_targets_use_case.ts) · [`src/application/usecases/setup/setup_batch_session_use_case.ts`](../src/application/usecases/setup/setup_batch_session_use_case.ts) · [`src/cli/setup_batch_adapter.ts`](../src/cli/setup_batch_adapter.ts) · [`src/cli/setup_source_adapter.ts`](../src/cli/setup_source_adapter.ts) · [`src/domain/setup_batch.ts`](../src/domain/setup_batch.ts) · [`src/domain/setup_credential_health.ts`](../src/domain/setup_credential_health.ts) · [`src/domain/setup_organization_reuse.ts`](../src/domain/setup_organization_reuse.ts) · [`src/infrastructure/composition/setup_batch_composition_root.ts`](../src/infrastructure/composition/setup_batch_composition_root.ts) · [`src/infrastructure/github/ports/github_setup_batch_protocol.ts`](../src/infrastructure/github/ports/github_setup_batch_protocol.ts) · [`src/infrastructure/github/ports/github_trusted_credential_health_protocol.ts`](../src/infrastructure/github/ports/github_trusted_credential_health_protocol.ts) · [`src/infrastructure/setup_batch_github_apply_adapter.ts`](../src/infrastructure/setup_batch_github_apply_adapter.ts) · [`src/infrastructure/setup_batch_github_read_adapter.ts`](../src/infrastructure/setup_batch_github_read_adapter.ts) · [`src/infrastructure/setup_batch_journal_adapter.ts`](../src/infrastructure/setup_batch_journal_adapter.ts) · [`src/infrastructure/setup_batch_workspace_adapter.ts`](../src/infrastructure/setup_batch_workspace_adapter.ts) · [`src/infrastructure/setup_trusted_credential_health_adapter.ts`](../src/infrastructure/setup_trusted_credential_health_adapter.ts) · [`src/application/policies/setup_remote_facts_policy.ts`](../src/application/policies/setup_remote_facts_policy.ts) · [`src/cli/setup_confirmation_adapter.ts`](../src/cli/setup_confirmation_adapter.ts) · [`src/cli/web_setup_adapters.ts`](../src/cli/web_setup_adapters.ts) · [`scripts/validate-agent-documentation.cjs`](../scripts/validate-agent-documentation.cjs) · [`src/utils/setup_workflow_upgrade.ts`](../src/utils/setup_workflow_upgrade.ts) · [`src/domain/setup_runner.ts`](../src/domain/setup_runner.ts) · [`src/application/policies/setup_runner_policy.ts`](../src/application/policies/setup_runner_policy.ts) · [`src/application/policies/setup_runner_question_policy.ts`](../src/application/policies/setup_runner_question_policy.ts) · [`src/application/policies/setup_runner_guidance_policy.ts`](../src/application/policies/setup_runner_guidance_policy.ts) · [`src/application/ports/setup_runner_ports.ts`](../src/application/ports/setup_runner_ports.ts) · [`src/infrastructure/setup_runner_discovery_adapter.ts`](../src/infrastructure/setup_runner_discovery_adapter.ts) · [`src/infrastructure/composition/setup_runner_composition_root.ts`](../src/infrastructure/composition/setup_runner_composition_root.ts) · [`src/utils/setup_installation_review.ts`](../src/utils/setup_installation_review.ts) · [`src/cli/setup_installation_review_presenter.ts`](../src/cli/setup_installation_review_presenter.ts) · [`src/application/policies/setup_runner_installation_summary_policy.ts`](../src/application/policies/setup_runner_installation_summary_policy.ts) · [`src/utils/setup_files.ts`](../src/utils/setup_files.ts) · [`src/domain/specification_catalog_path_policy.cjs`](../src/domain/specification_catalog_path_policy.cjs) · [`src/domain/sdd_prerequisite_policy.cjs`](../src/domain/sdd_prerequisite_policy.cjs) · [`src/application/contracts/setup_documentation.ts`](../src/application/contracts/setup_documentation.ts) · [`src/application/policies/setup_question_documentation_policy.ts`](../src/application/policies/setup_question_documentation_policy.ts) · [`web/src/components/SetupHelp.svelte`](../web/src/components/SetupHelp.svelte) · [`web/src/components/CompletedSetupHelp.svelte`](../web/src/components/CompletedSetupHelp.svelte) · [`src/application/policies/verification_runtime_policy.ts`](../src/application/policies/verification_runtime_policy.ts) · [`src/infrastructure/verification_runtime_manifest.ts`](../src/infrastructure/verification_runtime_manifest.ts) · [`src/infrastructure/verification_runtime_preflight.ts`](../src/infrastructure/verification_runtime_preflight.ts) · [`src/infrastructure/untrusted_command_environment.ts`](../src/infrastructure/untrusted_command_environment.ts) · [`src/application/ports/git_ports.ts`](../src/application/ports/git_ports.ts) · [`src/application/ports/bugbot_git_ports.ts`](../src/application/ports/bugbot_git_ports.ts) · [`src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts`](../src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts) · [`src/application/usecases/steps/commit/bugbot/verify_command_runner.ts`](../src/application/usecases/steps/commit/bugbot/verify_command_runner.ts) · [`src/cli/setup_config_file.ts`](../src/cli/setup_config_file.ts) · [`src/domain/copilot_comment_workflow.ts`](../src/domain/copilot_comment_workflow.ts) · [`src/infrastructure/copilot_comment_inputs.json`](../src/infrastructure/copilot_comment_inputs.json) +- Tests: [`src/data/repository/__tests__/repository_version_tags_query_repository.test.ts`](../src/data/repository/__tests__/repository_version_tags_query_repository.test.ts) · [`src/cli/__tests__/setup_command_options.test.ts`](../src/cli/__tests__/setup_command_options.test.ts) · [`src/data/repository/__tests__/setup_variable_write_failures.test.ts`](../src/data/repository/__tests__/setup_variable_write_failures.test.ts) · [`src/infrastructure/composition/__tests__/initial_setup_composition_root.test.ts`](../src/infrastructure/composition/__tests__/initial_setup_composition_root.test.ts) · [`src/application/policies/__tests__/setup_questionnaire_policy.test.ts`](../src/application/policies/__tests__/setup_questionnaire_policy.test.ts) · [`src/application/policies/__tests__/setup_configuration_policy.test.ts`](../src/application/policies/__tests__/setup_configuration_policy.test.ts) · [`src/application/policies/__tests__/setup_token_permission_policy.test.ts`](../src/application/policies/__tests__/setup_token_permission_policy.test.ts) · [`src/application/policies/__tests__/setup_remote_facts_policy.test.ts`](../src/application/policies/__tests__/setup_remote_facts_policy.test.ts) · [`src/application/policies/__tests__/setup_doctor_message_catalog.test.ts`](../src/application/policies/__tests__/setup_doctor_message_catalog.test.ts) · [`src/application/policies/__tests__/setup_doctor_report_policy.test.ts`](../src/application/policies/__tests__/setup_doctor_report_policy.test.ts) · [`src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts`](../src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts) · [`src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts`](../src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts) · [`src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_token_permissions_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_token_permissions_use_case.test.ts) · [`src/application/usecases/setup/__tests__/doctor_use_case.test.ts`](../src/application/usecases/setup/__tests__/doctor_use_case.test.ts) · [`src/application/usecases/setup/__tests__/merge_queue_readiness_use_case.test.ts`](../src/application/usecases/setup/__tests__/merge_queue_readiness_use_case.test.ts) · [`src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts`](../src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts) · [`src/application/usecases/actions/__tests__/setup_resource_provisioning.test.ts`](../src/application/usecases/actions/__tests__/setup_resource_provisioning.test.ts) · [`src/infrastructure/__tests__/setup_workspace_adapter.test.ts`](../src/infrastructure/__tests__/setup_workspace_adapter.test.ts) · [`src/infrastructure/__tests__/setup_remote_credential_health_adapter.test.ts`](../src/infrastructure/__tests__/setup_remote_credential_health_adapter.test.ts) · [`src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts`](../src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts) · [`src/infrastructure/__tests__/setup_permission_resource_probes.test.ts`](../src/infrastructure/__tests__/setup_permission_resource_probes.test.ts) · [`src/infrastructure/__tests__/setup_projects_probe_page_policy.test.ts`](../src/infrastructure/__tests__/setup_projects_probe_page_policy.test.ts) · [`src/infrastructure/composition/__tests__/setup_token_permissions_composition_root.test.ts`](../src/infrastructure/composition/__tests__/setup_token_permissions_composition_root.test.ts) · [`src/data/repository/__tests__/repository_variables_repository.test.ts`](../src/data/repository/__tests__/repository_variables_repository.test.ts) · [`src/cli/__tests__/setup_presenters.test.ts`](../src/cli/__tests__/setup_presenters.test.ts) · [`src/cli/__tests__/setup_journey_presenter.test.ts`](../src/cli/__tests__/setup_journey_presenter.test.ts) · [`src/cli/__tests__/setup_prompt_rendering.test.ts`](../src/cli/__tests__/setup_prompt_rendering.test.ts) · [`src/cli/__tests__/setup_token_permission_presenter.test.ts`](../src/cli/__tests__/setup_token_permission_presenter.test.ts) · [`src/__tests__/cli.test.ts`](../src/__tests__/cli.test.ts) · [`src/cli/__tests__/setup_terminal_driver.test.ts`](../src/cli/__tests__/setup_terminal_driver.test.ts) · [`src/architecture/__tests__/setup_doctor_boundaries.test.ts`](../src/architecture/__tests__/setup_doctor_boundaries.test.ts) · [`src/tooling/__tests__/documentation_pat_exception_policy.test.ts`](../src/tooling/__tests__/documentation_pat_exception_policy.test.ts) · [`src/infrastructure/__tests__/setup_pat_audit.test.ts`](../src/infrastructure/__tests__/setup_pat_audit.test.ts) · [`src/infrastructure/__tests__/setup_permission_projects_access.test.ts`](../src/infrastructure/__tests__/setup_permission_projects_access.test.ts) · [`src/infrastructure/__tests__/setup_credential_validation_adapter.test.ts`](../src/infrastructure/__tests__/setup_credential_validation_adapter.test.ts) · [`src/infrastructure/__tests__/setup_github_identity_query_adapter.test.ts`](../src/infrastructure/__tests__/setup_github_identity_query_adapter.test.ts) · [`src/infrastructure/__tests__/git_commit_adapter.test.ts`](../src/infrastructure/__tests__/git_commit_adapter.test.ts) · [`src/actions/__tests__/github_action_input.test.ts`](../src/actions/__tests__/github_action_input.test.ts) · [`src/infrastructure/__tests__/setup_permission_cleanup_contract.test.ts`](../src/infrastructure/__tests__/setup_permission_cleanup_contract.test.ts) · [`src/infrastructure/__tests__/setup_permission_actions_cleanup_timing.test.ts`](../src/infrastructure/__tests__/setup_permission_actions_cleanup_timing.test.ts) · [`src/infrastructure/__tests__/setup_permission_operator_actions.test.ts`](../src/infrastructure/__tests__/setup_permission_operator_actions.test.ts) · [`src/infrastructure/__tests__/setup_permission_journal_contract.test.ts`](../src/infrastructure/__tests__/setup_permission_journal_contract.test.ts) · [`src/infrastructure/__tests__/setup_permission_audit_transactions.test.ts`](../src/infrastructure/__tests__/setup_permission_audit_transactions.test.ts) · [`src/infrastructure/__tests__/setup_permission_write_failures.test.ts`](../src/infrastructure/__tests__/setup_permission_write_failures.test.ts) · [`src/infrastructure/__tests__/setup_permission_resource_failures.test.ts`](../src/infrastructure/__tests__/setup_permission_resource_failures.test.ts) · [`src/infrastructure/__tests__/setup_permission_boundary_failures.test.ts`](../src/infrastructure/__tests__/setup_permission_boundary_failures.test.ts) · [`src/infrastructure/__tests__/github_secret_encryption.test.ts`](../src/infrastructure/__tests__/github_secret_encryption.test.ts) · [`src/infrastructure/__tests__/setup_permission_organization_owner.test.ts`](../src/infrastructure/__tests__/setup_permission_organization_owner.test.ts) · [`src/infrastructure/__tests__/setup_pat_bootstrap_transactions.test.ts`](../src/infrastructure/__tests__/setup_pat_bootstrap_transactions.test.ts) · [`src/data/repository/__tests__/repository_actions_sdk_contract.integration.test.ts`](../src/data/repository/__tests__/repository_actions_sdk_contract.integration.test.ts) · [`src/data/repository/__tests__/repository_actions_resource_edge_cases.test.ts`](../src/data/repository/__tests__/repository_actions_resource_edge_cases.test.ts) · [`src/data/repository/__tests__/repository_selected_resource_grants.test.ts`](../src/data/repository/__tests__/repository_selected_resource_grants.test.ts) · [`src/infrastructure/__tests__/setup_permission_read_contract.test.ts`](../src/infrastructure/__tests__/setup_permission_read_contract.test.ts) · [`src/application/usecases/setup/__tests__/setup_workflow_pat_conflict.test.ts`](../src/application/usecases/setup/__tests__/setup_workflow_pat_conflict.test.ts) · [`src/application/usecases/setup/__tests__/setup_workflow_pat_credential_rotation.test.ts`](../src/application/usecases/setup/__tests__/setup_workflow_pat_credential_rotation.test.ts) · [`src/data/repository/__tests__/setup_organization_pat_inventory.test.ts`](../src/data/repository/__tests__/setup_organization_pat_inventory.test.ts) · [`src/cli/__tests__/web_setup_bot_pat_scope_conflict.test.ts`](../src/cli/__tests__/web_setup_bot_pat_scope_conflict.test.ts) · [`src/actions/__tests__/local_setup_apply_contract.test.ts`](../src/actions/__tests__/local_setup_apply_contract.test.ts) · [`src/cli/commands/__tests__/setup_policy.test.ts`](../src/cli/commands/__tests__/setup_policy.test.ts) · [`src/application/usecases/execution/__tests__/execution_issue_number_policy.test.ts`](../src/application/usecases/execution/__tests__/execution_issue_number_policy.test.ts) · [`src/application/usecases/execution/__tests__/setup_execution_workflow.test.ts`](../src/application/usecases/execution/__tests__/setup_execution_workflow.test.ts) · [`src/domain/__tests__/github_runtime_doctor.test.ts`](../src/domain/__tests__/github_runtime_doctor.test.ts) · [`src/domain/__tests__/copilot_command.test.ts`](../src/domain/__tests__/copilot_command.test.ts) · [`src/application/usecases/__tests__/comment_automation_use_case.test.ts`](../src/application/usecases/__tests__/comment_automation_use_case.test.ts) · [`src/application/policies/__tests__/github_runtime_doctor_policy.test.ts`](../src/application/policies/__tests__/github_runtime_doctor_policy.test.ts) · [`src/application/policies/__tests__/doctor_workflow_condition_policy.test.ts`](../src/application/policies/__tests__/doctor_workflow_condition_policy.test.ts) · [`src/application/policies/__tests__/github_runtime_doctor_presentation_policy.test.ts`](../src/application/policies/__tests__/github_runtime_doctor_presentation_policy.test.ts) · [`src/application/usecases/__tests__/read_copilot_doctor_workflow.test.ts`](../src/application/usecases/__tests__/read_copilot_doctor_workflow.test.ts) · [`src/application/usecases/__tests__/runtime_doctor_security_integration.test.ts`](../src/application/usecases/__tests__/runtime_doctor_security_integration.test.ts) · [`src/data/repository/github/__tests__/runtime_doctor_repository.test.ts`](../src/data/repository/github/__tests__/runtime_doctor_repository.test.ts) · [`src/infrastructure/composition/__tests__/github_runtime_doctor_composition_root.test.ts`](../src/infrastructure/composition/__tests__/github_runtime_doctor_composition_root.test.ts) · [`src/application/policies/__tests__/runtime_doctor_agent_activity.test.ts`](../src/application/policies/__tests__/runtime_doctor_agent_activity.test.ts) · [`src/application/policies/__tests__/doctor_workflow_matrix_policy.test.ts`](../src/application/policies/__tests__/doctor_workflow_matrix_policy.test.ts) · [`src/application/policies/__tests__/setup_approval_operator_permissions.test.ts`](../src/application/policies/__tests__/setup_approval_operator_permissions.test.ts) · [`src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts`](../src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts) · [`src/application/policies/__tests__/setup_batch_permission_policy.test.ts`](../src/application/policies/__tests__/setup_batch_permission_policy.test.ts) · [`src/application/policies/__tests__/setup_batch_policy.test.ts`](../src/application/policies/__tests__/setup_batch_policy.test.ts) · [`src/application/policies/__tests__/setup_batch_retry_policy.test.ts`](../src/application/policies/__tests__/setup_batch_retry_policy.test.ts) · [`src/application/policies/__tests__/setup_batch_selection_policy.test.ts`](../src/application/policies/__tests__/setup_batch_selection_policy.test.ts) · [`src/application/policies/__tests__/setup_organization_approval_draft.test.ts`](../src/application/policies/__tests__/setup_organization_approval_draft.test.ts) · [`src/application/policies/__tests__/setup_organization_import_policy.test.ts`](../src/application/policies/__tests__/setup_organization_import_policy.test.ts) · [`src/application/policies/__tests__/setup_organization_import_safety.test.ts`](../src/application/policies/__tests__/setup_organization_import_safety.test.ts) · [`src/application/policies/__tests__/setup_organization_variable_reuse_policy.test.ts`](../src/application/policies/__tests__/setup_organization_variable_reuse_policy.test.ts) · [`src/application/usecases/actions/__tests__/setup_organization_reuse_provisioning.test.ts`](../src/application/usecases/actions/__tests__/setup_organization_reuse_provisioning.test.ts) · [`src/application/usecases/setup/__tests__/apply_setup_batch_use_case.test.ts`](../src/application/usecases/setup/__tests__/apply_setup_batch_use_case.test.ts) · [`src/application/usecases/setup/__tests__/select_setup_batch_targets_use_case.test.ts`](../src/application/usecases/setup/__tests__/select_setup_batch_targets_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_batch_flow.test.ts`](../src/application/usecases/setup/__tests__/setup_batch_flow.test.ts) · [`src/application/usecases/setup/__tests__/setup_organization_import_wizard.test.ts`](../src/application/usecases/setup/__tests__/setup_organization_import_wizard.test.ts) · [`src/application/usecases/setup/__tests__/setup_organization_secret_reuse.test.ts`](../src/application/usecases/setup/__tests__/setup_organization_secret_reuse.test.ts) · [`src/cli/__tests__/setup_source_adapter.test.ts`](../src/cli/__tests__/setup_source_adapter.test.ts) · [`src/cli/__tests__/web_setup_batch_components.test.ts`](../src/cli/__tests__/web_setup_batch_components.test.ts) · [`src/cli/__tests__/web_setup_batch_selection.test.ts`](../src/cli/__tests__/web_setup_batch_selection.test.ts) · [`src/infrastructure/__tests__/setup_batch_github_apply_adapter.test.ts`](../src/infrastructure/__tests__/setup_batch_github_apply_adapter.test.ts) · [`src/infrastructure/__tests__/setup_batch_github_read_adapter.test.ts`](../src/infrastructure/__tests__/setup_batch_github_read_adapter.test.ts) · [`src/infrastructure/__tests__/setup_batch_local_adapters.test.ts`](../src/infrastructure/__tests__/setup_batch_local_adapters.test.ts) · [`src/infrastructure/__tests__/setup_reuse_empty_collections.integration.test.ts`](../src/infrastructure/__tests__/setup_reuse_empty_collections.integration.test.ts) · [`src/infrastructure/__tests__/setup_trusted_credential_health_adapter.test.ts`](../src/infrastructure/__tests__/setup_trusted_credential_health_adapter.test.ts) · [`src/infrastructure/__tests__/setup_trusted_health_sdk_contract.integration.test.ts`](../src/infrastructure/__tests__/setup_trusted_health_sdk_contract.integration.test.ts) · [`src/application/policies/__tests__/setup_batch_access_and_view.test.ts`](../src/application/policies/__tests__/setup_batch_access_and_view.test.ts) · [`src/cli/__tests__/setup_batch_adapter.test.ts`](../src/cli/__tests__/setup_batch_adapter.test.ts) · [`src/infrastructure/__tests__/setup_batch_composition.test.ts`](../src/infrastructure/__tests__/setup_batch_composition.test.ts) · [`src/infrastructure/__tests__/setup_batch_guidance_compatibility.test.ts`](../src/infrastructure/__tests__/setup_batch_guidance_compatibility.test.ts) · [`src/utils/__tests__/setup_workflow_upgrade.test.ts`](../src/utils/__tests__/setup_workflow_upgrade.test.ts) · [`src/cli/__tests__/setup_pat_intent_adapter.test.ts`](../src/cli/__tests__/setup_pat_intent_adapter.test.ts) · [`src/application/usecases/__tests__/push_single_action_contexts.test.ts`](../src/application/usecases/__tests__/push_single_action_contexts.test.ts) · [`src/application/policies/__tests__/setup_runner_policy.test.ts`](../src/application/policies/__tests__/setup_runner_policy.test.ts) · [`src/application/policies/__tests__/setup_runner_question_policy.test.ts`](../src/application/policies/__tests__/setup_runner_question_policy.test.ts) · [`src/infrastructure/__tests__/setup_runner_discovery_adapter.test.ts`](../src/infrastructure/__tests__/setup_runner_discovery_adapter.test.ts) · [`src/utils/__tests__/setup_runner_installation.test.ts`](../src/utils/__tests__/setup_runner_installation.test.ts) · [`src/cli/__tests__/web_setup_runner_components.test.ts`](../src/cli/__tests__/web_setup_runner_components.test.ts) · [`src/application/policies/__tests__/setup_runner_installation_summary_policy.test.ts`](../src/application/policies/__tests__/setup_runner_installation_summary_policy.test.ts) · [`src/application/usecases/setup/__tests__/setup_runner_planning.test.ts`](../src/application/usecases/setup/__tests__/setup_runner_planning.test.ts) · [`src/cli/__tests__/setup_runner_config_file.test.ts`](../src/cli/__tests__/setup_runner_config_file.test.ts) · [`src/infrastructure/__tests__/setup_runner_composition.test.ts`](../src/infrastructure/__tests__/setup_runner_composition.test.ts) · [`src/tooling/__tests__/setup_provisioning_workflow.test.ts`](../src/tooling/__tests__/setup_provisioning_workflow.test.ts) · [`src/infrastructure/__tests__/setup_sdd_prerequisites.test.ts`](../src/infrastructure/__tests__/setup_sdd_prerequisites.test.ts) · [`src/cli/__tests__/setup_documentation_navigation.test.ts`](../src/cli/__tests__/setup_documentation_navigation.test.ts) · [`src/application/policies/__tests__/setup_question_documentation_policy.test.ts`](../src/application/policies/__tests__/setup_question_documentation_policy.test.ts) · [`src/application/policies/__tests__/verification_runtime_policy.test.ts`](../src/application/policies/__tests__/verification_runtime_policy.test.ts) · [`src/infrastructure/__tests__/verification_runtime_preflight.test.ts`](../src/infrastructure/__tests__/verification_runtime_preflight.test.ts) · [`src/infrastructure/__tests__/verification_runtime_branch_sync.test.ts`](../src/infrastructure/__tests__/verification_runtime_branch_sync.test.ts) · [`src/infrastructure/__tests__/untrusted_command_environment.test.ts`](../src/infrastructure/__tests__/untrusted_command_environment.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/verify_command_runner.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/verify_command_runner.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts) · [`src/tooling/__tests__/verification_runtime_guidance.test.ts`](../src/tooling/__tests__/verification_runtime_guidance.test.ts) · [`src/infrastructure/__tests__/verification_setup_configuration.test.ts`](../src/infrastructure/__tests__/verification_setup_configuration.test.ts) · [`src/domain/__tests__/copilot_comment_workflow.test.ts`](../src/domain/__tests__/copilot_comment_workflow.test.ts) - User documentation: [`README.md`](../README.md) · [`docs/how-to-use.mdx`](../docs/how-to-use.mdx) · [`docs/configuration.mdx`](../docs/configuration.mdx) · [`docs/configuration-checklist.mdx`](../docs/configuration-checklist.mdx) · [`docs/authentication.mdx`](../docs/authentication.mdx) · [`docs/development/architecture.mdx`](../docs/development/architecture.mdx) · [`docs/security-operations/operations/provisioning.mdx`](../docs/security-operations/operations/provisioning.mdx) · [`docs/security-operations/operations/troubleshooting.mdx`](../docs/security-operations/operations/troubleshooting.mdx) · [`docs/security-operations/security/credentials.mdx`](../docs/security-operations/security/credentials.mdx) · [`docs/single-actions/workflow-and-cli.mdx`](../docs/single-actions/workflow-and-cli.mdx) · [`docs/security-operations/operations/verification.mdx`](../docs/security-operations/operations/verification.mdx) · [`docs/development/setup-pat-provider-audit-2026-10-06.md`](../docs/development/setup-pat-provider-audit-2026-10-06.md) · [`docs/issues/comment-commands.mdx`](../docs/issues/comment-commands.mdx) · [`docs/issues/branch-synchronization.mdx`](../docs/issues/branch-synchronization.mdx) · [`docs/setup-web.mdx`](../docs/setup-web.mdx) · [`docs/first-workflow.mdx`](../docs/first-workflow.mdx) · [`docs/using-the-docs.mdx`](../docs/using-the-docs.mdx) · [`docs/guides/index.mdx`](../docs/guides/index.mdx) · [`docs/guides/issues-and-branches.mdx`](../docs/guides/issues-and-branches.mdx) · [`docs/guides/review-pull-requests.mdx`](../docs/guides/review-pull-requests.mdx) · [`docs/guides/work-with-the-bot.mdx`](../docs/guides/work-with-the-bot.mdx) · [`docs/guides/releases-and-hotfixes.mdx`](../docs/guides/releases-and-hotfixes.mdx) · [`docs/agents/repository-collaboration.mdx`](../docs/agents/repository-collaboration.mdx) ### `local-web-setup-assistant` — Local web setup assistant - Owner: Copilot maintainers -- Last verified: 2026-10-20 -- Specifications: [`specs/local-web-setup-assistant.md`](./local-web-setup-assistant.md) · [`specs/setup-configuration-management.md`](./setup-configuration-management.md) +- Last verified: 2026-10-21 +- Specifications: [`specs/local-web-setup-assistant.md`](./local-web-setup-assistant.md) · [`specs/setup-configuration-management.md`](./setup-configuration-management.md) · [`specs/verification-setup-onboarding.md`](./verification-setup-onboarding.md) - Workflows: [`.github/workflows/ci_check.yml`](../.github/workflows/ci_check.yml) · [`.github/workflows/repowise.yml`](../.github/workflows/repowise.yml) · [`.github/workflows/setup_platform_smoke.yml`](../.github/workflows/setup_platform_smoke.yml) · [`.github/workflows/copilot_pull_request_approval.yml`](../.github/workflows/copilot_pull_request_approval.yml) - Entrypoints: [`src/cli/commands/setup.ts`](../src/cli/commands/setup.ts) · [`package.json`](../package.json) · [`web/src/main.ts`](../web/src/main.ts) -- Core code: [`web/src/App.svelte`](../web/src/App.svelte) · [`web/src/session/setupSession.ts`](../web/src/session/setupSession.ts) · [`web/src/components/ActionButton.svelte`](../web/src/components/ActionButton.svelte) · [`web/src/components/PairingPanel.svelte`](../web/src/components/PairingPanel.svelte) · [`web/src/lib/pairingCode.ts`](../web/src/lib/pairingCode.ts) · [`web/src/components/ContextPanel.svelte`](../web/src/components/ContextPanel.svelte) · [`web/src/i18n/permissionEvidence.ts`](../web/src/i18n/permissionEvidence.ts) · [`web/src/i18n/permissionProgress.ts`](../web/src/i18n/permissionProgress.ts) · [`web/src/components/PermissionProgressPanel.svelte`](../web/src/components/PermissionProgressPanel.svelte) · [`web/src/components/PromptCard.svelte`](../web/src/components/PromptCard.svelte) · [`web/src/components/ResultPanel.svelte`](../web/src/components/ResultPanel.svelte) · [`web/src/components/SetupPatCorrectionPanel.svelte`](../web/src/components/SetupPatCorrectionPanel.svelte) · [`web/src/components/ResourceProgress.svelte`](../web/src/components/ResourceProgress.svelte) · [`web/src/components/PlanPrompt.svelte`](../web/src/components/PlanPrompt.svelte) · [`web/src/components/PlanDecisionSummary.svelte`](../web/src/components/PlanDecisionSummary.svelte) · [`web/src/components/QuestionPrompt.svelte`](../web/src/components/QuestionPrompt.svelte) · [`web/src/components/FixedWorkflowNotice.svelte`](../web/src/components/FixedWorkflowNotice.svelte) · [`web/src/components/QuestionGuidance.svelte`](../web/src/components/QuestionGuidance.svelte) · [`web/src/components/DiscoveryNotice.svelte`](../web/src/components/DiscoveryNotice.svelte) · [`web/src/components/ProducerSelector.svelte`](../web/src/components/ProducerSelector.svelte) · [`web/src/lib/manualProducerIdentity.ts`](../web/src/lib/manualProducerIdentity.ts) · [`web/src/components/CoverageCheckEvidence.svelte`](../web/src/components/CoverageCheckEvidence.svelte) · [`web/src/components/ProjectSelector.svelte`](../web/src/components/ProjectSelector.svelte) · [`web/src/i18n/catalog.ts`](../web/src/i18n/catalog.ts) · [`web/src/i18n/projectTransitions.ts`](../web/src/i18n/projectTransitions.ts) · [`web/src/i18n/permissionTerms.ts`](../web/src/i18n/permissionTerms.ts) · [`web/src/components/StatusBanner.svelte`](../web/src/components/StatusBanner.svelte) · [`web/src/lib/questionAnswer.ts`](../web/src/lib/questionAnswer.ts) · [`web/src/lib/githubLink.ts`](../web/src/lib/githubLink.ts) · [`web/src/lib/focusOnRevision.ts`](../web/src/lib/focusOnRevision.ts) · [`web/src/i18n/featureNames.ts`](../web/src/i18n/featureNames.ts) · [`web/src/i18n/agentRoleNames.ts`](../web/src/i18n/agentRoleNames.ts) · [`web/src/i18n/checkEvidence.ts`](../web/src/i18n/checkEvidence.ts) · [`web/src/styles/controls.css`](../web/src/styles/controls.css) · [`web/src/styles/tokens.css`](../web/src/styles/tokens.css) · [`web/src/style.css`](../web/src/style.css) · [`src/application/contracts/web_setup_view.ts`](../src/application/contracts/web_setup_view.ts) · [`src/application/ports/setup_terminal_ports.ts`](../src/application/ports/setup_terminal_ports.ts) · [`src/application/errors/setup_interaction_cancelled_error.ts`](../src/application/errors/setup_interaction_cancelled_error.ts) · [`src/application/policies/merge_setup_overrides_policy.ts`](../src/application/policies/merge_setup_overrides_policy.ts) · [`src/application/policies/setup_remote_facts_policy.ts`](../src/application/policies/setup_remote_facts_policy.ts) · [`src/application/usecases/setup/prepare_setup_pat_intent_use_case.ts`](../src/application/usecases/setup/prepare_setup_pat_intent_use_case.ts) · [`src/application/usecases/setup/audit_configured_setup_pat_use_case.ts`](../src/application/usecases/setup/audit_configured_setup_pat_use_case.ts) · [`src/infrastructure/setup_permission_actions_probe.ts`](../src/infrastructure/setup_permission_actions_probe.ts) · [`src/infrastructure/setup_permission_issue_probe.ts`](../src/infrastructure/setup_permission_issue_probe.ts) · [`src/infrastructure/setup_permission_issue_cleanup.ts`](../src/infrastructure/setup_permission_issue_cleanup.ts) · [`src/infrastructure/setup_permission_probe_journal.ts`](../src/infrastructure/setup_permission_probe_journal.ts) · [`src/infrastructure/setup_permission_probe_transaction.ts`](../src/infrastructure/setup_permission_probe_transaction.ts) · [`src/infrastructure/setup_permission_resource_probes.ts`](../src/infrastructure/setup_permission_resource_probes.ts) · [`src/application/usecases/setup/verify_web_setup_apply_use_case.ts`](../src/application/usecases/setup/verify_web_setup_apply_use_case.ts) · [`src/application/usecases/setup/setup_session_coordinator.ts`](../src/application/usecases/setup/setup_session_coordinator.ts) · [`src/application/usecases/setup/verify_setup_pat_bootstrap_use_case.ts`](../src/application/usecases/setup/verify_setup_pat_bootstrap_use_case.ts) · [`src/cli_context.ts`](../src/cli_context.ts) · [`src/cli/setup_command_options.ts`](../src/cli/setup_command_options.ts) · [`src/cli/commands/setup_execution.ts`](../src/cli/commands/setup_execution.ts) · [`src/cli/setup_credential_collection.ts`](../src/cli/setup_credential_collection.ts) · [`src/cli/setup_pat_intent_adapter.ts`](../src/cli/setup_pat_intent_adapter.ts) · [`src/cli/setup_apply_authorization.ts`](../src/cli/setup_apply_authorization.ts) · [`src/cli/setup_outcome_adapter.ts`](../src/cli/setup_outcome_adapter.ts) · [`src/cli/web_setup_bridge.ts`](../src/cli/web_setup_bridge.ts) · [`src/cli/web_setup_adapters.ts`](../src/cli/web_setup_adapters.ts) · [`src/cli/web_setup_server.ts`](../src/cli/web_setup_server.ts) · [`src/cli/setup_apply_snapshot.ts`](../src/cli/setup_apply_snapshot.ts) · [`src/cli/setup_result_receipt.ts`](../src/cli/setup_result_receipt.ts) · [`src/application/usecases/actions/initial_setup_workflow.ts`](../src/application/usecases/actions/initial_setup_workflow.ts) · [`src/actions/local_action.ts`](../src/actions/local_action.ts) · [`src/cli/setup_session_guard.ts`](../src/cli/setup_session_guard.ts) · [`src/application/usecases/setup/setup_wizard_use_case.ts`](../src/application/usecases/setup/setup_wizard_use_case.ts) · [`src/application/usecases/setup/setup_questionnaire_controller.ts`](../src/application/usecases/setup/setup_questionnaire_controller.ts) · [`src/application/policies/setup_terminal_choice_policy.ts`](../src/application/policies/setup_terminal_choice_policy.ts) · [`src/cli/setup_terminal_driver.ts`](../src/cli/setup_terminal_driver.ts) · [`src/cli/setup_question_renderer.ts`](../src/cli/setup_question_renderer.ts) · [`src/application/usecases/setup/setup_journey_use_case.ts`](../src/application/usecases/setup/setup_journey_use_case.ts) · [`src/application/usecases/setup/setup_credentials_use_case.ts`](../src/application/usecases/setup/setup_credentials_use_case.ts) · [`src/application/policies/setup_questionnaire_policy.ts`](../src/application/policies/setup_questionnaire_policy.ts) · [`src/application/policies/setup_project_selection_policy.ts`](../src/application/policies/setup_project_selection_policy.ts) · [`src/application/ports/setup_project_discovery_port.ts`](../src/application/ports/setup_project_discovery_port.ts) · [`src/application/ports/setup_approval_check_discovery_port.ts`](../src/application/ports/setup_approval_check_discovery_port.ts) · [`src/infrastructure/github_setup_project_discovery_adapter.ts`](../src/infrastructure/github_setup_project_discovery_adapter.ts) · [`src/infrastructure/github_setup_approval_check_discovery_adapter.ts`](../src/infrastructure/github_setup_approval_check_discovery_adapter.ts) · [`src/application/policies/setup_question_documentation_policy.ts`](../src/application/policies/setup_question_documentation_policy.ts) · [`src/application/policies/setup_question_guidance_policy.ts`](../src/application/policies/setup_question_guidance_policy.ts) · [`src/application/policies/setup_question_purpose_policy.ts`](../src/application/policies/setup_question_purpose_policy.ts) · [`src/application/policies/setup_token_permission_policy.ts`](../src/application/policies/setup_token_permission_policy.ts) · [`src/application/policies/setup_configuration_plan.ts`](../src/application/policies/setup_configuration_plan.ts) · [`src/application/policies/setup_pat_creation_url_policy.ts`](../src/application/policies/setup_pat_creation_url_policy.ts) · [`src/infrastructure/composition/setup_credentials_composition_root.ts`](../src/infrastructure/composition/setup_credentials_composition_root.ts) · [`scripts/validate-npm-package.cjs`](../scripts/validate-npm-package.cjs) · [`scripts/smoke-test-npm-package.cjs`](../scripts/smoke-test-npm-package.cjs) · [`scripts/smoke-packaged-web-session.cjs`](../scripts/smoke-packaged-web-session.cjs) · [`scripts/validate-setup-assistant-acceptance.cjs`](../scripts/validate-setup-assistant-acceptance.cjs) · [`scripts/serve-web-setup-review.cjs`](../scripts/serve-web-setup-review.cjs) · [`scripts/validate-workflow-contract.cjs`](../scripts/validate-workflow-contract.cjs) · [`scripts/documentation_checkout_text.cjs`](../scripts/documentation_checkout_text.cjs) · [`scripts/set-cli-executable.cjs`](../scripts/set-cli-executable.cjs) · [`scripts/render-web-setup-component.cjs`](../scripts/render-web-setup-component.cjs) · [`web/src/i18n/permissionPrerequisite.ts`](../web/src/i18n/permissionPrerequisite.ts) · [`scripts/web-setup-review-views.cjs`](../scripts/web-setup-review-views.cjs) · [`src/application/usecases/setup/resolve_setup_workflow_pat_conflict_use_case.ts`](../src/application/usecases/setup/resolve_setup_workflow_pat_conflict_use_case.ts) · [`src/cli/setup_workflow_pat_storage_copy.ts`](../src/cli/setup_workflow_pat_storage_copy.ts) · [`web/src/components/WorkflowPatStorageNotice.svelte`](../web/src/components/WorkflowPatStorageNotice.svelte) · [`src/cli/commands/setup_policy.ts`](../src/cli/commands/setup_policy.ts) · [`src/application/usecases/execution/execution_issue_number_policy.ts`](../src/application/usecases/execution/execution_issue_number_policy.ts) · [`src/application/usecases/execution/setup_execution_workflow.ts`](../src/application/usecases/execution/setup_execution_workflow.ts) · [`src/domain/setup_management.ts`](../src/domain/setup_management.ts) · [`src/application/contracts/setup_management_view.ts`](../src/application/contracts/setup_management_view.ts) · [`src/application/ports/setup_management_ports.ts`](../src/application/ports/setup_management_ports.ts) · [`src/application/policies/setup_quick_settings_policy.ts`](../src/application/policies/setup_quick_settings_policy.ts) · [`src/application/policies/setup_management_policy.ts`](../src/application/policies/setup_management_policy.ts) · [`src/application/policies/setup_management_permissions_policy.ts`](../src/application/policies/setup_management_permissions_policy.ts) · [`src/application/usecases/setup/manage_setup_use_case.ts`](../src/application/usecases/setup/manage_setup_use_case.ts) · [`src/infrastructure/setup_management_workspace_adapter.ts`](../src/infrastructure/setup_management_workspace_adapter.ts) · [`src/cli/setup_management_adapter.ts`](../src/cli/setup_management_adapter.ts) · [`web/src/components/SetupManagementPanel.svelte`](../web/src/components/SetupManagementPanel.svelte) · [`web/src/components/ManagementInventory.svelte`](../web/src/components/ManagementInventory.svelte) · [`web/src/components/QuickSettingPrompt.svelte`](../web/src/components/QuickSettingPrompt.svelte) · [`web/src/i18n/managementCopy.ts`](../web/src/i18n/managementCopy.ts) · [`web/src/styles/management.css`](../web/src/styles/management.css) · [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`web/src/session/setupCommandTransport.ts`](../web/src/session/setupCommandTransport.ts) · [`scripts/serve-web-setup-journey.cjs`](../scripts/serve-web-setup-journey.cjs) · [`web/src/components/SetupHeader.svelte`](../web/src/components/SetupHeader.svelte) · [`web/src/components/WaitingPanel.svelte`](../web/src/components/WaitingPanel.svelte) · [`web/src/styles/layout.css`](../web/src/styles/layout.css) · [`web/src/i18n/en.ts`](../web/src/i18n/en.ts) · [`web/src/i18n/es.ts`](../web/src/i18n/es.ts) · [`web/src/i18n/fr.ts`](../web/src/i18n/fr.ts) · [`web/src/i18n/pt.ts`](../web/src/i18n/pt.ts) · [`web/src/i18n/sessionErrors.ts`](../web/src/i18n/sessionErrors.ts) · [`web/src/i18n/errors/en.ts`](../web/src/i18n/errors/en.ts) · [`web/src/i18n/errors/es.ts`](../web/src/i18n/errors/es.ts) · [`web/src/i18n/errors/fr.ts`](../web/src/i18n/errors/fr.ts) · [`web/src/i18n/errors/pt.ts`](../web/src/i18n/errors/pt.ts) · [`web/src/components/SetupSidebar.svelte`](../web/src/components/SetupSidebar.svelte) · [`web/src/components/RepositorySelector.svelte`](../web/src/components/RepositorySelector.svelte) · [`web/src/components/BatchSetupPanel.svelte`](../web/src/components/BatchSetupPanel.svelte) · [`web/src/components/BatchSafetyBanner.svelte`](../web/src/components/BatchSafetyBanner.svelte) · [`web/src/components/InstallationReview.svelte`](../web/src/components/InstallationReview.svelte) · [`web/src/components/RunnerQuestionDetails.svelte`](../web/src/components/RunnerQuestionDetails.svelte) · [`web/src/i18n/runnerCopy.ts`](../web/src/i18n/runnerCopy.ts) · [`scripts/web-setup-runner-review-fixtures.cjs`](../scripts/web-setup-runner-review-fixtures.cjs) · [`src/application/contracts/setup_documentation.ts`](../src/application/contracts/setup_documentation.ts) · [`src/cli/setup_journey_presenter.ts`](../src/cli/setup_journey_presenter.ts) · [`web/src/components/SetupHelp.svelte`](../web/src/components/SetupHelp.svelte) · [`web/src/components/CompletedSetupHelp.svelte`](../web/src/components/CompletedSetupHelp.svelte) -- Tests: [`src/__tests__/cli.test.ts`](../src/__tests__/cli.test.ts) · [`src/__tests__/cli_context_branch.test.ts`](../src/__tests__/cli_context_branch.test.ts) · [`src/__tests__/cli_context_root.test.ts`](../src/__tests__/cli_context_root.test.ts) · [`src/cli/__tests__/web_setup_bridge.test.ts`](../src/cli/__tests__/web_setup_bridge.test.ts) · [`src/cli/__tests__/web_setup_adapters.test.ts`](../src/cli/__tests__/web_setup_adapters.test.ts) · [`src/cli/__tests__/web_setup_palette.test.ts`](../src/cli/__tests__/web_setup_palette.test.ts) · [`src/cli/__tests__/web_setup_ui_helpers.test.ts`](../src/cli/__tests__/web_setup_ui_helpers.test.ts) · [`src/cli/__tests__/web_setup_browser_session.test.ts`](../src/cli/__tests__/web_setup_browser_session.test.ts) · [`src/cli/__tests__/web_setup_server.test.ts`](../src/cli/__tests__/web_setup_server.test.ts) · [`src/cli/__tests__/web_setup_browser_open.test.ts`](../src/cli/__tests__/web_setup_browser_open.test.ts) · [`src/cli/__tests__/setup_apply_snapshot.test.ts`](../src/cli/__tests__/setup_apply_snapshot.test.ts) · [`src/cli/__tests__/setup_result_receipt.test.ts`](../src/cli/__tests__/setup_result_receipt.test.ts) · [`src/cli/__tests__/setup_session_guard.test.ts`](../src/cli/__tests__/setup_session_guard.test.ts) · [`src/cli/__tests__/setup_command_options.test.ts`](../src/cli/__tests__/setup_command_options.test.ts) · [`src/cli/__tests__/web_setup_components.test.ts`](../src/cli/__tests__/web_setup_components.test.ts) · [`src/cli/__tests__/setup_terminal_driver.test.ts`](../src/cli/__tests__/setup_terminal_driver.test.ts) · [`src/cli/__tests__/setup_terminal_driver_stream_integration.test.ts`](../src/cli/__tests__/setup_terminal_driver_stream_integration.test.ts) · [`src/cli/__tests__/setup_presenters.test.ts`](../src/cli/__tests__/setup_presenters.test.ts) · [`src/cli/__tests__/web_setup_catalog.test.ts`](../src/cli/__tests__/web_setup_catalog.test.ts) · [`src/architecture/__tests__/web_setup_boundaries.test.ts`](../src/architecture/__tests__/web_setup_boundaries.test.ts) · [`src/application/usecases/setup/__tests__/prepare_setup_pat_intent_use_case.test.ts`](../src/application/usecases/setup/__tests__/prepare_setup_pat_intent_use_case.test.ts) · [`src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts`](../src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts) · [`src/infrastructure/__tests__/setup_permission_resource_probes.test.ts`](../src/infrastructure/__tests__/setup_permission_resource_probes.test.ts) · [`src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts`](../src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts`](../src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts) · [`src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts`](../src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts) · [`src/actions/__tests__/local_action.test.ts`](../src/actions/__tests__/local_action.test.ts) · [`src/tooling/__tests__/validate_workflow_contract.test.ts`](../src/tooling/__tests__/validate_workflow_contract.test.ts) · [`src/domain/__tests__/setup_approval_workflow.test.ts`](../src/domain/__tests__/setup_approval_workflow.test.ts) · [`src/tooling/__tests__/documentation_checkout_text.test.ts`](../src/tooling/__tests__/documentation_checkout_text.test.ts) · [`src/application/policies/__tests__/setup_remote_facts_policy.test.ts`](../src/application/policies/__tests__/setup_remote_facts_policy.test.ts) · [`src/application/usecases/setup/__tests__/verify_setup_pat_bootstrap_use_case.test.ts`](../src/application/usecases/setup/__tests__/verify_setup_pat_bootstrap_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts`](../src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts) · [`src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts) · [`src/application/policies/__tests__/setup_questionnaire_policy.test.ts`](../src/application/policies/__tests__/setup_questionnaire_policy.test.ts) · [`src/application/policies/__tests__/setup_project_selection_policy.test.ts`](../src/application/policies/__tests__/setup_project_selection_policy.test.ts) · [`src/infrastructure/__tests__/github_setup_project_discovery_adapter.test.ts`](../src/infrastructure/__tests__/github_setup_project_discovery_adapter.test.ts) · [`src/infrastructure/__tests__/github_setup_approval_check_discovery_adapter.test.ts`](../src/infrastructure/__tests__/github_setup_approval_check_discovery_adapter.test.ts) · [`src/infrastructure/__tests__/setup_check_discovery_sdk_contract.integration.test.ts`](../src/infrastructure/__tests__/setup_check_discovery_sdk_contract.integration.test.ts) · [`src/application/policies/__tests__/setup_question_documentation_policy.test.ts`](../src/application/policies/__tests__/setup_question_documentation_policy.test.ts) · [`src/application/policies/__tests__/setup_question_purpose_policy.test.ts`](../src/application/policies/__tests__/setup_question_purpose_policy.test.ts) · [`src/application/policies/__tests__/setup_token_permission_policy.test.ts`](../src/application/policies/__tests__/setup_token_permission_policy.test.ts) · [`src/architecture/__tests__/setup_doctor_boundaries.test.ts`](../src/architecture/__tests__/setup_doctor_boundaries.test.ts) · [`src/infrastructure/__tests__/setup_pat_audit.test.ts`](../src/infrastructure/__tests__/setup_pat_audit.test.ts) · [`src/infrastructure/__tests__/setup_permission_projects_access.test.ts`](../src/infrastructure/__tests__/setup_permission_projects_access.test.ts) · [`src/application/usecases/setup/__tests__/setup_workflow_pat_recovery.test.ts`](../src/application/usecases/setup/__tests__/setup_workflow_pat_recovery.test.ts) · [`src/cli/__tests__/web_setup_bot_pat_recovery.test.ts`](../src/cli/__tests__/web_setup_bot_pat_recovery.test.ts) · [`src/application/usecases/setup/__tests__/setup_workflow_pat_conflict.test.ts`](../src/application/usecases/setup/__tests__/setup_workflow_pat_conflict.test.ts) · [`src/application/usecases/setup/__tests__/setup_workflow_pat_credential_rotation.test.ts`](../src/application/usecases/setup/__tests__/setup_workflow_pat_credential_rotation.test.ts) · [`src/data/repository/__tests__/setup_organization_pat_inventory.test.ts`](../src/data/repository/__tests__/setup_organization_pat_inventory.test.ts) · [`src/cli/__tests__/web_setup_bot_pat_scope_conflict.test.ts`](../src/cli/__tests__/web_setup_bot_pat_scope_conflict.test.ts) · [`src/actions/__tests__/local_setup_apply_contract.test.ts`](../src/actions/__tests__/local_setup_apply_contract.test.ts) · [`src/cli/commands/__tests__/setup_policy.test.ts`](../src/cli/commands/__tests__/setup_policy.test.ts) · [`src/application/usecases/execution/__tests__/execution_issue_number_policy.test.ts`](../src/application/usecases/execution/__tests__/execution_issue_number_policy.test.ts) · [`src/application/usecases/execution/__tests__/setup_execution_workflow.test.ts`](../src/application/usecases/execution/__tests__/setup_execution_workflow.test.ts) · [`src/application/policies/__tests__/setup_management_policy.test.ts`](../src/application/policies/__tests__/setup_management_policy.test.ts) · [`src/application/usecases/setup/__tests__/manage_setup_use_case.test.ts`](../src/application/usecases/setup/__tests__/manage_setup_use_case.test.ts) · [`src/infrastructure/__tests__/setup_management_workspace_adapter.test.ts`](../src/infrastructure/__tests__/setup_management_workspace_adapter.test.ts) · [`src/cli/__tests__/setup_management_adapter.test.ts`](../src/cli/__tests__/setup_management_adapter.test.ts) · [`src/cli/__tests__/web_setup_management_components.test.ts`](../src/cli/__tests__/web_setup_management_components.test.ts) · [`src/cli/__tests__/web_setup_runner_components.test.ts`](../src/cli/__tests__/web_setup_runner_components.test.ts) · [`src/cli/__tests__/setup_documentation_navigation.test.ts`](../src/cli/__tests__/setup_documentation_navigation.test.ts) -- User documentation: [`README.md`](../README.md) · [`docs/how-to-use.mdx`](../docs/how-to-use.mdx) · [`docs/authentication.mdx`](../docs/authentication.mdx) · [`docs/issues/assignees-and-projects.mdx`](../docs/issues/assignees-and-projects.mdx) · [`docs/pull-requests/guarded-approval.mdx`](../docs/pull-requests/guarded-approval.mdx) · [`docs/configuration.mdx`](../docs/configuration.mdx) · [`docs/configuration-checklist.mdx`](../docs/configuration-checklist.mdx) · [`docs/development/architecture.mdx`](../docs/development/architecture.mdx) · [`docs/development/setup-assistant-review.mdx`](../docs/development/setup-assistant-review.mdx) · [`docs/development/testing.mdx`](../docs/development/testing.mdx) · [`docs/dependency-rules.md`](../docs/dependency-rules.md) · [`docs/security-operations/security/self-hosted-runners.mdx`](../docs/security-operations/security/self-hosted-runners.mdx) · [`docs/security-operations/operations/troubleshooting.mdx`](../docs/security-operations/operations/troubleshooting.mdx) · [`docs/security-operations/operations/provisioning.mdx`](../docs/security-operations/operations/provisioning.mdx) · [`docs/setup-web.mdx`](../docs/setup-web.mdx) · [`docs/first-workflow.mdx`](../docs/first-workflow.mdx) · [`docs/using-the-docs.mdx`](../docs/using-the-docs.mdx) · [`docs/guides/index.mdx`](../docs/guides/index.mdx) · [`docs/guides/issues-and-branches.mdx`](../docs/guides/issues-and-branches.mdx) · [`docs/guides/review-pull-requests.mdx`](../docs/guides/review-pull-requests.mdx) · [`docs/guides/work-with-the-bot.mdx`](../docs/guides/work-with-the-bot.mdx) · [`docs/guides/releases-and-hotfixes.mdx`](../docs/guides/releases-and-hotfixes.mdx) +- Core code: [`web/src/App.svelte`](../web/src/App.svelte) · [`web/src/session/setupSession.ts`](../web/src/session/setupSession.ts) · [`web/src/components/ActionButton.svelte`](../web/src/components/ActionButton.svelte) · [`web/src/components/PairingPanel.svelte`](../web/src/components/PairingPanel.svelte) · [`web/src/lib/pairingCode.ts`](../web/src/lib/pairingCode.ts) · [`web/src/components/ContextPanel.svelte`](../web/src/components/ContextPanel.svelte) · [`web/src/i18n/permissionEvidence.ts`](../web/src/i18n/permissionEvidence.ts) · [`web/src/i18n/permissionProgress.ts`](../web/src/i18n/permissionProgress.ts) · [`web/src/components/PermissionProgressPanel.svelte`](../web/src/components/PermissionProgressPanel.svelte) · [`web/src/components/PromptCard.svelte`](../web/src/components/PromptCard.svelte) · [`web/src/components/ResultPanel.svelte`](../web/src/components/ResultPanel.svelte) · [`web/src/components/SetupPatCorrectionPanel.svelte`](../web/src/components/SetupPatCorrectionPanel.svelte) · [`web/src/components/ResourceProgress.svelte`](../web/src/components/ResourceProgress.svelte) · [`web/src/components/PlanPrompt.svelte`](../web/src/components/PlanPrompt.svelte) · [`web/src/components/PlanDecisionSummary.svelte`](../web/src/components/PlanDecisionSummary.svelte) · [`web/src/components/QuestionPrompt.svelte`](../web/src/components/QuestionPrompt.svelte) · [`web/src/components/FixedWorkflowNotice.svelte`](../web/src/components/FixedWorkflowNotice.svelte) · [`web/src/components/QuestionGuidance.svelte`](../web/src/components/QuestionGuidance.svelte) · [`web/src/components/DiscoveryNotice.svelte`](../web/src/components/DiscoveryNotice.svelte) · [`web/src/components/ProducerSelector.svelte`](../web/src/components/ProducerSelector.svelte) · [`web/src/lib/manualProducerIdentity.ts`](../web/src/lib/manualProducerIdentity.ts) · [`web/src/components/CoverageCheckEvidence.svelte`](../web/src/components/CoverageCheckEvidence.svelte) · [`web/src/components/ProjectSelector.svelte`](../web/src/components/ProjectSelector.svelte) · [`web/src/i18n/catalog.ts`](../web/src/i18n/catalog.ts) · [`web/src/i18n/projectTransitions.ts`](../web/src/i18n/projectTransitions.ts) · [`web/src/i18n/permissionTerms.ts`](../web/src/i18n/permissionTerms.ts) · [`web/src/components/StatusBanner.svelte`](../web/src/components/StatusBanner.svelte) · [`web/src/lib/questionAnswer.ts`](../web/src/lib/questionAnswer.ts) · [`web/src/lib/githubLink.ts`](../web/src/lib/githubLink.ts) · [`web/src/lib/focusOnRevision.ts`](../web/src/lib/focusOnRevision.ts) · [`web/src/i18n/featureNames.ts`](../web/src/i18n/featureNames.ts) · [`web/src/i18n/agentRoleNames.ts`](../web/src/i18n/agentRoleNames.ts) · [`web/src/i18n/checkEvidence.ts`](../web/src/i18n/checkEvidence.ts) · [`web/src/styles/controls.css`](../web/src/styles/controls.css) · [`web/src/styles/tokens.css`](../web/src/styles/tokens.css) · [`web/src/style.css`](../web/src/style.css) · [`src/application/contracts/web_setup_view.ts`](../src/application/contracts/web_setup_view.ts) · [`src/application/ports/setup_terminal_ports.ts`](../src/application/ports/setup_terminal_ports.ts) · [`src/application/errors/setup_interaction_cancelled_error.ts`](../src/application/errors/setup_interaction_cancelled_error.ts) · [`src/application/policies/merge_setup_overrides_policy.ts`](../src/application/policies/merge_setup_overrides_policy.ts) · [`src/application/policies/setup_remote_facts_policy.ts`](../src/application/policies/setup_remote_facts_policy.ts) · [`src/application/usecases/setup/prepare_setup_pat_intent_use_case.ts`](../src/application/usecases/setup/prepare_setup_pat_intent_use_case.ts) · [`src/application/usecases/setup/audit_configured_setup_pat_use_case.ts`](../src/application/usecases/setup/audit_configured_setup_pat_use_case.ts) · [`src/infrastructure/setup_permission_actions_probe.ts`](../src/infrastructure/setup_permission_actions_probe.ts) · [`src/infrastructure/setup_permission_issue_probe.ts`](../src/infrastructure/setup_permission_issue_probe.ts) · [`src/infrastructure/setup_permission_issue_cleanup.ts`](../src/infrastructure/setup_permission_issue_cleanup.ts) · [`src/infrastructure/setup_permission_probe_journal.ts`](../src/infrastructure/setup_permission_probe_journal.ts) · [`src/infrastructure/setup_permission_probe_transaction.ts`](../src/infrastructure/setup_permission_probe_transaction.ts) · [`src/infrastructure/setup_permission_resource_probes.ts`](../src/infrastructure/setup_permission_resource_probes.ts) · [`src/application/usecases/setup/verify_web_setup_apply_use_case.ts`](../src/application/usecases/setup/verify_web_setup_apply_use_case.ts) · [`src/application/usecases/setup/setup_session_coordinator.ts`](../src/application/usecases/setup/setup_session_coordinator.ts) · [`src/application/usecases/setup/verify_setup_pat_bootstrap_use_case.ts`](../src/application/usecases/setup/verify_setup_pat_bootstrap_use_case.ts) · [`src/cli_context.ts`](../src/cli_context.ts) · [`src/cli/setup_command_options.ts`](../src/cli/setup_command_options.ts) · [`src/cli/commands/setup_execution.ts`](../src/cli/commands/setup_execution.ts) · [`src/cli/setup_credential_collection.ts`](../src/cli/setup_credential_collection.ts) · [`src/cli/setup_pat_intent_adapter.ts`](../src/cli/setup_pat_intent_adapter.ts) · [`src/cli/setup_apply_authorization.ts`](../src/cli/setup_apply_authorization.ts) · [`src/cli/setup_outcome_adapter.ts`](../src/cli/setup_outcome_adapter.ts) · [`src/cli/web_setup_bridge.ts`](../src/cli/web_setup_bridge.ts) · [`src/cli/web_setup_adapters.ts`](../src/cli/web_setup_adapters.ts) · [`src/cli/web_setup_server.ts`](../src/cli/web_setup_server.ts) · [`src/cli/setup_apply_snapshot.ts`](../src/cli/setup_apply_snapshot.ts) · [`src/cli/setup_result_receipt.ts`](../src/cli/setup_result_receipt.ts) · [`src/application/usecases/actions/initial_setup_workflow.ts`](../src/application/usecases/actions/initial_setup_workflow.ts) · [`src/actions/local_action.ts`](../src/actions/local_action.ts) · [`src/cli/setup_session_guard.ts`](../src/cli/setup_session_guard.ts) · [`src/application/usecases/setup/setup_wizard_use_case.ts`](../src/application/usecases/setup/setup_wizard_use_case.ts) · [`src/application/usecases/setup/setup_questionnaire_controller.ts`](../src/application/usecases/setup/setup_questionnaire_controller.ts) · [`src/application/policies/setup_terminal_choice_policy.ts`](../src/application/policies/setup_terminal_choice_policy.ts) · [`src/cli/setup_terminal_driver.ts`](../src/cli/setup_terminal_driver.ts) · [`src/cli/setup_question_renderer.ts`](../src/cli/setup_question_renderer.ts) · [`src/application/usecases/setup/setup_journey_use_case.ts`](../src/application/usecases/setup/setup_journey_use_case.ts) · [`src/application/usecases/setup/setup_credentials_use_case.ts`](../src/application/usecases/setup/setup_credentials_use_case.ts) · [`src/application/policies/setup_questionnaire_policy.ts`](../src/application/policies/setup_questionnaire_policy.ts) · [`src/application/policies/setup_project_selection_policy.ts`](../src/application/policies/setup_project_selection_policy.ts) · [`src/application/ports/setup_project_discovery_port.ts`](../src/application/ports/setup_project_discovery_port.ts) · [`src/application/ports/setup_approval_check_discovery_port.ts`](../src/application/ports/setup_approval_check_discovery_port.ts) · [`src/infrastructure/github_setup_project_discovery_adapter.ts`](../src/infrastructure/github_setup_project_discovery_adapter.ts) · [`src/infrastructure/github_setup_approval_check_discovery_adapter.ts`](../src/infrastructure/github_setup_approval_check_discovery_adapter.ts) · [`src/application/policies/setup_question_documentation_policy.ts`](../src/application/policies/setup_question_documentation_policy.ts) · [`src/application/policies/setup_question_guidance_policy.ts`](../src/application/policies/setup_question_guidance_policy.ts) · [`src/application/policies/setup_question_purpose_policy.ts`](../src/application/policies/setup_question_purpose_policy.ts) · [`src/application/policies/setup_token_permission_policy.ts`](../src/application/policies/setup_token_permission_policy.ts) · [`src/application/policies/setup_configuration_plan.ts`](../src/application/policies/setup_configuration_plan.ts) · [`src/application/policies/setup_pat_creation_url_policy.ts`](../src/application/policies/setup_pat_creation_url_policy.ts) · [`src/infrastructure/composition/setup_credentials_composition_root.ts`](../src/infrastructure/composition/setup_credentials_composition_root.ts) · [`scripts/validate-npm-package.cjs`](../scripts/validate-npm-package.cjs) · [`scripts/smoke-test-npm-package.cjs`](../scripts/smoke-test-npm-package.cjs) · [`scripts/smoke-packaged-web-session.cjs`](../scripts/smoke-packaged-web-session.cjs) · [`scripts/validate-setup-assistant-acceptance.cjs`](../scripts/validate-setup-assistant-acceptance.cjs) · [`scripts/serve-web-setup-review.cjs`](../scripts/serve-web-setup-review.cjs) · [`scripts/validate-workflow-contract.cjs`](../scripts/validate-workflow-contract.cjs) · [`scripts/documentation_checkout_text.cjs`](../scripts/documentation_checkout_text.cjs) · [`scripts/set-cli-executable.cjs`](../scripts/set-cli-executable.cjs) · [`scripts/render-web-setup-component.cjs`](../scripts/render-web-setup-component.cjs) · [`web/src/i18n/permissionPrerequisite.ts`](../web/src/i18n/permissionPrerequisite.ts) · [`scripts/web-setup-review-views.cjs`](../scripts/web-setup-review-views.cjs) · [`src/application/usecases/setup/resolve_setup_workflow_pat_conflict_use_case.ts`](../src/application/usecases/setup/resolve_setup_workflow_pat_conflict_use_case.ts) · [`src/cli/setup_workflow_pat_storage_copy.ts`](../src/cli/setup_workflow_pat_storage_copy.ts) · [`web/src/components/WorkflowPatStorageNotice.svelte`](../web/src/components/WorkflowPatStorageNotice.svelte) · [`src/cli/commands/setup_policy.ts`](../src/cli/commands/setup_policy.ts) · [`src/application/usecases/execution/execution_issue_number_policy.ts`](../src/application/usecases/execution/execution_issue_number_policy.ts) · [`src/application/usecases/execution/setup_execution_workflow.ts`](../src/application/usecases/execution/setup_execution_workflow.ts) · [`src/domain/setup_management.ts`](../src/domain/setup_management.ts) · [`src/application/contracts/setup_management_view.ts`](../src/application/contracts/setup_management_view.ts) · [`src/application/ports/setup_management_ports.ts`](../src/application/ports/setup_management_ports.ts) · [`src/application/policies/setup_quick_settings_policy.ts`](../src/application/policies/setup_quick_settings_policy.ts) · [`src/application/policies/setup_management_policy.ts`](../src/application/policies/setup_management_policy.ts) · [`src/application/policies/setup_management_permissions_policy.ts`](../src/application/policies/setup_management_permissions_policy.ts) · [`src/application/usecases/setup/manage_setup_use_case.ts`](../src/application/usecases/setup/manage_setup_use_case.ts) · [`src/infrastructure/setup_management_workspace_adapter.ts`](../src/infrastructure/setup_management_workspace_adapter.ts) · [`src/cli/setup_management_adapter.ts`](../src/cli/setup_management_adapter.ts) · [`web/src/components/SetupManagementPanel.svelte`](../web/src/components/SetupManagementPanel.svelte) · [`web/src/components/ManagementInventory.svelte`](../web/src/components/ManagementInventory.svelte) · [`web/src/components/QuickSettingPrompt.svelte`](../web/src/components/QuickSettingPrompt.svelte) · [`web/src/i18n/managementCopy.ts`](../web/src/i18n/managementCopy.ts) · [`web/src/styles/management.css`](../web/src/styles/management.css) · [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`web/src/session/setupCommandTransport.ts`](../web/src/session/setupCommandTransport.ts) · [`scripts/serve-web-setup-journey.cjs`](../scripts/serve-web-setup-journey.cjs) · [`web/src/components/SetupHeader.svelte`](../web/src/components/SetupHeader.svelte) · [`web/src/components/WaitingPanel.svelte`](../web/src/components/WaitingPanel.svelte) · [`web/src/styles/layout.css`](../web/src/styles/layout.css) · [`web/src/i18n/en.ts`](../web/src/i18n/en.ts) · [`web/src/i18n/es.ts`](../web/src/i18n/es.ts) · [`web/src/i18n/fr.ts`](../web/src/i18n/fr.ts) · [`web/src/i18n/pt.ts`](../web/src/i18n/pt.ts) · [`web/src/i18n/sessionErrors.ts`](../web/src/i18n/sessionErrors.ts) · [`web/src/i18n/errors/en.ts`](../web/src/i18n/errors/en.ts) · [`web/src/i18n/errors/es.ts`](../web/src/i18n/errors/es.ts) · [`web/src/i18n/errors/fr.ts`](../web/src/i18n/errors/fr.ts) · [`web/src/i18n/errors/pt.ts`](../web/src/i18n/errors/pt.ts) · [`web/src/components/SetupSidebar.svelte`](../web/src/components/SetupSidebar.svelte) · [`web/src/components/RepositorySelector.svelte`](../web/src/components/RepositorySelector.svelte) · [`web/src/components/BatchSetupPanel.svelte`](../web/src/components/BatchSetupPanel.svelte) · [`web/src/components/BatchSafetyBanner.svelte`](../web/src/components/BatchSafetyBanner.svelte) · [`web/src/components/InstallationReview.svelte`](../web/src/components/InstallationReview.svelte) · [`web/src/components/RunnerQuestionDetails.svelte`](../web/src/components/RunnerQuestionDetails.svelte) · [`web/src/i18n/runnerCopy.ts`](../web/src/i18n/runnerCopy.ts) · [`scripts/web-setup-runner-review-fixtures.cjs`](../scripts/web-setup-runner-review-fixtures.cjs) · [`src/application/contracts/setup_documentation.ts`](../src/application/contracts/setup_documentation.ts) · [`src/cli/setup_journey_presenter.ts`](../src/cli/setup_journey_presenter.ts) · [`web/src/components/SetupHelp.svelte`](../web/src/components/SetupHelp.svelte) · [`web/src/components/CompletedSetupHelp.svelte`](../web/src/components/CompletedSetupHelp.svelte) · [`src/domain/setup_verification_action.ts`](../src/domain/setup_verification_action.ts) · [`src/infrastructure/setup_verification_action.ts`](../src/infrastructure/setup_verification_action.ts) · [`src/application/policies/setup_verification_action_summary_policy.ts`](../src/application/policies/setup_verification_action_summary_policy.ts) +- Tests: [`src/__tests__/cli.test.ts`](../src/__tests__/cli.test.ts) · [`src/__tests__/cli_context_branch.test.ts`](../src/__tests__/cli_context_branch.test.ts) · [`src/__tests__/cli_context_root.test.ts`](../src/__tests__/cli_context_root.test.ts) · [`src/cli/__tests__/web_setup_bridge.test.ts`](../src/cli/__tests__/web_setup_bridge.test.ts) · [`src/cli/__tests__/web_setup_adapters.test.ts`](../src/cli/__tests__/web_setup_adapters.test.ts) · [`src/cli/__tests__/web_setup_palette.test.ts`](../src/cli/__tests__/web_setup_palette.test.ts) · [`src/cli/__tests__/web_setup_ui_helpers.test.ts`](../src/cli/__tests__/web_setup_ui_helpers.test.ts) · [`src/cli/__tests__/web_setup_browser_session.test.ts`](../src/cli/__tests__/web_setup_browser_session.test.ts) · [`src/cli/__tests__/web_setup_server.test.ts`](../src/cli/__tests__/web_setup_server.test.ts) · [`src/cli/__tests__/web_setup_browser_open.test.ts`](../src/cli/__tests__/web_setup_browser_open.test.ts) · [`src/cli/__tests__/setup_apply_snapshot.test.ts`](../src/cli/__tests__/setup_apply_snapshot.test.ts) · [`src/cli/__tests__/setup_result_receipt.test.ts`](../src/cli/__tests__/setup_result_receipt.test.ts) · [`src/cli/__tests__/setup_session_guard.test.ts`](../src/cli/__tests__/setup_session_guard.test.ts) · [`src/cli/__tests__/setup_command_options.test.ts`](../src/cli/__tests__/setup_command_options.test.ts) · [`src/cli/__tests__/web_setup_components.test.ts`](../src/cli/__tests__/web_setup_components.test.ts) · [`src/cli/__tests__/setup_terminal_driver.test.ts`](../src/cli/__tests__/setup_terminal_driver.test.ts) · [`src/cli/__tests__/setup_terminal_driver_stream_integration.test.ts`](../src/cli/__tests__/setup_terminal_driver_stream_integration.test.ts) · [`src/cli/__tests__/setup_presenters.test.ts`](../src/cli/__tests__/setup_presenters.test.ts) · [`src/cli/__tests__/web_setup_catalog.test.ts`](../src/cli/__tests__/web_setup_catalog.test.ts) · [`src/architecture/__tests__/web_setup_boundaries.test.ts`](../src/architecture/__tests__/web_setup_boundaries.test.ts) · [`src/application/usecases/setup/__tests__/prepare_setup_pat_intent_use_case.test.ts`](../src/application/usecases/setup/__tests__/prepare_setup_pat_intent_use_case.test.ts) · [`src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts`](../src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts) · [`src/infrastructure/__tests__/setup_permission_resource_probes.test.ts`](../src/infrastructure/__tests__/setup_permission_resource_probes.test.ts) · [`src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts`](../src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts`](../src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts) · [`src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts`](../src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts) · [`src/actions/__tests__/local_action.test.ts`](../src/actions/__tests__/local_action.test.ts) · [`src/tooling/__tests__/validate_workflow_contract.test.ts`](../src/tooling/__tests__/validate_workflow_contract.test.ts) · [`src/domain/__tests__/setup_approval_workflow.test.ts`](../src/domain/__tests__/setup_approval_workflow.test.ts) · [`src/tooling/__tests__/documentation_checkout_text.test.ts`](../src/tooling/__tests__/documentation_checkout_text.test.ts) · [`src/application/policies/__tests__/setup_remote_facts_policy.test.ts`](../src/application/policies/__tests__/setup_remote_facts_policy.test.ts) · [`src/application/usecases/setup/__tests__/verify_setup_pat_bootstrap_use_case.test.ts`](../src/application/usecases/setup/__tests__/verify_setup_pat_bootstrap_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts`](../src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts) · [`src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts) · [`src/application/policies/__tests__/setup_questionnaire_policy.test.ts`](../src/application/policies/__tests__/setup_questionnaire_policy.test.ts) · [`src/application/policies/__tests__/setup_project_selection_policy.test.ts`](../src/application/policies/__tests__/setup_project_selection_policy.test.ts) · [`src/infrastructure/__tests__/github_setup_project_discovery_adapter.test.ts`](../src/infrastructure/__tests__/github_setup_project_discovery_adapter.test.ts) · [`src/infrastructure/__tests__/github_setup_approval_check_discovery_adapter.test.ts`](../src/infrastructure/__tests__/github_setup_approval_check_discovery_adapter.test.ts) · [`src/infrastructure/__tests__/setup_check_discovery_sdk_contract.integration.test.ts`](../src/infrastructure/__tests__/setup_check_discovery_sdk_contract.integration.test.ts) · [`src/application/policies/__tests__/setup_question_documentation_policy.test.ts`](../src/application/policies/__tests__/setup_question_documentation_policy.test.ts) · [`src/application/policies/__tests__/setup_question_purpose_policy.test.ts`](../src/application/policies/__tests__/setup_question_purpose_policy.test.ts) · [`src/application/policies/__tests__/setup_token_permission_policy.test.ts`](../src/application/policies/__tests__/setup_token_permission_policy.test.ts) · [`src/architecture/__tests__/setup_doctor_boundaries.test.ts`](../src/architecture/__tests__/setup_doctor_boundaries.test.ts) · [`src/infrastructure/__tests__/setup_pat_audit.test.ts`](../src/infrastructure/__tests__/setup_pat_audit.test.ts) · [`src/infrastructure/__tests__/setup_permission_projects_access.test.ts`](../src/infrastructure/__tests__/setup_permission_projects_access.test.ts) · [`src/application/usecases/setup/__tests__/setup_workflow_pat_recovery.test.ts`](../src/application/usecases/setup/__tests__/setup_workflow_pat_recovery.test.ts) · [`src/cli/__tests__/web_setup_bot_pat_recovery.test.ts`](../src/cli/__tests__/web_setup_bot_pat_recovery.test.ts) · [`src/application/usecases/setup/__tests__/setup_workflow_pat_conflict.test.ts`](../src/application/usecases/setup/__tests__/setup_workflow_pat_conflict.test.ts) · [`src/application/usecases/setup/__tests__/setup_workflow_pat_credential_rotation.test.ts`](../src/application/usecases/setup/__tests__/setup_workflow_pat_credential_rotation.test.ts) · [`src/data/repository/__tests__/setup_organization_pat_inventory.test.ts`](../src/data/repository/__tests__/setup_organization_pat_inventory.test.ts) · [`src/cli/__tests__/web_setup_bot_pat_scope_conflict.test.ts`](../src/cli/__tests__/web_setup_bot_pat_scope_conflict.test.ts) · [`src/actions/__tests__/local_setup_apply_contract.test.ts`](../src/actions/__tests__/local_setup_apply_contract.test.ts) · [`src/cli/commands/__tests__/setup_policy.test.ts`](../src/cli/commands/__tests__/setup_policy.test.ts) · [`src/application/usecases/execution/__tests__/execution_issue_number_policy.test.ts`](../src/application/usecases/execution/__tests__/execution_issue_number_policy.test.ts) · [`src/application/usecases/execution/__tests__/setup_execution_workflow.test.ts`](../src/application/usecases/execution/__tests__/setup_execution_workflow.test.ts) · [`src/application/policies/__tests__/setup_management_policy.test.ts`](../src/application/policies/__tests__/setup_management_policy.test.ts) · [`src/application/usecases/setup/__tests__/manage_setup_use_case.test.ts`](../src/application/usecases/setup/__tests__/manage_setup_use_case.test.ts) · [`src/infrastructure/__tests__/setup_management_workspace_adapter.test.ts`](../src/infrastructure/__tests__/setup_management_workspace_adapter.test.ts) · [`src/cli/__tests__/setup_management_adapter.test.ts`](../src/cli/__tests__/setup_management_adapter.test.ts) · [`src/cli/__tests__/web_setup_management_components.test.ts`](../src/cli/__tests__/web_setup_management_components.test.ts) · [`src/cli/__tests__/web_setup_runner_components.test.ts`](../src/cli/__tests__/web_setup_runner_components.test.ts) · [`src/cli/__tests__/setup_documentation_navigation.test.ts`](../src/cli/__tests__/setup_documentation_navigation.test.ts) · [`src/infrastructure/__tests__/setup_verification_action.test.ts`](../src/infrastructure/__tests__/setup_verification_action.test.ts) · [`src/application/policies/__tests__/setup_verification_onboarding_policy.test.ts`](../src/application/policies/__tests__/setup_verification_onboarding_policy.test.ts) · [`src/cli/__tests__/setup_verification_onboarding_components.test.ts`](../src/cli/__tests__/setup_verification_onboarding_components.test.ts) · [`src/application/usecases/setup/__tests__/setup_verification_onboarding_flow.test.ts`](../src/application/usecases/setup/__tests__/setup_verification_onboarding_flow.test.ts) +- User documentation: [`README.md`](../README.md) · [`docs/how-to-use.mdx`](../docs/how-to-use.mdx) · [`docs/authentication.mdx`](../docs/authentication.mdx) · [`docs/issues/assignees-and-projects.mdx`](../docs/issues/assignees-and-projects.mdx) · [`docs/pull-requests/guarded-approval.mdx`](../docs/pull-requests/guarded-approval.mdx) · [`docs/configuration.mdx`](../docs/configuration.mdx) · [`docs/configuration-checklist.mdx`](../docs/configuration-checklist.mdx) · [`docs/development/architecture.mdx`](../docs/development/architecture.mdx) · [`docs/development/setup-assistant-review.mdx`](../docs/development/setup-assistant-review.mdx) · [`docs/development/testing.mdx`](../docs/development/testing.mdx) · [`docs/dependency-rules.md`](../docs/dependency-rules.md) · [`docs/security-operations/security/self-hosted-runners.mdx`](../docs/security-operations/security/self-hosted-runners.mdx) · [`docs/security-operations/operations/troubleshooting.mdx`](../docs/security-operations/operations/troubleshooting.mdx) · [`docs/security-operations/operations/provisioning.mdx`](../docs/security-operations/operations/provisioning.mdx) · [`docs/setup-web.mdx`](../docs/setup-web.mdx) · [`docs/first-workflow.mdx`](../docs/first-workflow.mdx) · [`docs/using-the-docs.mdx`](../docs/using-the-docs.mdx) · [`docs/guides/index.mdx`](../docs/guides/index.mdx) · [`docs/guides/issues-and-branches.mdx`](../docs/guides/issues-and-branches.mdx) · [`docs/guides/review-pull-requests.mdx`](../docs/guides/review-pull-requests.mdx) · [`docs/guides/work-with-the-bot.mdx`](../docs/guides/work-with-the-bot.mdx) · [`docs/guides/releases-and-hotfixes.mdx`](../docs/guides/releases-and-hotfixes.mdx) · [`docs/security-operations/operations/verification.mdx`](../docs/security-operations/operations/verification.mdx) · [`docs/security-operations/operations/upgrade-rollback.mdx`](../docs/security-operations/operations/upgrade-rollback.mdx) ### `guided-bot-pat-onboarding` — Guided bot PAT onboarding @@ -147,12 +147,12 @@ debt or convert unknown historic intent into a design decision. ### `issue-start-and-sdd-readiness` — Uniform issue start and pre-branch SDD readiness - Owner: Copilot maintainers -- Last verified: 2026-10-19 +- Last verified: 2026-10-21 - Specifications: [`specs/issue-start-and-branch-readiness.md`](./issue-start-and-branch-readiness.md) · [`specs/pre-branch-sdd-gate.md`](./pre-branch-sdd-gate.md) · [`specs/pre-branch-sdd-diff.md`](./pre-branch-sdd-diff.md) · [`specs/pre-branch-sdd-status-readiness.md`](./pre-branch-sdd-status-readiness.md) - Workflows: [`.github/workflows/copilot_issue.yml`](../.github/workflows/copilot_issue.yml) · [`.github/workflows/copilot_issue_comment.yml`](../.github/workflows/copilot_issue_comment.yml) · [`.github/workflows/copilot_commit.yml`](../.github/workflows/copilot_commit.yml) · [`.github/workflows/copilot_pull_request_comment.yml`](../.github/workflows/copilot_pull_request_comment.yml) - Entrypoints: [`action.yml`](../action.yml) · [`src/actions/common_action.ts`](../src/actions/common_action.ts) · [`src/actions/github_action.ts`](../src/actions/github_action.ts) -- Core code: [`src/domain/issue_workflow_runtime_policy.ts`](../src/domain/issue_workflow_runtime_policy.ts) · [`src/domain/copilot_lifecycle.ts`](../src/domain/copilot_lifecycle.ts) · [`src/data/model/execution.ts`](../src/data/model/execution.ts) · [`src/application/usecases/issue_workflow.ts`](../src/application/usecases/issue_workflow.ts) · [`src/application/usecases/steps/issue/prepare_branches_use_case.ts`](../src/application/usecases/steps/issue/prepare_branches_use_case.ts) · [`src/application/policies/setup_issue_workflow_policy.ts`](../src/application/policies/setup_issue_workflow_policy.ts) · [`src/application/policies/lifecycle_state_policy.ts`](../src/application/policies/lifecycle_state_policy.ts) · [`src/application/usecases/actions/synchronize_lifecycle_state_use_case.ts`](../src/application/usecases/actions/synchronize_lifecycle_state_use_case.ts) · [`src/infrastructure/git_commit_adapter.ts`](../src/infrastructure/git_commit_adapter.ts) · [`scripts/validate-specification-catalog.cjs`](../scripts/validate-specification-catalog.cjs) · [`src/domain/issue_start_policy.ts`](../src/domain/issue_start_policy.ts) · [`src/domain/pre_branch_sdd.ts`](../src/domain/pre_branch_sdd.ts) · [`src/application/ports/pre_branch_sdd_ports.ts`](../src/application/ports/pre_branch_sdd_ports.ts) · [`src/application/usecases/sdd/pre_branch_sdd_gate_use_case.ts`](../src/application/usecases/sdd/pre_branch_sdd_gate_use_case.ts) · [`src/application/usecases/steps/issue/reconcile_branch_readiness_use_case.ts`](../src/application/usecases/steps/issue/reconcile_branch_readiness_use_case.ts) · [`src/data/repository/branch/linked_branch_readiness_repository.ts`](../src/data/repository/branch/linked_branch_readiness_repository.ts) · [`src/infrastructure/pre_branch_sdd_workspace_adapter.ts`](../src/infrastructure/pre_branch_sdd_workspace_adapter.ts) · [`src/infrastructure/specification_catalog_validator.cjs`](../src/infrastructure/specification_catalog_validator.cjs) · [`src/actions/input_boolean_policy.ts`](../src/actions/input_boolean_policy.ts) · [`src/domain/issue_workflow_profile.ts`](../src/domain/issue_workflow_profile.ts) · [`src/application/usecases/read_copilot_status_workflow.ts`](../src/application/usecases/read_copilot_status_workflow.ts) · [`src/application/policies/status_command_policy.ts`](../src/application/policies/status_command_policy.ts) · [`src/application/policies/publication_message_catalog.ts`](../src/application/policies/publication_message_catalog.ts) · [`src/application/usecases/sdd/pre_branch_sdd_draft_workflow.ts`](../src/application/usecases/sdd/pre_branch_sdd_draft_workflow.ts) · [`src/data/model/application_error.ts`](../src/data/model/application_error.ts) · [`src/application/policies/application_error_message_catalog.ts`](../src/application/policies/application_error_message_catalog.ts) · [`src/domain/agent_response_length_failure.ts`](../src/domain/agent_response_length_failure.ts) · [`src/data/repository/agent_json_schema_validator.ts`](../src/data/repository/agent_json_schema_validator.ts) · [`src/application/ports/sdd_evidence_read_ports.ts`](../src/application/ports/sdd_evidence_read_ports.ts) · [`src/application/policies/sdd_issue_identity_policy.ts`](../src/application/policies/sdd_issue_identity_policy.ts) · [`src/application/policies/sdd_query_card_policy.ts`](../src/application/policies/sdd_query_card_policy.ts) · [`src/application/policies/sdd_status_policy.ts`](../src/application/policies/sdd_status_policy.ts) · [`src/application/usecases/sdd/sdd_evidence_query_use_case.ts`](../src/application/usecases/sdd/sdd_evidence_query_use_case.ts) · [`src/application/usecases/comment_automation_context.ts`](../src/application/usecases/comment_automation_context.ts) · [`src/application/usecases/comment_automation_command_workflow.ts`](../src/application/usecases/comment_automation_command_workflow.ts) · [`src/application/usecases/comment_automation_contracts.ts`](../src/application/usecases/comment_automation_contracts.ts) · [`src/application/usecases/issue_comment_use_case.ts`](../src/application/usecases/issue_comment_use_case.ts) · [`src/application/policies/semantic_result_publication_policy.ts`](../src/application/policies/semantic_result_publication_policy.ts) · [`src/infrastructure/composition/sdd_evidence_composition_root.ts`](../src/infrastructure/composition/sdd_evidence_composition_root.ts) · [`src/infrastructure/composition/main_run_route_composition_root.ts`](../src/infrastructure/composition/main_run_route_composition_root.ts) · [`src/domain/pre_branch_sdd_diff.ts`](../src/domain/pre_branch_sdd_diff.ts) · [`src/application/policies/sdd_diff_message_catalog.ts`](../src/application/policies/sdd_diff_message_catalog.ts) · [`src/application/policies/sdd_diff_presentation_policy.ts`](../src/application/policies/sdd_diff_presentation_policy.ts) · [`src/application/ports/sdd_diff_read_ports.ts`](../src/application/ports/sdd_diff_read_ports.ts) · [`src/application/usecases/sdd/sdd_diff_query_use_case.ts`](../src/application/usecases/sdd/sdd_diff_query_use_case.ts) · [`src/data/repository/sdd/sdd_diff_link_repository.ts`](../src/data/repository/sdd/sdd_diff_link_repository.ts) · [`src/infrastructure/composition/sdd_diff_composition_root.ts`](../src/infrastructure/composition/sdd_diff_composition_root.ts) · [`src/application/usecases/pull_request_review_comment_use_case.ts`](../src/application/usecases/pull_request_review_comment_use_case.ts) · [`src/application/usecases/steps/common/reply_publication_workflow.ts`](../src/application/usecases/steps/common/reply_publication_workflow.ts) · [`src/application/usecases/steps/common/publish_resume_workflow.ts`](../src/application/usecases/steps/common/publish_resume_workflow.ts) · [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`src/architecture/github_publication_mutation_baseline.json`](../src/architecture/github_publication_mutation_baseline.json) · [`src/domain/specification_catalog_path_policy.cjs`](../src/domain/specification_catalog_path_policy.cjs) · [`src/application/policies/github_runtime_doctor_policy.ts`](../src/application/policies/github_runtime_doctor_policy.ts) · [`src/infrastructure/setup_workspace_adapter.ts`](../src/infrastructure/setup_workspace_adapter.ts) · [`src/application/usecases/setup/doctor_use_case.ts`](../src/application/usecases/setup/doctor_use_case.ts) · [`src/application/policies/setup_doctor_message_catalog.ts`](../src/application/policies/setup_doctor_message_catalog.ts) · [`src/domain/sdd_prerequisite_policy.cjs`](../src/domain/sdd_prerequisite_policy.cjs) -- Tests: [`src/domain/__tests__/issue_workflow_runtime_policy.test.ts`](../src/domain/__tests__/issue_workflow_runtime_policy.test.ts) · [`src/data/model/__tests__/execution.test.ts`](../src/data/model/__tests__/execution.test.ts) · [`src/application/usecases/__tests__/issue_use_case.test.ts`](../src/application/usecases/__tests__/issue_use_case.test.ts) · [`src/application/usecases/steps/issue/__tests__/prepare_branches_use_case.test.ts`](../src/application/usecases/steps/issue/__tests__/prepare_branches_use_case.test.ts) · [`src/application/policies/__tests__/lifecycle_state_policy.test.ts`](../src/application/policies/__tests__/lifecycle_state_policy.test.ts) · [`src/application/usecases/actions/__tests__/synchronize_lifecycle_state_use_case.test.ts`](../src/application/usecases/actions/__tests__/synchronize_lifecycle_state_use_case.test.ts) · [`src/tooling/__tests__/validate_specification_catalog.test.ts`](../src/tooling/__tests__/validate_specification_catalog.test.ts) · [`src/domain/__tests__/issue_start_policy.test.ts`](../src/domain/__tests__/issue_start_policy.test.ts) · [`src/domain/__tests__/pre_branch_sdd.test.ts`](../src/domain/__tests__/pre_branch_sdd.test.ts) · [`src/application/usecases/steps/issue/__tests__/pre_branch_sdd_gate_use_case.test.ts`](../src/application/usecases/steps/issue/__tests__/pre_branch_sdd_gate_use_case.test.ts) · [`src/application/usecases/steps/issue/__tests__/reconcile_branch_readiness_use_case.test.ts`](../src/application/usecases/steps/issue/__tests__/reconcile_branch_readiness_use_case.test.ts) · [`src/infrastructure/__tests__/pre_branch_sdd_workspace_adapter.test.ts`](../src/infrastructure/__tests__/pre_branch_sdd_workspace_adapter.test.ts) · [`src/architecture/__tests__/github_publication_boundaries.test.ts`](../src/architecture/__tests__/github_publication_boundaries.test.ts) · [`src/actions/__tests__/input_boolean_policy.test.ts`](../src/actions/__tests__/input_boolean_policy.test.ts) · [`src/domain/__tests__/issue_workflow_profile.test.ts`](../src/domain/__tests__/issue_workflow_profile.test.ts) · [`src/application/policies/__tests__/status_command_policy.test.ts`](../src/application/policies/__tests__/status_command_policy.test.ts) · [`src/application/usecases/sdd/pre_branch_sdd_draft_workflow.test.ts`](../src/application/usecases/sdd/pre_branch_sdd_draft_workflow.test.ts) · [`src/application/policies/__tests__/application_error_presentation_policy.test.ts`](../src/application/policies/__tests__/application_error_presentation_policy.test.ts) · [`src/data/repository/__tests__/agent_json_schema_validator.test.ts`](../src/data/repository/__tests__/agent_json_schema_validator.test.ts) · [`src/application/policies/__tests__/sdd_issue_identity_policy.test.ts`](../src/application/policies/__tests__/sdd_issue_identity_policy.test.ts) · [`src/application/policies/__tests__/sdd_query_card_policy.test.ts`](../src/application/policies/__tests__/sdd_query_card_policy.test.ts) · [`src/application/policies/__tests__/sdd_status_policy.test.ts`](../src/application/policies/__tests__/sdd_status_policy.test.ts) · [`src/application/usecases/sdd/__tests__/sdd_evidence_query_use_case.test.ts`](../src/application/usecases/sdd/__tests__/sdd_evidence_query_use_case.test.ts) · [`src/data/repository/branch/__tests__/linked_branch_readiness_repository.test.ts`](../src/data/repository/branch/__tests__/linked_branch_readiness_repository.test.ts) · [`src/application/usecases/__tests__/read_copilot_status_workflow.test.ts`](../src/application/usecases/__tests__/read_copilot_status_workflow.test.ts) · [`src/infrastructure/composition/__tests__/main_run_route_composition_root.test.ts`](../src/infrastructure/composition/__tests__/main_run_route_composition_root.test.ts) · [`src/infrastructure/composition/__tests__/sdd_evidence_composition_root.test.ts`](../src/infrastructure/composition/__tests__/sdd_evidence_composition_root.test.ts) · [`src/domain/__tests__/pre_branch_sdd_diff.test.ts`](../src/domain/__tests__/pre_branch_sdd_diff.test.ts) · [`src/application/policies/__tests__/sdd_diff_presentation_policy.test.ts`](../src/application/policies/__tests__/sdd_diff_presentation_policy.test.ts) · [`src/application/usecases/sdd/__tests__/sdd_diff_query_use_case.test.ts`](../src/application/usecases/sdd/__tests__/sdd_diff_query_use_case.test.ts) · [`src/data/repository/sdd/__tests__/sdd_diff_link_repository.test.ts`](../src/data/repository/sdd/__tests__/sdd_diff_link_repository.test.ts) · [`src/infrastructure/composition/__tests__/sdd_diff_composition_root.test.ts`](../src/infrastructure/composition/__tests__/sdd_diff_composition_root.test.ts) · [`src/application/usecases/__tests__/sdd_diff_comment_interaction.test.ts`](../src/application/usecases/__tests__/sdd_diff_comment_interaction.test.ts) · [`src/application/usecases/steps/common/__tests__/sdd_diff_reply_publication.test.ts`](../src/application/usecases/steps/common/__tests__/sdd_diff_reply_publication.test.ts) · [`src/application/usecases/__tests__/sdd_status_workflow_integration.test.ts`](../src/application/usecases/__tests__/sdd_status_workflow_integration.test.ts) · [`src/tooling/__tests__/portable_specification_catalog.test.ts`](../src/tooling/__tests__/portable_specification_catalog.test.ts) · [`src/application/policies/__tests__/github_runtime_doctor_policy.test.ts`](../src/application/policies/__tests__/github_runtime_doctor_policy.test.ts) · [`src/infrastructure/__tests__/setup_sdd_prerequisites.test.ts`](../src/infrastructure/__tests__/setup_sdd_prerequisites.test.ts) · [`src/application/usecases/setup/__tests__/doctor_use_case.test.ts`](../src/application/usecases/setup/__tests__/doctor_use_case.test.ts) · [`src/infrastructure/__tests__/branch_sync_sdd_catalog.test.ts`](../src/infrastructure/__tests__/branch_sync_sdd_catalog.test.ts) · [`src/cli/__tests__/setup_presenters.test.ts`](../src/cli/__tests__/setup_presenters.test.ts) +- Core code: [`src/domain/issue_workflow_runtime_policy.ts`](../src/domain/issue_workflow_runtime_policy.ts) · [`src/domain/copilot_lifecycle.ts`](../src/domain/copilot_lifecycle.ts) · [`src/data/model/execution.ts`](../src/data/model/execution.ts) · [`src/application/usecases/issue_workflow.ts`](../src/application/usecases/issue_workflow.ts) · [`src/application/usecases/steps/issue/prepare_branches_use_case.ts`](../src/application/usecases/steps/issue/prepare_branches_use_case.ts) · [`src/application/policies/setup_issue_workflow_policy.ts`](../src/application/policies/setup_issue_workflow_policy.ts) · [`src/application/policies/lifecycle_state_policy.ts`](../src/application/policies/lifecycle_state_policy.ts) · [`src/application/usecases/actions/synchronize_lifecycle_state_use_case.ts`](../src/application/usecases/actions/synchronize_lifecycle_state_use_case.ts) · [`src/infrastructure/git_commit_adapter.ts`](../src/infrastructure/git_commit_adapter.ts) · [`scripts/validate-specification-catalog.cjs`](../scripts/validate-specification-catalog.cjs) · [`src/domain/issue_start_policy.ts`](../src/domain/issue_start_policy.ts) · [`src/domain/pre_branch_sdd.ts`](../src/domain/pre_branch_sdd.ts) · [`src/application/ports/pre_branch_sdd_ports.ts`](../src/application/ports/pre_branch_sdd_ports.ts) · [`src/application/usecases/sdd/pre_branch_sdd_gate_use_case.ts`](../src/application/usecases/sdd/pre_branch_sdd_gate_use_case.ts) · [`src/application/usecases/steps/issue/reconcile_branch_readiness_use_case.ts`](../src/application/usecases/steps/issue/reconcile_branch_readiness_use_case.ts) · [`src/data/repository/branch/linked_branch_readiness_repository.ts`](../src/data/repository/branch/linked_branch_readiness_repository.ts) · [`src/infrastructure/pre_branch_sdd_workspace_adapter.ts`](../src/infrastructure/pre_branch_sdd_workspace_adapter.ts) · [`src/infrastructure/specification_catalog_validator.cjs`](../src/infrastructure/specification_catalog_validator.cjs) · [`src/actions/input_boolean_policy.ts`](../src/actions/input_boolean_policy.ts) · [`src/domain/issue_workflow_profile.ts`](../src/domain/issue_workflow_profile.ts) · [`src/application/usecases/read_copilot_status_workflow.ts`](../src/application/usecases/read_copilot_status_workflow.ts) · [`src/application/policies/status_command_policy.ts`](../src/application/policies/status_command_policy.ts) · [`src/application/policies/publication_message_catalog.ts`](../src/application/policies/publication_message_catalog.ts) · [`src/application/usecases/sdd/pre_branch_sdd_draft_workflow.ts`](../src/application/usecases/sdd/pre_branch_sdd_draft_workflow.ts) · [`src/data/model/application_error.ts`](../src/data/model/application_error.ts) · [`src/application/policies/application_error_message_catalog.ts`](../src/application/policies/application_error_message_catalog.ts) · [`src/domain/agent_response_length_failure.ts`](../src/domain/agent_response_length_failure.ts) · [`src/data/repository/agent_json_schema_validator.ts`](../src/data/repository/agent_json_schema_validator.ts) · [`src/application/ports/sdd_evidence_read_ports.ts`](../src/application/ports/sdd_evidence_read_ports.ts) · [`src/application/policies/sdd_issue_identity_policy.ts`](../src/application/policies/sdd_issue_identity_policy.ts) · [`src/application/policies/sdd_query_card_policy.ts`](../src/application/policies/sdd_query_card_policy.ts) · [`src/application/policies/sdd_status_policy.ts`](../src/application/policies/sdd_status_policy.ts) · [`src/application/usecases/sdd/sdd_evidence_query_use_case.ts`](../src/application/usecases/sdd/sdd_evidence_query_use_case.ts) · [`src/application/usecases/comment_automation_context.ts`](../src/application/usecases/comment_automation_context.ts) · [`src/application/usecases/comment_automation_command_workflow.ts`](../src/application/usecases/comment_automation_command_workflow.ts) · [`src/application/usecases/comment_automation_contracts.ts`](../src/application/usecases/comment_automation_contracts.ts) · [`src/application/usecases/issue_comment_use_case.ts`](../src/application/usecases/issue_comment_use_case.ts) · [`src/application/policies/semantic_result_publication_policy.ts`](../src/application/policies/semantic_result_publication_policy.ts) · [`src/infrastructure/composition/sdd_evidence_composition_root.ts`](../src/infrastructure/composition/sdd_evidence_composition_root.ts) · [`src/infrastructure/composition/main_run_route_composition_root.ts`](../src/infrastructure/composition/main_run_route_composition_root.ts) · [`src/domain/pre_branch_sdd_diff.ts`](../src/domain/pre_branch_sdd_diff.ts) · [`src/application/policies/sdd_diff_message_catalog.ts`](../src/application/policies/sdd_diff_message_catalog.ts) · [`src/application/policies/sdd_diff_presentation_policy.ts`](../src/application/policies/sdd_diff_presentation_policy.ts) · [`src/application/ports/sdd_diff_read_ports.ts`](../src/application/ports/sdd_diff_read_ports.ts) · [`src/application/usecases/sdd/sdd_diff_query_use_case.ts`](../src/application/usecases/sdd/sdd_diff_query_use_case.ts) · [`src/data/repository/sdd/sdd_diff_link_repository.ts`](../src/data/repository/sdd/sdd_diff_link_repository.ts) · [`src/infrastructure/composition/sdd_diff_composition_root.ts`](../src/infrastructure/composition/sdd_diff_composition_root.ts) · [`src/application/usecases/pull_request_review_comment_use_case.ts`](../src/application/usecases/pull_request_review_comment_use_case.ts) · [`src/application/usecases/steps/common/reply_publication_workflow.ts`](../src/application/usecases/steps/common/reply_publication_workflow.ts) · [`src/application/usecases/steps/common/publish_resume_workflow.ts`](../src/application/usecases/steps/common/publish_resume_workflow.ts) · [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`src/architecture/github_publication_mutation_baseline.json`](../src/architecture/github_publication_mutation_baseline.json) · [`src/domain/specification_catalog_path_policy.cjs`](../src/domain/specification_catalog_path_policy.cjs) · [`src/application/policies/github_runtime_doctor_policy.ts`](../src/application/policies/github_runtime_doctor_policy.ts) · [`src/infrastructure/setup_workspace_adapter.ts`](../src/infrastructure/setup_workspace_adapter.ts) · [`src/application/usecases/setup/doctor_use_case.ts`](../src/application/usecases/setup/doctor_use_case.ts) · [`src/application/policies/setup_doctor_message_catalog.ts`](../src/application/policies/setup_doctor_message_catalog.ts) · [`src/domain/sdd_prerequisite_policy.cjs`](../src/domain/sdd_prerequisite_policy.cjs) · [`src/application/policies/sdd_analysis_status_policy.ts`](../src/application/policies/sdd_analysis_status_policy.ts) · [`src/domain/sdd_draft_consistency.ts`](../src/domain/sdd_draft_consistency.ts) +- Tests: [`src/domain/__tests__/issue_workflow_runtime_policy.test.ts`](../src/domain/__tests__/issue_workflow_runtime_policy.test.ts) · [`src/data/model/__tests__/execution.test.ts`](../src/data/model/__tests__/execution.test.ts) · [`src/application/usecases/__tests__/issue_use_case.test.ts`](../src/application/usecases/__tests__/issue_use_case.test.ts) · [`src/application/usecases/steps/issue/__tests__/prepare_branches_use_case.test.ts`](../src/application/usecases/steps/issue/__tests__/prepare_branches_use_case.test.ts) · [`src/application/policies/__tests__/lifecycle_state_policy.test.ts`](../src/application/policies/__tests__/lifecycle_state_policy.test.ts) · [`src/application/usecases/actions/__tests__/synchronize_lifecycle_state_use_case.test.ts`](../src/application/usecases/actions/__tests__/synchronize_lifecycle_state_use_case.test.ts) · [`src/tooling/__tests__/validate_specification_catalog.test.ts`](../src/tooling/__tests__/validate_specification_catalog.test.ts) · [`src/domain/__tests__/issue_start_policy.test.ts`](../src/domain/__tests__/issue_start_policy.test.ts) · [`src/domain/__tests__/pre_branch_sdd.test.ts`](../src/domain/__tests__/pre_branch_sdd.test.ts) · [`src/application/usecases/steps/issue/__tests__/pre_branch_sdd_gate_use_case.test.ts`](../src/application/usecases/steps/issue/__tests__/pre_branch_sdd_gate_use_case.test.ts) · [`src/application/usecases/steps/issue/__tests__/reconcile_branch_readiness_use_case.test.ts`](../src/application/usecases/steps/issue/__tests__/reconcile_branch_readiness_use_case.test.ts) · [`src/infrastructure/__tests__/pre_branch_sdd_workspace_adapter.test.ts`](../src/infrastructure/__tests__/pre_branch_sdd_workspace_adapter.test.ts) · [`src/architecture/__tests__/github_publication_boundaries.test.ts`](../src/architecture/__tests__/github_publication_boundaries.test.ts) · [`src/actions/__tests__/input_boolean_policy.test.ts`](../src/actions/__tests__/input_boolean_policy.test.ts) · [`src/domain/__tests__/issue_workflow_profile.test.ts`](../src/domain/__tests__/issue_workflow_profile.test.ts) · [`src/application/policies/__tests__/status_command_policy.test.ts`](../src/application/policies/__tests__/status_command_policy.test.ts) · [`src/application/usecases/sdd/pre_branch_sdd_draft_workflow.test.ts`](../src/application/usecases/sdd/pre_branch_sdd_draft_workflow.test.ts) · [`src/application/policies/__tests__/application_error_presentation_policy.test.ts`](../src/application/policies/__tests__/application_error_presentation_policy.test.ts) · [`src/data/repository/__tests__/agent_json_schema_validator.test.ts`](../src/data/repository/__tests__/agent_json_schema_validator.test.ts) · [`src/application/policies/__tests__/sdd_issue_identity_policy.test.ts`](../src/application/policies/__tests__/sdd_issue_identity_policy.test.ts) · [`src/application/policies/__tests__/sdd_query_card_policy.test.ts`](../src/application/policies/__tests__/sdd_query_card_policy.test.ts) · [`src/application/policies/__tests__/sdd_status_policy.test.ts`](../src/application/policies/__tests__/sdd_status_policy.test.ts) · [`src/application/usecases/sdd/__tests__/sdd_evidence_query_use_case.test.ts`](../src/application/usecases/sdd/__tests__/sdd_evidence_query_use_case.test.ts) · [`src/data/repository/branch/__tests__/linked_branch_readiness_repository.test.ts`](../src/data/repository/branch/__tests__/linked_branch_readiness_repository.test.ts) · [`src/application/usecases/__tests__/read_copilot_status_workflow.test.ts`](../src/application/usecases/__tests__/read_copilot_status_workflow.test.ts) · [`src/infrastructure/composition/__tests__/main_run_route_composition_root.test.ts`](../src/infrastructure/composition/__tests__/main_run_route_composition_root.test.ts) · [`src/infrastructure/composition/__tests__/sdd_evidence_composition_root.test.ts`](../src/infrastructure/composition/__tests__/sdd_evidence_composition_root.test.ts) · [`src/domain/__tests__/pre_branch_sdd_diff.test.ts`](../src/domain/__tests__/pre_branch_sdd_diff.test.ts) · [`src/application/policies/__tests__/sdd_diff_presentation_policy.test.ts`](../src/application/policies/__tests__/sdd_diff_presentation_policy.test.ts) · [`src/application/usecases/sdd/__tests__/sdd_diff_query_use_case.test.ts`](../src/application/usecases/sdd/__tests__/sdd_diff_query_use_case.test.ts) · [`src/data/repository/sdd/__tests__/sdd_diff_link_repository.test.ts`](../src/data/repository/sdd/__tests__/sdd_diff_link_repository.test.ts) · [`src/infrastructure/composition/__tests__/sdd_diff_composition_root.test.ts`](../src/infrastructure/composition/__tests__/sdd_diff_composition_root.test.ts) · [`src/application/usecases/__tests__/sdd_diff_comment_interaction.test.ts`](../src/application/usecases/__tests__/sdd_diff_comment_interaction.test.ts) · [`src/application/usecases/steps/common/__tests__/sdd_diff_reply_publication.test.ts`](../src/application/usecases/steps/common/__tests__/sdd_diff_reply_publication.test.ts) · [`src/application/usecases/__tests__/sdd_status_workflow_integration.test.ts`](../src/application/usecases/__tests__/sdd_status_workflow_integration.test.ts) · [`src/tooling/__tests__/portable_specification_catalog.test.ts`](../src/tooling/__tests__/portable_specification_catalog.test.ts) · [`src/application/policies/__tests__/github_runtime_doctor_policy.test.ts`](../src/application/policies/__tests__/github_runtime_doctor_policy.test.ts) · [`src/infrastructure/__tests__/setup_sdd_prerequisites.test.ts`](../src/infrastructure/__tests__/setup_sdd_prerequisites.test.ts) · [`src/application/usecases/setup/__tests__/doctor_use_case.test.ts`](../src/application/usecases/setup/__tests__/doctor_use_case.test.ts) · [`src/infrastructure/__tests__/branch_sync_sdd_catalog.test.ts`](../src/infrastructure/__tests__/branch_sync_sdd_catalog.test.ts) · [`src/cli/__tests__/setup_presenters.test.ts`](../src/cli/__tests__/setup_presenters.test.ts) · [`src/domain/__tests__/sdd_draft_consistency.test.ts`](../src/domain/__tests__/sdd_draft_consistency.test.ts) - User documentation: [`docs/issues/branch-management.mdx`](../docs/issues/branch-management.mdx) · [`docs/issues/workflow-setup.mdx`](../docs/issues/workflow-setup.mdx) · [`docs/issues/comment-commands.mdx`](../docs/issues/comment-commands.mdx) · [`docs/development/specifications.mdx`](../docs/development/specifications.mdx) · [`docs/issues/pre-branch-sdds.mdx`](../docs/issues/pre-branch-sdds.mdx) · [`docs/issues/index.mdx`](../docs/issues/index.mdx) · [`docs/issues/labels-and-branch-types.mdx`](../docs/issues/labels-and-branch-types.mdx) · [`docs/issues/configuration.mdx`](../docs/issues/configuration.mdx) · [`docs/configuration.mdx`](../docs/configuration.mdx) · [`docs/single-actions/workflow-and-cli.mdx`](../docs/single-actions/workflow-and-cli.mdx) ### `managed-issue-lifecycle` — Managed issue and branch lifecycle @@ -180,23 +180,23 @@ debt or convert unknown historic intent into a design decision. ### `bugbot-analysis-and-autofix` — Bugbot analysis, finding publication, and autofix - Owner: Copilot maintainers -- Last verified: 2026-10-13 +- Last verified: 2026-10-21 - Specifications: [`specs/bugbot-analysis-publication-and-autofix.md`](./bugbot-analysis-publication-and-autofix.md) · [`specs/bugbot-context-selection-and-budgeting.md`](./bugbot-context-selection-and-budgeting.md) · [`specs/bugbot-exhaustive-partitioned-analysis.md`](./bugbot-exhaustive-partitioned-analysis.md) - Workflows: [`.github/workflows/copilot_commit.yml`](../.github/workflows/copilot_commit.yml) · [`.github/workflows/copilot_pull_request.yml`](../.github/workflows/copilot_pull_request.yml) · [`.github/workflows/copilot_pull_request_comment.yml`](../.github/workflows/copilot_pull_request_comment.yml) - Entrypoints: [`src/application/usecases/steps/commit/detect_potential_problems_use_case.ts`](../src/application/usecases/steps/commit/detect_potential_problems_use_case.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_autofix_use_case.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_autofix_use_case.ts) -- Core code: [`src/domain/bugbot/context.ts`](../src/domain/bugbot/context.ts) · [`src/domain/bugbot/finding.ts`](../src/domain/bugbot/finding.ts) · [`src/domain/bugbot/finding_identity.ts`](../src/domain/bugbot/finding_identity.ts) · [`src/domain/bugbot/review_configuration.ts`](../src/domain/bugbot/review_configuration.ts) · [`src/application/policies/bounded_concurrency_policy.ts`](../src/application/policies/bounded_concurrency_policy.ts) · [`src/application/policies/bugbot_resolution_eligibility_policy.ts`](../src/application/policies/bugbot_resolution_eligibility_policy.ts) · [`src/application/policies/bugbot_result_finding_state_projection_policy.ts`](../src/application/policies/bugbot_result_finding_state_projection_policy.ts) · [`src/application/policies/bugbot_telemetry_projection_policy.ts`](../src/application/policies/bugbot_telemetry_projection_policy.ts) · [`src/application/policies/bugbot_diff_partition_policy.ts`](../src/application/policies/bugbot_diff_partition_policy.ts) · [`src/application/policies/bugbot_partition_completion_policy.ts`](../src/application/policies/bugbot_partition_completion_policy.ts) · [`src/application/policies/action_summary_policy.ts`](../src/application/policies/action_summary_policy.ts) · [`src/application/policies/copilot_evidence_policy.ts`](../src/application/policies/copilot_evidence_policy.ts) · [`src/application/ports/bugbot_git_ports.ts`](../src/application/ports/bugbot_git_ports.ts) · [`src/application/ports/bugbot_reconciliation_ports.ts`](../src/application/ports/bugbot_reconciliation_ports.ts) · [`src/application/ports/bugbot_scm_ports.ts`](../src/application/ports/bugbot_scm_ports.ts) · [`src/application/usecases/steps/commit/bugbot/schema.ts`](../src/application/usecases/steps/commit/bugbot/schema.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_review_operation_context.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_review_operation_context.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_context_request.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_context_request.ts) · [`src/application/usecases/steps/commit/bugbot/prepare_bugbot_findings_policy.ts`](../src/application/usecases/steps/commit/bugbot/prepare_bugbot_findings_policy.ts) · [`src/application/usecases/steps/commit/bugbot/analyze_bugbot_revision_use_case.ts`](../src/application/usecases/steps/commit/bugbot/analyze_bugbot_revision_use_case.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_partition_aggregation.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_partition_aggregation.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_review_context.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_review_context.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_review_telemetry.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_review_telemetry.ts) · [`src/application/usecases/steps/commit/bugbot/build_bugbot_prompt.ts`](../src/application/usecases/steps/commit/bugbot/build_bugbot_prompt.ts) · [`src/application/usecases/steps/commit/bugbot/load_bugbot_context_use_case.ts`](../src/application/usecases/steps/commit/bugbot/load_bugbot_context_use_case.ts) · [`src/application/usecases/steps/commit/bugbot/query_bugbot_findings.ts`](../src/application/usecases/steps/commit/bugbot/query_bugbot_findings.ts) · [`src/prompts/bugbot.ts`](../src/prompts/bugbot.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_previous_findings_context.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_previous_findings_context.ts) · [`src/application/usecases/steps/commit/bugbot/publish_findings_use_case.ts`](../src/application/usecases/steps/commit/bugbot/publish_findings_use_case.ts) · [`src/application/usecases/steps/commit/workspace_mutation_guard.ts`](../src/application/usecases/steps/commit/workspace_mutation_guard.ts) · [`src/data/repository/issue/bugbot_issue_comment_query_repository.ts`](../src/data/repository/issue/bugbot_issue_comment_query_repository.ts) · [`src/infrastructure/bound_bugbot_git_mutation_adapter.ts`](../src/infrastructure/bound_bugbot_git_mutation_adapter.ts) · [`src/infrastructure/composition/bugbot_scm_port_factory.ts`](../src/infrastructure/composition/bugbot_scm_port_factory.ts) · [`src/infrastructure/composition/bugbot_composition_root.ts`](../src/infrastructure/composition/bugbot_composition_root.ts) · [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`scripts/validate-coverage-budgets.cjs`](../scripts/validate-coverage-budgets.cjs) · [`src/application/usecases/comment_automation_action_workflow.ts`](../src/application/usecases/comment_automation_action_workflow.ts) · [`src/data/repository/pull_request/pull_request_lifecycle_repository.ts`](../src/data/repository/pull_request/pull_request_lifecycle_repository.ts) · [`src/application/usecases/comment_automation_command_workflow.ts`](../src/application/usecases/comment_automation_command_workflow.ts) · [`src/domain/copilot_command.ts`](../src/domain/copilot_command.ts) · [`src/application/usecases/comment_automation_contracts.ts`](../src/application/usecases/comment_automation_contracts.ts) · [`src/application/usecases/issue_comment_use_case.ts`](../src/application/usecases/issue_comment_use_case.ts) · [`src/application/usecases/pull_request_review_comment_use_case.ts`](../src/application/usecases/pull_request_review_comment_use_case.ts) · [`src/infrastructure/composition/main_run_route_composition_root.ts`](../src/infrastructure/composition/main_run_route_composition_root.ts) · [`src/infrastructure/github/ports/github_pull_request_provider_ports.ts`](../src/infrastructure/github/ports/github_pull_request_provider_ports.ts) · [`src/application/usecases/steps/commit/bugbot/dismiss_bugbot_findings_use_case.ts`](../src/application/usecases/steps/commit/bugbot/dismiss_bugbot_findings_use_case.ts) · [`src/application/policies/semantic_result_publication_policy.ts`](../src/application/policies/semantic_result_publication_policy.ts) · [`src/application/policies/publication_message_catalog.ts`](../src/application/policies/publication_message_catalog.ts) · [`src/application/usecases/steps/commit/bugbot/detect_bugbot_fix_intent_workflow.ts`](../src/application/usecases/steps/commit/bugbot/detect_bugbot_fix_intent_workflow.ts) · [`src/application/usecases/comment_automation_use_case.ts`](../src/application/usecases/comment_automation_use_case.ts) · [`src/infrastructure/filesystem/workspace_bugbot_rules_repository.ts`](../src/infrastructure/filesystem/workspace_bugbot_rules_repository.ts) · [`src/application/usecases/steps/commit/git_branch_checkout.ts`](../src/application/usecases/steps/commit/git_branch_checkout.ts) · [`src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts`](../src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts) · [`src/application/usecases/steps/commit/bugbot/commit_and_push_workflow.ts`](../src/application/usecases/steps/commit/bugbot/commit_and_push_workflow.ts) -- Tests: [`src/application/usecases/steps/commit/__tests__/bugbot_review_lifecycle.e2e.test.ts`](../src/application/usecases/steps/commit/__tests__/bugbot_review_lifecycle.e2e.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/bugbot_review_operation_context.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/bugbot_review_operation_context.test.ts) · [`src/application/policies/__tests__/bugbot_partition_completion_policy.test.ts`](../src/application/policies/__tests__/bugbot_partition_completion_policy.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/analyze_bugbot_revision_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/analyze_bugbot_revision_use_case.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/bugbot_partition_aggregation.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/bugbot_partition_aggregation.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/bugbot_context_request.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/bugbot_context_request.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/load_bugbot_context_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/load_bugbot_context_use_case.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/schema.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/schema.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/prepare_bugbot_findings.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/prepare_bugbot_findings.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/bugbot_review_context.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/bugbot_review_context.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/query_bugbot_findings.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/query_bugbot_findings.test.ts) · [`src/domain/bugbot/__tests__/context.test.ts`](../src/domain/bugbot/__tests__/context.test.ts) · [`src/data/repository/issue/__tests__/bugbot_issue_comment_query_repository.test.ts`](../src/data/repository/issue/__tests__/bugbot_issue_comment_query_repository.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/publish_findings_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/publish_findings_use_case.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/bugbot_autofix_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/bugbot_autofix_use_case.test.ts) · [`src/application/ports/__tests__/bugbot_port_boundaries.test.ts`](../src/application/ports/__tests__/bugbot_port_boundaries.test.ts) · [`src/infrastructure/composition/__tests__/bugbot_scm_port_factory.test.ts`](../src/infrastructure/composition/__tests__/bugbot_scm_port_factory.test.ts) · [`src/__tests__/api.test.ts`](../src/__tests__/api.test.ts) · [`src/domain/bugbot/__tests__/finding_identity.test.ts`](../src/domain/bugbot/__tests__/finding_identity.test.ts) · [`src/application/policies/__tests__/bugbot_result_finding_state_projection_policy.test.ts`](../src/application/policies/__tests__/bugbot_result_finding_state_projection_policy.test.ts) · [`src/application/policies/__tests__/bugbot_telemetry_projection_policy.test.ts`](../src/application/policies/__tests__/bugbot_telemetry_projection_policy.test.ts) · [`src/application/policies/__tests__/action_summary_policy.test.ts`](../src/application/policies/__tests__/action_summary_policy.test.ts) · [`src/application/policies/__tests__/copilot_evidence_policy.test.ts`](../src/application/policies/__tests__/copilot_evidence_policy.test.ts) · [`src/actions/__tests__/github_action_completion.test.ts`](../src/actions/__tests__/github_action_completion.test.ts) · [`src/tooling/__tests__/validate_workflow_contract.test.ts`](../src/tooling/__tests__/validate_workflow_contract.test.ts) · [`src/application/usecases/__tests__/comment_automation_action_workflow.test.ts`](../src/application/usecases/__tests__/comment_automation_action_workflow.test.ts) · [`src/data/repository/__tests__/pull_request_lifecycle_repository.test.ts`](../src/data/repository/__tests__/pull_request_lifecycle_repository.test.ts) · [`src/application/usecases/steps/commit/__tests__/detect_potential_problems_use_case.test.ts`](../src/application/usecases/steps/commit/__tests__/detect_potential_problems_use_case.test.ts) · [`src/application/usecases/__tests__/comment_automation_use_case.test.ts`](../src/application/usecases/__tests__/comment_automation_use_case.test.ts) · [`src/domain/__tests__/copilot_command.test.ts`](../src/domain/__tests__/copilot_command.test.ts) · [`src/infrastructure/composition/__tests__/main_run_route_composition_root.test.ts`](../src/infrastructure/composition/__tests__/main_run_route_composition_root.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/dismiss_bugbot_findings_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/dismiss_bugbot_findings_use_case.test.ts) · [`src/application/policies/__tests__/semantic_result_publication_policy.test.ts`](../src/application/policies/__tests__/semantic_result_publication_policy.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/detect_bugbot_fix_intent_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/detect_bugbot_fix_intent_use_case.test.ts) · [`src/infrastructure/filesystem/__tests__/workspace_bugbot_rules_repository.test.ts`](../src/infrastructure/filesystem/__tests__/workspace_bugbot_rules_repository.test.ts) · [`src/application/usecases/steps/commit/__tests__/git_branch_checkout.integration.test.ts`](../src/application/usecases/steps/commit/__tests__/git_branch_checkout.integration.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/workspace_changes.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/workspace_changes.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts) · [`src/application/usecases/__tests__/autofix_conversation_branch_authority.test.ts`](../src/application/usecases/__tests__/autofix_conversation_branch_authority.test.ts) +- Core code: [`src/domain/bugbot/context.ts`](../src/domain/bugbot/context.ts) · [`src/domain/bugbot/finding.ts`](../src/domain/bugbot/finding.ts) · [`src/domain/bugbot/finding_identity.ts`](../src/domain/bugbot/finding_identity.ts) · [`src/domain/bugbot/review_configuration.ts`](../src/domain/bugbot/review_configuration.ts) · [`src/application/policies/bounded_concurrency_policy.ts`](../src/application/policies/bounded_concurrency_policy.ts) · [`src/application/policies/bugbot_resolution_eligibility_policy.ts`](../src/application/policies/bugbot_resolution_eligibility_policy.ts) · [`src/application/policies/bugbot_result_finding_state_projection_policy.ts`](../src/application/policies/bugbot_result_finding_state_projection_policy.ts) · [`src/application/policies/bugbot_telemetry_projection_policy.ts`](../src/application/policies/bugbot_telemetry_projection_policy.ts) · [`src/application/policies/bugbot_diff_partition_policy.ts`](../src/application/policies/bugbot_diff_partition_policy.ts) · [`src/application/policies/bugbot_partition_completion_policy.ts`](../src/application/policies/bugbot_partition_completion_policy.ts) · [`src/application/policies/action_summary_policy.ts`](../src/application/policies/action_summary_policy.ts) · [`src/application/policies/copilot_evidence_policy.ts`](../src/application/policies/copilot_evidence_policy.ts) · [`src/application/ports/bugbot_git_ports.ts`](../src/application/ports/bugbot_git_ports.ts) · [`src/application/ports/bugbot_reconciliation_ports.ts`](../src/application/ports/bugbot_reconciliation_ports.ts) · [`src/application/ports/bugbot_scm_ports.ts`](../src/application/ports/bugbot_scm_ports.ts) · [`src/application/usecases/steps/commit/bugbot/schema.ts`](../src/application/usecases/steps/commit/bugbot/schema.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_review_operation_context.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_review_operation_context.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_context_request.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_context_request.ts) · [`src/application/usecases/steps/commit/bugbot/prepare_bugbot_findings_policy.ts`](../src/application/usecases/steps/commit/bugbot/prepare_bugbot_findings_policy.ts) · [`src/application/usecases/steps/commit/bugbot/analyze_bugbot_revision_use_case.ts`](../src/application/usecases/steps/commit/bugbot/analyze_bugbot_revision_use_case.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_partition_aggregation.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_partition_aggregation.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_review_context.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_review_context.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_review_telemetry.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_review_telemetry.ts) · [`src/application/usecases/steps/commit/bugbot/build_bugbot_prompt.ts`](../src/application/usecases/steps/commit/bugbot/build_bugbot_prompt.ts) · [`src/application/usecases/steps/commit/bugbot/load_bugbot_context_use_case.ts`](../src/application/usecases/steps/commit/bugbot/load_bugbot_context_use_case.ts) · [`src/application/usecases/steps/commit/bugbot/query_bugbot_findings.ts`](../src/application/usecases/steps/commit/bugbot/query_bugbot_findings.ts) · [`src/prompts/bugbot.ts`](../src/prompts/bugbot.ts) · [`src/application/usecases/steps/commit/bugbot/bugbot_previous_findings_context.ts`](../src/application/usecases/steps/commit/bugbot/bugbot_previous_findings_context.ts) · [`src/application/usecases/steps/commit/bugbot/publish_findings_use_case.ts`](../src/application/usecases/steps/commit/bugbot/publish_findings_use_case.ts) · [`src/application/usecases/steps/commit/workspace_mutation_guard.ts`](../src/application/usecases/steps/commit/workspace_mutation_guard.ts) · [`src/data/repository/issue/bugbot_issue_comment_query_repository.ts`](../src/data/repository/issue/bugbot_issue_comment_query_repository.ts) · [`src/infrastructure/bound_bugbot_git_mutation_adapter.ts`](../src/infrastructure/bound_bugbot_git_mutation_adapter.ts) · [`src/infrastructure/composition/bugbot_scm_port_factory.ts`](../src/infrastructure/composition/bugbot_scm_port_factory.ts) · [`src/infrastructure/composition/bugbot_composition_root.ts`](../src/infrastructure/composition/bugbot_composition_root.ts) · [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`scripts/validate-coverage-budgets.cjs`](../scripts/validate-coverage-budgets.cjs) · [`src/application/usecases/comment_automation_action_workflow.ts`](../src/application/usecases/comment_automation_action_workflow.ts) · [`src/data/repository/pull_request/pull_request_lifecycle_repository.ts`](../src/data/repository/pull_request/pull_request_lifecycle_repository.ts) · [`src/application/usecases/comment_automation_command_workflow.ts`](../src/application/usecases/comment_automation_command_workflow.ts) · [`src/domain/copilot_command.ts`](../src/domain/copilot_command.ts) · [`src/application/usecases/comment_automation_contracts.ts`](../src/application/usecases/comment_automation_contracts.ts) · [`src/application/usecases/issue_comment_use_case.ts`](../src/application/usecases/issue_comment_use_case.ts) · [`src/application/usecases/pull_request_review_comment_use_case.ts`](../src/application/usecases/pull_request_review_comment_use_case.ts) · [`src/infrastructure/composition/main_run_route_composition_root.ts`](../src/infrastructure/composition/main_run_route_composition_root.ts) · [`src/infrastructure/github/ports/github_pull_request_provider_ports.ts`](../src/infrastructure/github/ports/github_pull_request_provider_ports.ts) · [`src/application/usecases/steps/commit/bugbot/dismiss_bugbot_findings_use_case.ts`](../src/application/usecases/steps/commit/bugbot/dismiss_bugbot_findings_use_case.ts) · [`src/application/policies/semantic_result_publication_policy.ts`](../src/application/policies/semantic_result_publication_policy.ts) · [`src/application/policies/publication_message_catalog.ts`](../src/application/policies/publication_message_catalog.ts) · [`src/application/usecases/steps/commit/bugbot/detect_bugbot_fix_intent_workflow.ts`](../src/application/usecases/steps/commit/bugbot/detect_bugbot_fix_intent_workflow.ts) · [`src/application/usecases/comment_automation_use_case.ts`](../src/application/usecases/comment_automation_use_case.ts) · [`src/infrastructure/filesystem/workspace_bugbot_rules_repository.ts`](../src/infrastructure/filesystem/workspace_bugbot_rules_repository.ts) · [`src/application/usecases/steps/commit/git_branch_checkout.ts`](../src/application/usecases/steps/commit/git_branch_checkout.ts) · [`src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts`](../src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts) · [`src/application/usecases/steps/commit/bugbot/commit_and_push_workflow.ts`](../src/application/usecases/steps/commit/bugbot/commit_and_push_workflow.ts) · [`quality/bugbot/corpus.v1.json`](../quality/bugbot/corpus.v1.json) · [`quality/bugbot/reference-predictions.v1.json`](../quality/bugbot/reference-predictions.v1.json) · [`src/tooling/bugbot_benchmark_runner.ts`](../src/tooling/bugbot_benchmark_runner.ts) +- Tests: [`src/application/usecases/steps/commit/__tests__/bugbot_review_lifecycle.e2e.test.ts`](../src/application/usecases/steps/commit/__tests__/bugbot_review_lifecycle.e2e.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/bugbot_review_operation_context.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/bugbot_review_operation_context.test.ts) · [`src/application/policies/__tests__/bugbot_partition_completion_policy.test.ts`](../src/application/policies/__tests__/bugbot_partition_completion_policy.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/analyze_bugbot_revision_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/analyze_bugbot_revision_use_case.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/bugbot_partition_aggregation.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/bugbot_partition_aggregation.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/bugbot_context_request.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/bugbot_context_request.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/load_bugbot_context_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/load_bugbot_context_use_case.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/schema.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/schema.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/prepare_bugbot_findings.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/prepare_bugbot_findings.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/bugbot_review_context.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/bugbot_review_context.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/query_bugbot_findings.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/query_bugbot_findings.test.ts) · [`src/domain/bugbot/__tests__/context.test.ts`](../src/domain/bugbot/__tests__/context.test.ts) · [`src/data/repository/issue/__tests__/bugbot_issue_comment_query_repository.test.ts`](../src/data/repository/issue/__tests__/bugbot_issue_comment_query_repository.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/publish_findings_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/publish_findings_use_case.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/bugbot_autofix_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/bugbot_autofix_use_case.test.ts) · [`src/application/ports/__tests__/bugbot_port_boundaries.test.ts`](../src/application/ports/__tests__/bugbot_port_boundaries.test.ts) · [`src/infrastructure/composition/__tests__/bugbot_scm_port_factory.test.ts`](../src/infrastructure/composition/__tests__/bugbot_scm_port_factory.test.ts) · [`src/__tests__/api.test.ts`](../src/__tests__/api.test.ts) · [`src/domain/bugbot/__tests__/finding_identity.test.ts`](../src/domain/bugbot/__tests__/finding_identity.test.ts) · [`src/application/policies/__tests__/bugbot_result_finding_state_projection_policy.test.ts`](../src/application/policies/__tests__/bugbot_result_finding_state_projection_policy.test.ts) · [`src/application/policies/__tests__/bugbot_telemetry_projection_policy.test.ts`](../src/application/policies/__tests__/bugbot_telemetry_projection_policy.test.ts) · [`src/application/policies/__tests__/action_summary_policy.test.ts`](../src/application/policies/__tests__/action_summary_policy.test.ts) · [`src/application/policies/__tests__/copilot_evidence_policy.test.ts`](../src/application/policies/__tests__/copilot_evidence_policy.test.ts) · [`src/actions/__tests__/github_action_completion.test.ts`](../src/actions/__tests__/github_action_completion.test.ts) · [`src/tooling/__tests__/validate_workflow_contract.test.ts`](../src/tooling/__tests__/validate_workflow_contract.test.ts) · [`src/application/usecases/__tests__/comment_automation_action_workflow.test.ts`](../src/application/usecases/__tests__/comment_automation_action_workflow.test.ts) · [`src/data/repository/__tests__/pull_request_lifecycle_repository.test.ts`](../src/data/repository/__tests__/pull_request_lifecycle_repository.test.ts) · [`src/application/usecases/steps/commit/__tests__/detect_potential_problems_use_case.test.ts`](../src/application/usecases/steps/commit/__tests__/detect_potential_problems_use_case.test.ts) · [`src/application/usecases/__tests__/comment_automation_use_case.test.ts`](../src/application/usecases/__tests__/comment_automation_use_case.test.ts) · [`src/domain/__tests__/copilot_command.test.ts`](../src/domain/__tests__/copilot_command.test.ts) · [`src/infrastructure/composition/__tests__/main_run_route_composition_root.test.ts`](../src/infrastructure/composition/__tests__/main_run_route_composition_root.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/dismiss_bugbot_findings_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/dismiss_bugbot_findings_use_case.test.ts) · [`src/application/policies/__tests__/semantic_result_publication_policy.test.ts`](../src/application/policies/__tests__/semantic_result_publication_policy.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/detect_bugbot_fix_intent_use_case.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/detect_bugbot_fix_intent_use_case.test.ts) · [`src/infrastructure/filesystem/__tests__/workspace_bugbot_rules_repository.test.ts`](../src/infrastructure/filesystem/__tests__/workspace_bugbot_rules_repository.test.ts) · [`src/application/usecases/steps/commit/__tests__/git_branch_checkout.integration.test.ts`](../src/application/usecases/steps/commit/__tests__/git_branch_checkout.integration.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/workspace_changes.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/workspace_changes.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts) · [`src/application/usecases/__tests__/autofix_conversation_branch_authority.test.ts`](../src/application/usecases/__tests__/autofix_conversation_branch_authority.test.ts) · [`src/tooling/__tests__/bugbot_benchmark.test.ts`](../src/tooling/__tests__/bugbot_benchmark.test.ts) · [`src/tooling/__tests__/bugbot_benchmark_runner.test.ts`](../src/tooling/__tests__/bugbot_benchmark_runner.test.ts) · [`src/prompts/__tests__/bugbot.test.ts`](../src/prompts/__tests__/bugbot.test.ts) - User documentation: [`docs/bugbot/how-it-works.mdx`](../docs/bugbot/how-it-works.mdx) · [`docs/bugbot/detection.mdx`](../docs/bugbot/detection.mdx) · [`docs/bugbot/finding-publication.mdx`](../docs/bugbot/finding-publication.mdx) · [`docs/bugbot/autofix.mdx`](../docs/bugbot/autofix.mdx) · [`docs/bugbot/failure-scenarios.mdx`](../docs/bugbot/failure-scenarios.mdx) · [`docs/bugbot/quality-observability.mdx`](../docs/bugbot/quality-observability.mdx) · [`docs/bugbot/permissions.mdx`](../docs/bugbot/permissions.mdx) · [`docs/bugbot/programmatic-api.mdx`](../docs/bugbot/programmatic-api.mdx) · [`docs/bugbot/configuration.mdx`](../docs/bugbot/configuration.mdx) · [`docs/pull-requests/workflow-setup.mdx`](../docs/pull-requests/workflow-setup.mdx) · [`docs/issues/comment-commands.mdx`](../docs/issues/comment-commands.mdx) ### `branch-synchronization` — Branch synchronization and conflict recovery - Owner: Copilot maintainers -- Last verified: 2026-10-20 -- Specifications: [`specs/branch-synchronization-and-conflict-recovery.md`](./branch-synchronization-and-conflict-recovery.md) · [`specs/repository-verification-runtime-prerequisites.md`](./repository-verification-runtime-prerequisites.md) -- Workflows: [`.github/workflows/copilot_branch_sync.yml`](../.github/workflows/copilot_branch_sync.yml) · [`setup/workflows/copilot_branch_sync.yml`](../setup/workflows/copilot_branch_sync.yml) · [`.github/workflows/copilot_issue.yml`](../.github/workflows/copilot_issue.yml) · [`setup/workflows/copilot_issue.yml`](../setup/workflows/copilot_issue.yml) · [`setup/workflows/copilot_issue_comment.yml`](../setup/workflows/copilot_issue_comment.yml) · [`setup/workflows/copilot_pull_request_comment.yml`](../setup/workflows/copilot_pull_request_comment.yml) +- Last verified: 2026-10-22 +- Specifications: [`specs/branch-synchronization-and-conflict-recovery.md`](./branch-synchronization-and-conflict-recovery.md) · [`specs/repository-verification-runtime-prerequisites.md`](./repository-verification-runtime-prerequisites.md) · [`specs/repository-verification-setup-hooks.md`](./repository-verification-setup-hooks.md) +- Workflows: [`.github/workflows/copilot_branch_sync.yml`](../.github/workflows/copilot_branch_sync.yml) · [`setup/workflows/copilot_branch_sync.yml`](../setup/workflows/copilot_branch_sync.yml) · [`.github/workflows/copilot_issue.yml`](../.github/workflows/copilot_issue.yml) · [`setup/workflows/copilot_issue.yml`](../setup/workflows/copilot_issue.yml) · [`setup/workflows/copilot_issue_comment.yml`](../setup/workflows/copilot_issue_comment.yml) · [`setup/workflows/copilot_pull_request_comment.yml`](../setup/workflows/copilot_pull_request_comment.yml) · [`.github/workflows/copilot_comment_runtime.yml`](../.github/workflows/copilot_comment_runtime.yml) · [`.github/workflows/copilot_issue_comment.yml`](../.github/workflows/copilot_issue_comment.yml) · [`.github/workflows/copilot_pull_request_comment.yml`](../.github/workflows/copilot_pull_request_comment.yml) - Entrypoints: [`src/application/usecases/branch_sync/sync_branch_use_case.ts`](../src/application/usecases/branch_sync/sync_branch_use_case.ts) · [`src/application/usecases/actions/observe_branch_sync_use_case.ts`](../src/application/usecases/actions/observe_branch_sync_use_case.ts) -- Core code: [`src/domain/branch_sync_command.ts`](../src/domain/branch_sync_command.ts) · [`src/application/ports/branch_sync_ports.ts`](../src/application/ports/branch_sync_ports.ts) · [`src/application/policies/branch_sync_message_catalog.ts`](../src/application/policies/branch_sync_message_catalog.ts) · [`src/application/policies/branch_sync_notification_policy.ts`](../src/application/policies/branch_sync_notification_policy.ts) · [`src/application/usecases/branch_sync/branch_sync_execution_policy.ts`](../src/application/usecases/branch_sync/branch_sync_execution_policy.ts) · [`src/application/usecases/actions/observe_branch_sync_use_case.ts`](../src/application/usecases/actions/observe_branch_sync_use_case.ts) · [`src/application/usecases/push_single_action_contexts.ts`](../src/application/usecases/push_single_action_contexts.ts) · [`src/application/usecases/steps/common/transition_notification_workflow.ts`](../src/application/usecases/steps/common/transition_notification_workflow.ts) · [`src/data/repository/branch_sync/branch_dependency_policy.ts`](../src/data/repository/branch_sync/branch_dependency_policy.ts) · [`src/data/repository/branch_sync/branch_dependency_repository.ts`](../src/data/repository/branch_sync/branch_dependency_repository.ts) · [`src/infrastructure/composition/main_run_route_composition_root.ts`](../src/infrastructure/composition/main_run_route_composition_root.ts) · [`src/infrastructure/composition/push_single_action_capability_port_binding.ts`](../src/infrastructure/composition/push_single_action_capability_port_binding.ts) · [`src/infrastructure/branch_sync_workspace_adapter.ts`](../src/infrastructure/branch_sync_workspace_adapter.ts) · [`src/prompts/branch_sync_conflicts.ts`](../src/prompts/branch_sync_conflicts.ts) · [`src/data/model/application_error.ts`](../src/data/model/application_error.ts) · [`src/application/policies/application_error_message_catalog.ts`](../src/application/policies/application_error_message_catalog.ts) · [`src/infrastructure/git_commit_adapter.ts`](../src/infrastructure/git_commit_adapter.ts) · [`src/infrastructure/branch_sync_sdd_catalog.ts`](../src/infrastructure/branch_sync_sdd_catalog.ts) · [`src/domain/branch_sync_validation.ts`](../src/domain/branch_sync_validation.ts) · [`src/application/policies/lifecycle_state_policy.ts`](../src/application/policies/lifecycle_state_policy.ts) · [`src/infrastructure/branch_sync_communication_budget.ts`](../src/infrastructure/branch_sync_communication_budget.ts) · [`src/application/usecases/actions/retire_branch_sync_use_case.ts`](../src/application/usecases/actions/retire_branch_sync_use_case.ts) · [`src/application/ports/issue_completion_ports.ts`](../src/application/ports/issue_completion_ports.ts) · [`src/application/usecases/pull_request_workflow.ts`](../src/application/usecases/pull_request_workflow.ts) · [`src/application/usecases/pull_request_workflow_context.ts`](../src/application/usecases/pull_request_workflow_context.ts) · [`src/infrastructure/composition/pull_request_use_case_composition_root.ts`](../src/infrastructure/composition/pull_request_use_case_composition_root.ts) · [`src/actions/common_action.ts`](../src/actions/common_action.ts) · [`src/actions/github_action.ts`](../src/actions/github_action.ts) · [`scripts/validate-workflow-contract.cjs`](../scripts/validate-workflow-contract.cjs) · [`src/application/ports/reply_request_read_ports.ts`](../src/application/ports/reply_request_read_ports.ts) · [`src/domain/reply_request_digest.ts`](../src/domain/reply_request_digest.ts) · [`src/infrastructure/composition/reply_request_composition_root.ts`](../src/infrastructure/composition/reply_request_composition_root.ts) · [`src/data/repository/reply_request_repository.ts`](../src/data/repository/reply_request_repository.ts) · [`src/application/policies/verification_runtime_policy.ts`](../src/application/policies/verification_runtime_policy.ts) · [`src/infrastructure/verification_runtime_manifest.ts`](../src/infrastructure/verification_runtime_manifest.ts) · [`src/infrastructure/verification_runtime_preflight.ts`](../src/infrastructure/verification_runtime_preflight.ts) · [`src/infrastructure/untrusted_command_environment.ts`](../src/infrastructure/untrusted_command_environment.ts) · [`src/application/ports/git_ports.ts`](../src/application/ports/git_ports.ts) · [`src/application/ports/bugbot_git_ports.ts`](../src/application/ports/bugbot_git_ports.ts) · [`src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts`](../src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts) · [`src/application/usecases/steps/commit/bugbot/verify_command_runner.ts`](../src/application/usecases/steps/commit/bugbot/verify_command_runner.ts) · [`src/domain/closed_issue_reconciliation.ts`](../src/domain/closed_issue_reconciliation.ts) · [`src/application/errors/closed_issue_reconciliation_error.ts`](../src/application/errors/closed_issue_reconciliation_error.ts) -- Tests: [`src/application/policies/__tests__/branch_sync_notification_policy.test.ts`](../src/application/policies/__tests__/branch_sync_notification_policy.test.ts) · [`src/application/usecases/actions/__tests__/observe_branch_sync_use_case.test.ts`](../src/application/usecases/actions/__tests__/observe_branch_sync_use_case.test.ts) · [`src/application/usecases/branch_sync/__tests__/sync_branch_use_case.test.ts`](../src/application/usecases/branch_sync/__tests__/sync_branch_use_case.test.ts) · [`src/application/usecases/__tests__/push_single_action_contexts.test.ts`](../src/application/usecases/__tests__/push_single_action_contexts.test.ts) · [`src/application/usecases/steps/common/__tests__/transition_notification_workflow.test.ts`](../src/application/usecases/steps/common/__tests__/transition_notification_workflow.test.ts) · [`src/data/repository/branch_sync/__tests__/branch_dependency_policy.test.ts`](../src/data/repository/branch_sync/__tests__/branch_dependency_policy.test.ts) · [`src/data/repository/branch_sync/__tests__/branch_dependency_repository.test.ts`](../src/data/repository/branch_sync/__tests__/branch_dependency_repository.test.ts) · [`src/infrastructure/__tests__/branch_sync_workspace_adapter.test.ts`](../src/infrastructure/__tests__/branch_sync_workspace_adapter.test.ts) · [`src/infrastructure/composition/__tests__/push_single_action_capability_port_binding.test.ts`](../src/infrastructure/composition/__tests__/push_single_action_capability_port_binding.test.ts) · [`src/application/usecases/branch_sync/__tests__/branch_sync_execution_policy.test.ts`](../src/application/usecases/branch_sync/__tests__/branch_sync_execution_policy.test.ts) · [`src/application/errors/__tests__/application_error.test.ts`](../src/application/errors/__tests__/application_error.test.ts) · [`src/application/policies/__tests__/application_error_presentation_policy.test.ts`](../src/application/policies/__tests__/application_error_presentation_policy.test.ts) · [`src/infrastructure/__tests__/git_commit_adapter.test.ts`](../src/infrastructure/__tests__/git_commit_adapter.test.ts) · [`src/infrastructure/__tests__/branch_sync_sdd_catalog.test.ts`](../src/infrastructure/__tests__/branch_sync_sdd_catalog.test.ts) · [`src/infrastructure/__tests__/branch_sync_generated_bundle_validation.test.ts`](../src/infrastructure/__tests__/branch_sync_generated_bundle_validation.test.ts) · [`src/application/policies/__tests__/branch_sync_lifecycle_recovery.test.ts`](../src/application/policies/__tests__/branch_sync_lifecycle_recovery.test.ts) · [`src/infrastructure/__tests__/branch_sync_resolved_workspace.test.ts`](../src/infrastructure/__tests__/branch_sync_resolved_workspace.test.ts) · [`src/infrastructure/__tests__/branch_sync_communication_budget.test.ts`](../src/infrastructure/__tests__/branch_sync_communication_budget.test.ts) · [`src/application/usecases/actions/__tests__/retire_branch_sync_use_case.test.ts`](../src/application/usecases/actions/__tests__/retire_branch_sync_use_case.test.ts) · [`src/application/usecases/__tests__/pull_request_use_case.test.ts`](../src/application/usecases/__tests__/pull_request_use_case.test.ts) · [`src/actions/__tests__/common_action.test.ts`](../src/actions/__tests__/common_action.test.ts) · [`src/actions/__tests__/github_action.test.ts`](../src/actions/__tests__/github_action.test.ts) · [`src/tooling/__tests__/validate_workflow_contract.test.ts`](../src/tooling/__tests__/validate_workflow_contract.test.ts) · [`src/data/repository/__tests__/reply_request_repository.test.ts`](../src/data/repository/__tests__/reply_request_repository.test.ts) · [`src/infrastructure/composition/__tests__/reply_request_composition_root.test.ts`](../src/infrastructure/composition/__tests__/reply_request_composition_root.test.ts) · [`src/application/policies/__tests__/verification_runtime_policy.test.ts`](../src/application/policies/__tests__/verification_runtime_policy.test.ts) · [`src/infrastructure/__tests__/verification_runtime_preflight.test.ts`](../src/infrastructure/__tests__/verification_runtime_preflight.test.ts) · [`src/infrastructure/__tests__/verification_runtime_branch_sync.test.ts`](../src/infrastructure/__tests__/verification_runtime_branch_sync.test.ts) · [`src/infrastructure/__tests__/untrusted_command_environment.test.ts`](../src/infrastructure/__tests__/untrusted_command_environment.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/verify_command_runner.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/verify_command_runner.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts) · [`src/tooling/__tests__/verification_runtime_guidance.test.ts`](../src/tooling/__tests__/verification_runtime_guidance.test.ts) +- Core code: [`src/domain/branch_sync_command.ts`](../src/domain/branch_sync_command.ts) · [`src/application/ports/branch_sync_ports.ts`](../src/application/ports/branch_sync_ports.ts) · [`src/application/policies/branch_sync_message_catalog.ts`](../src/application/policies/branch_sync_message_catalog.ts) · [`src/application/policies/branch_sync_notification_policy.ts`](../src/application/policies/branch_sync_notification_policy.ts) · [`src/application/usecases/branch_sync/branch_sync_execution_policy.ts`](../src/application/usecases/branch_sync/branch_sync_execution_policy.ts) · [`src/application/usecases/actions/observe_branch_sync_use_case.ts`](../src/application/usecases/actions/observe_branch_sync_use_case.ts) · [`src/application/usecases/push_single_action_contexts.ts`](../src/application/usecases/push_single_action_contexts.ts) · [`src/application/usecases/steps/common/transition_notification_workflow.ts`](../src/application/usecases/steps/common/transition_notification_workflow.ts) · [`src/data/repository/branch_sync/branch_dependency_policy.ts`](../src/data/repository/branch_sync/branch_dependency_policy.ts) · [`src/data/repository/branch_sync/branch_dependency_repository.ts`](../src/data/repository/branch_sync/branch_dependency_repository.ts) · [`src/infrastructure/composition/main_run_route_composition_root.ts`](../src/infrastructure/composition/main_run_route_composition_root.ts) · [`src/infrastructure/composition/push_single_action_capability_port_binding.ts`](../src/infrastructure/composition/push_single_action_capability_port_binding.ts) · [`src/infrastructure/branch_sync_workspace_adapter.ts`](../src/infrastructure/branch_sync_workspace_adapter.ts) · [`src/prompts/branch_sync_conflicts.ts`](../src/prompts/branch_sync_conflicts.ts) · [`src/data/model/application_error.ts`](../src/data/model/application_error.ts) · [`src/application/policies/application_error_message_catalog.ts`](../src/application/policies/application_error_message_catalog.ts) · [`src/infrastructure/git_commit_adapter.ts`](../src/infrastructure/git_commit_adapter.ts) · [`src/infrastructure/branch_sync_sdd_catalog.ts`](../src/infrastructure/branch_sync_sdd_catalog.ts) · [`src/domain/branch_sync_validation.ts`](../src/domain/branch_sync_validation.ts) · [`src/application/policies/lifecycle_state_policy.ts`](../src/application/policies/lifecycle_state_policy.ts) · [`src/infrastructure/branch_sync_communication_budget.ts`](../src/infrastructure/branch_sync_communication_budget.ts) · [`src/application/usecases/actions/retire_branch_sync_use_case.ts`](../src/application/usecases/actions/retire_branch_sync_use_case.ts) · [`src/application/ports/issue_completion_ports.ts`](../src/application/ports/issue_completion_ports.ts) · [`src/application/usecases/pull_request_workflow.ts`](../src/application/usecases/pull_request_workflow.ts) · [`src/application/usecases/pull_request_workflow_context.ts`](../src/application/usecases/pull_request_workflow_context.ts) · [`src/infrastructure/composition/pull_request_use_case_composition_root.ts`](../src/infrastructure/composition/pull_request_use_case_composition_root.ts) · [`src/actions/common_action.ts`](../src/actions/common_action.ts) · [`src/actions/github_action.ts`](../src/actions/github_action.ts) · [`scripts/validate-workflow-contract.cjs`](../scripts/validate-workflow-contract.cjs) · [`src/application/ports/reply_request_read_ports.ts`](../src/application/ports/reply_request_read_ports.ts) · [`src/domain/reply_request_digest.ts`](../src/domain/reply_request_digest.ts) · [`src/infrastructure/composition/reply_request_composition_root.ts`](../src/infrastructure/composition/reply_request_composition_root.ts) · [`src/data/repository/reply_request_repository.ts`](../src/data/repository/reply_request_repository.ts) · [`src/application/policies/verification_runtime_policy.ts`](../src/application/policies/verification_runtime_policy.ts) · [`src/infrastructure/verification_runtime_manifest.ts`](../src/infrastructure/verification_runtime_manifest.ts) · [`src/infrastructure/verification_runtime_preflight.ts`](../src/infrastructure/verification_runtime_preflight.ts) · [`src/infrastructure/untrusted_command_environment.ts`](../src/infrastructure/untrusted_command_environment.ts) · [`src/application/ports/git_ports.ts`](../src/application/ports/git_ports.ts) · [`src/application/ports/bugbot_git_ports.ts`](../src/application/ports/bugbot_git_ports.ts) · [`src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts`](../src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts) · [`src/application/usecases/steps/commit/bugbot/verify_command_runner.ts`](../src/application/usecases/steps/commit/bugbot/verify_command_runner.ts) · [`src/domain/closed_issue_reconciliation.ts`](../src/domain/closed_issue_reconciliation.ts) · [`src/application/errors/closed_issue_reconciliation_error.ts`](../src/application/errors/closed_issue_reconciliation_error.ts) · [`src/application/policies/verification_setup_policy.ts`](../src/application/policies/verification_setup_policy.ts) · [`src/application/ports/verification_setup_ports.ts`](../src/application/ports/verification_setup_ports.ts) · [`src/infrastructure/verification_setup_snapshot.ts`](../src/infrastructure/verification_setup_snapshot.ts) · [`src/infrastructure/verification_setup_result.ts`](../src/infrastructure/verification_setup_result.ts) · [`src/infrastructure/verification_setup_runner.ts`](../src/infrastructure/verification_setup_runner.ts) · [`src/infrastructure/native_verification_protocol.ts`](../src/infrastructure/native_verification_protocol.ts) · [`src/infrastructure/native_verification_candidate.ts`](../src/infrastructure/native_verification_candidate.ts) · [`src/infrastructure/native_verification_staging.ts`](../src/infrastructure/native_verification_staging.ts) · [`src/infrastructure/native_verification_controller.ts`](../src/infrastructure/native_verification_controller.ts) · [`src/infrastructure/native_verification_profiles.ts`](../src/infrastructure/native_verification_profiles.ts) · [`src/infrastructure/native_verification_redaction.ts`](../src/infrastructure/native_verification_redaction.ts) · [`scripts/generate-native-verification-workflows.cjs`](../scripts/generate-native-verification-workflows.cjs) · [`src/infrastructure/verification_executable.ts`](../src/infrastructure/verification_executable.ts) · [`src/infrastructure/native_verification_source_runtime.ts`](../src/infrastructure/native_verification_source_runtime.ts) · [`scripts/prepare-native-source-action.cjs`](../scripts/prepare-native-source-action.cjs) · [`src/domain/copilot_comment_workflow.ts`](../src/domain/copilot_comment_workflow.ts) · [`src/infrastructure/copilot_comment_inputs.json`](../src/infrastructure/copilot_comment_inputs.json) · [`scripts/validate-comment-workflows.cjs`](../scripts/validate-comment-workflows.cjs) +- Tests: [`src/application/policies/__tests__/branch_sync_notification_policy.test.ts`](../src/application/policies/__tests__/branch_sync_notification_policy.test.ts) · [`src/application/usecases/actions/__tests__/observe_branch_sync_use_case.test.ts`](../src/application/usecases/actions/__tests__/observe_branch_sync_use_case.test.ts) · [`src/application/usecases/branch_sync/__tests__/sync_branch_use_case.test.ts`](../src/application/usecases/branch_sync/__tests__/sync_branch_use_case.test.ts) · [`src/application/usecases/__tests__/push_single_action_contexts.test.ts`](../src/application/usecases/__tests__/push_single_action_contexts.test.ts) · [`src/application/usecases/steps/common/__tests__/transition_notification_workflow.test.ts`](../src/application/usecases/steps/common/__tests__/transition_notification_workflow.test.ts) · [`src/data/repository/branch_sync/__tests__/branch_dependency_policy.test.ts`](../src/data/repository/branch_sync/__tests__/branch_dependency_policy.test.ts) · [`src/data/repository/branch_sync/__tests__/branch_dependency_repository.test.ts`](../src/data/repository/branch_sync/__tests__/branch_dependency_repository.test.ts) · [`src/infrastructure/__tests__/branch_sync_workspace_adapter.test.ts`](../src/infrastructure/__tests__/branch_sync_workspace_adapter.test.ts) · [`src/infrastructure/composition/__tests__/push_single_action_capability_port_binding.test.ts`](../src/infrastructure/composition/__tests__/push_single_action_capability_port_binding.test.ts) · [`src/application/usecases/branch_sync/__tests__/branch_sync_execution_policy.test.ts`](../src/application/usecases/branch_sync/__tests__/branch_sync_execution_policy.test.ts) · [`src/application/errors/__tests__/application_error.test.ts`](../src/application/errors/__tests__/application_error.test.ts) · [`src/application/policies/__tests__/application_error_presentation_policy.test.ts`](../src/application/policies/__tests__/application_error_presentation_policy.test.ts) · [`src/infrastructure/__tests__/git_commit_adapter.test.ts`](../src/infrastructure/__tests__/git_commit_adapter.test.ts) · [`src/infrastructure/__tests__/branch_sync_sdd_catalog.test.ts`](../src/infrastructure/__tests__/branch_sync_sdd_catalog.test.ts) · [`src/infrastructure/__tests__/branch_sync_generated_bundle_validation.test.ts`](../src/infrastructure/__tests__/branch_sync_generated_bundle_validation.test.ts) · [`src/application/policies/__tests__/branch_sync_lifecycle_recovery.test.ts`](../src/application/policies/__tests__/branch_sync_lifecycle_recovery.test.ts) · [`src/infrastructure/__tests__/branch_sync_resolved_workspace.test.ts`](../src/infrastructure/__tests__/branch_sync_resolved_workspace.test.ts) · [`src/infrastructure/__tests__/branch_sync_communication_budget.test.ts`](../src/infrastructure/__tests__/branch_sync_communication_budget.test.ts) · [`src/application/usecases/actions/__tests__/retire_branch_sync_use_case.test.ts`](../src/application/usecases/actions/__tests__/retire_branch_sync_use_case.test.ts) · [`src/application/usecases/__tests__/pull_request_use_case.test.ts`](../src/application/usecases/__tests__/pull_request_use_case.test.ts) · [`src/actions/__tests__/common_action.test.ts`](../src/actions/__tests__/common_action.test.ts) · [`src/actions/__tests__/github_action.test.ts`](../src/actions/__tests__/github_action.test.ts) · [`src/tooling/__tests__/validate_workflow_contract.test.ts`](../src/tooling/__tests__/validate_workflow_contract.test.ts) · [`src/data/repository/__tests__/reply_request_repository.test.ts`](../src/data/repository/__tests__/reply_request_repository.test.ts) · [`src/infrastructure/composition/__tests__/reply_request_composition_root.test.ts`](../src/infrastructure/composition/__tests__/reply_request_composition_root.test.ts) · [`src/application/policies/__tests__/verification_runtime_policy.test.ts`](../src/application/policies/__tests__/verification_runtime_policy.test.ts) · [`src/infrastructure/__tests__/verification_runtime_preflight.test.ts`](../src/infrastructure/__tests__/verification_runtime_preflight.test.ts) · [`src/infrastructure/__tests__/verification_runtime_branch_sync.test.ts`](../src/infrastructure/__tests__/verification_runtime_branch_sync.test.ts) · [`src/infrastructure/__tests__/untrusted_command_environment.test.ts`](../src/infrastructure/__tests__/untrusted_command_environment.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/verify_command_runner.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/verify_command_runner.test.ts) · [`src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts`](../src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts) · [`src/tooling/__tests__/verification_runtime_guidance.test.ts`](../src/tooling/__tests__/verification_runtime_guidance.test.ts) · [`src/application/policies/__tests__/verification_setup_policy.test.ts`](../src/application/policies/__tests__/verification_setup_policy.test.ts) · [`src/infrastructure/__tests__/verification_setup_snapshot.test.ts`](../src/infrastructure/__tests__/verification_setup_snapshot.test.ts) · [`src/infrastructure/__tests__/verification_setup_runner.test.ts`](../src/infrastructure/__tests__/verification_setup_runner.test.ts) · [`src/infrastructure/__tests__/verification_setup_configuration.test.ts`](../src/infrastructure/__tests__/verification_setup_configuration.test.ts) · [`src/infrastructure/__tests__/verification_setup_sync.test.ts`](../src/infrastructure/__tests__/verification_setup_sync.test.ts) · [`src/infrastructure/__tests__/native_verification_runner.test.ts`](../src/infrastructure/__tests__/native_verification_runner.test.ts) · [`src/infrastructure/__tests__/native_verification_protocol.test.ts`](../src/infrastructure/__tests__/native_verification_protocol.test.ts) · [`src/infrastructure/__tests__/native_verification_controller.test.ts`](../src/infrastructure/__tests__/native_verification_controller.test.ts) · [`src/infrastructure/__tests__/native_verification_redaction.test.ts`](../src/infrastructure/__tests__/native_verification_redaction.test.ts) · [`src/infrastructure/__tests__/native_verification_workflow.test.ts`](../src/infrastructure/__tests__/native_verification_workflow.test.ts) · [`src/infrastructure/__tests__/native_verification_profiles.test.ts`](../src/infrastructure/__tests__/native_verification_profiles.test.ts) · [`src/infrastructure/__tests__/verification_executable.test.ts`](../src/infrastructure/__tests__/verification_executable.test.ts) · [`src/infrastructure/__tests__/native_verification_post.test.ts`](../src/infrastructure/__tests__/native_verification_post.test.ts) · [`src/infrastructure/__tests__/native_verification_source_runtime.test.ts`](../src/infrastructure/__tests__/native_verification_source_runtime.test.ts) · [`src/domain/__tests__/copilot_comment_workflow.test.ts`](../src/domain/__tests__/copilot_comment_workflow.test.ts) - User documentation: [`docs/issues/branch-synchronization.mdx`](../docs/issues/branch-synchronization.mdx) · [`docs/issues/comment-commands.mdx`](../docs/issues/comment-commands.mdx) · [`docs/issues/notifications-and-auto-close.mdx`](../docs/issues/notifications-and-auto-close.mdx) · [`docs/development/architecture.mdx`](../docs/development/architecture.mdx) · [`docs/security-operations/operations/verification.mdx`](../docs/security-operations/operations/verification.mdx) · [`docs/security-operations/operations/troubleshooting.mdx`](../docs/security-operations/operations/troubleshooting.mdx) · [`docs/agents/repository-collaboration.mdx`](../docs/agents/repository-collaboration.mdx) ### `pull-request-lifecycle` — Pull request lifecycle and enrichment diff --git a/specs/agent-runtime-provider-and-model-routing.md b/specs/agent-runtime-provider-and-model-routing.md index 231037824..b4b3dcda5 100644 --- a/specs/agent-runtime-provider-and-model-routing.md +++ b/specs/agent-runtime-provider-and-model-routing.md @@ -1311,3 +1311,16 @@ in `docs/development/testing.mdx` MUST explain defaults, isolated probe, publication opt-in, runner recovery and partial evidence. Run full coverage, `validate:workflows`, `validate:documentation`, `validate:specifications` and the native platform smoke before declaring complete cross-platform acceptance. + +### Hosted Windows job headroom (2026-10-21, PR #654) + +The hosted platform fixture job uses a fixed 30-minute Windows limit and +20 minutes for Ubuntu/macOS. Evidence: run 39644175943 completed Windows in +19m34s; run 39645186744 reached the former 20-minute job bound during coverage +without an assertion failure. This increases only orchestration headroom: +agent process, PowerShell, ACL, credential, worker-concurrency and coverage +requirements remain unchanged. A fresh exact-head Windows pass is mandatory; +other platforms and a canceled run cannot substitute. Existing workflow and +platform checks remain the acceptance artifacts; this configuration amendment +adds no agent capability, user input or distinct application test case. See +docs/development/testing.mdx for contributor operation. diff --git a/specs/branch-synchronization-and-conflict-recovery.md b/specs/branch-synchronization-and-conflict-recovery.md index 59eff22fb..a40fb096c 100644 --- a/specs/branch-synchronization-and-conflict-recovery.md +++ b/specs/branch-synchronization-and-conflict-recovery.md @@ -719,3 +719,7 @@ retained effects and named failures for incomplete cleanup. Each card uses at most two targeted witness reads. This does not widen synchronization, branch, comment creation or deletion authority. Its eight new race/readback and bounded-diagnostic cases are counted only in the lifecycle extension's budget. + +## Repository setup amendment — issue #647 + +The [repository-owned setup contract](./repository-verification-setup-hooks.md) prepares the actual temporary merge immediately before each verification command when explicitly enabled. Composition captures immutable helper bytes from trusted main before workspace mutation; candidate edits never replace them. Setup and runtime preflight share the command's private environment. Setup failure follows existing abort behavior and withholds commit/push. Read-only status, dry run, aligned branches and empty command lists never execute the helper. The companion owns its incremental budget and local same-managed-ref acceptance; no release is included. diff --git a/specs/bugbot-analysis-publication-and-autofix.md b/specs/bugbot-analysis-publication-and-autofix.md index 2eea18086..9158e8869 100644 --- a/specs/bugbot-analysis-publication-and-autofix.md +++ b/specs/bugbot-analysis-publication-and-autofix.md @@ -2,9 +2,9 @@ - Status: As-built baseline - Date: 2026-09-11 -- Last updated: 2026-10-13 +- Last updated: 2026-10-21 - Catalog capability ID: `bugbot-analysis-and-autofix` -- Last verified: 2026-10-13; canonical autofix branch correction tracked in #494 +- Last verified: 2026-10-21; identity continuity and grounding correction tracked in #655 - Owners: Copilot maintainers - Scope: bounded change analysis, finding identity/publication, authorized autofix, and independent verification - Related issues/PRs: Bugbot review-state reconciliation SDD; architecture @@ -587,3 +587,40 @@ finding status. The owning SDD/catalog, generated catalog, documentation, architecture contracts, bundles, full suite/coverage and current-head CI/review must pass before this correction is complete. Native acceptance remains pending until the retry actually publishes and its review establishes current state. + +### Source-grounded review evidence — #655 (2026-10-21) + +The reviewer and real-agent benchmark share the same source-grounding instruction. +Before publication the model MUST try to disprove each alleged defect against +effective repository settings, inherited protocol/library defaults, short-circuit +guards, helper validation and actual caller/render paths. Arithmetic and current +locations must agree with cited evidence. A finding whose evidence withdraws its +own claim MUST be omitted, including low/info reports. This is a model instruction, +not a deterministic guarantee or an English-prose rejection heuristic. Valid +defects remain required when those protections are absent. The previous-finding +prompt traces the original precondition through current modules and requests the +exact retained ID when the same concern remains active. + +Allocate **eight added evaluation cases** only here: six negative cases from the +reported configuration, HTTP/1.0, arithmetic, short-circuit, helper-validation and +exclusive-render concerns, plus two positive controls for unsafe membership order +and simultaneous duplicate IDs. Existing prompt tests enforce the shared review +contract; benchmark tests classify each negative as a false positive and each +missed positive as a false negative. The corpus now has 38 cases. Ground-truth +arrays never enter the model prompt. Checked-in reference predictions test the +scorer contract and MUST NOT be claimed as an observed real-model improvement. + +The companion reconciliation SDD owns the 18 lifecycle cases and durable-ID +correction; no double counting. No confidence/severity gate, schema, permission, +runtime access or configuration changes. Documentation: quality/observability, +finding publication and failure scenarios. Acceptance: the reference evaluation +passes all existing thresholds, unsupported reports fail the isolated precision +gate, and missing positive controls fail recall. Full coverage, architecture, +catalog/specification, documentation and generated-package gates remain required. + +Primary sources supporting the synthetic examples: +[coverage.py configuration](https://coverage.readthedocs.io/en/latest/config.html) +documents TOML settings and branch measurement; +[Python BaseHTTPRequestHandler](https://docs.python.org/3/library/http.server.html#http.server.BaseHTTPRequestHandler.protocol_version) +documents its default HTTP/1.0 response protocol. The issue supplies exact consumer +source and runs; these fixtures do not claim to replay that external runtime. diff --git a/specs/bugbot-review-state-reconciliation.md b/specs/bugbot-review-state-reconciliation.md index 4bd9be5bf..8cee3fc89 100644 --- a/specs/bugbot-review-state-reconciliation.md +++ b/specs/bugbot-review-state-reconciliation.md @@ -1601,3 +1601,197 @@ from one trusted bot-owned complete current-head card; it grants no approval or mutation authority. Marker/reader tests (24 cases) belong exclusively to the comment automation SDD budget. User documentation explains recheck recovery when evidence is absent or stale. + + +### Actionable finding mutation failures (2026-10-21, #646) + +Observed: a native review and inline comment could persist before resolution +failed; the adapter and application discarded the failed operation/HTTP facts, +leaving only `provider.unavailable`. The exact consumer API cause remains unknown. +This amendment MUST preserve incomplete evidence and completed effects while +retaining closed stage (`publication`/`resolution`), adapter operation, first +finding ID, affected batch count, optional HTTP status and safe provider request +reference. Batch diagnosis names its first finding and count, without falsely +claiming which individual item failed inside an atomic provider request. + +Only integer HTTP 400–599 and a 1–64-character alphanumeric/colon/hyphen request +reference are retained. Raw error prose, response bodies, URLs, request headers, +credentials and rejected provider content MUST NOT cross this diagnostic boundary. +Finding IDs use a bounded 200-character identifier alphabet; unavailable or unsafe +IDs are represented explicitly. Existing locally computed fingerprints remain +reconciliation authority; diagnostic IDs grant no mutation permission. + +```text +Publish native review -> attempt durable reconciliation -> failure retains effects +-> safe diagnostic plus independent coverage -> correct cause -> normal recheck +-> fresh provider read -> reuse native finding and retained dismissal +``` + +Text equivalent: partial success is retained and diagnosed; a recheck discovers +existing provider state before continuing, without duplicate review/thread creation +or reversal of a durable human dismissal. There is no new automatic retry or +rollback and no change to freshness, ownership, evidence or mutation ordering. + +The semantic error class MUST preserve authorization, not-found, conflict, +rate-limit, client-contract and transient-provider categories. Recovery details +in the owned status card remain localized with existing English/Spanish catalogs. +Example: “Finding mutation failed: stage=resolution; operation=resolve-thread; +finding=backend/Dockerfile:20:healthcheck-requires-curl; affected=1; http-503; +provider reference=AB12:34CD. Completed effects are retained.” Correct access and +contract failures before retrying; restore availability for transient failures, +then recheck the same PR. Existing pending, attention and successful cards remain. +No new comment stream, permission, configuration input or durable marker schema. +Absent metadata remains unavailable; no inference of a specific provider cause. + +Conversation truncation MUST remain independently partial. Coverage can attach +up to 50 bounded provider identities for retained truncated sources (`issue:` +or `review:`), never comment text or arbitrary links. The aggregate shows +these identities under Incomplete coverage, separately from Recovery details. +A failed mutation cannot turn partial coverage into complete, and a coverage +limitation cannot conceal the semantic mutation failure. Existing projection +precedence (partial coverage may yield a partial projection with failed Result) +is retained. Old coverage without identities remains compatible and unverified. + +Adapters own safe provider metadata; application errors own the credential-free +mutation diagnostic; publication/resolution use cases bind finding identity; +reconciliation and catalog presentation consume typed facts. Domain coverage +adds optional source identities only. Typecheck, architecture, localization and +fault-injection regressions enforce these boundaries; SDKs remain outside policy. + +The additional budget is **26 distinct cases**: thirteen HTTP/classification/privacy +and error-preservation cases, five publication-stage identity/batch cases, one real +publication-to-failed-resolution-to-retry integration, two locale/projection and +independent-coverage cases, two exact-source/privacy cases and three adapter cases. +Existing global coverage/quality thresholds and all prior state/replay tests +remain required. Acceptance proves a persisted native review survives a subsequent +503, one recheck produces no duplicate native review/thread, dismissal bytes are +retained, and diagnostics distinguish that error from truncated conversation. +Documentation: Bugbot failure scenarios. Upgrade the Action and recheck the same +PR after recovery; rollback only loses richer diagnostics. Definition of Done: +all package, documentation, catalog and existing architecture gates pass; no live +consumer recovery is claimed by deterministic fixtures. + + +PR #651 review correction: batch mutation diagnostics MUST derive identity and +count from the publisher's actually queued new findings, excluding individually +updated or suppressed findings. Overflow summaries add their represented overflow +count; an overflow-only batch reports that count and an unavailable finding ID, +never a fabricated durable identity. The mixed/overflow cases above enforce this. + + +PR #651 status-classification correction: HTTP 408 and 425 MUST retain transient +`provider.unavailable` semantics rather than fall through to client-contract +failure. These are two additional cases in the budget above. +[RFC 9110 §15.5.9](https://www.rfc-editor.org/rfc/rfc9110.html#section-15.5.9) +describes retry of an outstanding request after 408; +[RFC 8470 §5.2](https://www.rfc-editor.org/rfc/rfc8470.html#section-5.2) +requires a retry after 425 to avoid early data. Copilot adds no automatic replay: a +normal recheck obtains fresh provider state before continuing, preserving completed +effects and dismissal intent. Other client statuses retain their explicit mapping. + + +PR #651 issue-route correction: only PR review publication enters the new typed +review-mutation diagnostic. Issue-comment publication retains its existing +application normalization path and MUST NOT be relabeled as `publish-comments` +or a PR recheck target. A distinct issue-path regression enforces this boundary. + +### Finding identity continuity — #655 (2026-10-21) + +Observed implementation defect: fingerprint matching selected a trusted existing +comment, but publication replaced its marker ID with the current model ID. The +final read then saw the new ID and retained the previous unresolved ID as an +unlinked unknown. [Issue #655](https://github.com/vypdev/copilot/issues/655) +provides the consumer evidence; the exact historical API outage remains unknown. +The #646 amendment above already owns mutation-stage/provider diagnostics. + +The matched durable key MUST be preserved while updating the same comment's +current title, file, location, evidence and locally computed fingerprints. Pure +domain matching returns both key and destination. A compatible direct ID wins; +otherwise location matching MUST be unique, followed by unique semantic matching +only when no location match exists. Ambiguous location evidence MUST NOT fall +through to a weaker semantic match. No fuzzy title comparison or model-supplied +identity authority is introduced. + +```text +Current model report -> unique trusted fingerprint match -> retain original ID + -> fold reports of that retained identity -> apply comment limit -> update thread + -> re-read original ID -> one linked current finding -> idempotent recheck +``` + +Text equivalent: retain the trusted finding key throughout analysis, publication +and final projection. The original marker and native comment/review identity +trace the old finding to its refreshed current content. Several current reports +matching that one retained key MUST occupy one comment slot. Unmatched reports +and ambiguous matches remain independent evidence; no historical thread is +deleted, automatically dismissed, or arbitrarily selected to make counts clean. +Direct publication and reconciliation callers use the same pure policy. + +Unknown rows MUST expose a bounded sanitized exact finding ID even without a +native link. Example partial card content: + +```markdown +## Bugbot: review incomplete +Run `/copilot recheck` after correcting the reported provider failure. +- [ ] unknown — Dashboard state — ui/src/model.ts:73:operations-empty +``` + +The existing pending, action-required, failure, complete and locale contracts +remain; no new status surface or notification is added. A true final-provider +omission still produces unknown and the original bounded diagnostic. Failed +marker or thread writes retain their completed effects and canonical finding ID +in the typed mutation diagnostic; one fresh provider read and normal recheck +converges without duplicate publication. Human dismissal retains precedence. + +State boundary: attempted but unpublished candidates are transient analysis +evidence, not durable native findings. Their unknown rows diagnose that attempt. +A later stochastic scan may supersede them; disappearance is neither explicit +verification nor a fix/dismissal. Operators MUST retain the failed run's IDs and +inspect those concerns. This correction does not add a second finding database +inside the derived status card or promise durable recovery of unpublished bodies. + +Architecture/configuration/security: domain policy remains pure; application +analysis, publication and final reconciliation share it; adapters and semantic +ports remain unchanged. Matching uses only trusted parsed existing markers and +locally computed fingerprints. No new permission, setting, marker version, +background retry or migration is required. Upgrade and recheck the current PR; +rollback retains visible history but reintroduces the re-keying risk. Existing +head, ownership, publication-before-resolution and conservative-count rules +remain non-configurable. + +Allocate **18 added deterministic lifecycle cases** only here: six domain +matching/ambiguity/immutability cases; six publication-to-projection/retry, +direct-call, failure, omission and human-dismissal replays; one partition +fold-before-limit case; two issue-ID/impossible-anchor publication cases; and +three localized/unsafe unknown-ID rendering cases. The eight quality-corpus +cases and strengthened prompt contracts are owned only by the analysis SDD. +Existing global thresholds remain; `finding.ts` requires 100% coverage and the +changed analysis/publication/reconciliation path requires 95% lines/statements +and 90% branches/functions. Deterministic fakes use no live model or waits. + +Acceptance/traceability: `finding.test.ts` proves unique durable-key matching and +ambiguity refusal; `finding_identity_replay.test.ts` proves changed model +ID/title/location yields one original linked record, zero orphan unknown, no +new native review, equal replay digest, safe failure diagnostics and dismissal +retention. Analyzer/publication tests prove comment-budget and issue/anchor +behavior; presentation tests prove bounded actionable IDs in English/Spanish. +Publication, failure and quality documentation describe recovery and evidence +limits. Definition of Done: these cases, coverage budgets, full suite, +architecture, specification/catalog, documentation, generated bundle/package +gates and current-head PR CI/review pass. Synthetic fixtures do not establish a +specific historical consumer API cause or live model-quality improvement. + +PR #658 review corrections: preserving a matched key MUST NOT let an incompatible +model report reuse that key and overwrite its evidence in downstream maps. Reserve +all durable and input IDs before allocation. Incompatible reports that collide +with a durable or already-emitted ID receive a short locally computed fingerprint +ID with a deterministic unused suffix; matched records retain their durable key. +Reapplying normalization and a fresh provider recheck MUST preserve both reports +and reuse both native threads. Reserve generated IDs against later input IDs too. + +Unknown IDs MUST render as literal code text, with a delimiter longer than any +embedded backtick run. Links, images and HTML in an ID cannot create navigation +or markup. GitHub's GFM renderer verified the malicious link/image/backtick/HTML +fixture as one inert code span. Add **six distinct cases** to this SDD's budget: +four domain collision/order/replay/reservation cases, one publication-to-projection +two-thread replay and one Markdown-injection case. Existing coverage thresholds +and all publication, identity and recovery rules remain required. diff --git a/specs/catalog.json b/specs/catalog.json index 73491e557..ca41fbc29 100644 --- a/specs/catalog.json +++ b/specs/catalog.json @@ -388,9 +388,9 @@ "id": "merge-queue-readiness", "title": "Merge queue readiness and effective target rules", "status": "implemented", - "scope": "Fail-closed validation of required checks and merge-group workflow support", + "scope": "Fail-closed validation of required checks and merge-group workflow support; optional manual-only RepoWise analysis with independent CI and verified required-check migration; cached RepoWise exports and bounded full-history secret processing with truthful completeness and resource evidence", "owner": "Copilot maintainers", - "lastVerified": "2026-10-15", + "lastVerified": "2026-10-21", "specs": [ "specs/merge-queue-readiness.md" ], @@ -414,7 +414,9 @@ "src/application/usecases/setup/merge_queue_readiness_use_case.ts", "src/data/repository/deployment/github_target_merge_capabilities_inspector.ts", "src/infrastructure/github/octokit_checks_adapters.ts", - "scripts/validate-workflow-contract.cjs" + "scripts/validate-workflow-contract.cjs", + "scripts/repowise_history.py", + "scripts/repowise_reports.py" ], "tests": [ "src/domain/__tests__/merge_queue_readiness.test.ts", @@ -422,11 +424,14 @@ "src/application/policies/__tests__/setup_doctor_message_catalog.test.ts", "src/application/usecases/setup/__tests__/merge_queue_readiness_use_case.test.ts", "src/data/repository/deployment/__tests__/github_deployment_adapters.test.ts", - "src/tooling/__tests__/validate_workflow_contract.test.ts" + "src/tooling/__tests__/validate_workflow_contract.test.ts", + "scripts/tests/test_repowise.py" ], "documentation": [ "docs/issues/deployment-orchestration.mdx", - "docs/security-operations/operations/verification.mdx" + "docs/security-operations/operations/verification.mdx", + "docs/development/testing.mdx", + "docs/security-operations/security/self-hosted-runners.mdx" ] }, { @@ -435,7 +440,7 @@ "status": "implemented", "scope": "Reconcile review snapshots, findings, threads, comments, and check conclusions", "owner": "Copilot maintainers", - "lastVerified": "2026-10-11", + "lastVerified": "2026-10-21", "specs": [ "specs/bugbot-review-state-reconciliation.md" ], @@ -471,7 +476,12 @@ "src/application/usecases/steps/commit/bugbot/prepare_bugbot_findings_policy.ts", "src/application/usecases/steps/commit/bugbot/publish_pr_review_comments.ts", "src/application/usecases/steps/commit/bugbot/synchronize_bugbot_review_presentation_use_case.ts", - "src/application/policies/bugbot_status_count_marker_policy.ts" + "src/application/policies/bugbot_status_count_marker_policy.ts", + "src/application/errors/bugbot_mutation_error.ts", + "src/data/repository/pull_request/pull_request_review_error_metadata.ts", + "src/domain/bugbot/finding.ts", + "src/application/usecases/steps/commit/bugbot/analyze_bugbot_revision_use_case.ts", + "src/application/usecases/steps/commit/bugbot/publish_findings_use_case.ts" ], "tests": [ "src/domain/bugbot/__tests__/review_state.test.ts", @@ -495,7 +505,13 @@ "src/application/usecases/actions/__tests__/synchronize_lifecycle_state_use_case.test.ts", "src/application/usecases/steps/commit/__tests__/detect_potential_problems_use_case.test.ts", "src/infrastructure/composition/__tests__/pull_request_use_case_composition_root.test.ts", - "src/tooling/__tests__/validate_workflow_contract.test.ts" + "src/tooling/__tests__/validate_workflow_contract.test.ts", + "src/application/errors/__tests__/bugbot_mutation_error.test.ts", + "src/application/usecases/steps/commit/bugbot/__tests__/finding_mutation_recovery.test.ts", + "src/domain/bugbot/__tests__/finding.test.ts", + "src/application/usecases/steps/commit/bugbot/__tests__/finding_identity_replay.test.ts", + "src/application/usecases/steps/commit/bugbot/__tests__/analyze_bugbot_revision_use_case.test.ts", + "src/application/usecases/steps/commit/bugbot/__tests__/publish_findings_use_case.test.ts" ], "documentation": [ "docs/bugbot/detection.mdx", @@ -515,7 +531,7 @@ "status": "implemented", "scope": "Shared GitHub Action lifecycle from event admission through durable user-facing results", "owner": "Copilot maintainers", - "lastVerified": "2026-10-14", + "lastVerified": "2026-10-21", "specs": [ "specs/execution-admission-queue-and-publication.md", "specs/execution-error-and-context-hardening.md", @@ -580,7 +596,11 @@ "src/application/usecases/steps/commit/check_changes_issue_size_workflow.ts", "src/application/usecases/steps/commit/update_change_size_labels.ts", "src/data/repository/project/project_board_item_query.ts", - "src/infrastructure/composition/change_size_project_membership_composition_root.ts" + "src/infrastructure/composition/change_size_project_membership_composition_root.ts", + "src/manager/description/configuration_handler.ts", + "src/manager/description/configuration_markers.ts", + "src/data/repository/issue/issue_content_repository.ts", + "src/data/repository/github/github_error_policy.ts" ], "tests": [ "src/tooling/__tests__/coverage_budget_validator.test.ts", @@ -617,7 +637,10 @@ "src/application/usecases/steps/commit/__tests__/check_changes_issue_size_use_case.test.ts", "src/application/usecases/steps/commit/__tests__/update_change_size_labels.test.ts", "src/data/repository/project/__tests__/project_board_visibility_recovery.test.ts", - "src/infrastructure/composition/__tests__/change_size_project_membership_composition_root.test.ts" + "src/infrastructure/composition/__tests__/change_size_project_membership_composition_root.test.ts", + "src/manager/description/__tests__/configuration_recovery.test.ts", + "src/manager/description/__tests__/configuration_handler.test.ts", + "src/data/repository/issue/__tests__/issue_content_repository.test.ts" ], "documentation": [ "docs/overview.mdx", @@ -627,7 +650,8 @@ "docs/bugbot/quality-observability.mdx", "docs/bugbot/failure-scenarios.mdx", "docs/development/architecture.mdx", - "docs/issues/assignees-and-projects.mdx" + "docs/issues/assignees-and-projects.mdx", + "docs/configuration.mdx" ] }, { @@ -737,7 +761,8 @@ "specs/setup-pat-permission-guidance-and-verification.md", "specs/github-runtime-doctor-command.md", "specs/organization-configuration-reuse-and-batch-setup.md", - "specs/setup-runner-profiles-and-installation-parity.md" + "specs/setup-runner-profiles-and-installation-parity.md", + "specs/copilot-comment-workflow-coordinator.md" ], "workflows": [ "setup/workflows/agent-cli-provisioning.yml", @@ -918,7 +943,10 @@ "src/application/ports/git_ports.ts", "src/application/ports/bugbot_git_ports.ts", "src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts", - "src/application/usecases/steps/commit/bugbot/verify_command_runner.ts" + "src/application/usecases/steps/commit/bugbot/verify_command_runner.ts", + "src/cli/setup_config_file.ts", + "src/domain/copilot_comment_workflow.ts", + "src/infrastructure/copilot_comment_inputs.json" ], "tests": [ "src/data/repository/__tests__/repository_version_tags_query_repository.test.ts", @@ -1048,7 +1076,9 @@ "src/infrastructure/__tests__/untrusted_command_environment.test.ts", "src/application/usecases/steps/commit/bugbot/__tests__/verify_command_runner.test.ts", "src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts", - "src/tooling/__tests__/verification_runtime_guidance.test.ts" + "src/tooling/__tests__/verification_runtime_guidance.test.ts", + "src/infrastructure/__tests__/verification_setup_configuration.test.ts", + "src/domain/__tests__/copilot_comment_workflow.test.ts" ], "documentation": [ "README.md", @@ -1082,10 +1112,11 @@ "status": "proposed", "scope": "Offer a packaged, loopback-only Svelte setup interface over the existing engine with four-language guidance, English CLI help, basic/custom first-run paths, editable question and plan review, source-labelled GitHub facts, assisted CI and Project evidence, role-separated PATs, and truthful itemized outcomes; inspect existing configuration and apply independent, scope-aware runtime adjustments with permission, drift and read-back verification", "owner": "Copilot maintainers", - "lastVerified": "2026-10-20", + "lastVerified": "2026-10-21", "specs": [ "specs/local-web-setup-assistant.md", - "specs/setup-configuration-management.md" + "specs/setup-configuration-management.md", + "specs/verification-setup-onboarding.md" ], "workflows": [ ".github/workflows/ci_check.yml", @@ -1243,7 +1274,10 @@ "src/application/contracts/setup_documentation.ts", "src/cli/setup_journey_presenter.ts", "web/src/components/SetupHelp.svelte", - "web/src/components/CompletedSetupHelp.svelte" + "web/src/components/CompletedSetupHelp.svelte", + "src/domain/setup_verification_action.ts", + "src/infrastructure/setup_verification_action.ts", + "src/application/policies/setup_verification_action_summary_policy.ts" ], "tests": [ "src/__tests__/cli.test.ts", @@ -1309,7 +1343,11 @@ "src/cli/__tests__/setup_management_adapter.test.ts", "src/cli/__tests__/web_setup_management_components.test.ts", "src/cli/__tests__/web_setup_runner_components.test.ts", - "src/cli/__tests__/setup_documentation_navigation.test.ts" + "src/cli/__tests__/setup_documentation_navigation.test.ts", + "src/infrastructure/__tests__/setup_verification_action.test.ts", + "src/application/policies/__tests__/setup_verification_onboarding_policy.test.ts", + "src/cli/__tests__/setup_verification_onboarding_components.test.ts", + "src/application/usecases/setup/__tests__/setup_verification_onboarding_flow.test.ts" ], "documentation": [ "README.md", @@ -1333,7 +1371,9 @@ "docs/guides/issues-and-branches.mdx", "docs/guides/review-pull-requests.mdx", "docs/guides/work-with-the-bot.mdx", - "docs/guides/releases-and-hotfixes.mdx" + "docs/guides/releases-and-hotfixes.mdx", + "docs/security-operations/operations/verification.mdx", + "docs/security-operations/operations/upgrade-rollback.mdx" ] }, { @@ -1457,7 +1497,7 @@ "status": "implemented", "scope": "Start every admitted issue with one explicit signal and publish a validated SDD before eligible Action-managed branch work; inspect verified SDD status and bounded structural publication comparisons", "owner": "Copilot maintainers", - "lastVerified": "2026-10-19", + "lastVerified": "2026-10-21", "specs": [ "specs/issue-start-and-branch-readiness.md", "specs/pre-branch-sdd-gate.md", @@ -1533,7 +1573,9 @@ "src/infrastructure/setup_workspace_adapter.ts", "src/application/usecases/setup/doctor_use_case.ts", "src/application/policies/setup_doctor_message_catalog.ts", - "src/domain/sdd_prerequisite_policy.cjs" + "src/domain/sdd_prerequisite_policy.cjs", + "src/application/policies/sdd_analysis_status_policy.ts", + "src/domain/sdd_draft_consistency.ts" ], "tests": [ "src/domain/__tests__/issue_workflow_runtime_policy.test.ts", @@ -1576,7 +1618,8 @@ "src/infrastructure/__tests__/setup_sdd_prerequisites.test.ts", "src/application/usecases/setup/__tests__/doctor_use_case.test.ts", "src/infrastructure/__tests__/branch_sync_sdd_catalog.test.ts", - "src/cli/__tests__/setup_presenters.test.ts" + "src/cli/__tests__/setup_presenters.test.ts", + "src/domain/__tests__/sdd_draft_consistency.test.ts" ], "documentation": [ "docs/issues/branch-management.mdx", @@ -1789,7 +1832,7 @@ "status": "implemented", "scope": "Select one canonical PR, exhaustively analyze its bounded diff partitions, publish stable findings atomically, and apply authorized verified fixes", "owner": "Copilot maintainers", - "lastVerified": "2026-10-13", + "lastVerified": "2026-10-21", "specs": [ "specs/bugbot-analysis-publication-and-autofix.md", "specs/bugbot-context-selection-and-budgeting.md", @@ -1858,7 +1901,10 @@ "src/infrastructure/filesystem/workspace_bugbot_rules_repository.ts", "src/application/usecases/steps/commit/git_branch_checkout.ts", "src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts", - "src/application/usecases/steps/commit/bugbot/commit_and_push_workflow.ts" + "src/application/usecases/steps/commit/bugbot/commit_and_push_workflow.ts", + "quality/bugbot/corpus.v1.json", + "quality/bugbot/reference-predictions.v1.json", + "src/tooling/bugbot_benchmark_runner.ts" ], "tests": [ "src/application/usecases/steps/commit/__tests__/bugbot_review_lifecycle.e2e.test.ts", @@ -1899,7 +1945,10 @@ "src/application/usecases/steps/commit/__tests__/git_branch_checkout.integration.test.ts", "src/application/usecases/steps/commit/bugbot/__tests__/workspace_changes.test.ts", "src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts", - "src/application/usecases/__tests__/autofix_conversation_branch_authority.test.ts" + "src/application/usecases/__tests__/autofix_conversation_branch_authority.test.ts", + "src/tooling/__tests__/bugbot_benchmark.test.ts", + "src/tooling/__tests__/bugbot_benchmark_runner.test.ts", + "src/prompts/__tests__/bugbot.test.ts" ], "documentation": [ "docs/bugbot/how-it-works.mdx", @@ -1921,10 +1970,11 @@ "status": "implemented", "scope": "Observe parent drift with one localized status card and transition-only notifications, then safely merge a parent branch into a linked working branch", "owner": "Copilot maintainers", - "lastVerified": "2026-10-20", + "lastVerified": "2026-10-22", "specs": [ "specs/branch-synchronization-and-conflict-recovery.md", - "specs/repository-verification-runtime-prerequisites.md" + "specs/repository-verification-runtime-prerequisites.md", + "specs/repository-verification-setup-hooks.md" ], "workflows": [ ".github/workflows/copilot_branch_sync.yml", @@ -1932,7 +1982,10 @@ ".github/workflows/copilot_issue.yml", "setup/workflows/copilot_issue.yml", "setup/workflows/copilot_issue_comment.yml", - "setup/workflows/copilot_pull_request_comment.yml" + "setup/workflows/copilot_pull_request_comment.yml", + ".github/workflows/copilot_comment_runtime.yml", + ".github/workflows/copilot_issue_comment.yml", + ".github/workflows/copilot_pull_request_comment.yml" ], "entrypoints": [ "src/application/usecases/branch_sync/sync_branch_use_case.ts", @@ -1981,7 +2034,25 @@ "src/application/usecases/steps/commit/bugbot/commit_and_push_preflight.ts", "src/application/usecases/steps/commit/bugbot/verify_command_runner.ts", "src/domain/closed_issue_reconciliation.ts", - "src/application/errors/closed_issue_reconciliation_error.ts" + "src/application/errors/closed_issue_reconciliation_error.ts", + "src/application/policies/verification_setup_policy.ts", + "src/application/ports/verification_setup_ports.ts", + "src/infrastructure/verification_setup_snapshot.ts", + "src/infrastructure/verification_setup_result.ts", + "src/infrastructure/verification_setup_runner.ts", + "src/infrastructure/native_verification_protocol.ts", + "src/infrastructure/native_verification_candidate.ts", + "src/infrastructure/native_verification_staging.ts", + "src/infrastructure/native_verification_controller.ts", + "src/infrastructure/native_verification_profiles.ts", + "src/infrastructure/native_verification_redaction.ts", + "scripts/generate-native-verification-workflows.cjs", + "src/infrastructure/verification_executable.ts", + "src/infrastructure/native_verification_source_runtime.ts", + "scripts/prepare-native-source-action.cjs", + "src/domain/copilot_comment_workflow.ts", + "src/infrastructure/copilot_comment_inputs.json", + "scripts/validate-comment-workflows.cjs" ], "tests": [ "src/application/policies/__tests__/branch_sync_notification_policy.test.ts", @@ -2015,7 +2086,22 @@ "src/infrastructure/__tests__/untrusted_command_environment.test.ts", "src/application/usecases/steps/commit/bugbot/__tests__/verify_command_runner.test.ts", "src/application/usecases/steps/commit/bugbot/__tests__/commit_verification_workspace.test.ts", - "src/tooling/__tests__/verification_runtime_guidance.test.ts" + "src/tooling/__tests__/verification_runtime_guidance.test.ts", + "src/application/policies/__tests__/verification_setup_policy.test.ts", + "src/infrastructure/__tests__/verification_setup_snapshot.test.ts", + "src/infrastructure/__tests__/verification_setup_runner.test.ts", + "src/infrastructure/__tests__/verification_setup_configuration.test.ts", + "src/infrastructure/__tests__/verification_setup_sync.test.ts", + "src/infrastructure/__tests__/native_verification_runner.test.ts", + "src/infrastructure/__tests__/native_verification_protocol.test.ts", + "src/infrastructure/__tests__/native_verification_controller.test.ts", + "src/infrastructure/__tests__/native_verification_redaction.test.ts", + "src/infrastructure/__tests__/native_verification_workflow.test.ts", + "src/infrastructure/__tests__/native_verification_profiles.test.ts", + "src/infrastructure/__tests__/verification_executable.test.ts", + "src/infrastructure/__tests__/native_verification_post.test.ts", + "src/infrastructure/__tests__/native_verification_source_runtime.test.ts", + "src/domain/__tests__/copilot_comment_workflow.test.ts" ], "documentation": [ "docs/issues/branch-synchronization.mdx", diff --git a/specs/copilot-comment-workflow-coordinator.md b/specs/copilot-comment-workflow-coordinator.md new file mode 100644 index 000000000..99df52d25 --- /dev/null +++ b/specs/copilot-comment-workflow-coordinator.md @@ -0,0 +1,348 @@ +# Copilot Comment Workflow Coordinator + +- Status: Draft +- Date: 2026-10-22 +- Catalog capability ID: setup-and-doctor +- Last verified: not applicable +- Owners: Copilot maintainers +- Scope: Centralize native issue-comment and pull-request-review-comment verification coordination in one versioned Copilot reusable workflow and specify safe consumer setup migration. +- Related issues/PRs: [Issue #662](https://github.com/vypdev/copilot/issues/662); related delivered work #647/#652 and #656/#657; dependent release #661 (3.10.0). +- Required review gates: product UX, architecture, testing, documentation, security/operations +- Open decisions blocking readiness: none + +## 1. Executive summary + +This companion specification defines one Copilot-owned reusable workflow for the complete native verification lifecycle used by issue-comment and pull-request-review-comment callbacks. Repository callbacks and setup templates call one versioned workflow instead of copying twenty setup/continue pairs and cleanup steps. The reusable workflow owns one job, so the existing native per-step timeout and same-job candidate environment remain intact. + +The safety rule is that only admitted, trusted verification work may reach the worker, and continuations verify the existing candidate without rerunning the agent or business operation. Secrets remain explicit and narrowly scoped; project setup receives no provider credentials or PAT inputs. + +```text +Comment callback -> versioned Copilot reusable workflow -> same-job Copilot Action and trusted dependency setup -> continuation and guarded publication -> reverse native post cleanup +``` + +## 2. Problem, current behavior, and evidence + +### 2.1 Problem + +Repository maintainers and Copilot maintainers must review and upgrade duplicated callback orchestration. The native dependency setup has twenty statically declared setup/continue pairs plus final cleanup, adding 579 lines to each distributed callback and duplicating those lines in source workflows. A generated composite coordinator cannot preserve the native per-step timeout because GitHub rejects `timeout-minutes` within composite steps. + +### 2.2 Current behavior + +1. Issue-comment and pull-request-review-comment callbacks admit events using existing bot, fork, and eligibility gates. +2. A native Copilot Action step runs with explicitly supplied configuration and credentials. +3. Native setup/continue steps prepare dependencies, preserve candidate identity, and wait for worker readiness. +4. Verification and publication guards run without rerunning the agent or business operation. +5. Native post actions clean up setup state in reverse order. + +The issue identifies these as current behavior and requires their preservation. Exact implementation-level names and current card text must be confirmed from the owning specifications and workflow evidence during implementation. + +### 2.3 Evidence + +- Code/workflow/documentation references: current comment callbacks and setup templates are catalogued under `setup-and-doctor`; existing setup owner is `specs/setup-runner-profiles-and-installation-parity.md`. The existing native verification owner remains `specs/repository-verification-setup-hooks.md` under `branch-synchronization`; implementation must retain that ownership and add a cross-reference. Catalog paths establish current locations only, not future runtime support. +- Incidents or concrete examples: twenty statically declared setup/continue pairs plus cleanup; 579 added lines per distributed comment callback. +- External primary sources: [GitHub runner action schema](https://github.com/actions/runner/blob/main/src/Runner.Worker/action_yaml.json); [same-repository self-reference announcement](https://github.blog/changelog/2026-07-30-reference-same-repository-actions-with-self-repository-syntax/). +- Unknowns: none block this design. Exact supported GitHub.com/runner/action-policy conditions must be documented and validated against the platform at implementation time. + +### 2.4 Retrospective classification (as-built baselines only) + +Not applicable: this is a prospective specification, not a reconstruction of an implemented baseline. + +## 3. Actors, surfaces, and terminology + +| Actor | Goal | Entry point | Visible surfaces | +|---|---|---|---| +| Repository maintainer | Install and upgrade compact comment callbacks safely | Setup or workflow maintenance | Workflow files, checks, setup preview and Apply | +| Comment author | Receive existing verification behavior | Issue or review comment | Existing result cards and linked run | +| Copilot operator | Diagnose a failed or incomplete verification | Workflow run | Job Summary, logs, issue/PR state | +| Copilot maintainer | Own central coordination and compatibility | Reusable workflow release | Versioned workflow, tests, docs, release notes | + +A **callback** is the repository-owned workflow triggered by a supported comment event. The **coordinator** is the Copilot reusable workflow that owns all native lifecycle phases in one job. **Candidate** means the existing admitted worker/candidate identity and environment; it is carried through continuation rather than recreated. **Trusted project setup** is the repository-owned composite dependency action. **Source callback** means a callback in Copilot itself and uses an exact same-commit self-repository workflow reference. **Installed callback** means a consumer callback and uses `vypdev/copilot/.github/workflows/copilot_comment_runtime.yml@v3`. + +## 4. Goals + +### 4.1 Goals + +1. Reduce each source and setup comment callback to at most 35 lines while centralizing all native phases in one reusable workflow. +2. Preserve existing admission, verification, publication, result-card, timeout, identity, credential, and cleanup behavior. +3. Let setup preview and Apply show the same runner route and safely recognize known reusable callers during configuration maintenance. +4. Provide actionable, reviewed migration for custom bootstrap steps without silently deleting them. + +### 4.2 Non-goals + +1. Replacing the repository-owned dependency action with a non-composite action. +2. Dispatching candidate setup to another job or rerunning the agent/business operation to continue verification. +3. Removing time limits or changing verification/publication semantics. +4. Publishing minor release #661 as part of this specification; it remains dependent on this work and its final-head review/checks. + +### 4.3 Fixed product/safety invariants + +1. Preserve admission and bot/fork gates, Variable and Secret semantics, twenty setup boundaries, five-minute native setup cancellation, 300-second worker readiness, and 120-minute job budget. +2. Preserve candidate identity, trusted-main Action pinning, credential-free verifier profiles, one-use continuations, and reverse native post cleanup. +3. Keep named Secrets explicit; provider credentials are scoped to the initial Copilot step. No unrestricted secrets inheritance and no provider credential/PAT inputs to project setup. +4. Unknown inputs, unsupported source identity, malformed runner JSON, and dependent expressions fail closed. +5. Do not drop custom bootstrap steps. Require reviewed migration with a concrete recovery path. +6. Require GitHub.com same-repository self-reference support and runner 2.336.0 or newer; the inspected source runner is 2.337.0. Repository Actions policy must allow the required references. + +## 5. Current versus proposed product journey + +| Stage | Current | Proposed | User/operator effect | +|---|---|---|---| +| Callback maintenance | Setup/continue orchestration is copied into callbacks and source workflows | Callback calls one versioned coordinator | Smaller review surface and centralized upgrades | +| Native job execution | Native phases run in callback job | Reusable workflow owns one job and all native phases | Per-step timeout and candidate environment remain available | +| Setup migration | Existing routes and custom bootstrap need to be recognized | Preview and Apply expose the same route; known reusable callers are recognized; custom steps require reviewed migration | No inferred runner access or silent loss of bootstrap | +| Upgrade | Consumers carry duplicated orchestration | Installed callback pins `@v3`; source callback uses exact same-commit self reference | Coordinator upgrades are explicit and reviewable | + +```mermaid +flowchart LR + C[Comment callback] --> W[Versioned Copilot reusable workflow] + W --> A[Same-commit Copilot Action] + A --> S[Trusted project composite setup] + S --> V[Continuation, verification and publication guards] + V --> P[Native reverse post cleanup] +``` + +Text equivalent: comment callback -> one-job reusable coordinator -> same-commit Copilot Action and trusted setup in the same job -> guarded continuation/publication -> reverse native cleanup. + +## 6. Functional behavior and state model + +### 6.1 Happy path + +1. The callback applies the existing event admission and bot/fork gates, then calls the coordinator with only supported named inputs and explicit named Secrets. +2. Source callbacks reference the workflow at the exact same-commit self repository revision. Installed callbacks reference `vypdev/copilot/.github/workflows/copilot_comment_runtime.yml@v3`. +3. The coordinator resolves supported runner routing and executes one job containing the Copilot Action, trusted project composite setup, continuation, verifier/publication guards, and native post cleanup. +4. Continuation consumes the one-use token and existing candidate identity; it does not rerun the agent or business operation. +5. Existing result cards and publication behavior remain unchanged. + +### 6.2 Alternative paths + +- Disabled, read-only, dry-run, and no-op modes retain their current behavior and do not gain side effects through centralization. +- Existing scalar, label, and group runner routes are retained or explicitly replaced during migration; preview and Apply display the same route. +- Unsupported runner configuration or callback identity fails closed with actionable recovery guidance. +- GitHub.com/runner/Actions-policy prerequisites not met: the callback cannot execute the coordinator; report a clear setup/operator error and link to prerequisites and remediation. +- Custom bootstrap steps: migration pauses for review and provides a documented recovery path; no step is silently discarded. + +### 6.3 State machine + +| State | Entered when | User-visible meaning | Allowed next states | Recovery/owner | +|---|---|---|---|---| +| Not admitted | Existing gates reject event | No verification run is started | Terminal | Existing callback behavior | +| Admitted | Event passes existing gates | Verification is starting | Running, failed | Coordinator/operator | +| Running | Native setup and worker proceed | Existing verification is in progress | Verifying, failed, canceled | Coordinator/operator | +| Verifying | One-use continuation resumes existing candidate | Existing candidate is checked | Published, failed, canceled | Coordinator/operator | +| Published | Existing publication guard allows result | Existing result is available | Terminal | Existing publication behavior | +| Failed/canceled | Guard, timeout, platform, or execution failure | Verification did not complete or was blocked | Retry only under existing policy | Operator uses run diagnostics and recovery docs | + +Duplicate and stale events remain subject to existing admission and one-use continuation semantics. Canceled setup runs retain native post cleanup. No continuation re-executes the agent/business operation. + +## 7. User-facing configuration + +| Input | Type | Recommended default | Allowed values/range | Scope/persistence | +|---|---|---|---|---| +| Installed coordinator ref | Workflow reference | `v3` | Reviewed supported version tags | Callback source, committed and upgraded explicitly | +| Source coordinator ref | Workflow reference | Exact same-commit self-repository reference | Exact caller commit only | Source workflow invocation | +| Runner route | Existing scalar/label/group route representation | Preserve configured route | Valid existing route values; malformed JSON and dependent expressions rejected | Repository setup configuration | +| Coordinator secrets | Named Secret bindings | Existing explicit named bindings | Only supported named Secrets | Passed to coordinator; provider credential scope remains initial Copilot step | +| Job budget | Fixed duration | 120 minutes | Not configurable by consumer | Coordinator job | +| Native setup timeout | Fixed duration | 5 minutes per native setup step | Not configurable by consumer | Coordinator step | +| Worker readiness | Fixed duration | 300 seconds | Not configurable by consumer | Coordinator wait | + +Validation MUST reject unknown workflow inputs, malformed runner JSON, dependent expressions, and unsupported source identity. Route handling MUST preserve existing valid scalar/label/group semantics. Configuration preview and Apply MUST expose identical effective routing. Recommended configuration uses the installed `@v3` reference and existing validated route; the source-workflow alternative uses the exact same-commit self reference. Correctness limits, gates, credential scope, and timeout budgets are not configurable. Existing Variable and Secret behavior is preserved; operation-time snapshot/reread behavior must match the current owning contract. + +## 8. Clean Architecture + +### 8.1 Responsibilities and dependency direction + +| Layer/boundary | Owns | Must not own/import | +|---|---|---| +| Domain/pure policy | Known workflow identity, input allowlist, route recognition and validation decisions | GitHub SDK or workflow runtime DTOs | +| Application | Setup preview/Apply and maintenance decisions; immutable semantic inputs/outputs | Concrete runner or GitHub process concerns | +| Adapters/data | Mapping repository configuration and workflow facts into semantic contracts | Product policy or inferred permissions | +| Infrastructure/composition | Reusable workflow wiring, native steps, secrets mapping, runner execution | Decisions that weaken invariant gates | +| Entrypoints | Compact event callback, existing admission and coordinator invocation | Duplicated orchestration | +| Presentation | Setup preview/Apply route display and actionable migration guidance | Mutations or runner-route inference | + +```mermaid +flowchart LR + E[Comment callback] --> W[Reusable workflow entrypoint] + W --> N[Native same-job phases] + A[Setup application policy] --> P[Known-workflow and route policy] + I[Repository/workflow adapters] --> A + A --> U[Preview and Apply presentation] + N --> X[GitHub Actions and trusted composite] +``` + +### 8.2 Contracts, state, and trust boundaries + +- Pure decisions: accepted coordinator identity/version, known reusable caller recognition, supported inputs, and valid runner-route shape. +- Application contracts: setup preview and Apply expose the same effective route and migration outcome; unsupported facts produce explicit errors. +- Semantic ports: read workflow identity/configuration and apply only validated setup changes. +- Durable state/schema ownership: existing repository Variables, Secrets, workflow files, and continuation state retain their existing owners and schemas. +- Concurrency/idempotency strategy: preserve existing admission, one-use continuation, candidate identity, and publication guards. +- Trusted and untrusted inputs: issue/comment payloads, repository configuration, expressions, and workflow inputs are untrusted until validated; only supported named values cross the coordinator boundary. +- Provider error mapping: distinguish unsupported platform/reference/policy from workflow execution failure and provide actionable setup/operator recovery. + +### 8.3 Executable architecture constraints + +A pure known-workflow contract MUST target 100% branch coverage. Automated checks MUST parse workflow YAML and verify one-job native ownership, allowed inputs/Secrets, source and installed reference forms, timeout placement, callback line limits, setup route parity, and absence of unrestricted secrets inheritance or credential/PAT setup inputs. Dependency/contract checks MUST ensure pure policy does not import provider SDKs and setup presentation does not mutate configuration. + +## 9. UI/UX and content contract + +### 9.1 Information hierarchy + +Existing result cards remain unchanged and continue to show current status, completed facts, next transition, action requirement, impact, and inspectable links before technical details. Setup migration guidance leads with the route that will be applied and any human action required. + +### 9.2 Representative primary view + +The coordinator does not introduce a new issue/review card. Existing cards are normative and must be preserved byte/semantically as established by the verification owner. Setup preview should communicate the concrete effective route and migration decision: + +```markdown +## Comment workflow setup preview + +**Current status:** Ready to apply the Copilot comment workflow update. + +**Runner route:** `labels: [self-hosted, linux]` + +**Action required:** Review the listed custom bootstrap migration before applying. + +## Changes + +- [x] The callback will call Copilot's comment coordinator at `v3`. +- [x] The configured runner route is preserved in preview and Apply. +- [ ] Custom bootstrap step requires maintainer review. + +## What happens next + +Apply the reviewed workflow update, then inspect the first run's checks and Job Summary. +``` + +Variants: pending/no action reports that no run is required; action required links to migration review; blocked/failed identifies impact, cause, action, retained configuration and run link; partially complete states which setup files changed and which remain untouched; completed links to the applied workflow and verification run. No new comment or notification is emitted solely for coordinator adoption. + +### 9.3 Issue, PR, and comment behavior + +- Deterministic titles and purpose: preserve the existing result-card titles and purposes exactly. +- What merge/close/retry will do: preserve current callback semantics; rerun/retry follows existing admission and does not resume by rerunning the agent through the continuation path. +- Durable marker and idempotent update policy: retain existing markers and one-use continuation policy. +- Comment/notification budget: no additional comments or notifications due to centralization. +- Labels and checks as supplemental state: preserve existing checks and publication guards. +- Direct links and navigation: existing issue/PR and workflow-run links remain descriptive and usable. + +### 9.4 Accessibility, localization, and responsive behavior + +Preserve the existing locale and fallback contract of result cards. New setup guidance uses plain text, descriptive links, semantic headings and short lists; it remains readable on narrow screens and in light/dark themes. Escape untrusted values and do not render configuration as executable Markdown, mentions, HTML markers, commands, or arbitrary URLs. Diagrams have adjacent text equivalents. + +## 10. Failure, recovery, and cleanup + +| Failure/partial state | User impact | Retained facts | Automatic retry | Required action | Cleanup | +|---|---|---|---|---|---| +| Unsupported ref, runner, or Actions policy | Callback cannot start coordinator | Existing configuration and callback remain | No | Meet documented GitHub.com, runner 2.336.0+, and policy prerequisites | No setup state created | +| Unknown input or malformed route JSON | Setup/run fails closed | Original configuration retained | No | Correct supported input/route; inspect preview | No inferred permissions/routes | +| Setup step times out | Verification cannot continue | Candidate and prior facts remain subject to existing semantics | Existing policy only | Inspect failed step and retry through supported entrypoint | Native reverse post cleanup | +| Worker readiness exceeds 300 seconds | Verification is blocked | Candidate identity retained where existing runtime permits | Existing policy only | Inspect run and use documented recovery | Native cleanup | +| Job reaches 120-minute budget | Job is canceled | Completed facts and logs retained | Existing policy only | Inspect timeout location before retry | Native post cleanup runs where platform permits | +| Custom bootstrap migration is unreviewed | Setup Apply is blocked | Existing workflow/configuration retained | No | Review migration and apply explicitly | No silent deletion | +| Publication guard rejects result | No result is published | Verification evidence retained | No automatic publication retry beyond current contract | Follow existing operator guidance | Setup cleanup completes | + +Errors follow impact -> cause -> action -> retained state and must not claim successful prior effects failed. + +## 11. Security, permissions, and privacy + +1. Preserve existing event admission, bot/fork gates, and least-privilege permissions. Coordinator permissions must be explicit and no broader than the existing native callback contract. +2. Treat workflow inputs, event data, repository configuration, route JSON, and expressions as untrusted. Reject unknown or ambiguous values; never infer runner access. +3. Named Secrets remain explicit. Do not use unrestricted secrets inheritance. Provider credentials are scoped to the initial Copilot step and must not be passed to project setup. +4. Preserve trusted-main Action pinning, candidate identity, credential-free verifier profiles, one-use continuations, and guarded publication. Logs and summaries must not expose Secret values or sensitive environment data. + +## 12. Observability and operational UX + +- User-facing state: existing cards and checks remain the source of verification outcome. +- Job Summary/operator evidence: identify callback type, coordinator version/ref, admitted phase, setup/continuation outcome, verifier/publication guard outcome, and cleanup status without secret values. +- Logs, metrics, and correlation: preserve existing run/event/candidate correlation identifiers and sanitize untrusted fields. +- Pending external dependency versus workflow failure: distinguish platform prerequisite/reference rejection from native step failure. +- Rate-limit/retry behavior: preserve existing provider retry behavior and bounds. +- Noise/comment budget: centralization adds no comments or notifications. + +## 13. Compatibility, migration, rollout, and rollback + +Source callbacks use the exact same-commit self-repository workflow reference. Installed callbacks use `vypdev/copilot/.github/workflows/copilot_comment_runtime.yml@v3`. The coordinator uses GitHub's self-repository Action reference so an exact caller SHA cannot drift to another Action version. Require GitHub.com support, runner 2.336.0 or later, and compatible Actions policy; document these prerequisites and how to upgrade the pinned workflow ref. + +Migration MUST preserve source-only jobs and consumer Action bytes and auxiliary assets. Setup MUST retain or explicitly replace existing scalar/label/group routes, display the same route in preview and Apply, and recognize known reusable callers during maintenance. Unknown inputs, unsupported source identity, malformed runner JSON, and dependent expressions fail closed. Custom bootstrap steps require reviewed migration and actionable recovery. Rollout follows the Action-managed issue branch and reviewed PR lifecycle; do not create, rename, or force-push managed branches manually. Keep unrelated release-review changes out absent concrete dependency. Release #661 remains unpublished until this dependency and its final-head checks/review are complete. Rollback restores the prior callback workflow and configuration while preserving existing candidate and result facts; no irreversible effect is introduced by the coordinator itself. + +## 14. Testing strategy and numeric budget + +Minimum additional risk-derived floor: 40 distinct cases shared once across both capabilities; do not double count a case because both callback types use it. + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| Workflow/security mutations | 16 | Admission/bot/fork gates; explicit secrets; no inherit-all; credential scope; trusted pin; timeouts; one job; same-job candidate; continuation; cleanup; publication guards; input rejection | +| Routing/migration/idempotency | 12 | Scalar/label/group routes; preview/Apply parity; known caller recognition; malformed JSON; dependent expressions; custom bootstrap review; source-only jobs; assets/bytes; replay and one-use semantics | +| Configuration inspection/identity/credential scope | 12 | Known workflow contract; supported source identity; installed ref; unknown input; unsupported runner/platform/policy; Variable/Secret semantics; credential boundary; failure recovery | +| **Total** | **40** | No double counting | + +Repository coverage gates remain in force. Changed modules meet existing thresholds; new pure known-workflow policy targets 100% branch coverage. Tests parse workflow structure rather than grep prose, and cover both callback entrypoints against shared coordinator contracts. Use deterministic fixtures and fakes without real waits or live services. Preserve and extend golden result-card fixtures with semantic assertions. Manual UX evidence reviews setup preview/Apply parity and existing result cards at narrow width and light/dark themes. Full implementation validation includes all repository validators, full coverage, package/build smoke, and real native acceptance on Linux, Windows, and macOS. + +## 15. Documentation and discoverability + +| Audience | Artifact/page | Required content | Validation/navigation | +|---|---|---|---| +| User | `docs/issues/comment-commands.mdx` | Existing result behavior and run links remain unchanged | Documentation link/contract checks | +| Setup owner | `docs/setup-web.mdx`, `docs/configuration.mdx`, `docs/configuration-checklist.mdx` | Coordinator installation, route preview/Apply parity, supported inputs and secrets | Fixtures and documentation validators | +| Operator | `docs/security-operations/operations/verification.mdx`, `docs/security-operations/operations/troubleshooting.mdx` | Prerequisites, failure states, timeout/cleanup, recovery | Operator decision-tree review | +| Contributor | `docs/development/architecture.mdx`, `specs/copilot-comment-workflow-coordinator.md`, both existing owning specs | Boundaries, workflow contracts, pinned-ref upgrades, migration | Architecture and specification validation | + +Update user/operator/upgrade documentation, tests, generated bundles, catalog evidence, and `specs/CATALOG.md` together. Document GitHub.com, runner 2.336.0+, Actions-policy prerequisites and pinned-ref upgrades. Cross-reference the branch-synchronization verification SDD without changing its ownership. Keep examples synchronized with contract fixtures. + +## 16. Acceptance scenarios + +1. Given an admitted issue-comment event, when its callback invokes the installed coordinator, then the existing result and publication behavior completes through one job with the same candidate and cleanup semantics. +2. Given a source callback, when it invokes the coordinator, then the workflow reference resolves to the exact same commit and the Action reference cannot drift. +3. Given a setup with a scalar, label, or group route, when preview and Apply run, then both show and apply the same route. +4. Given malformed runner JSON, dependent expressions, an unknown input, or unsupported source identity, when setup or workflow validation occurs, then it fails closed and gives actionable recovery without inferring permissions. +5. Given a worker continuation, when verification resumes, then the one-use continuation verifies the existing candidate and does not rerun the agent or business operation. +6. Given a native setup timeout, worker readiness timeout, or job timeout, when the run stops, then the configured five-minute, 300-second, and 120-minute limits apply and reverse native post cleanup runs where supported. +7. Given provider Secrets, when the coordinator runs, then named Secrets are explicit, provider credentials reach only the initial Copilot step, and project setup receives no provider/PAT input. +8. Given custom bootstrap steps, when setup migration is previewed, then Apply requires reviewed migration and presents actionable recovery without silently dropping steps. +9. Given disabled, read-only, dry-run, or no-op configuration, when the callback executes, then existing semantics and user-facing cards are retained. +10. Given GitHub.com or runner/Actions-policy prerequisites are unmet, when the callback is invoked, then failure is clear and points to prerequisite remediation. +11. Given the documentation and generated bundles are updated, when repository validation runs, then specification/catalog, workflow, coverage, package/build, and cross-platform native acceptance gates are satisfied. + +## 17. Requirements traceability + +| Requirement | Policy/use case/adapter/presentation | Test or evidence | Documentation | +|---|---|---|---| +| Central coordinator and one-job native lifecycle | Workflow composition | Workflow structure contracts; 16 workflow/security cases | Architecture and verification docs | +| Exact source and installed references | Entrypoint/workflow adapter | Ref identity contract cases | Upgrade guide | +| Preserve route and migration behavior | Setup policy and preview/Apply | 12 routing/migration/idempotency cases | Setup/configuration docs | +| Credential and trust boundaries | Workflow inputs and Secret mapping | 12 identity/credential cases plus security mutations | Security credentials and operations docs | +| Existing behavior and result cards | Existing verification owner and presentation | Golden and semantic compatibility assertions | Comment commands and verification docs | +| Platform prerequisites and recovery | Infrastructure/operator guidance | Platform/ref failure contracts | Troubleshooting and upgrade docs | + +## 18. Implementation sequence + +1. Record workflow input/Secret contracts, supported source identity, runner route rules, and architecture checks. +2. Implement pure known-workflow/input/route policy and achieve full branch coverage. +3. Update setup preview/Apply and configuration maintenance recognition with migration outcomes. +4. Implement the central reusable workflow with all native phases and contract tests. +5. Migrate source and setup callbacks, preserving source-only jobs, Action bytes/assets, and custom bootstrap through reviewed migration. +6. Update both owning specifications by cross-reference/change, catalog evidence, generated bundles, user/operator/upgrade docs, and fixtures together. +7. Run repository validators, full coverage, package/build smoke, and real native acceptance on Linux, Windows, and macOS; obtain review and final-head checks before release dependency proceeds. + +## 19. Definition of Done + +- [ ] Source and setup comment callbacks are each at most 35 lines and one central workflow owns all native phases. +- [ ] Existing admission, bot/fork gates, Variable/Secret semantics, time limits, candidate identity, pinning, verifier profiles, continuation, publication, cards, and cleanup are preserved. +- [ ] No unrestricted secrets inheritance or provider/PAT inputs to project setup; named Secret scope is verified. +- [ ] Setup preview and Apply expose identical routes; known callers are recognized; malformed/unknown/ambiguous inputs fail closed. +- [ ] Custom bootstrap steps have reviewed migration and actionable recovery; source-only jobs, consumer Action bytes, and auxiliary assets are preserved. +- [ ] GitHub.com, runner, Actions-policy prerequisites and pinned-ref upgrades are documented. +- [ ] Numeric 40-case budget passes, existing coverage gates remain, and new pure known-workflow contract has full branch coverage. +- [ ] Linux, Windows, and macOS native acceptance, repository validators, full coverage, and package/build smoke pass. +- [ ] User/setup/operator/contributor and upgrade documentation, owning-spec cross-references, generated bundles, catalog evidence, and `specs/CATALOG.md` are current; `pnpm run validate:specifications` passes. +- [ ] Existing result cards pass UX review; failure, migration, security, cleanup, and accessibility requirements are satisfied. +- [ ] Final-head checks and review are complete before dependent release #661 is published. +- [ ] No readiness-blocking decision remains unresolved. + +## 20. References and decisions + +- Primary sources: [GitHub runner action schema](https://github.com/actions/runner/blob/main/src/Runner.Worker/action_yaml.json); [GitHub same-repository self-reference announcement](https://github.blog/changelog/2026-07-30-reference-same-repository-actions-with-self-repository-syntax/). +- Related specs/ADRs/issues/PRs: [Issue #662](https://github.com/vypdev/copilot/issues/662); existing setup owner `specs/setup-runner-profiles-and-installation-parity.md` under `setup-and-doctor`; existing verification owner `specs/repository-verification-setup-hooks.md` under `branch-synchronization`; #647/#652 and #656/#657; dependent release #661. +- Decisions and rejected alternatives: one reusable workflow owns the complete job; generated orchestration in every consumer rejected for duplication/review cost; composite coordinator rejected because it cannot preserve native per-step cancellation; another candidate setup job rejected because it breaks same-job worker/candidate environment; removing time limits is outside scope. Maintainer approved a concise new companion at `specs/copilot-comment-workflow-coordinator.md` under `setup-and-doctor`. +- Follow-up work explicitly outside this spec: publishing release #661 before this issue's implementation and final-head checks/review; unrelated release-review corrections without a concrete dependency. \ No newline at end of file diff --git a/specs/execution-error-and-context-hardening.md b/specs/execution-error-and-context-hardening.md index 4c5bc2675..d19bb0d58 100644 --- a/specs/execution-error-and-context-hardening.md +++ b/specs/execution-error-and-context-hardening.md @@ -804,3 +804,138 @@ pure cases cover native closure, closed label callbacks, open state and missing state. They belong only to this owner: the #474 extension is now 15 execution cases, separate from 56 semantic publication and six autofix cases. Terminal routing/bot-event tests belong to branch synchronization and are not recounted. + +### Stored configuration diagnostics and recovery: #635 (2026-10-21) + +**Problem and preserved contract.** Run +[39565969565](https://github.com/vypdev/zstandard/actions/runs/39565969565/job/119108205733) +rejected a PR block without a schema version. Rejection is intentional: +only the current durable schema is supported. The defect was that the reader +logged a semantic configuration error but rethrew its raw cause; the final +boundary consequently presented `workflow.failed` and retryable true. An +unlinked PR without any block remains eligible for its ordinary PR route. + +**Journey and architecture.** The description adapter maps read failures to +semantic provider/authorization errors. The configuration reader performs strict +parsing/validation and throws `configuration.invalid` with one closed recovery +descriptor: `stored-configuration-schema-missing`, +`stored-configuration-schema-unsupported`, or `stored-configuration-invalid`. +Only a positive safe issue/PR number and expected version, plus a nonnegative +safe numeric actual version for the unsupported case, cross this boundary. +Malformed JSON, values, fields and incomplete delimiters use the invalid +descriptor without copying body/schema text. + +```text +Read issue/PR -> validate stored block -> fail with safe configuration facts + -> localized annotation + Job Summary -> maintainer correction -> rerun +``` + +The flow reads first, rejects unsupported state before PR/issue route mutations, +and exposes a manual recovery action. The final Action boundary MUST preserve +code, nonretryability and correlation identity. It uses existing presentation and +summary ports even when execution setup never completed. Summary publication +failure MUST NOT replace the original failed annotation or turn the run into +success. Existing architecture/taint checks enforce the application/model/adapter +boundaries; raw causes remain private. + +**Configuration and security.** No setting, schema version change, compatibility +reader, automatic migration/reset, workflow, setup step or extra comment is +introduced. Supported state and absent blocks keep their existing behavior. +The failure MUST leave the issue/PR body and configuration untouched. Missing, +old, future and malformed versions MUST remain failed and nonretryable without +correction. A version number alone never establishes valid managed state. +Provider failures retain their own categories and retryability. Closed variable +validation excludes arbitrary text, URLs, credentials and extra fields. + +**GitHub content and recovery.** English and Spanish catalogs cover all three +diagnoses. Other early locales use the established atomic fallback without a +new model call. A fixed recovery URL is inserted by presentation after +localization, so translations cannot supply URLs and remain subject to existing +safe-text validation. Representative missing-schema content: + +```text +Impact: Automation stopped for issue/PR #144: the stored configuration has no +schema version; version 3 is required. +Error code: configuration.invalid +Action: A maintainer must review the recovery guide before correcting the block. +Retained state: The issue/PR description and stored configuration were not changed by this read. +Retryable: No +Reference: +``` + +The complete action links to +[recovery](/security-operations/operations/troubleshooting#unsupported-stored-configuration) +and requires preservation of the original body before removing only a verified +obsolete unmanaged block. If managed branch, release, hotfix or orchestration +state may exist, the operator MUST stop for maintainer review and verified +supported-state restoration. It MUST NOT advise blindly adding a schema version, +deleting managed state, or skipping a failed check. Repeating unchanged invalid +state remains failed without writes. After verified obsolete-marker removal, +the real unlinked setup route MUST configure without inventing an issue link. + +Pending/completed states retain their existing presentation. Partial mutation, +new cancellation/race machinery and navigation registration are not applicable +to this early read failure. Rollout changes only diagnostics; rollback reverts +the diagnostic change while preserving strict validation. Existing in-flight +managed state is never automatically rewritten. + +**Verification floor: 15 distinct cases**, owned only by this extension: + +| Area | Cases | Acceptance/evidence | +|---|---:|---| +| Payload/routing | 6 | absent block, missing version, old version, future version, malformed JSON, valid current state | +| Propagation/provider | 3 | final annotation/summary preserve code/reference/retry; authorization and transient reads retain their own categories | +| Presentation/security | 4 | English, Spanish/fallback, hostile/oversized text excluded, no blind managed-state removal/version edits | +| Recovery/replay | 2 | unchanged replay fails without writes; deliberate obsolete-marker removal recovers an unlinked PR | + +`configuration_recovery.test.ts` owns payload and real setup/replay evidence; +`github_action.test.ts` owns annotation/summary/reference/fallback and summary +failure evidence; issue-content adapter and error/presentation suites own +provider mapping and bounded descriptor tests. Additional malformed-value, +marker, forged-variable and mapping cases do not reduce this floor. +Assertions inspect structured semantics and absence of mutation, not only +snapshots. Existing repository and changed-module coverage thresholds, type +checking, architecture/taint guards, documentation and specification validation +remain required. Inspect a narrow annotation/Job Summary and its recovery link +for readability; native replay of the new diagnostic remains a separate live +verification step until the change is deployed. + +**Documentation and delivery.** Update configuration persistence, error reference +and troubleshooting (including a stable recovery heading), plus the execution +catalog evidence and generated catalog. The implementation sequence is closed +facts/reader, final boundary and localization, adapter mapping, deterministic +tests, docs/catalog, then validation. Done requires all acceptance rows to pass, +generated evidence to be current and strict rejection to remain intact. + +### Literal configuration marker mentions: release review #660 (2026-10-21) + +Finding 4342237487 exposed a false configuration error for an ordinary mention +of one delimiter. The description-format adapter MUST distinguish such prose, +inline/indented quotes and closed, unpaired code examples from actual state. +Actual delimiters begin a line with at most three spaces. A complete legacy +record inside a code fence MUST retain strict parsing, not become absent: this +preserves the previous reader's state ownership and existing recovery guidance. +Multiple complete records, incomplete actual delimiters and potential state +behind an unclosed fence MUST fail closed without provider writes or state loss. +JSON backticks, CRLF records and single-line records beginning a line remain +supported. No payload schema, permission, locale, setting or reset is added. + +Both reading and persistence MUST use the same description-format policy in +src/manager/description/configuration_markers.ts. A first write appends state +after literal mentions without altering the human prefix; it closes a dangling +code example with no existing record before appending owned metadata. An update +replaces only the verified owned span. Generic non-configuration content blocks +retain their existing adapter. The existing configuration.invalid diagnosis, +nonretryability and maintainer recovery UI apply to ambiguous state. Rollback +selects the prior reader while preserving description history and state. + +The additional floor is **21 distinct cases** in configuration_recovery.test.ts: +nine ordinary mention/unpaired fence variants, six legacy/format/selection +boundaries, three actual malformed/duplicate/ambiguous-state guards and three +write/read preservation journeys. Every rejection asserts no provider write; +write cases preserve the original human text and read the resulting supported +state. Changed format policy targets at least 95% lines and 90% branches, with +the existing global quality gates unchanged. These tests establish this format +boundary rather than provider runtime readiness. Update troubleshooting, catalog +evidence and generated catalog, then pass focused/full tests, type/lint, +documentation/specification checks and rebuilt package gates before release. diff --git a/specs/local-web-setup-assistant.md b/specs/local-web-setup-assistant.md index ef167c155..c5aed2829 100644 --- a/specs/local-web-setup-assistant.md +++ b/specs/local-web-setup-assistant.md @@ -47,6 +47,13 @@ installation questionnaire. Terminal behavior and full-wizard guards remain. ## 1. Executive summary +The additive verification starter, shared activation question, create/preserve +review and upgrade behavior are defined in the catalogued companion +[`verification-setup-onboarding.md`](./verification-setup-onboarding.md). It uses +the existing boolean and setup approval pipeline; consumer action assets remain +outside generator overwrite/retirement ownership. + + The default `copilot setup` remains the terminal wizard. `copilot setup --web` starts a short-lived web assistant on this machine and opens the default browser. It presents repository identity, setup choices, the temporary setup @@ -2415,8 +2422,9 @@ called secure. That external policy review remains an open security gate. The 2026-10-05 runner-cost decision supersedes only the blanket hosted-runner requirement for the repository's `CI Check` and `RepoWise code health` jobs. -Both MUST use an Ubuntu self-hosted `codex` runner for repository-owned PRs, -pushes, and manual runs. A fork PR or any merge-group event MUST instead use +As amended by issue #639 on 2026-10-21, `CI Check` MUST use an Ubuntu +self-hosted `codex` runner for repository-owned PRs, pushes, and manual runs. +A fork PR or any merge-group event MUST instead use disposable `ubuntu-latest`: a merge group can contain fork code but its event does not expose the original PR trust classification to the runner selector. The quality checks still run without executing that code on a persistent @@ -2445,6 +2453,17 @@ exception. A fresh run on each selected runner type is required before calling the routing operationally verified; static workflow checks alone do not prove runner availability or the outcome of remote jobs. +Issue #639 supersedes RepoWise's automatic routing cases above. RepoWise MUST +now run only under `workflow_dispatch` on Ubuntu `codex` with the native selected +repository ref; it MUST NOT run on PR, push or merge-group events or be required +for them. The retained CI routing cases still prove the fork/merge-group trust +boundary. The [manual-only migration contract](./merge-queue-readiness.md#manual-only-repowise-migration-2026-10-21-issue-639) +and its [bounded-analysis follow-up](./merge-queue-readiness.md#bounded-manual-repowise-analysis-2026-10-21-issue-644) +define the 60-case regression floor, live required-check evidence, immutable +revision reporting, measured phase budgets and cleanup, operator journey, +failure/retry behavior and complete final-revision manual acceptance. This is a workflow +scheduling change with no setup-session, PAT, web UX or new configuration change. + The first [RepoWise run on `e197cb0c`](https://github.com/vypdev/copilot/actions/runs/37289899480) failed workflow validation before any job started. Its job-level `env` used `runner.temp`, which GitHub's [context availability table](https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#context-availability) @@ -2613,8 +2632,9 @@ pass; the prior manual result does not substitute for it. recovery, and PAT cleanup/renewal guidance are linked and validated. - [ ] Build, lint, typecheck, coverage, architecture, workflow, package, documentation, catalog generation, and `validate:specifications` pass. -- [ ] Repository-owned CI and RepoWise run on self-hosted Ubuntu, fork PRs on - hosted Ubuntu, and the approval observer on self-hosted `codex`. +- [ ] Repository-owned CI and manual-only RepoWise run on self-hosted Ubuntu; + CI for fork PRs/merge groups runs on hosted Ubuntu, and the approval + observer runs on self-hosted `codex`. The self-hosted macOS, Ubuntu and Windows fixture matrix is manual only. npm publication remains hosted for Trusted Publishing. All six platform jobs pass their full fixture, package, coverage and validator contracts; @@ -2935,3 +2955,18 @@ help and retained question, and public Git-ref documentation renders correctly. That inspection is agent evidence, not a substitute for the outstanding human accessibility or cross-platform acceptance reviews. No open product decision blocks this bounded amendment. Related work: issues #617 and PR #618. + +### Hosted Windows verification budget (2026-10-21, PR #654) + +The synchronized pre-branch SDD fix reached the hosted Windows job's 20-minute +limit without a failing assertion (run 39645186744). The preceding exact-base +Windows job took 19 minutes 34 seconds (run 39644175943). The hosted Windows +job MUST have a fixed 30-minute limit to complete native setup, isolated +fixtures, package checks and full coverage; hosted Ubuntu/macOS retain 20. +The existing complete suite, two-worker cap, subprocess deadlines, coverage and +acceptance budgets, documentation gates and deferred cleanup remain mandatory. +A canceled or timed-out run is missing evidence, never a pass. Acceptance is a +successful fresh Windows run on the reviewed head, alongside the other platform +jobs. Existing parsed workflow-contract checks cover this configuration change; +no new application behavior or test count is introduced. Contributor guidance +is in docs/development/testing.mdx; no consumer setting or migration is added. diff --git a/specs/merge-queue-readiness.md b/specs/merge-queue-readiness.md index 3506bf285..cad8b464e 100644 --- a/specs/merge-queue-readiness.md +++ b/specs/merge-queue-readiness.md @@ -4,7 +4,7 @@ complete; clean-tree bundle validation and controlled live queue validation remain external completion gates - Date: 2026-09-10 -- Last updated: 2026-09-15 +- Last updated: 2026-10-21 - Owners: `vypdev/copilot` product and engineering maintainers - Scope: discover the effective merge policy of every deployment target and prevent a managed pull request from entering an unusable merge queue. @@ -89,7 +89,11 @@ longer exhibit these behaviors. 6. Enqueueing does not pass GraphQL `expectedHeadOid`, and queue membership is not read before a retry. -### 2.3 Live repository evidence captured on 2026-09-10 +### 2.3 Historical repository evidence captured on 2026-09-10 + +The RepoWise required-check and automatic-trigger facts below are historical. +The manual-only migration below supersedes them; queue readiness still inspects +live effective rules rather than assuming that this snapshot remains current. - `GET /repos/vypdev/copilot/branches/master/protection` returned `404 Branch not protected` because no classic protection rule applies. @@ -116,6 +120,9 @@ longer exhibit these behaviors. ### Event-scoped advisory history correction (2026-10-14) +This event-range contract is retained as historical evidence. The manual-only +migration below retires the automatic event-base path. + Dogfooding [#496](https://github.com/vypdev/copilot/issues/496) reproduced a RepoWise 0.45.0 `MemoryError` while batch-reading all historical blobs in [run 38472995406](https://github.com/vypdev/copilot/actions/runs/38472995406). @@ -151,6 +158,201 @@ historical audit. Run workflow/specification/documentation validators and the workflow regression suite; no coverage threshold is reduced. A fresh exact-head run must prove the producer reaches artifact upload and reports any incomplete advisory scan honestly; it is still an open gate. + +### Manual-only RepoWise migration (2026-10-21, issue #639) + +RepoWise MUST run only through `workflow_dispatch`. PRs, pushes, merge groups, +schedules and reusable-workflow calls MUST NOT launch it. CI and merge queue +MUST complete without a RepoWise result. This supersedes the earlier required +RepoWise producer and event-range scanning contract, without changing runtime +queue-readiness policy or any consumer's required checks. + +Live GitHub inspection on 2026-10-21 found active repository ruleset +`25205979` (`Release automation required CI`) requiring only GitHub Actions +`CI Check` on both `master` and `develop`. Classic protection on `master` is +absent (404); classic protection on `develop` also requires only `CI Check`. +The old `Master Push Check` and `Develop Push Check` rulesets are disabled. +RepoWise therefore needs no live protection change for this migration. Operators +MUST recheck effective rules before rollout; if RepoWise becomes required again, +remove only that requirement before retiring automatic triggers, preserving all +other checks. A manual-only required producer remains unsupported by the existing +fail-closed merge-queue preflight; no attestation may bypass that known fact. + +```text +Maintainer -> Actions / RepoWise Code Health / Run workflow -> select reviewed ref + -> bounded analysis -> commit-bound Job Summary and report artifact +PR / push / merge group -> normal CI -> no RepoWise dependency +``` + +Text equivalent: maintainers explicitly select a reviewed repository branch and +inspect that run's summary and artifact; automatic change validation does not +start or await RepoWise. The native selector uses the repository default branch +unless another ref is selected. No new input, secret, runtime option or durable +application state is introduced. Dispatch is available because the workflow +already exists on the default branch. CLI example: +`gh workflow run repowise.yml --ref develop`. + +The workflow owns event admission, Ubuntu `codex` runner selection, read-only +contents permission and originally a 30-minute job budget. Checkout MUST retain the selected +revision and full history without credentials. The original advisory subprocesses used +90-second and 2 GiB limits; issue #644 supersedes these budgets below. Manual +security scanning covers full reachable history. Per-ref `repowise-` concurrency cancels an older manual run for the same +ref without sharing CI's group. Python environments and reports remain isolated +by run/attempt, with unconditional upload followed by cleanup. No domain, use +case, port, provider DTO or composition change is needed: the repository workflow +is the adapter boundary, enforced by the existing parsed-YAML contract validator. + +| Visible state | Meaning and next action | Retained evidence | +|---|---|---| +| Queued/running | Analysis requested; open this Actions run, no automatic CI wait | Native run/ref identity | +| Complete | Read `Analyzed revision: ` and download `repowise-code-health` | `revision.txt`, index log, health Markdown/JSON, advisory status; 14 days | +| Partial | `security: incomplete (exit )`; inspect the warning before retrying | Completed health reports remain; no complete-audit claim | +| Failed | A core setup/index/health step failed; inspect logs and retry after correction | Available files upload even after failure | +| Canceled | A newer run for the same ref replaced this one, or an operator canceled it | Native cancellation state; runner loss/cancellation can prevent upload | + +The existing English Job Summary adds only the immutable commit SHA; it does not +render an untrusted branch name. Native GitHub status and artifact links provide +navigation in narrow/light/dark views. There are no new bot comments or locale +inputs. Restoring automatic execution would require coordinated workflow, +contract, documentation and required-check review; restoring only a required +RepoWise rule would block change validation. + +Regression floor: **24 distinct workflow-contract cases**: one valid manual +dispatch, five forbidden automatic/reusable triggers, one missing dispatch, +seven budget/permission/checkout/concurrency mutations, one Ubuntu runner +selection, and nine scan/report/revision/summary/artifact mutations. Retain the +existing Python-isolation, cleanup and incomplete-scan cases and all repository +coverage thresholds. These deterministic YAML mutations cover admission, +execution bounds and reporting; runtime policy, localization and new provider +adapter tests are not applicable because those contracts do not change. + +Acceptance and traceability: + +| Observable requirement | Evidence | Documentation | +|---|---|---| +| Automatic events do not launch RepoWise | Parsed trigger mutations plus final-head PR run inventory | `docs/development/testing.mdx` | +| Manual selected-revision reports remain useful and bounded | Execution/report mutations plus final-head manual run and artifact | testing and self-hosted runner guides | +| CI/merge queue can complete independently | Live rules above, retained merge-group contracts and final-head CI | deployment and release-process guides | + +Run workflow regressions, workflow/documentation/specification validators, and +Graphify update. Completion requires a real manual run on the final revision and +review of its summary/artifact; a queued run or static test is insufficient. +Catalog evidence and the runner appendix in the setup-assistant SDD MUST agree. + +### Bounded manual RepoWise analysis (2026-10-21, issue #644) + +Status: implemented contract; native final-revision evidence is required before +completion. Owner: Copilot maintainers. No open design decisions. This section +supersedes the original budgets, incomplete-status handling and regression count +above; admission, permissions, checkout, isolation and retention stay in force. + +The [previous manual run](https://github.com/vypdev/copilot/actions/runs/39573977241) +spent 20m37s in the job: indexing took 8m6s, health ran twice, dead-code exceeded +90 seconds and full-history security raised `MemoryError` under 2 GiB. Historical +JavaScript blobs alone total approximately 9.2 GB. Upstream +[RepoWise 0.58.0](https://github.com/repowise-dev/repowise/releases/tag/v0.58.0) +serves stored health/dead-code, but its history reader still materializes all +blobs. Upgrading alone does not resolve the memory failure. A local single-worker +streaming trial covered 22,975 source blobs / 9,515,793,415 bytes in 1232 seconds; +this CPU measurement motivates the fixed two-worker queue rather than merely +extending the history deadline. Native final-head metrics remain the release gate. + +```text +Manual selected ref -> one fresh standard index -> cached health MD/JSON + safe dead-code + -> full-history secret scan, two bounded analysis workers + -> validated reports + scope/timings -> artifact + summary +``` + +Text equivalent: index once, export stored results, scan full history with bounded +blob residency, validate completeness, and publish evidence. No application +runtime, setup session, domain model, provider port or public configuration changes +are needed. The workflow owns execution and cleanup; `repowise_reports.py` owns +phase sequencing, resource limits, validation and summary presentation; +`repowise_history.py` adapts pinned RepoWise/Git interfaces. Neither imports the +TypeScript application. YAML mutation tests enforce wiring; Python fixtures enforce +the private-package adapter and output semantics. + +Fixed, non-configurable execution budgets: + +| Phase | Wall limit | Virtual memory per process | Behavior | +|---|---:|---:|---| +| Fresh standard index | 900s | 4096 MiB | No prose/editor/key/hook setup or worktree seeding; 500 commits for git analytics | +| Each cached health format | 60s | 2048 MiB | All indexed origins, refactoring targets, no recomputation | +| Cached safe-only dead-code | 60s | 2048 MiB | Requires successful dead-code phase and matching index SHA | +| Full-history security | 1200s | 2048 MiB coordinator; 1024 MiB per worker | Two workers, all reachable refs/commits, supported source extensions, RepoWise secret kinds and upstream allowlists | +| Complete job | 40 minutes | Phase limits above | Leaves two minutes beyond summed phase ceilings for setup/publication | + +The 500-commit analytics setting preserves the former index default and MUST NOT +limit history security. Bundles remain included. The history adapter MUST retain +upstream provenance, secret kinds, deduplication, line suppression, path allowlists +and multiline PEM detection. It MUST fail on Git enumeration/read/persistence +errors. At most two tasks/results are in flight, with one request/response per worker. +The reader retains no blob cache; results are consumed in upstream history order. +Memory scales with metadata plus current blob processing, not total historical +content. Existing upstream metadata tables are still materialized. A single giant +blob can exceed the process cap; that is incomplete, never silently skipped. + +The adapter uses two spawned processes with a fixed-width prefetch queue. +Negative results do not copy source text back to the coordinator; positive results +retain complete text for unchanged fingerprint/material handling. Worker failures +propagate, and timeout kills the entire process group, including workers and Git. +The adapter omits call/code-smell analysis that upstream history mode discards, +and uses a conservative literal prefilter before the unchanged secret detectors. +Fixtures MUST compare every supported secret kind, Unicode keyword matching, +multiline PEM and removed/other-ref secrets against upstream behavior. The +version is pinned exactly; any upgrade requires compatibility fixtures before +publication. No remote cache or stale index is accepted. JSON health identifies +`source: index`; index events MUST confirm ready status plus completed health and +dead-code analysis at HEAD. Security MUST match the reachable commit count and +requested/read source-blob count. Malformed JSON is removed instead of published +as a complete report. + +The artifact MUST contain `revision.txt`, `scope.json` (SHA, ref snapshot, tool +version and explicit scopes), `timings.json`, `history-resources.json`, per-phase +logs/resource records, `summary.md`, advisory status and all completed reports. +RSS is GNU time's largest-process peak, not a sum of simultaneous processes; +virtual-memory limits apply to each process. Security output is RepoWise's JSON +aggregate, not a guarantee that no secrets exist. The local database is removed +and findings/secret material are not added to the artifact. + +The English summary shows status first by phase, SHA, seconds and peak RSS with +artifact/retry instructions. Example rows: `dead-code | complete | 2.1 | 96.0` and +`security | incomplete | 1200 | —`. Completed analysis says "Analysis complete. +Findings are advisory"; partial analysis says "Analysis incomplete. Inspect phase +logs in the artifact, fix the cause, then rerun." Incomplete scans now fail this +optional job while preserving completed reports. Index failure blocks cached +exports but still attempts the independent history scan. Timeout kills the process +group. Cancellation/runner loss can still prevent publication; retry manually. +No comments, locale settings or automatic retries are introduced. Native GitHub +queued/running/canceled states and artifact links remain the navigation; textual +statuses and plain tables work on narrow screens and in light/dark mode. + +Regression floor: **60 distinct cases**, comprising the retained **21** manual +workflow admission/permission/isolation/wiring/report mutations and **39** Python +cases: 14 detector/version compatibility, 5 blob/Git protocol/error cases, +1 deleted-secret/other-ref/provenance integration, 15 resource/report/failure cases, +and 4 bounded-prefetch/order/worker-failure/delegation cases. Cases use synthetic credentials, temporary repositories and mocked clocks/ +processes for timeouts; they do not need live services or real waits. The Python +suite runs in the pinned Python 3.12 manual environment before analysis. Repository +Jest coverage thresholds remain in force; the standalone Python adapter uses +behavioral compatibility/failure evidence rather than a new percentage threshold. + +| Requirement | Acceptance/evidence | Documentation | +|---|---|---| +| Cached results belong to completed current index | Progress/state/JSON guards, fixtures and final-head artifact | Testing guide | +| Full history completes without bulk contents | All-kind differential fixtures, deleted/other-ref provenance, native counts/RSS/bytes/timing | Testing + runner guides | +| Failures remain truthful and bounded | Protocol, malformed data, exit, timeout/group kill, partial summary fixtures | Retry instructions | +| Optional workflow remains isolated | Parsed YAML regressions, CI and manual final-head run | Manual dispatch guide | + +Roll out only through the linked PR. Rollback restores the former pin/workflow +but also restores known incomplete scans; it must not restore automatic triggers +or required checks. Definition of Done: the numeric test budget passes; workflow, +documentation and specification validators pass; catalog evidence and Graphify +are current; native final-head analysis produces **complete dead-code and security** +with measured time/memory and inspected summary/artifact; CI passes independently. +A queued run, green partial job, or merely relaxed limits is insufficient. + +### Other merge-queue evidence from the original implementation - Copilot's own required PR context is produced for merge groups by the dedicated `copilot_pull_request_merge_queue.yml` workflow. Keeping that lightweight producer separate avoids a skipped duplicate check on every @@ -549,7 +751,6 @@ Queue rule: required Producer Source Evidence CI Check GitHub Actions Verified · ci_check.yml handles merge_group -RepoWise code health GitHub Actions Verified · repowise.yml handles merge_group No action required. Rerun `copilot doctor` after changing rules, workflows, or attestations and before the next release. @@ -874,3 +1075,26 @@ feature must prevent and violates the event-driven no-polling architecture. for merge-queue targets. - Automatic edits to rulesets or vendor CI. - A live destructive merge-queue test in a user repository. + + +### Publication callback policy parity (2026-10-21, #643) + +Preparation, normal publication, reconciliation-only resume and managed-PR +continuation MUST all pass the live `MERGE_QUEUE_CHECK_ATTESTATIONS` Repository +Variable with an absent-value `[]` fallback. Consumer templates and source +release/hotfix workflows share this contract. A normal callback starts +reconciliation just as resume does; neither may substitute an empty literal or +a snapshotted preparation value. Target selection, producer identity, failed +policy handling and retained publication state remain unchanged. No new input, +permission, UI state, automatic retry or deployment is introduced. + +Flow: prepared promotion -> confirmed publication -> live target policy -> +reconciliation, or the existing blocked recovery state. Existing status cards +and recovery guidance remain authoritative; install updated generated workflows +to adopt the correction. The added numeric test budget is **24 distinct cases**: +source/consumer × release/hotfix × preparation/publication/resume × missing/stale +input. Existing continuation tests cover its fourth entrypoint. Structural +workflow validation rejects either omission or a literal value; all canonical +workflows must pass. Documentation: deployment orchestration's live-policy mapping. +Acceptance: each entrypoint supplies the expression on the actual Action step; +no publication/release is launched to test wiring. diff --git a/specs/pre-branch-sdd-gate.md b/specs/pre-branch-sdd-gate.md index 57b071ff5..6823b7f4f 100644 --- a/specs/pre-branch-sdd-gate.md +++ b/specs/pre-branch-sdd-gate.md @@ -1085,3 +1085,226 @@ migration; adapted standards retain that rule in a numbered section. The canonical normative rule MUST occur inside one numbered section; concatenating fragments across section boundaries cannot establish it. Two additional adapter cases cover this boundary, included in the 91-case amendment floor. + + +### Safe rejected ownership and bounded recovery (2026-10-21, #636) + +Observed defect: semantic ownership validation could reject a successful model +response before any issue card, leaving only generic workflow failure. The gate +MUST preserve validation and classify update-owner mismatch, unknown companion +owner, registered companion path, registered new owner and registered new path +with closed typed reasons. When both companion constraints fail, unknown owner +has deterministic precedence. Generated owner/path values and response text MUST +NOT enter this diagnostic. The immutable snapshot and catalog remain authoritative. + +The recovery policy is **one analysis per invocation, zero automatic repairs**. +A maintainer clarifies the catalog ID/path in the same issue and reruns the +original workflow, which performs fresh analysis and unchanged freshness checks. +This amendment selects the maintainer-recovery option; invalid proposals never +become invented clarification plans or stored validated owners. Existing answers, +SDDs and published branches/commits are retained. A provider outage or malformed +shape remains its existing failure, not an ownership retry. + +```text +Analysis -> semantic rejection -> owned diagnostic -> maintainer clarification +-> normal rerun -> fresh valid analysis -> unchanged draft/publication checks +``` + +Text equivalent: a rejected decision blocks; a human clarifies the same issue; +a fresh invocation may progress only after normal semantic and publication checks. + +UI: **SDD work status: analysis blocked** explains that no new draft/publication +was prepared, gives the specific closed cause, then asks the maintainer to clarify +and rerun. English/Spanish copy uses the issue locale. An owned, issue-bound +`copilot:sdd-analysis-status:v1` diagnostic is reused and unchanged retries emit +no mutation. It has no readiness marker, no questions, proposed values, commands, +external URLs or new configuration. A later validated owner updates it to +“Publication and branch readiness remain subject to their checks.” Existing +pending/question, partial-publication and completed cards retain their contracts. +A foreign marker is never overwritten. Failed comment publication remains blocked. + +Domain owns typed semantic failures; the application presentation policy owns +closed localized content; the use case uses its existing bound comment port. +No SDK, filesystem, process or provider DTO crosses into either pure module. +Typecheck, architecture tests and fault-injected use-case tests enforce the +boundary. No credential or permission expansion, migration or new state schema. +Upgrade the Action, clarify the same issue and rerun; rollback loses this +additional diagnosis but cannot authorize invalid ownership. + +The additional budget is **22 distinct cases**: five typed domain classifications; +ten use-case reason/locale boundaries; seven retry, recovery, identity, provider, +malformed-analysis and comment-failure cases. Existing valid update/companion/new tests remain required. +Acceptance checks that invalid analysis makes no draft validation or publication +call, does not add `branched`, leaks no proposed identifiers or response, and is +not parsed as readiness. Documentation: ownership analysis recovery in the +pre-branch SDD guide. Definition of Done also requires existing global quality, +package and catalog gates, preserved safety checks and review of both locale +messages; tests do not claim a live consumer recovery. + +### Generated draft consistency (2026-10-21, #653) + +Issue [#653](https://github.com/vypdev/copilot/issues/653) documented a published +companion that reused a baseline case ID for the opposite authentication +behavior, had offsetting area-allocation errors and one-sided requirement links, +and cited a nonexistent documentation update path. Arithmetic and catalog +validity alone did not establish a coherent generated contract. This amendment +requires internal publication consistency; Draft/Proposed publication MUST +remain separate from product, security, operator and runtime acceptance. + +Generated candidates MUST use these visible English-header tables in their +canonical numbered sections; localized surrounding prose remains supported: + +| Section | Columns | Contract | +|---|---|---| +| 4 | Requirement / Behavior | Unique stable IDs for the draft's requirements | +| 14 | Area / Minimum distinct cases / Behaviors/risks covered | Positive integer allocations and one final Total | +| 14 | Case ID / Area / Requirements / Scenario | One distinct full case ID, exact area, comma-separated requirement IDs and observable scenario per row | +| 15 | Path / Change | Immutable existing files for update/reference; explicitly absent proposed files for create | +| 17 | Requirement / Cases | Comma-separated full case IDs; exact reciprocal links for every requirement | + +Missing, duplicate, malformed, empty, hidden or fenced inventories block. Every +area's allocation MUST equal its distinct inventory count, and the total MUST +match both. Cases and requirements MUST name only defined IDs and agree in both +directions. Uncovered goals and generic documentation checks cannot establish +acceptance. These structural checks cannot certify the completeness or meaning +of every natural-language requirement; human review remains mandatory. + +Every catalogued SDD for the selected owner MUST be read at the immutable base. +Its full case IDs are reserved, including namespaces inferred from legacy +shorthand rows/ranges. A new case MUST NOT redefine a reserved ID, even when its +scenario seems similar. Baseline references use full IDs and do not count as +new cases. New cases use a separate namespace, such as identity-development-C01. +Unavailable owners, more than 30,000 serialized reserved-ID characters, or a +legacy range spanning over 1,000 increments block without truncation or repair +of the immutable owner. These fixed bounds have no public setting. Retained +owners keep their existing prose budgets and bytes; only new candidates need +the tables. No catalog or durable-status schema migration is introduced. + +The workspace MUST resolve cited paths against the immutable Git tree, not +uncommitted files or the post-write scratch tree. Repository-relative code +spans, ordinary file citations and relative Markdown destinations are checked; +external URLs and local anchors do not claim repository existence. Existing +files can use any language/layout. Future files MUST be explicitly declared +create, absent from the base and outside symlink/submodule or regular-file +parents. Update/reference declarations require regular files. The selected new +SDD is itself proposed. This flow writes only the selected SDD/catalog files. + +```text +answered plan -> read all immutable owners -> reserve baseline case identities + -> draft visible inventories -> check cases, areas, mappings and paths + -> one shared repair, or specific non-ready recovery + -> unchanged freshness/link/first-commit proof -> draft publication + -> independent human and runtime acceptance +``` + +Text equivalent: owner evidence precedes drafting; deterministic validation +accepts a candidate or spends the existing single repair. Repeated contradiction +stops before publication. The existing branch/commit proof still follows. + +Architecture: the pure src/domain/sdd_draft_consistency.ts policy owns inventory, +identity, budget, mapping and path decisions without filesystem, process, +provider or presentation imports. Application code reads every owner through +the existing port and supplies reserved IDs to both bounded drafting attempts. +The workspace adapter supplies immutable regular-file/directory/blocked-path +sets, validates before composing the retained owner or writing, and always +removes scratch worktrees. Recovery extracts and revalidates the proposed +appendix and verifies recomposed bytes, preserving the existing first commit. +This avoids treating retained owner cases as new definitions during replay. +Existing architecture, type, catalog and publication tests enforce the boundary. + +UX retains the existing localized error surface and notification budget. +Pending: validation runs with answers retained. Action required/blocked: after +the shared repair, a closed category identifies case identities, allocations, +requirement mappings or paths. Representative content: "SDD publication stopped +after one automatic repair: per-area allocations disagree with the distinct +case inventory. Review the draft tables; reconcile each area and the total with +the enumerated cases. Retry the same issue workflow." Retained state says +answers and published SDDs remain and no draft was published. Partial push +success keeps the exact branch/commit for ordinary replay. Complete means the +consistent draft was published; runtime acceptance remains open. English and +Spanish messages use the existing impact/action/retained-state order, textual +headings, mobile/screen-reader behavior and closed sanitized content. Rejected +Markdown, case IDs, paths and diagnostic text MUST NOT enter repair instructions +or public messages. There is no additional card, label, credential or setting. + +The amendment has a minimum **126 distinct cases**, separate from earlier floors: + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| Pure consistency policy | 95 | Owner collisions and aliases, hidden/malformed inventories, invalid/valid fence and comment boundaries, offsetting budgets, reciprocal mappings, immutable/proposed paths and relative URL components, mutually incompatible proposed paths, portable layouts and bounded ranges | +| Application and bounded draft workflow | 9 | All-owner reads, missing/oversized context, blocked publication, four closed repairs and corrected-draft revalidation | +| Publication replay boundaries | 5 | Minimum/maximum candidate lengths, normalized outer whitespace, retained prefix and exact recomposition | +| Real Git workspace | 13 | Each reported contradiction and falsely closed code block blocks publication; valid relative-link queries resolve immutable/proposed evidence; ignores uncommitted evidence, preserves the owner and removes scratch worktrees | +| Localized recovery | 4 | All four closed variants render English/Spanish retained state without runtime acceptance claims | +| **Total** | **126** | Existing cases are not recounted | + +Repository coverage thresholds remain mandatory; new pure policy targets at +least 95% lines, with negative/boundary branch fixtures. Tests use deterministic +text/agents and local bare remotes without providers or sleeps. Existing +update/companion publication and post-push recovery fixtures remain required. +Human content review checks the specific recovery action and the separation of +publication/runtime status; no new interactive layout requires visual testing. + +Acceptance/traceability: sdd_draft_consistency.test.ts proves that a case changed +to an owner ID, offsetting allocations, a one-sided link or a missing document +fails its specific category. Workspace tests repeat the four failures against +Git objects and prove no branch or scratch workspace remains. Gate tests prove +every owner reaches reservation and exhausted validation never publishes. +Draft workflow tests prove closed feedback, specific recovery and the shared +two-attempt ceiling. Presentation tests prove both locales. Corrected tables +and intentional new paths pass; existing owner bytes and verified replay remain +preserved. Fixtures establish consistency, not live provider or runtime quality. + +Delivery sequence/Definition of Done: implement pure policy and tests; bind +immutable inventory and owner context; preserve verified replay; add localized +closed recovery; update docs/issues/pre-branch-sdds.mdx, catalog evidence and +CATALOG; pass specification, documentation, architecture, type, lint, test, +build and package gates. All new evidence files MUST exist. No runtime +prerequisite, framework or acceptance check may be weakened. In-flight drafts +use the contract at their next validation. Rollback selects the previous Action +version without rewriting historical commits or branches. + +PR #654 review finding 4339327223 closes an inventory exemption: section 15 MUST +include the selected SDD itself, with create when absent from the immutable base +and update when it already exists. Reference, omission or a self-link cannot +substitute for this row. No SDD path is implicitly pre-approved. Ten additional +pure cases cover these declarations and malformed table/fence boundaries; five +workspace cases cover omitted update/companion rows, unsafe owner evidence and +recovery rejection for a replaced owner or changed revalidation bytes. They are +included once in the amendment floor above. The existing closed path +recovery, shared retry ceiling and localized publication/acceptance distinction +remain unchanged. + +PR #654 review finding 4340243954 requires a matching code fence to close only +when it has at most three leading spaces and only spaces or tabs after its +marker, following [CommonMark fenced-code rules](https://spec.commonmark.org/0.31.2/#fenced-code-blocks). +An info string remains valid on an opening fence. Text after a possible closing +marker, a shorter/different marker or four leading spaces cannot expose the +enclosed contract. Comment syntax inside a fence is literal and MUST NOT be +removed before deciding whether that original line closes the fence. Fence +markers inside HTML comments cannot alter the surrounding visible contract. +Sixteen pure regressions cover invalid backtick/tilde closers, owner reservations, +valid longer closers with trailing whitespace and comment/fence precedence; two real +Git regressions reject update/companion publication while preserving the owner +and cleaning scratch worktrees. These eighteen cases raise the amendment floor +from 93 to 111. No new setting, retry, diagnostic category or public status is +introduced; docs/issues/pre-branch-sdds.mdx explains the visible-table boundary. + +PR #654 review finding 4340463276 requires relative Markdown destinations to +resolve their repository pathname independently of URL queries and fragments. +The validator separates literal `?`/`#` delimiters before percent decoding the +pathname, preserving encoded path characters for the existing safety/existence +checks. Query-only or fragment-only destinations keep the current SDD; queries +cannot make a missing, invalidly encoded or unsafe pathname valid. Seven pure +and two real Git update/companion cases cover existing/proposed paths, combined +query/fragment destinations and negative evidence. These nine cases raise the +floor from 111 to 120; docs/issues/pre-branch-sdds.mdx documents the URL behavior. + +Release PR #660 finding 4342237483 requires all proposed files to be compatible +with one another as well as the immutable tree. A proposed regular file MUST +NOT also be an ancestor of another proposed file, independent of table order +or nesting depth. Six additional pure cases reject both orders at direct and +deeper depths and accept siblings and distinct pathname prefixes. They raise +the pure floor to 95 and the amendment total to 126. Existing closed path +diagnostics, one-repair budget, immutable evidence and no-publication behavior +remain unchanged; the pre-branch SDD guide documents this boundary. diff --git a/specs/repository-verification-runtime-prerequisites.md b/specs/repository-verification-runtime-prerequisites.md index 1d3b45837..46f96ce6a 100644 --- a/specs/repository-verification-runtime-prerequisites.md +++ b/specs/repository-verification-runtime-prerequisites.md @@ -317,3 +317,7 @@ this change adds no stateful retry or remote race boundary. inference, credential broadening and parsing untrusted failed-command output. - Outside scope: live consumer Kotlin/Gradle retest, other home/cache variables, automatic setup questionnaire requirements, automatic dependency provisioning. + +## Optional repository setup amendment — issue #647 + +The [repository-owned setup contract](./repository-verification-setup-hooks.md) adds an explicit disabled-default `verification-setup` boolean. When enabled, a trusted main-branch Node helper prepares each candidate command environment before these existing fixed runtime probes. The runtime declaration remains a version-only policy and never supplies script paths, commands, credentials or installer arguments. With setup disabled, prerequisite behavior is unchanged. The companion owns its incremental tests and bounded setup limits; all existing no-push, isolation and preflight constraints remain required. diff --git a/specs/repository-verification-setup-hooks.md b/specs/repository-verification-setup-hooks.md new file mode 100644 index 000000000..791c74b91 --- /dev/null +++ b/specs/repository-verification-setup-hooks.md @@ -0,0 +1,311 @@ +# Repository-owned native verification setup + +- Status: Ready for implementation +- Date: 2026-10-22 +- Catalog capability ID: branch-synchronization +- Last verified: 2026-10-22 +- Owners: Copilot maintainers +- Scope: Prepare authorized repository verification through a trusted native composite action, without editing generated workflows. +- Related issues/PRs: [#647](https://github.com/vypdev/copilot/issues/647), [#652](https://github.com/vypdev/copilot/pull/652) +- Required review gates: product UX, architecture, testing, documentation, security/operations +- Open decisions blocking readiness: none; the maintainer selected a same-job composite dependency action on 2026-10-21 and centralized reusable-workflow coordination on 2026-10-22. + +## 1. Executive summary + +A repository MAY opt into a consumer-owned `.github/actions/copilot-verification-setup/action.yml` using `runs.using: composite`. GitHub Actions MUST execute its native `uses`/`run` steps after Copilot prepares the candidate and before runtime preflight and each verification command. Copilot MUST retain its existing authorization, verification and publication gates. + +```text +Authorized operation -> prepare candidate -> native composite setup + -> credential-free runtime preflight -> verification -> publication guards -> push +``` + +This replaces the unreleased Node ESM prototype in PR #652. There is no custom YAML interpreter or cross-job candidate transport. A Copilot-owned reusable workflow encapsulates the complete same-job coordination; the dependency action remains consumer-owned and composite. + +## 2. Problem, current behavior, and evidence + +### 2.1 Problem + +Consumer projects need different runtimes and dependencies. Editing generated Copilot workflows to install them creates maintenance drift. A separate application CI job does not provision the job doing a temporary branch merge or automated fix. + +### 2.2 Current behavior + +The existing `GitCommitAdapter` prepares a fresh credential-free environment for every verification command. Runtime prerequisites are probed before the command. `SyncBranchUseCase` validates the resulting merge and rereads remote heads before publication; the shared commit preflight validates safe workspace paths. These gates remain authoritative. + +### 2.3 Evidence + +- Central boundaries: `SyncBranchUseCase.verifyPreparedMerge`, shared `runCommitAndPushPreflight`, `GitCommitAdapter.execute`. +- Only issue-comment and review-comment composition roots construct the mutation adapter. Issue/PR/push/review-state analysis callbacks may forward configuration but do not thereby execute verification. `CommitUseCase` analyzes push metadata and is not a mutation verifier. +- [Composite action metadata](https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax) defines native steps; [GitHub's tutorial](https://docs.github.com/en/actions/tutorials/create-actions/create-a-composite-action) documents local actions. +- Consumer incident: [homeassistant-gateway #19](https://github.com/vypdev/homeassistant-gateway/issues/19). + +### 2.4 Retrospective classification + +Not applicable: this is a prospective change. The earlier Node implementation is superseded, not a supported compatibility surface. + +## 3. Actors, surfaces, and terminology + +| Actor | Goal | Surface | +|---|---|---| +| Repository maintainer | Review dependencies once and enable preparation | Consumer action, setup configuration, Repository Variable | +| Authorized contributor | Synchronize or request file changes | Existing issue/PR commands and result comments | +| Operator | Locate setup failure and recover | Named native Actions steps, existing result card, run logs | + +The **trusted source** is the configured main/production remote branch captured at an immutable Git commit. The **candidate** is the actual workspace after merge/fixer changes. A **native boundary** pauses an already admitted operation; it does not authorize or replay one. + +## 4. Goals, non-goals, and fixed invariants + +### 4.1 Goals + +1. Let each repository declare native setup actions and shell steps. +2. Prepare the candidate's current dependencies before every configured verifier. +3. Preserve consumer YAML and auxiliary assets during setup/update. +4. Provide inspectable native steps and actionable failures. + +### 4.2 Non-goals + +Consumer-owned reusable workflows and job matrices inside the dependency hook, YAML emulation, local Actions emulation, arbitrary helper paths and release/deployment changes are out of scope. The Copilot-owned reusable coordinator is in scope and retains the complete operation and native setup in one job. + +### 4.3 Fixed product/safety invariants + +- Setup MUST NOT grant modification authority or run for forks rejected by existing admission. +- Read-only, dry-run, aligned/no-op and empty-verifier operations MUST NOT execute setup. +- Candidate edits MUST NOT replace the captured action or its auxiliary files. +- Failure, timeout, malformed handoff, changed candidate or invalid runtime paths MUST withhold the command and publication. +- Each verification command MUST use a fresh private HOME; only validated runtime directories and JAVA_HOME return to its environment. + +## 5. Current versus proposed product journey + +| Stage | Existing | Proposed | +|---|---|---| +| Adoption | Edit generated workflow or provision runner | Review consumer composite onto trusted main, update generated workflows, enable opt-in | +| Candidate preparation | Agent/temporary merge | Unchanged | +| Dependencies | Preinstalled in same job | Native consumer composite, in that same job and candidate workspace | +| Verification/publication | Credential-free checks and existing guards | Same checks and guards after successful setup | + +```mermaid +sequenceDiagram + participant C as Admitted Copilot operation + participant R as GitHub Actions runner + participant Y as Trusted consumer composite + C->>C: Prepare candidate and close agent profiles + C->>R: Pause at verification boundary + R->>Y: Execute pinned YAML and assets + Y-->>R: Native success or failure, runtime paths + R->>C: Continue the existing operation once + C->>C: Validate unchanged candidate and runtime paths + C->>C: Preflight, verify, apply publication guards +``` + +Text equivalent: Copilot prepares the candidate, pauses, the runner executes trusted setup, and the same operation resumes only after validating the unchanged candidate. No agent is rerun. + +## 6. Functional behavior and state model + +### 6.1 Happy path + +1. Composition MUST capture immutable trusted Git objects before candidate mutation. The action directory is limited to 32 regular files, 64 KiB per file and 256 KiB total. Its root metadata MUST be `action.yml`, valid composite YAML with 1–32 steps. Asset paths MUST use portable ASCII letters/digits/underscore/dot/dash/slash, at most 200 characters, without empty/parent segments or Windows reserved names. Symlinks, submodules, unsafe paths and nested local `uses` actions are rejected. Native external actions and reviewed auxiliary scripts are supported. +2. At the existing verifier boundary, a private same-job worker MUST retain the admitted call stack. Generated workflows do not rerun the full operation to continue it. +3. The worker MUST bind HEAD, symbolic branch, index, tracked changes and publishable untracked contents. Git observations are bounded to 16 MiB, 256 untracked files and 16 MiB aggregate untracked contents; oversized candidates fail closed. Ignored dependency caches are excluded. +4. The trusted snapshot MUST be staged at the reserved local metadata path `.git/copilot-verification-setup`, outside publishable candidate files. Native execution requires the normal directory-based `.git` checkout produced by generated `actions/checkout` steps. The candidate's consumer action directory MUST never be rewritten. Staging MUST persist until native post steps finish. Runner state MUST retain the initial source SHA and digest of all captured file paths, bytes and modes. Before each runner-managed aggregate composite post phase, a trusted Copilot post step MUST use its initially pinned absolute Git executable to restore that exact snapshot from Git objects at the pinned SHA and verify the saved digest, never a moved branch or candidate file. This aggregate phase contains the nested actions' post hooks; it is not a composite YAML `post` key or a restoration between individual nested hooks. An unknown preexisting staging directory MUST fail closed without being overwritten. +5. The continuation MUST match the session, current request, run, attempt, job and workspace. Duplicate/stale responses fail closed. The candidate identity MUST still match. +6. Only new existing PATH directories within the workspace, private HOME or trusted tool cache, and an approved JAVA_HOME, MAY reach the verifier. The existing closed 16-KiB result validation and eight-directory ceiling remain in force. +7. Runtime preflight and the configured command MUST execute in that same fresh environment. Basename resolution MUST use its validated PATH, preserving virtual-environment invocation paths rather than the worker PATH or canonical binary target. Subsequent commands repeat setup with a new HOME and the current manifests. + +### 6.2 Alternative paths + +GitHub's [accepted runner lifecycle ADR](https://github.com/actions/runner/blob/main/docs/adrs/1144-composite-actions.md#prepost-steps-in-nested-actions) +defines the aggregate post step and reverse ordering used above. The trusted +worker output channel belongs to Copilot; repository verification processes +receive the closed environment without GitHub file-command or worker-session +paths. Same-user filesystem access remains the explicit §11 operator boundary. + +Disabled setup preserves existing behavior. Enabled setup without native workflow support, including local CLI verification, MUST fail closed with an explanation to update workflows and run in GitHub Actions. Snapshot errors are deferred on routes that do not verify. No automatic setup retry or shared readiness cache is permitted. + +### 6.3 State machine + +| State | Meaning | Next/recovery | +|---|---|---| +| Disabled/skipped | No preparation requested | Existing operation | +| Prepared candidate | Authorized workspace ready | Pending native setup | +| Pending setup | Native runner owns current setup request | Ready, failed, canceled, timed out | +| Ready | Native success and candidate/runtime validation passed | Preflight and command | +| Blocked | No safe successful continuation | Existing abort/result publication; operator repairs and reruns | +| Complete | Existing operation and its result publication completed | Private session cleanup | + +## 7. User-facing configuration + +| Surface | Name/type | Default/range | Scope | +|---|---|---|---| +| Action | `verification-setup`, boolean | `false`; only true/false | Invocation | +| Repository Variable | `VERIFICATION_SETUP` | `false`; true/false | Generated workflow | +| Setup config | `repository.verificationSetup`, optional boolean | absent means false | Installation plan | +| Consumer file | Fixed composite directory above | No path override | Repository-owned, never installer-owned | + +The setup configuration plans the Variable; generated workflows forward its value. An explicit direct Action input applies to that invocation. Invalid values MUST fail validation. Runtimes are not inferred. Recommended adoption: review the action onto trusted main, update generated workflows with `copilot setup`, then enable the Variable. Alternative: remain disabled and provision dependencies before Copilot in the same job. + +The 20-command limit, five-minute native setup timeout, snapshot/result/path bounds, source trust and publication checks are intentionally non-configurable. The former Node helper protocol and 64-KiB suppressed-output ceiling are retired; native step logs use GitHub Actions semantics. + +## 8. Clean Architecture design + +### 8.1 Responsibilities and dependency direction + +| Boundary | Responsibility | Forbidden responsibility | +|---|---|---| +| Pure policy/application ports | Closed limits/errors, immutable prepared snapshot | Runner APIs or process implementation | +| Existing application use cases | Admission, candidate preparation, verification and publication decisions | Native YAML interpretation or duplicate phase orchestration | +| Git adapter/setup runner | Pause precisely before probes/command, validate resume | New mutation authorization | +| Infrastructure snapshot/staging/protocol/controller | Trusted objects, persistent native staging, same-job process lifecycle | Provider business policy or model execution replay | +| Entrypoint/generated workflows | Dispatch native phases and native `uses` | Reimplement verifier/publication rules | +| Presentation | Existing localized result/error surfaces | Executable helper output as policy | + +### 8.2 Contracts, state, and trust boundaries + +The session contains bounded non-secret metadata and private operational logs. Worker stdout/stderr redact configured secrets and dynamic masking commands before bytes reach disk; PAT/model credentials are never serialized as log content. Credentials remain in the admitted worker's memory/environment as in the existing Action; child verifier environments remain allowlisted. Session provenance, request UUIDs and one-use responses prevent accidental replay across jobs/candidates. Root Action post-job cleanup owns cancellation and private directory removal. The reusable coordinator MUST use GitHub self-repository `$/` references for its initial Action and every continuation/post registration. GitHub resolves these to the called workflow repository and exact commit in its independent Action cache, including when the caller pins a full SHA; candidate files cannot replace this runtime. No second independently moving Action version is permitted. The standalone native acceptance fixture retains its explicitly owned source snapshot. Post hooks run only for the native callback phases, preserving ordinary direct Action behavior. Dependency-only profiles remain private until nested native post steps finish, then the original Action post step removes them; no later verifier reuses them. No artifacts or remote checkpoints are created. + +The workflow's fixed native phases support at most 20 setup boundaries per operation. Worker log forwarding preserves complete runner-command lines, with a 1-MiB single-line memory bound; this is distinct from native setup logs. Worker outputs are bounded to 256 KiB. + +### 8.3 Executable architecture constraints + +Existing architecture/dependency tests remain mandatory. The workflow validator MUST compare the central reusable workflow and compact source/distributed callers with the canonical generator, including events, bot/fork admission, explicit secret bindings, permissions, runner routing, conditions, timeout, runtime-only env and same-commit Action references/inputs. All six existing configuration callbacks retain explicit opt-in forwarding. + +## 9. UI/UX and content contract + +### 9.1 Information hierarchy + +Existing issue/PR result cards remain the primary operation status. Named Actions steps expose preparation and continuation; no new comment stream or labels are introduced. Users see impact, cause, action and retained state before technical details. + +### 9.2 Representative primary views + +| State | Representative content | +|---|---| +| Pending | Actions: “Prepare repository verification 1”. Operation remains in progress; no user action. | +| Action required | “Repository setup blocked verification (native-workflow-required). Update the generated Copilot workflows and run this operation in GitHub Actions; the local CLI cannot execute composite actions.” | +| Failed | “Repository setup blocked verification (process-failed). Review the trusted action and rerun. Verification, commit and push are withheld.” | +| Partially complete | Candidate prepared; setup failed; no remote publication. Existing sync abort restores the local merge. | +| Complete | “Repository setup completed; runtime preflight and verification may proceed.” Existing operation then reports its actual publication result. | + +### 9.3 Issue, PR, and comment behavior + +No additional comments: the existing bounded result publication owns success/failure and links to the run. Native raw setup logs MUST NOT be copied into issue/PR content. Diagnostics identify the fixed path, closed cause and pinned source SHA. + +### 9.4 Accessibility and localization + +Existing localized result cards and plain-text error fallback remain in force. Native diagnostic step names are English operational labels. Text accompanies every diagram; no color-only states or new responsive layout is introduced. Helper stdout is never interpreted as commands to Copilot or Markdown publication content. + +## 10. Failure, recovery, and cleanup + +| Failure | Impact and action | Cleanup/retry | +|---|---|---| +| Missing/invalid trusted action | No verifier/push; review trusted directory | No automatic retry | +| Native failure or timeout | No verifier/push; inspect native step logs and repair | Worker abort/finally preserves candidate files and uses existing sync recovery | +| Stale/cross-job/replayed response | No continuation; rerun fresh operation | Private session canceled | +| Candidate changed during setup | No verifier/push; make setup dependency-only | Candidate action unchanged; existing recovery | +| Invalid runtime output | No verifier/push; install under approved roots | Fresh HOME disposed | +| Job canceled/worker exits | No new publication; inspect retained operation result | Post action signals cancellation, waits up to 10 seconds, terminates remaining worker and cleans owned staging after native posts | + +Request cleanup MUST run only after the invocation validates its native session and successfully publishes its own request. Invalid session paths or identity, and failures before request creation, MUST leave preexisting request files untouched. Successful and failed continuations MUST remove their owned request. Three distinct rejection regressions cover invalid path, invalid identity and failure before request creation; existing success/failure cases assert owned cleanup. + +Native setup steps have `timeout-minutes: 5`; the worker also rejects readiness after 300 seconds. The enclosing existing job timeout remains authoritative. A force-killed worker cannot promise application finally blocks ran: the Action cleans its own staging, and normal runner checkout cleanup/operator recovery owns remaining job-local candidate state. Already-completed remote effects MUST retain their existing truthful result semantics. + +## 11. Security, permissions, and privacy + +Native setup receives only runtime metadata from the private verifier environment, never Copilot's PAT/model inputs or evidence token. Callers MUST explicitly forward the existing named Secrets to the reusable workflow; unrestricted `secrets: inherit` is not generated. The coordinator MUST keep provider secrets scoped to the initial Copilot Action step, not the job or consumer action. Checkout credentials remain unpersisted. Native actions can use runner facilities required for normal Actions execution; they are reviewed executable maintainer code. + +This preserves the trusted-runner boundary and makes no OS-sandbox claim: same-user processes and service-level credentials remain an operator trust concern. PATH/JAVA_HOME are validated after setup; arbitrary `GITHUB_ENV` keys do not enter the verifier. Native external action versions and dependency caches are maintained by the repository owner. Nested local `uses` is excluded because its deferred post scripts could otherwise refer to candidate assets outside the trusted staging tree. + +## 12. Observability and operational UX + +Logs name the fixed action and pinned source SHA, preparation success, and the existing verification result. Native Actions logs expose setup commands normally; maintainers MUST avoid printing secrets. No new secret-bearing artifacts, telemetry fields or result comments are added. The operation worker drains ordinary Action logs in order so masking commands retain their framing. + +## 13. Compatibility, migration, rollout, and rollback + +Installer onboarding is specified by the existing setup capability's companion +[`verification-setup-onboarding.md`](./verification-setup-onboarding.md): seed the +fixed action only if missing, preserve existing consumer bytes and auxiliaries, +show the shared terminal/web activation question (default false), and document +CLI/Action-ref/workflow upgrades. Seeding a file does not transfer generator +ownership or alter this native execution/trusted-main contract. The generated +placeholder fails until the owner customizes it and reviews it onto trusted main. + + +Existing installations remain disabled by default. The unreleased `.copilot/verification-setup.mjs` prototype is removed rather than maintained as a second execution mode. Consumers opting in MUST update generated callbacks before activation and review the composite directory onto trusted main. Setup/install/update MUST preserve that directory and all its assets. Rollback disables the Variable and restores ordinary same-job provisioning; no remote migration, release or tag is required. + +## 14. Testing strategy and numeric budget + +Minimum **193 distinct automated cases**, allocated without double counting: + +| Area | Minimum | Risk | +|---|---:|---| +| Policy/configuration | 30 | Defaults, invalid values, closed runtime schema | +| Trusted snapshot/assets | 22 | Pinning, hashes, file modes, malformed/native metadata | +| Native protocol/controller | 36 | Lifecycle, output framing, replay, timeout, cancellation | +| Candidate/runner orchestration | 24 | Ordering, fresh profiles, candidate identity, failure gates | +| Workflows/setup contracts | 58 | Native step structure, env, limits, source/distribution, preservation | +| Real Git/composition integration | 8 | Exact managed ref, merge manifests, abort/push guards | +| Runtime result filesystem security | 15 | Bounds, links, containment, races, owned staging and three early-rejection request ownership cases | +| **Total** | **193** | Native rewrite adds at least 70 cases beyond retained applicable baseline; release review adds three ownership cases | + +Repository-wide thresholds remain in force. New pure policy targets 100% branches; changed setup adapters target aggregate 95% lines/statements and 90% branches/functions. Deterministic unit fakes cover runner responses without interpreting YAML. Separate native CI acceptance MUST execute real composite `uses`/`run` steps with Python/pytest and Node/pnpm on hosted Linux, Windows and macOS, asserting candidate changes, trusted-source selection, fresh profiles candidate preservation, source-runtime immutability even after candidate bundle changes, and final post cleanup. Controlled local Git acceptance covers the exact same managed branch and no release. Native CI evidence is additional to the distinct Jest budget. + +## 15. Documentation and discoverability + +| Audience | Deliverable | Validation | +|---|---|---| +| User/operator | Verification page: normal flow, Python/Node YAML, native logs, limits, failures and CLI constraint | Documentation links and workflow fixtures | +| Setup owner | Setup configuration reference and same-job adoption order | Setup parser/planning and update-preservation tests | +| Contributor | Generated agent guide, source contract, SDD/catalog evidence | Guidance/specification validation | + +## 16. Acceptance scenarios + +1. Disabled repositories run existing verification unchanged. +2. Enabled authorized sync prepares dependencies from the temporary merged manifests, verifies and pushes only its existing managed branch. +3. A candidate/model change to the action does not execute; trusted YAML/assets run, the original candidate bytes remain unchanged. +4. Setup success precedes runtime probes; every command gets a fresh HOME. Read-only, dry-run, no-op and empty-command paths execute no setup. +5. Failed/canceled/timed-out setup, changed candidate, malformed output or replayed/cross-job continuation blocks verification and publication and cleans owned staging. +6. Native Python/pytest and Node/pnpm acceptance passes on all three hosted platforms. No PAT/model credentials are forwarded to the consumer action or verifier. +7. Updating Copilot twice preserves the consumer directory. Old/missing native callback support and CLI opt-in fail with actionable help. +8. Existing post-verification remote-head/workspace guards and truthful partial-success reporting remain authoritative. + +## 17. Requirements traceability + +| Requirements | Implementation/evidence | Documentation | +|---|---|---| +| §§4–7 source/defaults/routes | Policy, snapshot, config/composition and sync tests | Verification/setup reference | +| §6 native handoff/candidate | Runner, protocol, staging, controller tests | Architecture/recovery | +| §§8–11 workflows/security/cleanup | Structural mutation tests, result filesystem tests, platform fixture | Native steps and trust boundary | +| §§12–16 compatibility/acceptance | Setup preservation, real Git integration, hosted native acceptance | Migration/operator guide | + +## 18. Implementation sequence + +1. Resolve native contract and update specification/issue/PR. +2. Capture composite assets, implement bounded same-job native handoff and cleanup. +3. Generate native callbacks and enforce their structure. +4. Replace prototype tests; add native platform acceptance and real Git integration. +5. Update docs/guidance/catalog/bundles and validate all repository gates. +6. Resolve findings, wait for every required check on the final head, then merge to develop as explicitly authorized. + +## 19. Definition of Done + +- [x] Normative acceptance and traceability are covered. +- [ ] Native runner executes the composite at the actual candidate verification boundary. +- [x] Architecture, numeric budget, coverage and workflow mutation checks pass. +- [x] Defaults, limits, CLI behavior, failures, replay and cancellation match documentation. +- [x] User/setup/operator/contributor docs, native UI labels and safe diagnostics are reviewed. +- [x] Generated guidance/catalog/bundles and required validations pass. +- [ ] All three hosted native acceptance jobs pass; controlled Git sync preserves the same managed ref. +- [ ] Final-head checks pass and no unresolved review findings remain before merge. + +## 20. References and decisions + +The maintainer selected the composite approach in the task on 2026-10-21. [Issue decision record](https://github.com/vypdev/copilot/issues/647#issuecomment-6318551564). Related contracts: `branch-synchronization`, repository verification prerequisites and the shared automated commit pipeline in the specification catalog. A reusable workflow and a Node ESM helper were rejected for this delivery; no second execution mode is retained. + + +### 20.1 Central comment coordinator — issue #662 + +The [coordinator companion](./copilot-comment-workflow-coordinator.md) owns the +incremental 40-case encapsulation contract. Source and installed callbacks call +one Copilot-owned workflow; the whole operation remains in one job. The consumer +dependency action remains composite. The companion defines compact callers, +same-commit self references, named Secret isolation, unchanged timeout/cleanup +behavior, safe runner migration, effective configuration inspection, platform +prerequisites, docs and rollout. This document retains the verifier and trusted +setup execution contract; no cross-job candidate transport is introduced. diff --git a/specs/setup-configuration-management.md b/specs/setup-configuration-management.md index efff5a0d1..f21fe0328 100644 --- a/specs/setup-configuration-management.md +++ b/specs/setup-configuration-management.md @@ -12,6 +12,13 @@ ## 1. Executive summary +The additive verification starter, shared activation question, create/preserve +review and upgrade behavior are defined in the catalogued companion +[`verification-setup-onboarding.md`](./verification-setup-onboarding.md). It uses +the existing boolean and setup approval pipeline; consumer action assets remain +outside generator overwrite/retirement ownership. + + Opening web setup MUST begin with a configuration panel after repository confirmation and browser pairing. A new repository explains that Copilot is not configured and offers **Start setup**. An existing repository offers **Read configuration from GitHub**, **Quick adjustments**, and **Run the complete assistant**. Reading the panel MUST NOT mutate anything or request a bot PAT. ```text diff --git a/specs/setup-runner-profiles-and-installation-parity.md b/specs/setup-runner-profiles-and-installation-parity.md index d309e5f26..8b6f35660 100644 --- a/specs/setup-runner-profiles-and-installation-parity.md +++ b/specs/setup-runner-profiles-and-installation-parity.md @@ -507,3 +507,32 @@ isolated fixed version probes and safe blocked recovery. Runner selection does n install project language tools. Existing consumers without the declaration retain legacy verification. This companion owns its shared incremental numeric test budget; do not count it twice across the setup and synchronization capabilities. + + +## Compact comment coordinator amendment — issue #662 + +Comment callbacks now delegate their complete job to the Copilot-owned reusable +workflow specified in [comment coordinator](./copilot-comment-workflow-coordinator.md). +Their reviewed route is serialized in `with.runs-on` JSON instead of a native +job `runs-on` key. The pure `copilot_comment_workflow` contract recognizes only +the known versioned coordinator and the exact source self-repository reference; +YAML and workspace adapters retain parsing, migration, preview and Apply. + +Setup MUST retain scalar/label/group routes from both old native jobs and new +coordinator calls, apply explicit profile precedence, show the same per-role +routing in review, and write exactly the reviewed YAML. Dynamic or malformed +runner input MUST block rather than fall back. Source self-repository callbacks +remain complete source-owned assets. Custom legacy bootstrap steps MUST require +reviewed migration before switching job shapes; no steps may silently disappear. +Known reusable installation inspection MUST preserve effective Variable/default +and literal override semantics without reading Secret values or claiming an +unverified local Action identity. Runner 2.336.0+ and GitHub platform support are +additional coordinator prerequisites, not evidence of access or capacity. + +Verification maps these requirements to the new pure contract cases, comment +upgrade cases, installation reader cases and preview/Apply parity fixture. Their +shared incremental **40-case** budget is owned by the native-setup amendment and +is not counted twice here. Existing role isolation, coverage gates, receipts, +backup and recovery remain unchanged. Update verification, upgrade and runner +operations docs, regenerate catalog evidence/bundles, and pass all validators +before publication. diff --git a/specs/verification-setup-onboarding.md b/specs/verification-setup-onboarding.md new file mode 100644 index 000000000..869d90c70 --- /dev/null +++ b/specs/verification-setup-onboarding.md @@ -0,0 +1,429 @@ +# Verification Setup Onboarding Specification + +- Status: Implemented in source; final-head CI and review pending +- Date: 2026-10-21 +- Catalog capability ID: `local-web-setup-assistant` +- Last verified: 2026-10-21 (local focused suites, package smoke and responsive fixture; final-head evidence remains pending) +- Owners: Copilot maintainers +- Scope: Complete onboarding for the repository-owned verification setup starter, its explicit activation choice, and safe upgrade guidance. +- Related issues/PRs: [Issue #656](https://github.com/vypdev/copilot/issues/656), #647, #652; existing owning specifications: [`specs/local-web-setup-assistant.md`](./local-web-setup-assistant.md), [`specs/setup-configuration-management.md`](./setup-configuration-management.md); native execution contract: [`specs/repository-verification-setup-hooks.md`](./repository-verification-setup-hooks.md). +- Required review gates: product UX, architecture, testing, documentation, security/operations +- Open decisions blocking readiness: none + +## 1. Executive summary + +Setup will offer to create the fixed consumer-owned action `.github/actions/copilot-verification-setup/action.yml` when absent and clearly report preservation when it exists. A minimal composite starter fails with instructions until customized, so generation cannot imply that verification is ready. The shared terminal and web questionnaire will expose the existing `repository.verificationSetup` boolean, disabled by default. Enabling it opts into the existing native setup hook contract; it does not configure dependencies or establish that the hook has been reviewed on the trusted main branch. + +Setup, workflow upgrade, batch setup, and package installation must preserve existing consumer action bytes and auxiliary files. Dry-run, cancellation, and declined approval make no writes. A create operation must reject unsafe paths, symlinks, wrong file kinds, collisions, and a file that appears after preview, without truncating or replacing consumer data. Documentation will explain the separate CLI, remote Action reference, and committed workflow upgrade layers, including ordered migration and rollback. + +```text +Inspect fixed action path -> create starter if absent / preserve if present -> choose VERIFICATION_SETUP -> review plan -> apply -> customize and review on trusted main -> merge -> run real verification +``` + +## 2. Problem, current behavior, and evidence + +### 2.1 Problem + +Repository maintainers cannot discover the native verification starter or its activation option through the normal setup journey. They must create the action themselves and infer an upgrade sequence from separate documents. This adds setup friction and risks overwriting consumer configuration if generator ownership is unclear. + +### 2.2 Current behavior + +1. The installer generates event workflows but no consumer verification setup action. +2. `verificationSetup` may be configured and is represented as a Variable, but there is no dedicated questionnaire prompt. +3. The native setup contract exists; this follow-up completes onboarding and upgrade UX. +4. Version 3.9.3 is the last published release; support merged into `develop` is not thereby a published release. + +These facts are supplied by the issue evidence; implementation behavior proposed here is not yet established. + +### 2.3 Evidence + +- Code and tests: `src/utils/setup_files.ts`, `src/application/policies/setup_questionnaire_policy.ts`, `src/application/policies/setup_configuration_plan.ts`, `src/infrastructure/__tests__/verification_setup_configuration.test.ts`. +- Documentation: `docs/security-operations/operations/verification.mdx`. +- Related source contract: `specs/repository-verification-setup-hooks.md`. +- Incidents or concrete examples: none supplied. +- External primary sources: not applicable. +- Unknowns: implementation details and exact existing package/adapter extension points are for implementation discovery; they do not change the fixed product contract. + +### 2.4 Retrospective classification (as-built baselines only) + +Not applicable: this is a prospective companion specification, not a reconstruction of an implemented baseline. + +## 3. Actors, surfaces, and terminology + +| Actor | Goal | Entry point | Visible surfaces | +|---|---|---|---| +| Repository maintainer | Install or upgrade generated workflows safely | `copilot setup`, workflow update, batch setup | Terminal/web wizard, plan, result, repository files | +| Verification owner | Define project-specific preparation | Trusted main branch after PR | Consumer action, review and merge, real verification run | +| Operator/contributor | Diagnose setup and package behavior | Documentation and CI | Upgrade guide, tests, package artifact | + +The **consumer action** is the fixed path above and remains consumer-owned after initial creation. **Starter** means a fail-closed composite action with a customization instruction. **Activation** means the existing `repository.verificationSetup` boolean / `VERIFICATION_SETUP` binding. **Trusted main** means the repository's configured trusted main branch (`MAIN_BRANCH`), not a branch inferred from the installer PR. Generator ownership of workflow files does not imply ownership of consumer action assets. + +## 4. Goals + +### 4.1 Goals + +1. Offer an explicit create-or-preserve result in initial setup and workflow upgrades, including local and batch flows. +2. Ask the existing verification activation question in the shared terminal/web questionnaire and explain the choice in plan and result. +3. Ship and publish a minimal starter that fails until customized, without guessing languages, dependencies, commands, or running installation during setup. +4. Preserve consumer assets across repeated setup, workflow updates, deselection, and batch maintenance. +5. Document upgrade layers, ordered migration, rollback, trusted-branch review, and the distinction between merge and release. + +### 4.2 Non-goals + +1. Automatically enabling verification or inferring project dependencies and commands. +2. Running dependency installation or claiming runtime readiness during setup. +3. Replacing, retiring, or managing consumer action contents or auxiliary files after creation. +4. Publishing a release or installing changes into other repositories as part of this specification. + +### 4.3 Fixed product/safety invariants + +1. Create only when the fixed path is absent; preserve existing regular-file bytes and auxiliary files. +2. `verificationSetup` remains an explicit boolean, disabled by default; configuration and preselection are respected, including organization reuse. +3. Creating an installer PR does not establish runtime readiness. The owner must customize, review, and merge on trusted main, then run real verification. +4. Existing manifest receipts, permission checks, review gates, runner selections, and credential handling remain intact. +5. Missing-only creation never follows unsafe parent links, overwrites collisions, or truncates a file created between preview and Apply. + +## 5. Current versus proposed product journey + +| Stage | Current | Proposed | User/operator effect | +|---|---|---|---| +| Inspect action | No generated starter; user discovers path themselves | Show create if absent or preserve if present | Ownership outcome is visible | +| Choose activation | Config-only; no dedicated question | Shared explicit boolean prompt with help | Same decision in terminal and web | +| Review plan | No joined guidance | Show action result and enabled/disabled state | User sees consequence before Apply | +| Upgrade | Layers are scattered across docs | Ordered CLI, Action ref, workflow migration and rollback | Safer, reviewable upgrade | +| Runtime readiness | May be inferred from setup | Explicitly requires customization, trusted-main review/merge, and real run | No false readiness claim | + +```mermaid +flowchart LR + A[Run setup or upgrade] --> B[Inspect fixed consumer path] + B --> C{Action exists?} + C -->|No| D[Plan missing-only starter creation] + C -->|Yes| E[Plan preserve existing action] + D --> F[Choose VERIFICATION_SETUP] + E --> F + F --> G[Review and apply plan] + G --> H[Customize and review on trusted main] + H --> I[Merge and run real verification] +``` + +Text equivalent: setup inspects the fixed path, plans creation or preservation, records the explicit activation choice, applies only an approved safe plan, then the owner customizes and reviews on trusted main before merging and running verification. + +## 6. Functional behavior and state model + +### 6.1 Happy path + +1. The setup application gathers the current action-path state without writing. +2. If absent, the plan offers creation of the packaged starter; if a regular file exists, it offers preservation and reports that no bytes will change. +3. The questionnaire asks whether to enable `VERIFICATION_SETUP`, with concise help and a link to verification guidance. It honors configured or preselected values and organization reuse. +4. The plan and result display both the action outcome and activation state. Apply rechecks absence atomically before creation. +5. The owner customizes the placeholder, reviews and merges it on trusted main, then runs a real verification. + +### 6.2 Alternative paths + +- Existing regular action: preserve bytes; do not merge starter content or rewrite line endings. +- Existing directory, symlink, dangling link, or other collision: block with path and corrective action; retain contents. +- Disabled activation: create/preserve result is still visible; generated workflow binding remains disabled. +- Dry-run, cancel, declined approval: show planned outcome where applicable, write nothing. +- Batch setup: apply the same per-repository inspect/plan/recheck rules; one collision does not authorize replacement in another repository. +- File appears after preview: report stale plan and preserve the newly created file; require a refreshed plan. + +### 6.3 State machine + +| State | Entered when | User-visible meaning | Allowed next states | Recovery/owner | +|---|---|---|---|---| +| Inspected absent | No path entry exists | Starter can be planned | Planned create, blocked | Setup application | +| Inspected present | Regular file exists | Consumer action will be preserved | Planned preserve | Setup application | +| Planned | User reviews proposed result and flag | No write has happened | Applied, canceled, declined, stale, blocked | User / setup application | +| Applied | Approved safe plan completes | Starter created if absent; existing action untouched | Customize/review | Repository maintainer | +| Blocked | Unsafe path, file kind, or collision | No unsafe write occurred | Correct path and retry | Repository maintainer | +| Runtime reviewed | Customized action merged on trusted main | Owner-defined setup is available | Verified or failed run | Verification owner | + +Duplicate setup and workflow updates are idempotent for consumer assets. Stale plans are rejected at Apply. Cancellation and declined approval terminate without writes. Partial batch success reports each repository outcome independently and never retries a destructive replacement. + +## 7. User-facing configuration + +| Input | Type | Recommended default | Allowed values/range | Scope/persistence | +|---|---|---|---|---| +| `repository.verificationSetup` / `VERIFICATION_SETUP` | Boolean | `false` — opt-in must remain explicit | `true` or `false` | Existing repository configuration and setup snapshot; existing organization reuse and override precedence apply | + +Validation accepts only the existing boolean contract; malformed values follow current configuration validation and must not silently enable. The questionnaire's explicit answer takes effect through existing setup precedence; configured/preselected values are honored and shown. The value controls activation only, not starter content, dependency installation, or readiness. Missing legacy values resolve to disabled. No arbitrary command, URL, ref, or secret is accepted as part of this feature. Safety invariants in §4.3 are not configurable. + +Recommended example: leave `verificationSetup: false` until the owner customizes and reviews the action. Meaningful alternative: set it to `true` after deciding to activate the native hook; readiness still requires the owner-defined action to be merged and exercised. + +## 8. Clean Architecture + +### 8.1 Responsibilities and dependency direction + +| Layer/boundary | Owns | Must not own/import | +|---|---|---| +| Domain/pure policy | Boolean normalization, create/preserve/block decision, stale-plan rules | Filesystem APIs, GitHub SDK, UI framework | +| Application | Setup questionnaire, immutable plan/result, batch orchestration and Apply sequencing | Concrete filesystem/process APIs or presentation strings as policy | +| Adapters/data | Safe path inspection and atomic missing-only creation; package asset resolution | Product decisions or overwrite policy | +| Infrastructure/composition | Wire local and batch adapters and packaged starter | Duplicate business rules | +| Entrypoints | Adapt terminal/web answers and approvals | Independent questionnaire semantics or duplicated orchestration | +| Presentation | Render help, plan, blockers, outcomes in terminal/web | Filesystem mutation or flag-policy decisions | + +```mermaid +flowchart LR + E[CLI and web entrypoints] --> A[Setup application] + A --> D[Pure ownership and activation policies] + A --> P[Workspace and package asset ports] + I[Safe filesystem/package adapters] --> P + A --> V[Terminal/web plan and result models] +``` + +Text equivalent: terminal and web entrypoints call the same application policies and ports; safe adapters perform approved file operations; presentation renders application outcomes. + +### 8.2 Contracts, state, and trust boundaries + +- Pure decisions: action absent/present/unsafe and activation choice map to immutable plan outcomes. +- Application contracts: plan includes inspected state, intended action, flag value, and whether Apply needs revalidation; result distinguishes created, preserved, unchanged, and blocked. +- Semantic ports: inspect fixed consumer path and create a supplied packaged asset only if absent; no general overwrite operation is exposed for this asset. +- Durable state/schema ownership: preserve the existing configuration schema and manifest receipts; no new durable state is required. +- Concurrency/idempotency: Apply performs an atomic create-if-absent or equivalent exclusive operation; never truncate. Recheck parent components without following links. Stale inspection returns a blocker. +- Trusted and untrusted inputs: config, user answers, filesystem entries, and repository contents are data. Path is fixed by product contract, not supplied as arbitrary user input. Starter is package-controlled; consumer action contents are untrusted consumer-owned data. +- Provider error mapping: permission, unsafe path, wrong file kind, collision, and I/O failures become actionable outcomes without leaking credentials or claiming success. + +### 8.3 Executable architecture constraints + +Automated boundary checks MUST ensure questionnaire semantics are shared by terminal and web, pure policies have no filesystem/UI imports, application ports contain no provider DTOs, and only the safe adapter can create the consumer starter. Contract tests MUST verify packaged asset presence and local/batch parity. Existing setup permission, manifest receipt, review, runner, and credential contracts remain enforced. + +## 9. UI/UX and content contract + +### 9.1 Information hierarchy + +1. Current action-path outcome and activation state. +2. What setup changed or preserved. +3. Next step: customize/review/merge/run when enabled or intended. +4. Whether human action is required. +5. Impact and inspectable plan/result. +6. Technical diagnostics in expandable or secondary output. + +### 9.2 Representative primary view + +```markdown +# Verification setup + +> **Current status:** Starter created; verification activation is enabled. +> +> **Action required:** Customize the placeholder, review and merge on `MAIN_BRANCH`, then run a real verification. + +## Progress + +- [x] Created `.github/actions/copilot-verification-setup/action.yml` because it was absent. +- [x] Set `VERIFICATION_SETUP` to enabled. +- [x] Customize and review the action on the configured trusted main branch. + +## What happens next + +The starter fails until its placeholder is replaced. This setup result does not prove runtime readiness. + +## Links + +[Verification setup and upgrade guide](../security-operations/operations/verification.mdx) +``` + +Concrete state variants: + +- **Pending/no action:** “Plan only: the action is absent and would be created; verification remains disabled. No files have changed.” +- **Action required:** “Existing action preserved byte-for-byte. Activation is enabled; review your action on trusted main and run verification.” +- **Blocked:** “No action file was changed. The target path is a symlink/collision; inspect and correct the path, then rerun setup.” +- **Partial batch:** “2 repositories updated; 1 was blocked because its target is not a regular file. Successful repositories remain complete; correct the blocked path and retry that repository.” +- **Complete:** “Starter created (or existing action preserved); activation is disabled/enabled as selected. Customize and review before relying on verification.” + +### 9.3 Issue, PR, and comment behavior + +This feature does not require new issue/PR automation or comments; these surfaces are not applicable to runtime setup. If setup creates or updates an implementation PR, its description must state what was created/preserved, activation state, required customization/review/run steps, and that merging into `develop` does not publish a release. Use deterministic setup plan labels and existing result/receipt mechanisms; do not add notification comments. Link to the canonical issue and verification guide where relevant. Merge of an installer PR is not evidence of consumer runtime readiness. + +### 9.4 Accessibility, localization, and responsive behavior + +Use the existing shared terminal/web questionnaire content and supported web locales English, Spanish, French, and Portuguese, with the repository's existing fallback. The activation question must include text help; no color-only or icon-only state. Keep plan/result readable at narrow widths and in light/dark themes. Use descriptive links and semantic headings. Treat repository paths and existing action content as untrusted text: escape for terminal/web/Markdown contexts; do not render executable Markdown, mentions, commands, or URLs from file contents. + +## 10. Failure, recovery, and cleanup + +| Failure/partial state | User impact | Retained facts | Automatic retry | Required action | Cleanup | +|---|---|---|---|---|---| +| Dry-run/cancel/decline | No starter or config write | Plan/decision only | No | Re-run and approve if desired | None | +| Unsafe parent symlink | Creation blocked | Existing path and contents intact | No | Replace/inspect unsafe parent, then rerun | None | +| Target collision/wrong kind | Creation blocked | Collision unchanged | No | Resolve path manually | None | +| Target appears after preview | Stale plan blocked | New file intact | No | Refresh plan; preserve new file | None | +| Permission/I/O error | Setup may be incomplete | Any already completed independent repository outcomes are reported | Bounded only under existing setup rules | Correct permission or storage issue, retry affected item | No automatic removal of consumer files | +| Starter customized incorrectly | Runtime verification fails closed or owner-defined behavior fails | Consumer action retained | Owner-controlled | Fix, review, merge, rerun | Consumer-owned cleanup | + +Errors follow impact → cause → action → retained state. Successful creation in one batch repository must not be described as failed because another repository was blocked. + +## 11. Security, permissions, and privacy + +1. Use existing setup authorization and permission gates; do not add permissions for creating a local consumer file. +2. Treat filesystem entries and repository content as untrusted. Do not follow symlinked parents, execute setup commands, infer dependencies, or accept arbitrary paths. +3. Do not log secrets or action contents. Report fixed paths and sanitized causes only. +4. Use exclusive missing-only creation to resist races; a collision or stale preview must never overwrite user data. +5. The starter explicitly fails with a customization instruction until its placeholder step is replaced; it must not silently succeed as a no-op. + +## 12. Observability and operational UX + +The plan/result records per-repository created, preserved, disabled/enabled, blocked, canceled, and unchanged outcomes. Existing receipts remain authoritative for workflow files and permissions; consumer action preservation is reported separately and is not converted into generator ownership. Logs use existing correlation and redaction conventions. Do not add metrics or comments solely for this local setup behavior. Distinguish an external verification failure from setup-plan failure, and link users to the action and run when available. + +## 13. Compatibility, migration, rollout, and rollback + +- Existing configuration remains valid; absent activation remains disabled. No schema migration is required. +- Three independent upgrade layers must be documented and reviewed in order: (1) installed CLI version, (2) remote Action reference such as floating `@v3` versus exact version/SHA, and (3) committed generated workflow files. Changing one does not update the others. +- Migration: back up/review current workflows and consumer action; update the CLI using the normal release channel; inspect remote Action reference and choose the repository's pinning policy; run workflow upgrade; review create/preserve result and diff; configure activation explicitly; customize action; open/review/merge changes on configured trusted `MAIN_BRANCH`; run a real verification and inspect its result. +- If the consumer action already exists, migration preserves it. If absent, the starter is fail-closed until customized. +- Rollback: disable `VERIFICATION_SETUP` through the normal configuration path; revert generated workflow changes or restore the previously reviewed Action ref according to repository policy; restore action bytes from the reviewed backup/commit if owner changes caused the issue. Do not delete consumer assets automatically. +- A merge into `develop` is not a published release. Consumers receive a CLI change only through a published package/release and a remote Action change only through its published/ref update. + +## 14. Testing strategy and numeric budget + +Minimum: 48 distinct focused cases, with no double counting. + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| Domain/configuration/pure planning | 8 | Boolean default/precedence, create/preserve/block decisions, invalid values | +| State/application/idempotency/races | 10 | Repeat setup, cancellation, decline, stale plan, file appears before Apply, batch isolation | +| Adapters/provider contracts | 8 | Safe parent inspection, symlink rejection, exclusive create, permission and I/O mapping | +| Workflows/setup/schema | 6 | Local/batch parity, existing manifest receipts, gates, runner/credential invariants | +| UI/UX/localization/sanitization | 6 | Terminal/web parity, enabled/disabled guidance, blocker and result content, locale and path escaping | +| Integration/security/migration/packaging | 10 | npm inclusion, fail-closed starter, docs flow, rollback, package/local integration, unsafe path/race security | +| **Total** | **48** | Distinct behaviors only | + +Preserve repository-wide coverage budgets. New pure policy branches MUST reach 100%; new adapter lines/statements MUST reach 95% and branches/functions 90%, where the repository tooling reports those metrics. Add at least 48 distinct focused cases as allocated above; parameter rows count only when behavior differs. Use deterministic filesystem fakes and controlled race hooks, no real waits or live services. Include structural package/workflow contract checks, semantic assertions beyond snapshots, and golden terminal/web plan/result fixtures. Manual UX evidence must confirm the create/preserve and activation guidance is understandable in both entrypoints and at narrow web widths. + +## 15. Documentation and discoverability + +| Audience | Artifact/page | Required content | Validation/navigation | +|---|---|---|---| +| User | `docs/security-operations/operations/verification.mdx` | Starter, explicit activation, create/preserve, customization and runtime readiness | Existing docs navigation/link validation | +| Setup owner | `docs/configuration.mdx` and setup guidance | Boolean default, precedence, examples, plan/result meaning | Configuration contract tests | +| Operator | Verification operations guide | Troubleshooting blockers, batch partial results, migration and rollback | Documentation checkout/link validation | +| Contributor | `docs/development/architecture.mdx` and relevant spec | Ownership boundary, safe adapter, package asset and test constraints | Architecture and specification validation | + +The upgrade guide must clearly separate installed CLI, remote Action ref (`@v3` versus exact version/SHA), and committed generated workflows. Give ordered migration and rollback steps, state that merge into develop is not a release, and say that creating an installer PR does not prove runtime readiness. Keep examples synchronized with fixtures. + +## 16. Acceptance scenarios + +Scenario IDs use the `VSO-` namespace and are unique. + +1. **VSO-01 absent create:** Given the fixed path is absent, when an approved setup applies, then it creates the packaged starter exactly once and reports “created.” +2. **VSO-02 existing preserve:** Given a regular consumer action and auxiliary files exist, when setup or workflow upgrade runs repeatedly, then all bytes and auxiliary files remain unchanged and the result says “preserved.” +3. **VSO-03 fail closed:** Given the generated starter is used uncustomized, when its placeholder step runs, then it exits unsuccessfully with a clear customization instruction. +4. **VSO-04 wizard parity:** Given terminal or web setup, when the user answers activation, then both use the same explicit boolean question and guidance. +5. **VSO-05 default and reuse:** Given no value is configured, then the default is disabled; given a preselected/configured or organization-reused value, then it is respected and shown. +6. **VSO-06 activation meaning:** Given activation is enabled, then plan/result state it enables the existing hook only and does not claim dependency configuration or readiness. +7. **VSO-07 no-write exits:** Given dry-run, cancellation, or declined approval, when setup ends, then no starter or configuration write occurs. +8. **VSO-08 unsafe path:** Given a symlinked parent, dangling link, directory collision, or invalid file kind, then setup blocks with an actionable reason and preserves contents. +9. **VSO-09 race safety:** Given a file appears after preview, when Apply executes, then it is not truncated or replaced and the plan is reported stale. +10. **VSO-10 local and batch:** Given local or batch setup, then each repository receives the same create/preserve rules and independent truthful outcomes. +11. **VSO-11 package:** Given the npm package is built, then the starter asset is present at the expected packaged location and the packaged setup can resolve it. +12. **VSO-12 upgrade/rollback docs:** Given a maintainer follows the guide, then CLI, remote Action ref, and committed workflows are distinct ordered layers with rollback guidance; merge into develop is not described as release. +13. **VSO-13 consumer ownership:** Given activation is deselected or batch maintenance repeats, then no consumer action is retired or overwritten. +14. **VSO-14 review gates:** Given implementation is proposed for merge, then existing receipts, permission checks, review gates, runner choices, and credential handling still pass their contracts. +15. **VSO-15 final-head delivery:** Given the PR is ready, then it is merged into `develop` only after applicable final-head checks pass and no findings remain unresolved; no release or external installation is implied. + +## 17. Requirements traceability + +| Requirement | Policy/use case/adapter/presentation | Test or evidence | Documentation | +|---|---|---|---| +| Create if absent; preserve if present | Ownership policy, setup plan, safe filesystem port | VSO-01, VSO-02, VSO-08, VSO-09 | Verification operations guide | +| Explicit activation and default | Questionnaire policy and shared view model | VSO-04, VSO-05, VSO-06 | Configuration and verification pages | +| Fail-closed starter and package inclusion | Package asset and execution contract | VSO-03, VSO-11 | Verification guide | +| Dry-run, cancellation, decline, batch | Application orchestration and Apply adapter | VSO-07, VSO-10 | Setup and troubleshooting guidance | +| Preserve existing setup gates | Existing workflow and receipt contracts | VSO-14 | Contributor architecture guidance | +| Upgrade and rollback layers | Documentation and release guidance | VSO-12 | Verification operations guide | +| Final-head PR delivery | Repository workflow gates | VSO-15 | Contributor/release guidance | + +## 18. Implementation sequence + +1. Confirm existing ownership and configuration contracts; add pure ownership decision and questionnaire contract tests. +2. Add safe missing-only filesystem/package port behavior with race and unsafe-path tests. +3. Wire shared application plan and result for local and batch setup without changing existing receipts or gates. +4. Add shared terminal/web prompt, help, enabled/disabled guidance, blockers, and localized content. +5. Package the fail-closed starter and validate packed npm assets. +6. Update verification and configuration documentation with migration, rollback, and release distinction. +7. Complete acceptance trace, numeric coverage thresholds, manual UX review, specification/catalog checks, and applicable final-head checks before merge. + +## 19. Definition of Done + +- [x] Every normative requirement maps to acceptance and traceability. +- [x] Consumer action creation is missing-only, race-safe, and preserves existing bytes and auxiliary files. +- [x] Shared terminal/web activation uses the existing boolean, remains disabled by default, and respects preselected/configured values. +- [x] Starter fails with customization instructions until replaced; setup performs no inferred installation. +- [x] Local, batch, and packaged flows satisfy the same ownership contract. +- [x] Existing receipts, permission checks, review gates, runner selections, and credential handling remain valid. +- [x] Numeric 48-case budget and pure-policy/adapter coverage thresholds pass; repository-wide budgets remain satisfied. +- [x] Accessibility, localization, responsive content, sanitization, and UX review pass. +- [x] Migration, rollback, three-layer upgrade, and release distinction are documented and discoverable. +- [x] Failure, partial success, retry, race, security, and cleanup scenarios pass. +- [x] Required generated artifacts and repository validation commands pass. +- [x] `specs/catalog.json` and `specs/CATALOG.md` are current and `pnpm run validate:specifications` passes. +- [ ] PR is merged into `develop` only after applicable final-head checks pass and no findings remain unresolved; no release is implied. +- [x] No readiness-blocking decision remains unresolved. + +## 20. References and decisions + +- Primary sources: supplied issue evidence for `src/utils/setup_files.ts`, setup questionnaire and plan policies, `src/infrastructure/__tests__/verification_setup_configuration.test.ts`, and `docs/security-operations/operations/verification.mdx` on `develop`. +- Related specs: [`specs/local-web-setup-assistant.md`](./local-web-setup-assistant.md), [`specs/setup-configuration-management.md`](./setup-configuration-management.md), [`specs/repository-verification-setup-hooks.md`](./repository-verification-setup-hooks.md). +- Related issue/PRs: [Issue #656](https://github.com/vypdev/copilot/issues/656), #647, #652. +- Decisions: companion owned by existing `local-web-setup-assistant` capability; native execution contract remains in `repository-verification-setup-hooks.md`; consumer action is create-once and consumer-owned; activation is explicit; starter is fail-closed; no automatic release or installation into other repositories. +- Follow-up outside scope: publishing a release and installing changes into consumer repositories. +### Implementation and local verification evidence + +The create-once adapter is `src/infrastructure/setup_verification_action.ts`; +`src/domain/setup_verification_action.ts` fixes its path and public review facts. +`setup_files.ts` and `setup_installation_review.ts` share this adapter. The +reviewed create/preserve state travels through CLI/application/workspace contracts +so a changed path blocks Apply; exclusive creation also rejects a final collision. +Batch inventory preserves the exact action as an unchanged base-tree entry and +rejects unsafe parent/file modes and case collisions before downloading blobs. +The action never enters the generator ownership manifest. + +Executable coverage is in `setup_verification_action.test.ts`, +`setup_verification_onboarding_policy.test.ts`, +`setup_verification_onboarding_flow.test.ts`, +`setup_verification_onboarding_components.test.ts`, and focused additions to the +batch inventory/workspace, initial setup workflow and context projection suites. +The new summary policy and file adapter have explicit coverage budgets. The complete local suite after review correction passed: 707 suites, 11,607 +passed tests and 35 existing skips, including all 97 VSO cases present at that measurement. Two additional +platform-neutral post-validation regressions pass in the focused suite, bringing +the source total to 99 distinct VSO cases. The pure +summary has 100% coverage; the safe adapter exceeds every enforced budget. All +repository coverage budgets and setup acceptance validation pass. Package validation and an extracted npm +smoke verify the starter and its CLI resolver. The credential-free +`serve-web-setup-review.cjs runner-plan` fixture was reviewed at 1280 px and 375 px, +including Spanish: the fixed path wraps and the create/disabled/trusted-main and +customization guidance remain readable. SSR contracts cover create/preserve/blocked, +enabled/disabled and completion navigation in all four supported locales. + +No release or consumer installation was performed. Final PR checks and resolved +finding evidence belong to the linked implementation PR. + +### Review correction: parent replacement at Apply + +[PR #657](https://github.com/vypdev/copilot/pull/657#discussion_r4340366893) +identified a real race in path-based exclusive creation: a checked parent could +be replaced before the leaf open. The corrected adapter walks fixed single-name +components from a pinned repository directory. It keeps each directory descriptor +open while matching `fstat` and `lstat` identities, enters that same directory, +and confirms its identity with BigInt device/inode values before the next +relative operation. The OS working directory pins the validated location, so a +later parent replacement cannot redirect creation. The bounded section contains +no awaits or user callbacks, restores the caller's physical cwd and closes handles +in `finally`; setup's file application and isolated batch rendering are synchronous +main-thread entrypoints. The selected checkout root remains the existing trusted +setup anchor. + +The leaf uses exclusive creation, final route checks reject relocation, and +failure cleanup addresses only the created inode in the pinned directory. New +regressions cover replacement before directory entry, replacement of both a leaf +parent and an ancestor just before opening the file, symlink and directory swaps, +directory access/identity failure, and cwd restoration. They assert that creation +never reaches the external target, including transient creation before cleanup. +Windows may reject a pinned-directory rename; the test verifies that denial or +that the original validated location is retained. Final three-platform CI remains +a delivery gate. + +Primary API evidence: [Node filesystem APIs](https://nodejs.org/docs/latest-v24.x/api/fs.html), +[Node process directory API](https://nodejs.org/docs/latest-v24.x/api/process.html#processchdirdirectory), +[POSIX pathname resolution](https://pubs.opengroup.org/onlinepubs/009696699/basedefs/xbd_chap04.html), +[Windows current-directory lifetime](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setcurrentdirectory), +and [libuv's Windows directory-compatible opener](https://github.com/libuv/libuv/blob/v1.x/src/win/fs.c). diff --git a/src/actions/__tests__/github_action.test.ts b/src/actions/__tests__/github_action.test.ts index ecf959668..898a1ebfb 100644 --- a/src/actions/__tests__/github_action.test.ts +++ b/src/actions/__tests__/github_action.test.ts @@ -677,6 +677,49 @@ describe('runGitHubActionEntry', () => { jest.clearAllMocks(); }); + it.each([ + ['en-US', '{"branchType":"feature"}', 'has no schema version', 'Retryable: No'], + ['es-MX', '{"schemaVersion":2}', 'versión de esquema almacenada 2', 'Reintentable: No'], + ['fr-FR', '{"schemaVersion":99}', 'stored schema version 99', 'Retryable: No'], + ])('preserves real stored-configuration diagnostics in the annotation and summary for %s', async (locale, json, causeText, retryText) => { + (core.getInput as jest.Mock).mockImplementation((key: string) => key === INPUT_KEYS.REPOSITORY_LOCALE ? locale : ''); + const { ConfigurationHandler: RealHandler } = jest.requireActual('../../manager/description/configuration_handler'); + const updateDescription = jest.fn(); + const reader = new RealHandler({ + getDescription: jest.fn(async () => ''), + updateDescription, + }); + const failure = await reader.get({ owner: 'o', repository: 'r', issueNumber: 144, token: 'fixture' }).catch(error => error); + await runGitHubActionEntry(async () => { throw failure; }); + const annotation = (core.setFailed as jest.Mock).mock.calls[0][0] as string; + const markdown = (core.summary.addRaw as jest.Mock).mock.calls[0][0] as string; + for (const surface of [annotation, markdown]) { + expect(surface).toContain(causeText); + expect(surface).toContain('144'); + expect(surface).toContain('configuration.invalid'); + expect(surface).toContain(failure.correlationId); + expect(surface).toContain('#unsupported-stored-configuration'); + expect(surface).not.toContain('workflow.failed'); + expect(surface).not.toContain(json); + } + expect(annotation).toContain(retryText); + expect(core.summary.write).toHaveBeenCalledTimes(1); + expect(core.setFailed).toHaveBeenCalledTimes(1); + expect(updateDescription).not.toHaveBeenCalled(); + }); + + it('keeps the configuration failure when summary publication fails', async () => { + (core.getInput as jest.Mock).mockReturnValue(''); + (core.summary.write as jest.Mock).mockRejectedValueOnce(new Error('PRIVATE-SUMMARY-FAILURE')); + const failure = new ApplicationError('configuration.invalid', 'Safe detail.', { + recovery: { id: 'stored-configuration-schema-missing', variables: { issueNumber: 144, expectedVersion: 3 } }, + }); + await expect(runGitHubActionEntry(async () => { throw failure; })).resolves.toBeUndefined(); + expect(core.setFailed).toHaveBeenCalledTimes(1); + expect(core.setFailed).toHaveBeenCalledWith(expect.stringContaining('configuration.invalid')); + expect(core.setFailed).not.toHaveBeenCalledWith(expect.stringContaining('PRIVATE-SUMMARY-FAILURE')); + }); + it('lets Node preserve an existing failure exit code after a resolved run', async () => { const previousExitCode = process.exitCode; process.exitCode = 1; diff --git a/src/actions/github_action.ts b/src/actions/github_action.ts index 4baae0618..83967c200 100644 --- a/src/actions/github_action.ts +++ b/src/actions/github_action.ts @@ -1,3 +1,4 @@ +import { runNativeVerificationEntry } from '../infrastructure/native_verification_controller'; import { createNativeStatusReadPort } from '../infrastructure/composition/issue_completion_composition_root'; import * as core from '@actions/core'; import * as github from '@actions/github'; @@ -23,7 +24,7 @@ import { activeAgentTasks, isUnaddressedCommentEvent } from '../application/poli import { createActorAuthorizationRepository } from '../infrastructure/composition/actor_authorization_composition_root'; import { runAtApplicationErrorBoundary } from '../application/errors/application_error_context'; import { toApplicationError } from '../application/errors/application_error'; -import { renderApplicationErrorText } from '../application/policies/application_error_presentation_policy'; +import { renderApplicationErrorMarkdown, renderApplicationErrorText } from '../application/policies/application_error_presentation_policy'; import { bindIssueCommentPublication } from '../infrastructure/composition/push_single_action_capability_port_binding'; import { bindPublicationSourceQuery } from '../infrastructure/composition/shared_capability_port_binding'; import { GithubPublicationSourceRepository } from '../data/repository/github_publication_source_repository'; @@ -230,7 +231,15 @@ export async function runGitHubActionEntry( } catch (cause: unknown) { const semanticError = toApplicationError(cause, 'workflow.failed', 'GitHub Action execution failed.'); logError(semanticError); - core.setFailed(renderApplicationErrorText(semanticError, earlyGithubActionErrorMessage())); + const message = earlyGithubActionErrorMessage(); + core.setFailed(renderApplicationErrorText(semanticError, message)); + if (semanticError.recovery?.id.startsWith('stored-configuration-')) { + try { + await createGithubActionSummaryCompositionRoot().publish(renderApplicationErrorMarkdown(semanticError, message)); + } catch (summaryCause) { + logError(toApplicationError(summaryCause, 'provider.unavailable', 'Unable to publish the configuration failure summary.')); + } + } } }); } @@ -247,5 +256,5 @@ function earlyGithubActionErrorMessage(): ApplicationErrorMessageReader { // Only auto-run when executed as the action entry (not when imported by tests) /* istanbul ignore next -- the bundled production entry is covered by the Action smoke path. */ if (typeof process.env.JEST_WORKER_ID === 'undefined') { - void runGitHubActionEntry(); + void runGitHubActionEntry(() => runNativeVerificationEntry(runGitHubActionEntry)); } diff --git a/src/actions/github_action_execution.ts b/src/actions/github_action_execution.ts index 003e6cfb7..333506181 100644 --- a/src/actions/github_action_execution.ts +++ b/src/actions/github_action_execution.ts @@ -86,6 +86,7 @@ export async function buildGithubActionExecution( eventInputs, ), preBranchSdd: parseIssueWorkflowBoolean(getInput(INPUT_KEYS.PRE_BRANCH_SDD), INPUT_KEYS.PRE_BRANCH_SDD, false), + verificationSetup: parseIssueWorkflowBoolean(getInput(INPUT_KEYS.VERIFICATION_SETUP), INPUT_KEYS.VERIFICATION_SETUP, false), pullRequest: buildPullRequest( parseIntegerInput(getInput(INPUT_KEYS.PULL_REQUEST_DESIRED_ASSIGNEES_COUNT), 0), parseIntegerInput(getInput(INPUT_KEYS.PULL_REQUEST_DESIRED_REVIEWERS_COUNT), 0), diff --git a/src/actions/local_action_configuration_sections.ts b/src/actions/local_action_configuration_sections.ts index 40c614b98..03960c691 100644 --- a/src/actions/local_action_configuration_sections.ts +++ b/src/actions/local_action_configuration_sections.ts @@ -185,6 +185,7 @@ export function readLocalWorkflowConfiguration( commitPrefixBuilder: read(INPUT_KEYS.COMMIT_PREFIX_TRANSFORMS) || 'replace-slash', issueManagedBranches: parseIssueWorkflowBoolean(read(INPUT_KEYS.ISSUE_MANAGED_BRANCHES), INPUT_KEYS.ISSUE_MANAGED_BRANCHES, true), preBranchSdd: parseIssueWorkflowBoolean(read(INPUT_KEYS.PRE_BRANCH_SDD), INPUT_KEYS.PRE_BRANCH_SDD, false), + verificationSetup: parseIssueWorkflowBoolean(read(INPUT_KEYS.VERIFICATION_SETUP), INPUT_KEYS.VERIFICATION_SETUP, false), reopenIssueOnPush: isEnabledInput(read(INPUT_KEYS.REOPEN_ISSUE_ON_PUSH)), issueDesiredAssigneesCount: parseIntegerInput(read(INPUT_KEYS.DESIRED_ASSIGNEES_COUNT), 0), pullRequestDesiredAssigneesCount: parseIntegerInput(read(INPUT_KEYS.PULL_REQUEST_DESIRED_ASSIGNEES_COUNT), 0), diff --git a/src/actions/local_action_execution.ts b/src/actions/local_action_execution.ts index 5cc94c60d..0300b59e2 100644 --- a/src/actions/local_action_execution.ts +++ b/src/actions/local_action_execution.ts @@ -17,7 +17,7 @@ export function buildLocalActionExecution( debug, singleAction, singleActionIssue, singleActionVersion, singleActionTitle, singleActionChangelog, singleActionMessage, singleActionCommentId, singleActionCommentMode, singleActionOperationId, inactivityThresholdHours, - commitPrefixBuilder, issueManagedBranches, preBranchSdd, reopenIssueOnPush, issueDesiredAssigneesCount, + commitPrefixBuilder, issueManagedBranches, preBranchSdd, verificationSetup, reopenIssueOnPush, issueDesiredAssigneesCount, pullRequestDesiredAssigneesCount, pullRequestDesiredReviewersCount, titleEmoji, branchManagementEmoji, token, agentModel, aiPullRequestDescriptionMode, aiMembersOnly, aiIgnoreFiles, aiIncludeReasoning, bugbotSeverity, @@ -58,6 +58,7 @@ export function buildLocalActionExecution( commitPrefixBuilder, issue: buildIssue(issueManagedBranches, reopenIssueOnPush, issueDesiredAssigneesCount, additionalParams), preBranchSdd, + verificationSetup, pullRequest: buildPullRequest(pullRequestDesiredAssigneesCount, pullRequestDesiredReviewersCount, additionalParams), emoji: buildEmoji(titleEmoji, branchManagementEmoji), tokens: buildTokens(token), diff --git a/src/application/contracts/bugbot_reconciliation.ts b/src/application/contracts/bugbot_reconciliation.ts index 192ac3f24..3fd4a673c 100644 --- a/src/application/contracts/bugbot_reconciliation.ts +++ b/src/application/contracts/bugbot_reconciliation.ts @@ -1,3 +1,4 @@ +import type { BugbotMutationDiagnostic } from '../errors/bugbot_mutation_error'; import type { BugbotIssueComment } from '../ports/bugbot_issue_read_ports'; import type { BugbotReviewNavigation } from '../ports/bugbot_review_navigation_ports'; import type { @@ -60,6 +61,7 @@ export type BugbotReconciliationSnapshotResult = }; export type BugbotPresentationDiagnostic = + | { readonly code: 'finding-mutation-failed'; readonly mutation: BugbotMutationDiagnostic } | { readonly code: 'operation-failed'; readonly operatorMessage: string } | { readonly code: 'identity-unavailable' } | { readonly code: 'snapshot-pull-request-comments-failed' } diff --git a/src/application/contracts/input_keys.ts b/src/application/contracts/input_keys.ts index 9debb36ff..2a6725222 100644 --- a/src/application/contracts/input_keys.ts +++ b/src/application/contracts/input_keys.ts @@ -219,6 +219,7 @@ export const INPUT_KEYS = { // Issue ISSUE_MANAGED_BRANCHES: 'issue-managed-branches', PRE_BRANCH_SDD: 'pre-branch-sdd', + VERIFICATION_SETUP: 'verification-setup', REOPEN_ISSUE_ON_PUSH: 'reopen-issue-on-push', DESIRED_ASSIGNEES_COUNT: 'desired-assignees-count', diff --git a/src/application/contracts/setup_documentation.ts b/src/application/contracts/setup_documentation.ts index c5a082a43..064221987 100644 --- a/src/application/contracts/setup_documentation.ts +++ b/src/application/contracts/setup_documentation.ts @@ -3,4 +3,5 @@ export const SETUP_DOCUMENTATION = { tutorial: 'https://docs.page/vypdev/copilot/setup-web', firstWorkflow: 'https://docs.page/vypdev/copilot/first-workflow', recovery: 'https://docs.page/vypdev/copilot/security-operations/operations/troubleshooting', + verification: 'https://docs.page/vypdev/copilot/security-operations/operations/verification#repository-owned-setup', } as const; diff --git a/src/application/errors/__tests__/application_error.test.ts b/src/application/errors/__tests__/application_error.test.ts index b6ce587c3..fb585a96c 100644 --- a/src/application/errors/__tests__/application_error.test.ts +++ b/src/application/errors/__tests__/application_error.test.ts @@ -9,6 +9,18 @@ import { runAtApplicationErrorBoundary, runWithApplicationErrorCorrelation } fro const CORRELATION_ID = '6f173f89-96a3-4fc8-b90e-4f8f48e0e319'; describe('ApplicationError', () => { + it.each([ + { id: 'stored-configuration-schema-missing', variables: { issueNumber: 0, expectedVersion: 3 } }, + { id: 'stored-configuration-invalid', variables: { issueNumber: 144, expectedVersion: 0 } }, + { id: 'stored-configuration-schema-unsupported', variables: { issueNumber: 144, expectedVersion: 3, actualVersion: 'PRIVATE' } }, + { id: 'stored-configuration-schema-unsupported', variables: { issueNumber: 144, expectedVersion: 3, actualVersion: -1 } }, + { id: 'stored-configuration-schema-unsupported', variables: { issueNumber: 144, expectedVersion: 3, actualVersion: Number.MAX_SAFE_INTEGER + 1 } }, + { id: 'stored-configuration-schema-missing', variables: { issueNumber: 144, expectedVersion: 3, body: 'PRIVATE' } }, + ])('rejects forged stored-configuration facts: $id $variables', recovery => { + expect(() => new ApplicationError('configuration.invalid', 'Invalid state.', { + recovery: recovery as never, + })).toThrow(); + }); it('rejects a forged branch synchronization diagnostic descriptor', () => { expect(() => new ApplicationError('workflow.failed', 'private', { recovery: { id: 'branch-sync-resolution-invalid', variables: { validationCode: 'TOKEN=secret', command: '/copilot sync-branch' } } as never, diff --git a/src/application/errors/__tests__/bugbot_mutation_error.test.ts b/src/application/errors/__tests__/bugbot_mutation_error.test.ts new file mode 100644 index 000000000..ba197af62 --- /dev/null +++ b/src/application/errors/__tests__/bugbot_mutation_error.test.ts @@ -0,0 +1,36 @@ +import { BugbotMutationError, bugbotMutationError } from '../bugbot_mutation_error'; +import { PullRequestReviewOperationError, toPullRequestReviewOperationError } from '../../ports/pull_request_review_errors'; + +it.each([ + [401, 'authorization.credential-invalid'], [403, 'authorization.denied'], [404, 'provider.not-found'], + [409, 'provider.conflict'], [422, 'provider.contract-invalid'], [429, 'provider.rate-limited'], + [408, 'provider.unavailable'], [425, 'provider.unavailable'], + [503, 'provider.unavailable'], +])('preserves safe HTTP %s metadata and classifies recovery as %s', (status, code) => { + const cause = new PullRequestReviewOperationError('resolve-thread', { providerStatus: status, providerReference: 'AB12:34CD' }); + const error = bugbotMutationError(cause, 'resolution', ['backend/Dockerfile:20:healthcheck-requires-curl'], 'mark-resolved'); + expect(error).toMatchObject({ code, diagnostic: { stage: 'resolution', operation: 'resolve-thread', + providerStatus: `http-${status}`, providerReference: 'AB12:34CD' } }); + expect(JSON.stringify(error)).not.toMatch(/private-/); + if (status === 408 || status === 425) expect(error.retryable).toBe(true); +}); + +it('drops malformed provider status/reference and unsafe finding markup', () => { + const cause = new PullRequestReviewOperationError('publish-comments', { providerStatus: 400.5, providerReference: '@team\nsecret' }); + const error = bugbotMutationError(cause, 'publication', ['@team' } }; + const html = await markup('InstallationReview', { review }); + expect(html).toContain(verificationSetupText(action, 'en')); expect(html).toContain(verificationSetupText('enabled', 'en')); + expect(html).toContain('<script>'); expect(html).not.toContain('

                                                                                                          {tr('botRenewal', $setupLocale)}

                                                                                                          +

                                                                                                          {verificationSetupText('result', $setupLocale)} {verificationSetupText('guide', $setupLocale)} ↗

                                                                                                          {tr('setupNextWorkflow', $setupLocale)} {tr('firstWorkflowGuide', $setupLocale)} ↗

                                                                                                          diff --git a/web/src/components/InstallationReview.svelte b/web/src/components/InstallationReview.svelte index 0cb0b288f..625e1f59e 100644 --- a/web/src/components/InstallationReview.svelte +++ b/web/src/components/InstallationReview.svelte @@ -2,9 +2,17 @@ import type { WebSetupPlan } from '../../../src/application/contracts/web_setup_view'; import { runnerText } from '../i18n/runnerCopy'; import { setupLocale } from '../i18n/localeStore'; + import { verificationSetupText } from '../i18n/verificationSetupCopy'; export let review: NonNullable;
                                                                                                          + {#if review.verificationSetup}
                                                                                                          +

                                                                                                          {verificationSetupText('title', $setupLocale)}

                                                                                                          +

                                                                                                          {verificationSetupText(review.verificationSetup.action, $setupLocale)}: .github/actions/copilot-verification-setup/action.yml

                                                                                                          +

                                                                                                          {verificationSetupText(review.verificationSetup.enabled ? 'enabled' : 'disabled', $setupLocale)}

                                                                                                          +

                                                                                                          {verificationSetupText('main', $setupLocale)}: {review.verificationSetup.mainBranch}

                                                                                                          +

                                                                                                          {verificationSetupText('next', $setupLocale)}

                                                                                                          +
                                                                                                          {/if}

                                                                                                          {runnerText('title', $setupLocale)}

                                                                                                          {runnerText('help', $setupLocale)}

                                                                                                          {#if review.blockers.length}

                                                                                                          {runnerText('blockedAction', $setupLocale)}

                                                                                                          {runnerText('blockers', $setupLocale)}
                                                                                                            {#each review.blockers as blocker}
                                                                                                          • {blocker}
                                                                                                          • {/each}
                                                                                                          {/if} diff --git a/web/src/components/SetupHelp.svelte b/web/src/components/SetupHelp.svelte index b7c4bf399..e78c8bed7 100644 --- a/web/src/components/SetupHelp.svelte +++ b/web/src/components/SetupHelp.svelte @@ -2,6 +2,7 @@ import { SETUP_DOCUMENTATION } from '../../../src/application/contracts/setup_documentation'; import { tr } from '../i18n/catalog'; import { setupLocale } from '../i18n/localeStore'; + import { verificationSetupText } from '../i18n/verificationSetupCopy'; diff --git a/web/src/i18n/verificationSetupCopy.ts b/web/src/i18n/verificationSetupCopy.ts new file mode 100644 index 000000000..0d8ae542b --- /dev/null +++ b/web/src/i18n/verificationSetupCopy.ts @@ -0,0 +1,8 @@ +import type { SetupLocale } from './catalog'; +const copy = { + en: { title: 'Verification setup', create: 'Create the starter only if missing', preserve: 'Preserve the existing project action byte-for-byte', blocked: 'Blocked: inspect the unsafe action path', enabled: 'VERIFICATION_SETUP: enabled', disabled: 'VERIFICATION_SETUP: disabled', main: 'Trusted main branch', next: 'The starter fails until customized. Review and merge the project dependencies onto configured MAIN_BRANCH, then run a real verification. An installer PR does not prove runtime readiness.', result: 'Inspect .github/actions/copilot-verification-setup/action.yml. Setup creates it only if missing and preserves existing project actions. Customize the placeholder and review on MAIN_BRANCH before enabling VERIFICATION_SETUP, then run a real verification.', guide: 'Verification setup and upgrade guide' }, + es: { title: 'Preparación de la verificación', create: 'Crear la plantilla solo si falta', preserve: 'Conservar intacta la acción existente del proyecto', blocked: 'Bloqueado: revisa la ruta insegura de la acción', enabled: 'VERIFICATION_SETUP: activado', disabled: 'VERIFICATION_SETUP: desactivado', main: 'Rama principal de confianza', next: 'La plantilla falla hasta personalizarla. Revisa y fusiona las dependencias del proyecto en la MAIN_BRANCH configurada y ejecuta una verificación real. Una PR de instalación no demuestra que el entorno funcione.', result: 'Revisa .github/actions/copilot-verification-setup/action.yml. Setup lo crea solo si falta y conserva la acción existente. Personaliza la plantilla y revísala en MAIN_BRANCH antes de activar VERIFICATION_SETUP; después ejecuta una verificación real.', guide: 'Guía de preparación y actualización de la verificación' }, + fr: { title: 'Préparation de la vérification', create: 'Créer le modèle seulement si absent', preserve: 'Conserver intégralement l’action existante du projet', blocked: 'Bloqué : inspectez le chemin non sûr de l’action', enabled: 'VERIFICATION_SETUP : activé', disabled: 'VERIFICATION_SETUP : désactivé', main: 'Branche principale de confiance', next: 'Le modèle échoue avant personnalisation. Révisez et fusionnez les dépendances du projet sur MAIN_BRANCH, puis lancez une vraie vérification. Une PR d’installation ne prouve pas le fonctionnement.', result: 'Inspectez .github/actions/copilot-verification-setup/action.yml. Setup le crée seulement si absent et conserve l’action existante. Personnalisez et révisez le modèle sur MAIN_BRANCH avant d’activer VERIFICATION_SETUP, puis lancez une vraie vérification.', guide: 'Guide de préparation et de mise à niveau de la vérification' }, + pt: { title: 'Preparação da verificação', create: 'Criar o modelo só se faltar', preserve: 'Preservar integralmente a ação existente do projeto', blocked: 'Bloqueado: inspecione o caminho inseguro da ação', enabled: 'VERIFICATION_SETUP: ativo', disabled: 'VERIFICATION_SETUP: desativado', main: 'Ramo principal de confiança', next: 'O modelo falha até ser personalizado. Reveja e faça merge das dependências na MAIN_BRANCH configurada, depois execute uma verificação real. Uma PR de instalação não comprova o funcionamento.', result: 'Inspecione .github/actions/copilot-verification-setup/action.yml. Setup cria-o só se faltar e preserva a ação existente. Personalize e reveja o modelo na MAIN_BRANCH antes de ativar VERIFICATION_SETUP, depois execute uma verificação real.', guide: 'Guia de preparação e atualização da verificação' }, +} as const; +export function verificationSetupText(key: keyof typeof copy.en, locale: SetupLocale): string { return copy[locale][key]; }