diff --git a/.agents/pm/chores/pm-github-sx18.toon b/.agents/pm/chores/pm-github-sx18.toon new file mode 100644 index 0000000..0495ad0 --- /dev/null +++ b/.agents/pm/chores/pm-github-sx18.toon @@ -0,0 +1,24 @@ +id: pm-github-sx18 +title: Enable GitHub CodeQL code scanning +description: "Add .github/workflows/codeql.yml (javascript-typescript, build-mode none, weekly staggered schedule). GET code-scanning/alerts returned 404 no-analysis-found, so the Security tab could not distinguish clean from never-ran. Advisory check only, not added to branch protection." +type: Chore +status: in_progress +priority: 2 +tags: [] +created_at: "2026-08-22T17:43:42.366Z" +updated_at: "2026-08-22T18:00:00.764Z" +author: "harness:ox-alpha" +notes[1]{created_at,author,text}: + "2026-08-22T17:43:54.385Z","harness:ox-alpha","Verified 2026-08-22: gh api repos/unbraind/pm-github/code-scanning/alerts -> 404 'no analysis found'. Workflow pins github/codeql-action v4 (fleet major-tag convention), permissions limited to security-events:write/actions:read/contents:read." +files[1]{path,scope,note}: + .github/workflows/codeql.yml,project,CodeQL scanning workflow - javascript-typescript build-mode none weekly staggered cron +tests[2]: + - command: "gh run list -R unbraind/pm-github --workflow codeql.yml --branch ci/enable-codeql-scanning --limit 1 --json conclusion --jq '.[0].conclusion'" + scope: project + assert_stdout_regex[1]: ^success$ + note: "The CodeQL workflow must have a COMPLETED SUCCESSFUL run on this branch. Asserting the conclusion rather than the presence of a run: gh run list prints a failed run too, so an unasserted invocation passes while the scan is broken." + - command: "gh api repos/unbraind/pm-github/code-scanning/analyses --jq '[.[]|select(.tool.name==\"CodeQL\")]|length'" + scope: project + assert_stdout_regex[1]: "^[1-9][0-9]*$" + note: "At least one CodeQL analysis must exist. Deliberately queries /analyses, not /alerts: an empty /alerts array is ambiguous between analysed-and-clean and never-analysed, and that ambiguity is the exact defect this change removes. /analyses answers did-a-scan-run directly, so a clean repo passes and an unscanned one fails closed with HTTP 404." +body: "" diff --git a/.agents/pm/history/pm-github-sx18.jsonl b/.agents/pm/history/pm-github-sx18.jsonl new file mode 100644 index 0000000..a045b74 --- /dev/null +++ b/.agents/pm/history/pm-github-sx18.jsonl @@ -0,0 +1,9 @@ +{"ts":"2026-08-22T17:43:42.366Z","author":"harness:ox-alpha","author_source":"asserted","agent_harness":"pi","agent_model":"stealth/ox-alpha","agent_model_source":"environment","agent_instance":"73ffe9cf6d87e6e059050f65","agent_provenance":{"model":{"value":"stealth/ox-alpha","source":"environment"},"effort":null,"role":{"value":"implementer","source":"argv"},"topic":null},"op":"create","patch":[{"op":"add","path":"/metadata/id","value":"pm-github-sx18"},{"op":"add","path":"/metadata/title","value":"Enable GitHub CodeQL code scanning"},{"op":"add","path":"/metadata/description","value":"Add .github/workflows/codeql.yml (javascript-typescript, build-mode none, weekly staggered schedule). GET code-scanning/alerts returned 404 no-analysis-found, so the Security tab could not distinguish clean from never-ran. Advisory check only, not added to branch protection."},{"op":"add","path":"/metadata/type","value":"Chore"},{"op":"add","path":"/metadata/status","value":"open"},{"op":"add","path":"/metadata/priority","value":2},{"op":"add","path":"/metadata/tags","value":[]},{"op":"add","path":"/metadata/created_at","value":"2026-08-22T17:43:42.366Z"},{"op":"add","path":"/metadata/updated_at","value":"2026-08-22T17:43:42.366Z"},{"op":"add","path":"/metadata/author","value":"harness:ox-alpha"}],"before_hash":"3cc22dff72be7b14824654a7a64ea62b04799939b2fee54c1b5f52ca60bf6df0","after_hash":"f21c68bd3ac2d5ddb85375c3f69f92ec1f33e402340904c6800129bc95717f89","item_hash_version":2,"message":""} +{"ts":"2026-08-22T17:43:53.564Z","author":"harness:ox-alpha","author_source":"asserted","agent_harness":"pi","agent_model":"stealth/ox-alpha","agent_model_source":"environment","agent_instance":"73ffe9cf6d87e6e059050f65","agent_provenance":{"model":{"value":"stealth/ox-alpha","source":"environment"},"effort":null,"role":{"value":"implementer","source":"argv"},"topic":null},"op":"update","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-08-22T17:43:53.564Z"},{"op":"replace","path":"/metadata/status","value":"in_progress"}],"before_hash":"f21c68bd3ac2d5ddb85375c3f69f92ec1f33e402340904c6800129bc95717f89","after_hash":"41f5916e9f28a6ba329ddbd47f69197552b429ea82392ad03fc72b1f34864493","item_hash_version":2} +{"ts":"2026-08-22T17:43:53.976Z","author":"harness:ox-alpha","author_source":"asserted","agent_harness":"pi","agent_model":"stealth/ox-alpha","agent_model_source":"environment","agent_instance":"73ffe9cf6d87e6e059050f65","agent_provenance":{"model":{"value":"stealth/ox-alpha","source":"environment"},"effort":null,"role":null,"topic":null},"op":"files_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-08-22T17:43:53.976Z"},{"op":"add","path":"/metadata/files","value":[{"path":".github/workflows/codeql.yml","scope":"project","note":"CodeQL scanning workflow - javascript-typescript build-mode none weekly staggered cron"}]}],"before_hash":"41f5916e9f28a6ba329ddbd47f69197552b429ea82392ad03fc72b1f34864493","after_hash":"6d39c1edacca1c493748e73983049370ebec15528114637e2218f59a90bf07ea","item_hash_version":2} +{"ts":"2026-08-22T17:43:54.386Z","author":"harness:ox-alpha","author_source":"asserted","agent_harness":"pi","agent_model":"stealth/ox-alpha","agent_model_source":"environment","agent_instance":"73ffe9cf6d87e6e059050f65","agent_provenance":{"model":{"value":"stealth/ox-alpha","source":"environment"},"effort":null,"role":null,"topic":null},"op":"note_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-08-22T17:43:54.386Z"},{"op":"add","path":"/metadata/notes","value":[{"created_at":"2026-08-22T17:43:54.385Z","author":"harness:ox-alpha","text":"Verified 2026-08-22: gh api repos/unbraind/pm-github/code-scanning/alerts -> 404 'no analysis found'. Workflow pins github/codeql-action v4 (fleet major-tag convention), permissions limited to security-events:write/actions:read/contents:read."}]}],"before_hash":"6d39c1edacca1c493748e73983049370ebec15528114637e2218f59a90bf07ea","after_hash":"163a8bedd573e0a27b228d5531cf777b316a703cdd88de7ff527d28433d29a3e","item_hash_version":2} +{"ts":"2026-08-22T17:43:54.780Z","author":"harness:ox-alpha","author_source":"asserted","agent_harness":"pi","agent_model":"stealth/ox-alpha","agent_model_source":"environment","agent_instance":"73ffe9cf6d87e6e059050f65","agent_provenance":{"model":{"value":"stealth/ox-alpha","source":"environment"},"effort":null,"role":null,"topic":null},"op":"tests_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-08-22T17:43:54.780Z"},{"op":"add","path":"/metadata/tests","value":[{"command":"gh run list -R unbraind/pm-github --branch ci/enable-codeql-scanning","scope":"project","note":"CodeQL workflow run succeeds on the PR branch"}]}],"before_hash":"163a8bedd573e0a27b228d5531cf777b316a703cdd88de7ff527d28433d29a3e","after_hash":"eba66200d904b6205fea2eb071a6291d09dd0f2c94ad96a3c2f7852258ee6c49","item_hash_version":2} +{"ts":"2026-08-22T17:43:55.186Z","author":"harness:ox-alpha","author_source":"asserted","agent_harness":"pi","agent_model":"stealth/ox-alpha","agent_model_source":"environment","agent_instance":"73ffe9cf6d87e6e059050f65","agent_provenance":{"model":{"value":"stealth/ox-alpha","source":"environment"},"effort":null,"role":null,"topic":null},"op":"tests_add","patch":[{"op":"add","path":"/metadata/tests/1","value":{"command":"gh api repos/unbraind/pm-github/code-scanning/alerts","scope":"project","assert_stdout_regex":["rule_id|most_recent_instance|analysis_key"],"note":"code-scanning alerts endpoint returns an analysis instead of 404 no-analysis-found"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-22T17:43:55.186Z"}],"before_hash":"eba66200d904b6205fea2eb071a6291d09dd0f2c94ad96a3c2f7852258ee6c49","after_hash":"3a1a33f00425b625041a885994decf27bd12c8e5fd96a769cb7aeb8784e79bde","item_hash_version":2} +{"ts":"2026-08-22T17:59:59.257Z","author":"codex","author_source":"configured","agent_harness":"claude-code","agent_instance":"d8080bf24e1b0babea915d0e","agent_provenance":{"model":null,"effort":{"value":"xhigh","source":"environment"},"role":null,"topic":null},"op":"tests_remove","patch":[{"op":"remove","path":"/metadata/tests/1"},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-22T17:59:59.257Z"}],"before_hash":"3a1a33f00425b625041a885994decf27bd12c8e5fd96a769cb7aeb8784e79bde","after_hash":"3575b4516e8eeef428ee7a2c8512060022d374c2cb4d7ab0448af688d04a99db","item_hash_version":2,"context":{"agent_provenance_outcomes":{"model":{"status":"failed","reason":"resolver_failed","resolver":"claude_session_file","rule_version":"v1"},"version":{"status":"failed","reason":"resolver_failed","resolver":"claude_session_file","rule_version":"v1"}}}} +{"ts":"2026-08-22T17:59:59.729Z","author":"codex","author_source":"configured","agent_harness":"claude-code","agent_instance":"d8080bf24e1b0babea915d0e","agent_provenance":{"model":null,"effort":{"value":"xhigh","source":"environment"},"role":null,"topic":null},"op":"tests_remove","patch":[{"op":"remove","path":"/metadata/tests"},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-22T17:59:59.729Z"}],"before_hash":"3575b4516e8eeef428ee7a2c8512060022d374c2cb4d7ab0448af688d04a99db","after_hash":"0e8165f05850957c22602f68fa824c007c6a29e3bdd8bffcde633c1735977610","item_hash_version":2,"context":{"agent_provenance_outcomes":{"model":{"status":"failed","reason":"resolver_failed","resolver":"claude_session_file","rule_version":"v1"},"version":{"status":"failed","reason":"resolver_failed","resolver":"claude_session_file","rule_version":"v1"}}}} +{"ts":"2026-08-22T18:00:00.764Z","author":"codex","author_source":"configured","agent_harness":"claude-code","agent_instance":"d8080bf24e1b0babea915d0e","agent_provenance":{"model":null,"effort":{"value":"xhigh","source":"environment"},"role":null,"topic":null},"op":"tests_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-08-22T18:00:00.764Z"},{"op":"add","path":"/metadata/tests","value":[{"command":"gh run list -R unbraind/pm-github --workflow codeql.yml --branch ci/enable-codeql-scanning --limit 1 --json conclusion --jq '.[0].conclusion'","scope":"project","assert_stdout_regex":["^success$"],"note":"The CodeQL workflow must have a COMPLETED SUCCESSFUL run on this branch. Asserting the conclusion rather than the presence of a run: gh run list prints a failed run too, so an unasserted invocation passes while the scan is broken."},{"command":"gh api repos/unbraind/pm-github/code-scanning/analyses --jq '[.[]|select(.tool.name==\"CodeQL\")]|length'","scope":"project","assert_stdout_regex":["^[1-9][0-9]*$"],"note":"At least one CodeQL analysis must exist. Deliberately queries /analyses, not /alerts: an empty /alerts array is ambiguous between analysed-and-clean and never-analysed, and that ambiguity is the exact defect this change removes. /analyses answers did-a-scan-run directly, so a clean repo passes and an unscanned one fails closed with HTTP 404."}]}],"before_hash":"0e8165f05850957c22602f68fa824c007c6a29e3bdd8bffcde633c1735977610","after_hash":"87a80952db0eb89c38cd8c0d69c35d100652a13f33de8c3ff62119ce1ae03793","item_hash_version":2,"context":{"agent_provenance_outcomes":{"model":{"status":"failed","reason":"resolver_failed","resolver":"claude_session_file","rule_version":"v1"},"version":{"status":"failed","reason":"resolver_failed","resolver":"claude_session_file","rule_version":"v1"}}}} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..818231d --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,40 @@ +name: CodeQL + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + # Weekly CodeQL scan, minute/hour staggered across the pm fleet so the + # repos do not all fire against the API at the same time. + - cron: "43 3 * * 1" + +concurrency: + group: codeql-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + codeql: + permissions: + security-events: write + actions: read + contents: read + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + persist-credentials: false + + - name: Initialize CodeQL + uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4 + with: + languages: javascript-typescript + # These packages are analyzed from source without a compiled build. + build-mode: none + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4 + with: + category: "/language:javascript-typescript"