diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2ad92cf..9aebb81 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1,2 @@ * @Coding-Autopilot-System/core +/.github/ @Coding-Autopilot-System/core diff --git a/.github/workflows/autopilot-create-issue.yml b/.github/workflows/autopilot-create-issue.yml index bb3807c..962e81e 100644 --- a/.github/workflows/autopilot-create-issue.yml +++ b/.github/workflows/autopilot-create-issue.yml @@ -15,6 +15,7 @@ jobs: create-issue: if: ${{ github.event.workflow_run.conclusion == 'failure' }} runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Create or update issue uses: actions/github-script@v9 diff --git a/.github/workflows/autopilot-docs-daily.yml b/.github/workflows/autopilot-docs-daily.yml index 670b0a9..09695a3 100644 --- a/.github/workflows/autopilot-docs-daily.yml +++ b/.github/workflows/autopilot-docs-daily.yml @@ -14,6 +14,7 @@ permissions: jobs: docs: runs-on: ubuntu-latest + timeout-minutes: 15 env: ORG: ${{ vars.ORG || github.repository_owner }} GH_TOKEN: ${{ secrets.ORG_READ_TOKEN || github.token }} diff --git a/.github/workflows/autopilot-operator.yml b/.github/workflows/autopilot-operator.yml index c6c1cf0..e46c88d 100644 --- a/.github/workflows/autopilot-operator.yml +++ b/.github/workflows/autopilot-operator.yml @@ -13,6 +13,8 @@ permissions: jobs: operator: runs-on: [self-hosted, Windows] + # Cover the intended batch work: clone, Codex, dependency install, and tests. + timeout-minutes: 60 env: ORG: ${{ vars.ORG }} GH_TOKEN: ${{ secrets.ORG_AUTOPILOT_TOKEN }} diff --git a/.github/workflows/autopilot-org-installer.yml b/.github/workflows/autopilot-org-installer.yml index 60697e1..2d312bb 100644 --- a/.github/workflows/autopilot-org-installer.yml +++ b/.github/workflows/autopilot-org-installer.yml @@ -13,6 +13,7 @@ permissions: jobs: installer: runs-on: ubuntu-latest + timeout-minutes: 15 env: ORG: ${{ vars.ORG }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 1def497..27c1752 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -4,10 +4,14 @@ on: branches: ["main", "master"] pull_request: branches: ["main", "master"] +permissions: + contents: read + jobs: analyze: name: Analyze runs-on: ubuntu-latest + timeout-minutes: 15 permissions: actions: read contents: read diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 0f43fae..276236a 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -14,6 +14,7 @@ concurrency: jobs: build: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@v6 - uses: actions/setup-python@v5 @@ -29,6 +30,7 @@ jobs: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest + timeout-minutes: 10 needs: build steps: - name: Deploy to GitHub Pages diff --git a/.github/workflows/pr-lint.yml b/.github/workflows/pr-lint.yml index 2f71474..afc713b 100644 --- a/.github/workflows/pr-lint.yml +++ b/.github/workflows/pr-lint.yml @@ -3,9 +3,14 @@ on: pull_request: types: ['opened', 'edited', 'reopened', 'synchronize'] +permissions: + contents: read + pull-requests: read + jobs: main: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: amannn/action-semantic-pull-request@v5 env: diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 987cba1..6d4fb1b 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -3,9 +3,15 @@ on: schedule: - cron: '30 1 * * *' +permissions: + contents: read + issues: write + pull-requests: write + jobs: stale: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/stale@v8 with: diff --git a/memory/examples/20260704_operator-timeout-safe.md b/memory/examples/20260704_operator-timeout-safe.md new file mode 100644 index 0000000..9a0bd14 --- /dev/null +++ b/memory/examples/20260704_operator-timeout-safe.md @@ -0,0 +1,8 @@ +# F-07 operator timeout safety + +Issue Description: The GitHub Actions operator job could time out after marking an issue `in-progress`, leaving it stranded until a later manual cleanup. +State: The workflow timeout was too short for the intended batch work of clone, Codex, dependency install, and tests. +Action: Increased `.github/workflows/autopilot-operator.yml` timeout to 60 minutes and added a contract assertion in `tests/contract-tests.ps1`. +Result: The operator job now has enough time for its designed batch work, and CI prevents the timeout from being reduced unnoticed. +Diff Patch: Updated the workflow timeout and added a workflow contract check. +Rationale: Batch automation should not strand claim-state on a predictable timeout boundary. diff --git a/tests/contract-tests.ps1 b/tests/contract-tests.ps1 index a1b00e1..9fed160 100644 --- a/tests/contract-tests.ps1 +++ b/tests/contract-tests.ps1 @@ -23,6 +23,7 @@ Assert-TextMatch -Text $operator -Pattern 'Assert-SafeChangeSet' -Message "Opera Assert-TextMatch -Text $operator -Pattern 'ALLOW_UNVERIFIED' -Message "Operator must enforce verification by default." Assert-TextMatch -Text $workflow -Pattern 'secrets\.ORG_AUTOPILOT_TOKEN' -Message "Workflow must use an explicit org mutation token." Assert-TextNotMatch -Text $workflow -Pattern 'GH_TOKEN: \$\{\{ secrets\.GITHUB_TOKEN \}\}' -Message "Workflow must not use repository token for org mutations." +Assert-TextMatch -Text $workflow -Pattern 'timeout-minutes: 60' -Message "Operator workflow must allow enough time for the intended batch work." Assert-TextNotMatch -Text $installer -Pattern 'autofix,queued,docs' -Message "Installer must not queue automation before repository opt-in."