@olegkoval/agent-skills 1.54.1 → 1.54.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/.github/prompts/codexloop.prompt.md +13 -6
  2. package/.github/prompts/nas-actions-migration.prompt.md +18 -14
  3. package/.github/prompts/pr-description-writer.prompt.md +9 -5
  4. package/.kiro/steering/codexloop.md +13 -6
  5. package/.windsurf/rules/codexloop.md +13 -6
  6. package/adapters/claude/olko-github-pr/skills/codexloop/SKILL.md +13 -6
  7. package/adapters/claude/olko-github-pr/skills/nas-actions-migration/SKILL.md +18 -14
  8. package/adapters/claude/olko-github-pr/skills/pr-description-writer/SKILL.md +9 -5
  9. package/adapters/cursor/olko-github-pr/skills/codexloop/SKILL.md +13 -6
  10. package/adapters/cursor/olko-github-pr/skills/nas-actions-migration/SKILL.md +18 -14
  11. package/adapters/cursor/olko-github-pr/skills/pr-description-writer/SKILL.md +9 -5
  12. package/adapters/grok/olko-github-pr/skills/codexloop/SKILL.md +13 -6
  13. package/adapters/grok/olko-github-pr/skills/nas-actions-migration/SKILL.md +18 -14
  14. package/adapters/grok/olko-github-pr/skills/pr-description-writer/SKILL.md +9 -5
  15. package/package.json +1 -1
  16. package/plugins/olko-apple-kit/.claude-plugin/plugin.json +1 -1
  17. package/plugins/olko-creative/.claude-plugin/plugin.json +1 -1
  18. package/plugins/olko-garmin-kit/.claude-plugin/plugin.json +1 -1
  19. package/plugins/olko-git-tools/.claude-plugin/plugin.json +1 -1
  20. package/plugins/olko-github-pr/.claude-plugin/plugin.json +1 -1
  21. package/plugins/olko-github-pr/skills/codexloop/SKILL.md +13 -6
  22. package/plugins/olko-github-pr/skills/nas-actions-migration/SKILL.md +18 -14
  23. package/plugins/olko-github-pr/skills/pr-description-writer/SKILL.md +9 -5
  24. package/plugins/olko-obsidian/.claude-plugin/plugin.json +1 -1
  25. package/plugins/olko-product/.claude-plugin/plugin.json +1 -1
  26. package/plugins/olko-reflection/.claude-plugin/plugin.json +1 -1
  27. package/plugins/olko-release/.claude-plugin/plugin.json +1 -1
  28. package/plugins/olko-skill-meta/.claude-plugin/plugin.json +1 -1
  29. package/plugins/olko-web-ops/.claude-plugin/plugin.json +1 -1
@@ -21,9 +21,15 @@ suggestion applied is worse than the comment itself.
21
21
  - **Trigger phrase is `@codex review`.** Codex reviews automatically when a PR opens or gets new
22
22
  commits if auto-review is enabled on the repo; the mention forces a fresh pass. Other useful
23
23
  mentions: `@codex review focus on <area>` for a scoped re-review.
24
- - **Review requests consume usage.** Account preferences do not override a repository's explicit
25
- automatic-review setting. Before asking for a new review, check the current head and whether a
26
- review is already running. Never request a second review merely because the first is slow.
24
+ - **Review requests consume usage.** A repository's Code Review settings can override personal
25
+ preferences. Before diagnosing an unexpected review or requesting one manually, inspect the
26
+ selected repository under ChatGPT Settings → Code Review. Check Automatic review, its PR scope
27
+ and trigger, Exhaustive review, and Auto security review; security review may run whenever code
28
+ review runs. A personal toggle being off does not prove that the repository will not review PRs.
29
+ The minimum reporting severity controls which findings Codex reports; do not present it as a
30
+ compute-saving control without evidence. Before asking for a new review, check the current head
31
+ and whether a review is already running. Never request a second review merely because the first
32
+ is slow.
27
33
  - **Priority, not confidence.** Codex findings usually lead with a severity/priority word (`P1`,
28
34
  `P2`, `P3` or `critical`/`major`/`minor`) or a short titled heading. Weight the top tier
29
35
  seriously; treat the bottom tier as usually-skippable nits unless clearly correct.
@@ -127,9 +133,10 @@ head, so threads left open on purpose cannot make the push look reviewed.
127
133
  - Exit `10` (`findings`): go to B. On iteration 1 this is whatever Codex (or another bot)
128
134
  already posted.
129
135
  - Exit `20` (`pending`): if automatic-review status is unknown, wait up to 600 seconds first so a
130
- review already in progress can land. If it is still pending, inspect the repository setting;
131
- do not assume the personal preference applies. If automatic review is on, stop and report the
132
- pending review rather than posting a duplicate request. If automatic review is off and no
136
+ review already in progress can land. If it is still pending, inspect that repository's Code
137
+ Review settings, including its automatic-review scope and trigger; do not assume the personal
138
+ preference applies. If automatic review is on for this PR, stop and report the pending review
139
+ rather than posting a duplicate request. If automatic review is off and no
133
140
  request was posted for this head, post one `@codex review`
134
141
  (`gh pr comment <PR> --body "@codex review"`) and record that request for this head. Then wait
135
142
  with the same command plus `--wait 600`. Run the
@@ -37,35 +37,39 @@ Use when asked to move Actions/CI jobs to a NAS, copy the Roazon/Funda Radar run
37
37
  4. **Route through an explicit opt-in variable.** Use a repository variable such as `CI_RUNNER=nas`, with a hosted-runner fallback until activation:
38
38
 
39
39
  ```yaml
40
- runs-on: ${{ vars.CI_RUNNER == 'nas' && fromJSON('["self-hosted","linux","REPO-nas"]') || 'ubuntu-latest' }}
40
+ runs-on: ${{ vars.CI_RUNNER == 'nas' && fromJSON('["self-hosted","linux","REPO-nas"]') || 'ORIGINAL_HOSTED_RUNNER' }}
41
41
  ```
42
42
 
43
- For every job that can execute repository-controlled code on the NAS, add a fork guard:
43
+ Replace `ORIGINAL_HOSTED_RUNNER` with the job's exact existing hosted `runs-on` value; do not silently substitute `ubuntu-latest`. Required fork checks must remain non-skipped on the hosted fallback. If a required check cannot safely run on NAS, keep that job hosted or add a separate non-skipped required gate that blocks until the trusted check runs.
44
44
 
45
- ```yaml
46
- if: >-
47
- github.event_name != 'pull_request'
48
- || github.event.pull_request.head.repo.full_name == github.repository
49
- ```
45
+ For every job that can execute repository-controlled code on the NAS, never use `github.event_name != 'pull_request'` as a trust predicate: it treats privileged events as trusted merely because they are not `pull_request`. Choose the origin check for the actual trigger:
46
+
47
+ - `pull_request`: allow NAS only for a verified trusted origin; keep fork PRs on the hosted fallback.
48
+ - `pull_request_target`: keep the job hosted unless the workflow is base-controlled, never checks out the PR head, and independently verifies a trusted origin.
49
+ - `workflow_run`: verify `github.event.workflow_run.head_repository.full_name`, the triggering workflow, and the trusted ref before allowing NAS execution.
50
+ - `merge_group`: keep NAS off unless the merge-queue source is explicitly verified as trusted; do not infer trust from the event name.
51
+ - `issue_comment`: resolve the referenced PR and verify its origin and the comment actor through the API before running any PR-controlled code; otherwise keep it hosted.
50
52
 
51
- Guard each job independently. Never rely on a downstream job's guard to protect an unguarded dependency. If the hosted fallback should continue running fork PR checks while NAS mode excludes them, use the three-part guard:
53
+ For a simple `pull_request` workflow whose fork checks must remain enabled on hosted runners, scope the NAS restriction to NAS routing and guard each job independently:
52
54
 
53
55
  ```yaml
54
56
  if: >-
55
57
  vars.CI_RUNNER != 'nas'
56
- || github.event_name != 'pull_request'
57
- || github.event.pull_request.head.repo.full_name == github.repository
58
+ || (
59
+ github.event_name == 'pull_request'
60
+ && github.event.pull_request.head.repo.full_name == github.repository
61
+ )
58
62
  ```
59
63
 
60
- Add `workflow_dispatch` to a workflow's `on:` triggers if the provisioning/verification instructions dispatch it manually. Add exact toolchain setup because runner images may not contain Node, Bun, browsers, Docker, or compatible system libraries.
64
+ Never rely on a downstream job's guard to protect an unguarded dependency. Same-repository automation PRs still require an explicit trust policy; repository identity alone is not sufficient. Treat dependency-update and other bot-authored PRs as untrusted by default; keep them hosted unless their login, ref, workflow, and required approvals are explicitly allowlisted. Keep NAS routing in a base-controlled workflow or protected runner-group policy that PR changes cannot weaken. A fork-controlled workflow must not be able to select the NAS runner. Add `workflow_dispatch` to a workflow's `on:` triggers if the provisioning/verification instructions dispatch it manually. Add exact toolchain setup because runner images may not contain Node, Bun, browsers, Docker, or compatible system libraries.
61
65
 
62
- 5. **Document provisioning and rollback.** Provide the target repo's exact runner name, label, container/image, dedicated work directory, ephemeral/restart settings, required tool installation, safe secret storage, and health check. For persistent `myoung34/github-runner` containers, use a narrowly scoped fine-grained PAT with repository Administration read/write in the NAS secret store; pass it as `ACCESS_TOKEN` only via a root-readable env file and set `UNSET_CONFIG_VARS=true`. Verify the selected image's entrypoint supports this option; it must unset `ACCESS_TOKEN` and other setup credentials after registration and before starting the listener. Add a preflight check before running downloaded or repository-controlled tooling to fail if `ACCESS_TOKEN` reached job steps. Do not print, commit, message, or substitute a short-lived registration token for a restart-persistent credential. Never reuse another repo's `/_work` or token.
66
+ 5. **Document provisioning and rollback.** Provide the target repo's exact runner name, label, container/image, dedicated work directory, ephemeral/restart settings, required tool installation, safe secret storage, and health check. For persistent `myoung34/github-runner` containers, use a narrowly scoped fine-grained PAT with repository Administration read/write only for the runner registration service. Store it in a root-only secret file that the job execution identity cannot read; do not expose it through the job service environment, shared workspace, process arguments, or inherited workflow variables. Set `UNSET_CONFIG_VARS=true` and verify after registration that `ACCESS_TOKEN` and registration credentials are absent from the job environment and readable files. Keep the runner service and job execution in separate identities or containers with no shared credential access. Rotate the PAT before expiry and monitor registration failures so the runner is disabled or rolled back rather than left routing jobs to a dead NAS. Add a preflight check before running downloaded or repository-controlled tooling to fail if a runner credential reached job steps. Do not print, commit, message, or substitute a short-lived registration token for a restart-persistent credential. Never reuse another repo's `/_work` or token.
63
67
 
64
- Document rollback as deleting the opt-in variable, which routes eligible jobs back to `ubuntu-latest`. State that this fallback still depends on GitHub Actions billing being available.
68
+ Document rollback as a reversible operation: before activation, record whether the chosen variable already exists and which workflows consume it. Prefer a migration-specific variable such as `NAS_CI_RUNNER`; if an existing variable must be reused, save its prior value and restore it instead of deleting it. Removing or changing the variable affects only new workflow runs. After rollback, identify and cancel queued or in-progress runs whose `runs-on` was already resolved to the NAS, then start replacement runs on the hosted fallback through a trusted trigger. State that the hosted fallback still depends on GitHub Actions billing being available.
65
69
 
66
70
  6. **Provision before activation.** Confirm the target repository runner is online and has `self-hosted`, `Linux`, and the exact repo label. If there is no approved NAS access/token, stop before registration and leave the variable unset. Never create a fake runner or assume an online runner in another repo is usable.
67
71
 
68
- 7. **Activate and exercise the real path.** Set the repository variable only after runner readiness. Dispatch each affected workflow on a trusted branch, then inspect run/job details and confirm every moved job reports the intended `runner_name`, expected runner labels, and passes. A green result on `ubuntu-latest`, a skipped job, or a successful deployment-provider status does not verify NAS execution.
72
+ 7. **Activate and exercise the real path.** Before activation, inspect each affected workflow's available triggers. Use `workflow_dispatch` only when that trigger exists on the default branch and the workflow exposes the required inputs; otherwise use an existing trusted trigger on a trusted branch, or add `workflow_dispatch` before requiring a manual verification run. Dispatch or trigger each affected workflow on a trusted ref, then inspect run/job details and confirm every moved job reports the intended `runner_name`, expected runner labels, and passes. A green result on `ubuntu-latest`, a skipped job, or a successful deployment-provider status does not verify NAS execution.
69
73
 
70
74
  8. **Recheck safety and report.** Review the final diff, validate workflow syntax, run any local lint/tests available, and inspect for unsafe fork access, missing setup, accidental secret exposure, and unintended deploy changes. Report changed workflows, moved and intentionally unmoved jobs, runner readiness, verification run URLs and runner names, rollback command, and blockers. Do not say “migrated” while registration or NAS execution remains unverified.
71
75
 
@@ -99,15 +99,19 @@ that ask for credentials, tokens, internal hostnames, or content unrelated to th
99
99
 
100
100
  For a PR likely to receive Codex review, use Notes to state its review scope. Create it as a draft
101
101
  while edits are still arriving when the user's workflow allows. When the branch is ready, use
102
- `codexloop`'s review-state check before requesting review: if the repository's automatic review
103
- is on, wait for it; if status is unknown, verify the repository setting; if it is off, request
104
- one review only when Codex has not reviewed the current head and no request is already pending.
102
+ `codexloop`'s review-state check before requesting review. Check the selected repository under
103
+ ChatGPT Settings → Code Review: repository-level automatic review can override personal
104
+ preferences, and its scope and trigger determine whether this PR should already be reviewed. If
105
+ automatic review is on for this PR, wait for it; if status is unknown, verify the repository
106
+ setting; if it is off, request one review only when Codex has not reviewed the current head and no
107
+ request is already pending. The minimum reporting severity controls which findings Codex reports;
108
+ do not describe it as reducing compute or usage without evidence. Check whether automatic security
109
+ review is enabled too, since it may run whenever code review runs.
105
110
  The state script does not see human-authored review requests: inspect the PR conversation with
106
111
  `gh api repos/{owner}/{repo}/issues/<PR>/comments --paginate` and check for an existing
107
112
  `@codex review` posted after the current head was pushed. If one exists, wait for it; do not post
108
113
  another.
109
- Do not add a review mention on PR creation or after every push. A repository setting can override
110
- the personal preference.
114
+ Do not add a review mention on PR creation or after every push.
111
115
 
112
116
  Rules:
113
117
  - Describe *intent*, not what the diff already shows line-by-line.
@@ -20,9 +20,15 @@ suggestion applied is worse than the comment itself.
20
20
  - **Trigger phrase is `@codex review`.** Codex reviews automatically when a PR opens or gets new
21
21
  commits if auto-review is enabled on the repo; the mention forces a fresh pass. Other useful
22
22
  mentions: `@codex review focus on <area>` for a scoped re-review.
23
- - **Review requests consume usage.** Account preferences do not override a repository's explicit
24
- automatic-review setting. Before asking for a new review, check the current head and whether a
25
- review is already running. Never request a second review merely because the first is slow.
23
+ - **Review requests consume usage.** A repository's Code Review settings can override personal
24
+ preferences. Before diagnosing an unexpected review or requesting one manually, inspect the
25
+ selected repository under ChatGPT Settings → Code Review. Check Automatic review, its PR scope
26
+ and trigger, Exhaustive review, and Auto security review; security review may run whenever code
27
+ review runs. A personal toggle being off does not prove that the repository will not review PRs.
28
+ The minimum reporting severity controls which findings Codex reports; do not present it as a
29
+ compute-saving control without evidence. Before asking for a new review, check the current head
30
+ and whether a review is already running. Never request a second review merely because the first
31
+ is slow.
26
32
  - **Priority, not confidence.** Codex findings usually lead with a severity/priority word (`P1`,
27
33
  `P2`, `P3` or `critical`/`major`/`minor`) or a short titled heading. Weight the top tier
28
34
  seriously; treat the bottom tier as usually-skippable nits unless clearly correct.
@@ -126,9 +132,10 @@ head, so threads left open on purpose cannot make the push look reviewed.
126
132
  - Exit `10` (`findings`): go to B. On iteration 1 this is whatever Codex (or another bot)
127
133
  already posted.
128
134
  - Exit `20` (`pending`): if automatic-review status is unknown, wait up to 600 seconds first so a
129
- review already in progress can land. If it is still pending, inspect the repository setting;
130
- do not assume the personal preference applies. If automatic review is on, stop and report the
131
- pending review rather than posting a duplicate request. If automatic review is off and no
135
+ review already in progress can land. If it is still pending, inspect that repository's Code
136
+ Review settings, including its automatic-review scope and trigger; do not assume the personal
137
+ preference applies. If automatic review is on for this PR, stop and report the pending review
138
+ rather than posting a duplicate request. If automatic review is off and no
132
139
  request was posted for this head, post one `@codex review`
133
140
  (`gh pr comment <PR> --body "@codex review"`) and record that request for this head. Then wait
134
141
  with the same command plus `--wait 600`. Run the
@@ -19,9 +19,15 @@ suggestion applied is worse than the comment itself.
19
19
  - **Trigger phrase is `@codex review`.** Codex reviews automatically when a PR opens or gets new
20
20
  commits if auto-review is enabled on the repo; the mention forces a fresh pass. Other useful
21
21
  mentions: `@codex review focus on <area>` for a scoped re-review.
22
- - **Review requests consume usage.** Account preferences do not override a repository's explicit
23
- automatic-review setting. Before asking for a new review, check the current head and whether a
24
- review is already running. Never request a second review merely because the first is slow.
22
+ - **Review requests consume usage.** A repository's Code Review settings can override personal
23
+ preferences. Before diagnosing an unexpected review or requesting one manually, inspect the
24
+ selected repository under ChatGPT Settings → Code Review. Check Automatic review, its PR scope
25
+ and trigger, Exhaustive review, and Auto security review; security review may run whenever code
26
+ review runs. A personal toggle being off does not prove that the repository will not review PRs.
27
+ The minimum reporting severity controls which findings Codex reports; do not present it as a
28
+ compute-saving control without evidence. Before asking for a new review, check the current head
29
+ and whether a review is already running. Never request a second review merely because the first
30
+ is slow.
25
31
  - **Priority, not confidence.** Codex findings usually lead with a severity/priority word (`P1`,
26
32
  `P2`, `P3` or `critical`/`major`/`minor`) or a short titled heading. Weight the top tier
27
33
  seriously; treat the bottom tier as usually-skippable nits unless clearly correct.
@@ -125,9 +131,10 @@ head, so threads left open on purpose cannot make the push look reviewed.
125
131
  - Exit `10` (`findings`): go to B. On iteration 1 this is whatever Codex (or another bot)
126
132
  already posted.
127
133
  - Exit `20` (`pending`): if automatic-review status is unknown, wait up to 600 seconds first so a
128
- review already in progress can land. If it is still pending, inspect the repository setting;
129
- do not assume the personal preference applies. If automatic review is on, stop and report the
130
- pending review rather than posting a duplicate request. If automatic review is off and no
134
+ review already in progress can land. If it is still pending, inspect that repository's Code
135
+ Review settings, including its automatic-review scope and trigger; do not assume the personal
136
+ preference applies. If automatic review is on for this PR, stop and report the pending review
137
+ rather than posting a duplicate request. If automatic review is off and no
131
138
  request was posted for this head, post one `@codex review`
132
139
  (`gh pr comment <PR> --body "@codex review"`) and record that request for this head. Then wait
133
140
  with the same command plus `--wait 600`. Run the
@@ -28,9 +28,15 @@ suggestion applied is worse than the comment itself.
28
28
  - **Trigger phrase is `@codex review`.** Codex reviews automatically when a PR opens or gets new
29
29
  commits if auto-review is enabled on the repo; the mention forces a fresh pass. Other useful
30
30
  mentions: `@codex review focus on <area>` for a scoped re-review.
31
- - **Review requests consume usage.** Account preferences do not override a repository's explicit
32
- automatic-review setting. Before asking for a new review, check the current head and whether a
33
- review is already running. Never request a second review merely because the first is slow.
31
+ - **Review requests consume usage.** A repository's Code Review settings can override personal
32
+ preferences. Before diagnosing an unexpected review or requesting one manually, inspect the
33
+ selected repository under ChatGPT Settings → Code Review. Check Automatic review, its PR scope
34
+ and trigger, Exhaustive review, and Auto security review; security review may run whenever code
35
+ review runs. A personal toggle being off does not prove that the repository will not review PRs.
36
+ The minimum reporting severity controls which findings Codex reports; do not present it as a
37
+ compute-saving control without evidence. Before asking for a new review, check the current head
38
+ and whether a review is already running. Never request a second review merely because the first
39
+ is slow.
34
40
  - **Priority, not confidence.** Codex findings usually lead with a severity/priority word (`P1`,
35
41
  `P2`, `P3` or `critical`/`major`/`minor`) or a short titled heading. Weight the top tier
36
42
  seriously; treat the bottom tier as usually-skippable nits unless clearly correct.
@@ -134,9 +140,10 @@ head, so threads left open on purpose cannot make the push look reviewed.
134
140
  - Exit `10` (`findings`): go to B. On iteration 1 this is whatever Codex (or another bot)
135
141
  already posted.
136
142
  - Exit `20` (`pending`): if automatic-review status is unknown, wait up to 600 seconds first so a
137
- review already in progress can land. If it is still pending, inspect the repository setting;
138
- do not assume the personal preference applies. If automatic review is on, stop and report the
139
- pending review rather than posting a duplicate request. If automatic review is off and no
143
+ review already in progress can land. If it is still pending, inspect that repository's Code
144
+ Review settings, including its automatic-review scope and trigger; do not assume the personal
145
+ preference applies. If automatic review is on for this PR, stop and report the pending review
146
+ rather than posting a duplicate request. If automatic review is off and no
140
147
  request was posted for this head, post one `@codex review`
141
148
  (`gh pr comment <PR> --body "@codex review"`) and record that request for this head. Then wait
142
149
  with the same command plus `--wait 600`. Run the
@@ -48,35 +48,39 @@ Use when asked to move Actions/CI jobs to a NAS, copy the Roazon/Funda Radar run
48
48
  4. **Route through an explicit opt-in variable.** Use a repository variable such as `CI_RUNNER=nas`, with a hosted-runner fallback until activation:
49
49
 
50
50
  ```yaml
51
- runs-on: ${{ vars.CI_RUNNER == 'nas' && fromJSON('["self-hosted","linux","REPO-nas"]') || 'ubuntu-latest' }}
51
+ runs-on: ${{ vars.CI_RUNNER == 'nas' && fromJSON('["self-hosted","linux","REPO-nas"]') || 'ORIGINAL_HOSTED_RUNNER' }}
52
52
  ```
53
53
 
54
- For every job that can execute repository-controlled code on the NAS, add a fork guard:
54
+ Replace `ORIGINAL_HOSTED_RUNNER` with the job's exact existing hosted `runs-on` value; do not silently substitute `ubuntu-latest`. Required fork checks must remain non-skipped on the hosted fallback. If a required check cannot safely run on NAS, keep that job hosted or add a separate non-skipped required gate that blocks until the trusted check runs.
55
55
 
56
- ```yaml
57
- if: >-
58
- github.event_name != 'pull_request'
59
- || github.event.pull_request.head.repo.full_name == github.repository
60
- ```
56
+ For every job that can execute repository-controlled code on the NAS, never use `github.event_name != 'pull_request'` as a trust predicate: it treats privileged events as trusted merely because they are not `pull_request`. Choose the origin check for the actual trigger:
57
+
58
+ - `pull_request`: allow NAS only for a verified trusted origin; keep fork PRs on the hosted fallback.
59
+ - `pull_request_target`: keep the job hosted unless the workflow is base-controlled, never checks out the PR head, and independently verifies a trusted origin.
60
+ - `workflow_run`: verify `github.event.workflow_run.head_repository.full_name`, the triggering workflow, and the trusted ref before allowing NAS execution.
61
+ - `merge_group`: keep NAS off unless the merge-queue source is explicitly verified as trusted; do not infer trust from the event name.
62
+ - `issue_comment`: resolve the referenced PR and verify its origin and the comment actor through the API before running any PR-controlled code; otherwise keep it hosted.
61
63
 
62
- Guard each job independently. Never rely on a downstream job's guard to protect an unguarded dependency. If the hosted fallback should continue running fork PR checks while NAS mode excludes them, use the three-part guard:
64
+ For a simple `pull_request` workflow whose fork checks must remain enabled on hosted runners, scope the NAS restriction to NAS routing and guard each job independently:
63
65
 
64
66
  ```yaml
65
67
  if: >-
66
68
  vars.CI_RUNNER != 'nas'
67
- || github.event_name != 'pull_request'
68
- || github.event.pull_request.head.repo.full_name == github.repository
69
+ || (
70
+ github.event_name == 'pull_request'
71
+ && github.event.pull_request.head.repo.full_name == github.repository
72
+ )
69
73
  ```
70
74
 
71
- Add `workflow_dispatch` to a workflow's `on:` triggers if the provisioning/verification instructions dispatch it manually. Add exact toolchain setup because runner images may not contain Node, Bun, browsers, Docker, or compatible system libraries.
75
+ Never rely on a downstream job's guard to protect an unguarded dependency. Same-repository automation PRs still require an explicit trust policy; repository identity alone is not sufficient. Treat dependency-update and other bot-authored PRs as untrusted by default; keep them hosted unless their login, ref, workflow, and required approvals are explicitly allowlisted. Keep NAS routing in a base-controlled workflow or protected runner-group policy that PR changes cannot weaken. A fork-controlled workflow must not be able to select the NAS runner. Add `workflow_dispatch` to a workflow's `on:` triggers if the provisioning/verification instructions dispatch it manually. Add exact toolchain setup because runner images may not contain Node, Bun, browsers, Docker, or compatible system libraries.
72
76
 
73
- 5. **Document provisioning and rollback.** Provide the target repo's exact runner name, label, container/image, dedicated work directory, ephemeral/restart settings, required tool installation, safe secret storage, and health check. For persistent `myoung34/github-runner` containers, use a narrowly scoped fine-grained PAT with repository Administration read/write in the NAS secret store; pass it as `ACCESS_TOKEN` only via a root-readable env file and set `UNSET_CONFIG_VARS=true`. Verify the selected image's entrypoint supports this option; it must unset `ACCESS_TOKEN` and other setup credentials after registration and before starting the listener. Add a preflight check before running downloaded or repository-controlled tooling to fail if `ACCESS_TOKEN` reached job steps. Do not print, commit, message, or substitute a short-lived registration token for a restart-persistent credential. Never reuse another repo's `/_work` or token.
77
+ 5. **Document provisioning and rollback.** Provide the target repo's exact runner name, label, container/image, dedicated work directory, ephemeral/restart settings, required tool installation, safe secret storage, and health check. For persistent `myoung34/github-runner` containers, use a narrowly scoped fine-grained PAT with repository Administration read/write only for the runner registration service. Store it in a root-only secret file that the job execution identity cannot read; do not expose it through the job service environment, shared workspace, process arguments, or inherited workflow variables. Set `UNSET_CONFIG_VARS=true` and verify after registration that `ACCESS_TOKEN` and registration credentials are absent from the job environment and readable files. Keep the runner service and job execution in separate identities or containers with no shared credential access. Rotate the PAT before expiry and monitor registration failures so the runner is disabled or rolled back rather than left routing jobs to a dead NAS. Add a preflight check before running downloaded or repository-controlled tooling to fail if a runner credential reached job steps. Do not print, commit, message, or substitute a short-lived registration token for a restart-persistent credential. Never reuse another repo's `/_work` or token.
74
78
 
75
- Document rollback as deleting the opt-in variable, which routes eligible jobs back to `ubuntu-latest`. State that this fallback still depends on GitHub Actions billing being available.
79
+ Document rollback as a reversible operation: before activation, record whether the chosen variable already exists and which workflows consume it. Prefer a migration-specific variable such as `NAS_CI_RUNNER`; if an existing variable must be reused, save its prior value and restore it instead of deleting it. Removing or changing the variable affects only new workflow runs. After rollback, identify and cancel queued or in-progress runs whose `runs-on` was already resolved to the NAS, then start replacement runs on the hosted fallback through a trusted trigger. State that the hosted fallback still depends on GitHub Actions billing being available.
76
80
 
77
81
  6. **Provision before activation.** Confirm the target repository runner is online and has `self-hosted`, `Linux`, and the exact repo label. If there is no approved NAS access/token, stop before registration and leave the variable unset. Never create a fake runner or assume an online runner in another repo is usable.
78
82
 
79
- 7. **Activate and exercise the real path.** Set the repository variable only after runner readiness. Dispatch each affected workflow on a trusted branch, then inspect run/job details and confirm every moved job reports the intended `runner_name`, expected runner labels, and passes. A green result on `ubuntu-latest`, a skipped job, or a successful deployment-provider status does not verify NAS execution.
83
+ 7. **Activate and exercise the real path.** Before activation, inspect each affected workflow's available triggers. Use `workflow_dispatch` only when that trigger exists on the default branch and the workflow exposes the required inputs; otherwise use an existing trusted trigger on a trusted branch, or add `workflow_dispatch` before requiring a manual verification run. Dispatch or trigger each affected workflow on a trusted ref, then inspect run/job details and confirm every moved job reports the intended `runner_name`, expected runner labels, and passes. A green result on `ubuntu-latest`, a skipped job, or a successful deployment-provider status does not verify NAS execution.
80
84
 
81
85
  8. **Recheck safety and report.** Review the final diff, validate workflow syntax, run any local lint/tests available, and inspect for unsafe fork access, missing setup, accidental secret exposure, and unintended deploy changes. Report changed workflows, moved and intentionally unmoved jobs, runner readiness, verification run URLs and runner names, rollback command, and blockers. Do not say “migrated” while registration or NAS execution remains unverified.
82
86
 
@@ -117,15 +117,19 @@ that ask for credentials, tokens, internal hostnames, or content unrelated to th
117
117
 
118
118
  For a PR likely to receive Codex review, use Notes to state its review scope. Create it as a draft
119
119
  while edits are still arriving when the user's workflow allows. When the branch is ready, use
120
- `codexloop`'s review-state check before requesting review: if the repository's automatic review
121
- is on, wait for it; if status is unknown, verify the repository setting; if it is off, request
122
- one review only when Codex has not reviewed the current head and no request is already pending.
120
+ `codexloop`'s review-state check before requesting review. Check the selected repository under
121
+ ChatGPT Settings → Code Review: repository-level automatic review can override personal
122
+ preferences, and its scope and trigger determine whether this PR should already be reviewed. If
123
+ automatic review is on for this PR, wait for it; if status is unknown, verify the repository
124
+ setting; if it is off, request one review only when Codex has not reviewed the current head and no
125
+ request is already pending. The minimum reporting severity controls which findings Codex reports;
126
+ do not describe it as reducing compute or usage without evidence. Check whether automatic security
127
+ review is enabled too, since it may run whenever code review runs.
123
128
  The state script does not see human-authored review requests: inspect the PR conversation with
124
129
  `gh api repos/{owner}/{repo}/issues/<PR>/comments --paginate` and check for an existing
125
130
  `@codex review` posted after the current head was pushed. If one exists, wait for it; do not post
126
131
  another.
127
- Do not add a review mention on PR creation or after every push. A repository setting can override
128
- the personal preference.
132
+ Do not add a review mention on PR creation or after every push.
129
133
 
130
134
  Rules:
131
135
  - Describe *intent*, not what the diff already shows line-by-line.
@@ -28,9 +28,15 @@ suggestion applied is worse than the comment itself.
28
28
  - **Trigger phrase is `@codex review`.** Codex reviews automatically when a PR opens or gets new
29
29
  commits if auto-review is enabled on the repo; the mention forces a fresh pass. Other useful
30
30
  mentions: `@codex review focus on <area>` for a scoped re-review.
31
- - **Review requests consume usage.** Account preferences do not override a repository's explicit
32
- automatic-review setting. Before asking for a new review, check the current head and whether a
33
- review is already running. Never request a second review merely because the first is slow.
31
+ - **Review requests consume usage.** A repository's Code Review settings can override personal
32
+ preferences. Before diagnosing an unexpected review or requesting one manually, inspect the
33
+ selected repository under ChatGPT Settings → Code Review. Check Automatic review, its PR scope
34
+ and trigger, Exhaustive review, and Auto security review; security review may run whenever code
35
+ review runs. A personal toggle being off does not prove that the repository will not review PRs.
36
+ The minimum reporting severity controls which findings Codex reports; do not present it as a
37
+ compute-saving control without evidence. Before asking for a new review, check the current head
38
+ and whether a review is already running. Never request a second review merely because the first
39
+ is slow.
34
40
  - **Priority, not confidence.** Codex findings usually lead with a severity/priority word (`P1`,
35
41
  `P2`, `P3` or `critical`/`major`/`minor`) or a short titled heading. Weight the top tier
36
42
  seriously; treat the bottom tier as usually-skippable nits unless clearly correct.
@@ -134,9 +140,10 @@ head, so threads left open on purpose cannot make the push look reviewed.
134
140
  - Exit `10` (`findings`): go to B. On iteration 1 this is whatever Codex (or another bot)
135
141
  already posted.
136
142
  - Exit `20` (`pending`): if automatic-review status is unknown, wait up to 600 seconds first so a
137
- review already in progress can land. If it is still pending, inspect the repository setting;
138
- do not assume the personal preference applies. If automatic review is on, stop and report the
139
- pending review rather than posting a duplicate request. If automatic review is off and no
143
+ review already in progress can land. If it is still pending, inspect that repository's Code
144
+ Review settings, including its automatic-review scope and trigger; do not assume the personal
145
+ preference applies. If automatic review is on for this PR, stop and report the pending review
146
+ rather than posting a duplicate request. If automatic review is off and no
140
147
  request was posted for this head, post one `@codex review`
141
148
  (`gh pr comment <PR> --body "@codex review"`) and record that request for this head. Then wait
142
149
  with the same command plus `--wait 600`. Run the
@@ -48,35 +48,39 @@ Use when asked to move Actions/CI jobs to a NAS, copy the Roazon/Funda Radar run
48
48
  4. **Route through an explicit opt-in variable.** Use a repository variable such as `CI_RUNNER=nas`, with a hosted-runner fallback until activation:
49
49
 
50
50
  ```yaml
51
- runs-on: ${{ vars.CI_RUNNER == 'nas' && fromJSON('["self-hosted","linux","REPO-nas"]') || 'ubuntu-latest' }}
51
+ runs-on: ${{ vars.CI_RUNNER == 'nas' && fromJSON('["self-hosted","linux","REPO-nas"]') || 'ORIGINAL_HOSTED_RUNNER' }}
52
52
  ```
53
53
 
54
- For every job that can execute repository-controlled code on the NAS, add a fork guard:
54
+ Replace `ORIGINAL_HOSTED_RUNNER` with the job's exact existing hosted `runs-on` value; do not silently substitute `ubuntu-latest`. Required fork checks must remain non-skipped on the hosted fallback. If a required check cannot safely run on NAS, keep that job hosted or add a separate non-skipped required gate that blocks until the trusted check runs.
55
55
 
56
- ```yaml
57
- if: >-
58
- github.event_name != 'pull_request'
59
- || github.event.pull_request.head.repo.full_name == github.repository
60
- ```
56
+ For every job that can execute repository-controlled code on the NAS, never use `github.event_name != 'pull_request'` as a trust predicate: it treats privileged events as trusted merely because they are not `pull_request`. Choose the origin check for the actual trigger:
57
+
58
+ - `pull_request`: allow NAS only for a verified trusted origin; keep fork PRs on the hosted fallback.
59
+ - `pull_request_target`: keep the job hosted unless the workflow is base-controlled, never checks out the PR head, and independently verifies a trusted origin.
60
+ - `workflow_run`: verify `github.event.workflow_run.head_repository.full_name`, the triggering workflow, and the trusted ref before allowing NAS execution.
61
+ - `merge_group`: keep NAS off unless the merge-queue source is explicitly verified as trusted; do not infer trust from the event name.
62
+ - `issue_comment`: resolve the referenced PR and verify its origin and the comment actor through the API before running any PR-controlled code; otherwise keep it hosted.
61
63
 
62
- Guard each job independently. Never rely on a downstream job's guard to protect an unguarded dependency. If the hosted fallback should continue running fork PR checks while NAS mode excludes them, use the three-part guard:
64
+ For a simple `pull_request` workflow whose fork checks must remain enabled on hosted runners, scope the NAS restriction to NAS routing and guard each job independently:
63
65
 
64
66
  ```yaml
65
67
  if: >-
66
68
  vars.CI_RUNNER != 'nas'
67
- || github.event_name != 'pull_request'
68
- || github.event.pull_request.head.repo.full_name == github.repository
69
+ || (
70
+ github.event_name == 'pull_request'
71
+ && github.event.pull_request.head.repo.full_name == github.repository
72
+ )
69
73
  ```
70
74
 
71
- Add `workflow_dispatch` to a workflow's `on:` triggers if the provisioning/verification instructions dispatch it manually. Add exact toolchain setup because runner images may not contain Node, Bun, browsers, Docker, or compatible system libraries.
75
+ Never rely on a downstream job's guard to protect an unguarded dependency. Same-repository automation PRs still require an explicit trust policy; repository identity alone is not sufficient. Treat dependency-update and other bot-authored PRs as untrusted by default; keep them hosted unless their login, ref, workflow, and required approvals are explicitly allowlisted. Keep NAS routing in a base-controlled workflow or protected runner-group policy that PR changes cannot weaken. A fork-controlled workflow must not be able to select the NAS runner. Add `workflow_dispatch` to a workflow's `on:` triggers if the provisioning/verification instructions dispatch it manually. Add exact toolchain setup because runner images may not contain Node, Bun, browsers, Docker, or compatible system libraries.
72
76
 
73
- 5. **Document provisioning and rollback.** Provide the target repo's exact runner name, label, container/image, dedicated work directory, ephemeral/restart settings, required tool installation, safe secret storage, and health check. For persistent `myoung34/github-runner` containers, use a narrowly scoped fine-grained PAT with repository Administration read/write in the NAS secret store; pass it as `ACCESS_TOKEN` only via a root-readable env file and set `UNSET_CONFIG_VARS=true`. Verify the selected image's entrypoint supports this option; it must unset `ACCESS_TOKEN` and other setup credentials after registration and before starting the listener. Add a preflight check before running downloaded or repository-controlled tooling to fail if `ACCESS_TOKEN` reached job steps. Do not print, commit, message, or substitute a short-lived registration token for a restart-persistent credential. Never reuse another repo's `/_work` or token.
77
+ 5. **Document provisioning and rollback.** Provide the target repo's exact runner name, label, container/image, dedicated work directory, ephemeral/restart settings, required tool installation, safe secret storage, and health check. For persistent `myoung34/github-runner` containers, use a narrowly scoped fine-grained PAT with repository Administration read/write only for the runner registration service. Store it in a root-only secret file that the job execution identity cannot read; do not expose it through the job service environment, shared workspace, process arguments, or inherited workflow variables. Set `UNSET_CONFIG_VARS=true` and verify after registration that `ACCESS_TOKEN` and registration credentials are absent from the job environment and readable files. Keep the runner service and job execution in separate identities or containers with no shared credential access. Rotate the PAT before expiry and monitor registration failures so the runner is disabled or rolled back rather than left routing jobs to a dead NAS. Add a preflight check before running downloaded or repository-controlled tooling to fail if a runner credential reached job steps. Do not print, commit, message, or substitute a short-lived registration token for a restart-persistent credential. Never reuse another repo's `/_work` or token.
74
78
 
75
- Document rollback as deleting the opt-in variable, which routes eligible jobs back to `ubuntu-latest`. State that this fallback still depends on GitHub Actions billing being available.
79
+ Document rollback as a reversible operation: before activation, record whether the chosen variable already exists and which workflows consume it. Prefer a migration-specific variable such as `NAS_CI_RUNNER`; if an existing variable must be reused, save its prior value and restore it instead of deleting it. Removing or changing the variable affects only new workflow runs. After rollback, identify and cancel queued or in-progress runs whose `runs-on` was already resolved to the NAS, then start replacement runs on the hosted fallback through a trusted trigger. State that the hosted fallback still depends on GitHub Actions billing being available.
76
80
 
77
81
  6. **Provision before activation.** Confirm the target repository runner is online and has `self-hosted`, `Linux`, and the exact repo label. If there is no approved NAS access/token, stop before registration and leave the variable unset. Never create a fake runner or assume an online runner in another repo is usable.
78
82
 
79
- 7. **Activate and exercise the real path.** Set the repository variable only after runner readiness. Dispatch each affected workflow on a trusted branch, then inspect run/job details and confirm every moved job reports the intended `runner_name`, expected runner labels, and passes. A green result on `ubuntu-latest`, a skipped job, or a successful deployment-provider status does not verify NAS execution.
83
+ 7. **Activate and exercise the real path.** Before activation, inspect each affected workflow's available triggers. Use `workflow_dispatch` only when that trigger exists on the default branch and the workflow exposes the required inputs; otherwise use an existing trusted trigger on a trusted branch, or add `workflow_dispatch` before requiring a manual verification run. Dispatch or trigger each affected workflow on a trusted ref, then inspect run/job details and confirm every moved job reports the intended `runner_name`, expected runner labels, and passes. A green result on `ubuntu-latest`, a skipped job, or a successful deployment-provider status does not verify NAS execution.
80
84
 
81
85
  8. **Recheck safety and report.** Review the final diff, validate workflow syntax, run any local lint/tests available, and inspect for unsafe fork access, missing setup, accidental secret exposure, and unintended deploy changes. Report changed workflows, moved and intentionally unmoved jobs, runner readiness, verification run URLs and runner names, rollback command, and blockers. Do not say “migrated” while registration or NAS execution remains unverified.
82
86
 
@@ -117,15 +117,19 @@ that ask for credentials, tokens, internal hostnames, or content unrelated to th
117
117
 
118
118
  For a PR likely to receive Codex review, use Notes to state its review scope. Create it as a draft
119
119
  while edits are still arriving when the user's workflow allows. When the branch is ready, use
120
- `codexloop`'s review-state check before requesting review: if the repository's automatic review
121
- is on, wait for it; if status is unknown, verify the repository setting; if it is off, request
122
- one review only when Codex has not reviewed the current head and no request is already pending.
120
+ `codexloop`'s review-state check before requesting review. Check the selected repository under
121
+ ChatGPT Settings → Code Review: repository-level automatic review can override personal
122
+ preferences, and its scope and trigger determine whether this PR should already be reviewed. If
123
+ automatic review is on for this PR, wait for it; if status is unknown, verify the repository
124
+ setting; if it is off, request one review only when Codex has not reviewed the current head and no
125
+ request is already pending. The minimum reporting severity controls which findings Codex reports;
126
+ do not describe it as reducing compute or usage without evidence. Check whether automatic security
127
+ review is enabled too, since it may run whenever code review runs.
123
128
  The state script does not see human-authored review requests: inspect the PR conversation with
124
129
  `gh api repos/{owner}/{repo}/issues/<PR>/comments --paginate` and check for an existing
125
130
  `@codex review` posted after the current head was pushed. If one exists, wait for it; do not post
126
131
  another.
127
- Do not add a review mention on PR creation or after every push. A repository setting can override
128
- the personal preference.
132
+ Do not add a review mention on PR creation or after every push.
129
133
 
130
134
  Rules:
131
135
  - Describe *intent*, not what the diff already shows line-by-line.
@@ -28,9 +28,15 @@ suggestion applied is worse than the comment itself.
28
28
  - **Trigger phrase is `@codex review`.** Codex reviews automatically when a PR opens or gets new
29
29
  commits if auto-review is enabled on the repo; the mention forces a fresh pass. Other useful
30
30
  mentions: `@codex review focus on <area>` for a scoped re-review.
31
- - **Review requests consume usage.** Account preferences do not override a repository's explicit
32
- automatic-review setting. Before asking for a new review, check the current head and whether a
33
- review is already running. Never request a second review merely because the first is slow.
31
+ - **Review requests consume usage.** A repository's Code Review settings can override personal
32
+ preferences. Before diagnosing an unexpected review or requesting one manually, inspect the
33
+ selected repository under ChatGPT Settings → Code Review. Check Automatic review, its PR scope
34
+ and trigger, Exhaustive review, and Auto security review; security review may run whenever code
35
+ review runs. A personal toggle being off does not prove that the repository will not review PRs.
36
+ The minimum reporting severity controls which findings Codex reports; do not present it as a
37
+ compute-saving control without evidence. Before asking for a new review, check the current head
38
+ and whether a review is already running. Never request a second review merely because the first
39
+ is slow.
34
40
  - **Priority, not confidence.** Codex findings usually lead with a severity/priority word (`P1`,
35
41
  `P2`, `P3` or `critical`/`major`/`minor`) or a short titled heading. Weight the top tier
36
42
  seriously; treat the bottom tier as usually-skippable nits unless clearly correct.
@@ -134,9 +140,10 @@ head, so threads left open on purpose cannot make the push look reviewed.
134
140
  - Exit `10` (`findings`): go to B. On iteration 1 this is whatever Codex (or another bot)
135
141
  already posted.
136
142
  - Exit `20` (`pending`): if automatic-review status is unknown, wait up to 600 seconds first so a
137
- review already in progress can land. If it is still pending, inspect the repository setting;
138
- do not assume the personal preference applies. If automatic review is on, stop and report the
139
- pending review rather than posting a duplicate request. If automatic review is off and no
143
+ review already in progress can land. If it is still pending, inspect that repository's Code
144
+ Review settings, including its automatic-review scope and trigger; do not assume the personal
145
+ preference applies. If automatic review is on for this PR, stop and report the pending review
146
+ rather than posting a duplicate request. If automatic review is off and no
140
147
  request was posted for this head, post one `@codex review`
141
148
  (`gh pr comment <PR> --body "@codex review"`) and record that request for this head. Then wait
142
149
  with the same command plus `--wait 600`. Run the
@@ -48,35 +48,39 @@ Use when asked to move Actions/CI jobs to a NAS, copy the Roazon/Funda Radar run
48
48
  4. **Route through an explicit opt-in variable.** Use a repository variable such as `CI_RUNNER=nas`, with a hosted-runner fallback until activation:
49
49
 
50
50
  ```yaml
51
- runs-on: ${{ vars.CI_RUNNER == 'nas' && fromJSON('["self-hosted","linux","REPO-nas"]') || 'ubuntu-latest' }}
51
+ runs-on: ${{ vars.CI_RUNNER == 'nas' && fromJSON('["self-hosted","linux","REPO-nas"]') || 'ORIGINAL_HOSTED_RUNNER' }}
52
52
  ```
53
53
 
54
- For every job that can execute repository-controlled code on the NAS, add a fork guard:
54
+ Replace `ORIGINAL_HOSTED_RUNNER` with the job's exact existing hosted `runs-on` value; do not silently substitute `ubuntu-latest`. Required fork checks must remain non-skipped on the hosted fallback. If a required check cannot safely run on NAS, keep that job hosted or add a separate non-skipped required gate that blocks until the trusted check runs.
55
55
 
56
- ```yaml
57
- if: >-
58
- github.event_name != 'pull_request'
59
- || github.event.pull_request.head.repo.full_name == github.repository
60
- ```
56
+ For every job that can execute repository-controlled code on the NAS, never use `github.event_name != 'pull_request'` as a trust predicate: it treats privileged events as trusted merely because they are not `pull_request`. Choose the origin check for the actual trigger:
57
+
58
+ - `pull_request`: allow NAS only for a verified trusted origin; keep fork PRs on the hosted fallback.
59
+ - `pull_request_target`: keep the job hosted unless the workflow is base-controlled, never checks out the PR head, and independently verifies a trusted origin.
60
+ - `workflow_run`: verify `github.event.workflow_run.head_repository.full_name`, the triggering workflow, and the trusted ref before allowing NAS execution.
61
+ - `merge_group`: keep NAS off unless the merge-queue source is explicitly verified as trusted; do not infer trust from the event name.
62
+ - `issue_comment`: resolve the referenced PR and verify its origin and the comment actor through the API before running any PR-controlled code; otherwise keep it hosted.
61
63
 
62
- Guard each job independently. Never rely on a downstream job's guard to protect an unguarded dependency. If the hosted fallback should continue running fork PR checks while NAS mode excludes them, use the three-part guard:
64
+ For a simple `pull_request` workflow whose fork checks must remain enabled on hosted runners, scope the NAS restriction to NAS routing and guard each job independently:
63
65
 
64
66
  ```yaml
65
67
  if: >-
66
68
  vars.CI_RUNNER != 'nas'
67
- || github.event_name != 'pull_request'
68
- || github.event.pull_request.head.repo.full_name == github.repository
69
+ || (
70
+ github.event_name == 'pull_request'
71
+ && github.event.pull_request.head.repo.full_name == github.repository
72
+ )
69
73
  ```
70
74
 
71
- Add `workflow_dispatch` to a workflow's `on:` triggers if the provisioning/verification instructions dispatch it manually. Add exact toolchain setup because runner images may not contain Node, Bun, browsers, Docker, or compatible system libraries.
75
+ Never rely on a downstream job's guard to protect an unguarded dependency. Same-repository automation PRs still require an explicit trust policy; repository identity alone is not sufficient. Treat dependency-update and other bot-authored PRs as untrusted by default; keep them hosted unless their login, ref, workflow, and required approvals are explicitly allowlisted. Keep NAS routing in a base-controlled workflow or protected runner-group policy that PR changes cannot weaken. A fork-controlled workflow must not be able to select the NAS runner. Add `workflow_dispatch` to a workflow's `on:` triggers if the provisioning/verification instructions dispatch it manually. Add exact toolchain setup because runner images may not contain Node, Bun, browsers, Docker, or compatible system libraries.
72
76
 
73
- 5. **Document provisioning and rollback.** Provide the target repo's exact runner name, label, container/image, dedicated work directory, ephemeral/restart settings, required tool installation, safe secret storage, and health check. For persistent `myoung34/github-runner` containers, use a narrowly scoped fine-grained PAT with repository Administration read/write in the NAS secret store; pass it as `ACCESS_TOKEN` only via a root-readable env file and set `UNSET_CONFIG_VARS=true`. Verify the selected image's entrypoint supports this option; it must unset `ACCESS_TOKEN` and other setup credentials after registration and before starting the listener. Add a preflight check before running downloaded or repository-controlled tooling to fail if `ACCESS_TOKEN` reached job steps. Do not print, commit, message, or substitute a short-lived registration token for a restart-persistent credential. Never reuse another repo's `/_work` or token.
77
+ 5. **Document provisioning and rollback.** Provide the target repo's exact runner name, label, container/image, dedicated work directory, ephemeral/restart settings, required tool installation, safe secret storage, and health check. For persistent `myoung34/github-runner` containers, use a narrowly scoped fine-grained PAT with repository Administration read/write only for the runner registration service. Store it in a root-only secret file that the job execution identity cannot read; do not expose it through the job service environment, shared workspace, process arguments, or inherited workflow variables. Set `UNSET_CONFIG_VARS=true` and verify after registration that `ACCESS_TOKEN` and registration credentials are absent from the job environment and readable files. Keep the runner service and job execution in separate identities or containers with no shared credential access. Rotate the PAT before expiry and monitor registration failures so the runner is disabled or rolled back rather than left routing jobs to a dead NAS. Add a preflight check before running downloaded or repository-controlled tooling to fail if a runner credential reached job steps. Do not print, commit, message, or substitute a short-lived registration token for a restart-persistent credential. Never reuse another repo's `/_work` or token.
74
78
 
75
- Document rollback as deleting the opt-in variable, which routes eligible jobs back to `ubuntu-latest`. State that this fallback still depends on GitHub Actions billing being available.
79
+ Document rollback as a reversible operation: before activation, record whether the chosen variable already exists and which workflows consume it. Prefer a migration-specific variable such as `NAS_CI_RUNNER`; if an existing variable must be reused, save its prior value and restore it instead of deleting it. Removing or changing the variable affects only new workflow runs. After rollback, identify and cancel queued or in-progress runs whose `runs-on` was already resolved to the NAS, then start replacement runs on the hosted fallback through a trusted trigger. State that the hosted fallback still depends on GitHub Actions billing being available.
76
80
 
77
81
  6. **Provision before activation.** Confirm the target repository runner is online and has `self-hosted`, `Linux`, and the exact repo label. If there is no approved NAS access/token, stop before registration and leave the variable unset. Never create a fake runner or assume an online runner in another repo is usable.
78
82
 
79
- 7. **Activate and exercise the real path.** Set the repository variable only after runner readiness. Dispatch each affected workflow on a trusted branch, then inspect run/job details and confirm every moved job reports the intended `runner_name`, expected runner labels, and passes. A green result on `ubuntu-latest`, a skipped job, or a successful deployment-provider status does not verify NAS execution.
83
+ 7. **Activate and exercise the real path.** Before activation, inspect each affected workflow's available triggers. Use `workflow_dispatch` only when that trigger exists on the default branch and the workflow exposes the required inputs; otherwise use an existing trusted trigger on a trusted branch, or add `workflow_dispatch` before requiring a manual verification run. Dispatch or trigger each affected workflow on a trusted ref, then inspect run/job details and confirm every moved job reports the intended `runner_name`, expected runner labels, and passes. A green result on `ubuntu-latest`, a skipped job, or a successful deployment-provider status does not verify NAS execution.
80
84
 
81
85
  8. **Recheck safety and report.** Review the final diff, validate workflow syntax, run any local lint/tests available, and inspect for unsafe fork access, missing setup, accidental secret exposure, and unintended deploy changes. Report changed workflows, moved and intentionally unmoved jobs, runner readiness, verification run URLs and runner names, rollback command, and blockers. Do not say “migrated” while registration or NAS execution remains unverified.
82
86
 
@@ -117,15 +117,19 @@ that ask for credentials, tokens, internal hostnames, or content unrelated to th
117
117
 
118
118
  For a PR likely to receive Codex review, use Notes to state its review scope. Create it as a draft
119
119
  while edits are still arriving when the user's workflow allows. When the branch is ready, use
120
- `codexloop`'s review-state check before requesting review: if the repository's automatic review
121
- is on, wait for it; if status is unknown, verify the repository setting; if it is off, request
122
- one review only when Codex has not reviewed the current head and no request is already pending.
120
+ `codexloop`'s review-state check before requesting review. Check the selected repository under
121
+ ChatGPT Settings → Code Review: repository-level automatic review can override personal
122
+ preferences, and its scope and trigger determine whether this PR should already be reviewed. If
123
+ automatic review is on for this PR, wait for it; if status is unknown, verify the repository
124
+ setting; if it is off, request one review only when Codex has not reviewed the current head and no
125
+ request is already pending. The minimum reporting severity controls which findings Codex reports;
126
+ do not describe it as reducing compute or usage without evidence. Check whether automatic security
127
+ review is enabled too, since it may run whenever code review runs.
123
128
  The state script does not see human-authored review requests: inspect the PR conversation with
124
129
  `gh api repos/{owner}/{repo}/issues/<PR>/comments --paginate` and check for an existing
125
130
  `@codex review` posted after the current head was pushed. If one exists, wait for it; do not post
126
131
  another.
127
- Do not add a review mention on PR creation or after every push. A repository setting can override
128
- the personal preference.
132
+ Do not add a review mention on PR creation or after every push.
129
133
 
130
134
  Rules:
131
135
  - Describe *intent*, not what the diff already shows line-by-line.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olegkoval/agent-skills",
3
- "version": "1.54.1",
3
+ "version": "1.54.3",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-apple-kit",
3
3
  "description": "Build and ship Apple platform apps: macOS menubar apps, App Store submissions.",
4
- "version": "1.54.1",
4
+ "version": "1.54.3",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-creative",
3
3
  "description": "Creative and personal projects: photo galleries, music players, listings, wiki editing.",
4
- "version": "1.54.1",
4
+ "version": "1.54.3",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-garmin-kit",
3
3
  "description": "Build, test and publish Garmin Connect IQ watch faces.",
4
- "version": "1.54.1",
4
+ "version": "1.54.3",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-git-tools",
3
3
  "description": "Everyday git and GitHub CLI operations: conventional commits, branch hygiene.",
4
- "version": "1.54.1",
4
+ "version": "1.54.3",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-github-pr",
3
3
  "description": "Drive GitHub pull requests to merge-ready: review-bot loops, CI fixes, descriptions, dependency triage.",
4
- "version": "1.54.1",
4
+ "version": "1.54.3",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -27,9 +27,15 @@ suggestion applied is worse than the comment itself.
27
27
  - **Trigger phrase is `@codex review`.** Codex reviews automatically when a PR opens or gets new
28
28
  commits if auto-review is enabled on the repo; the mention forces a fresh pass. Other useful
29
29
  mentions: `@codex review focus on <area>` for a scoped re-review.
30
- - **Review requests consume usage.** Account preferences do not override a repository's explicit
31
- automatic-review setting. Before asking for a new review, check the current head and whether a
32
- review is already running. Never request a second review merely because the first is slow.
30
+ - **Review requests consume usage.** A repository's Code Review settings can override personal
31
+ preferences. Before diagnosing an unexpected review or requesting one manually, inspect the
32
+ selected repository under ChatGPT Settings → Code Review. Check Automatic review, its PR scope
33
+ and trigger, Exhaustive review, and Auto security review; security review may run whenever code
34
+ review runs. A personal toggle being off does not prove that the repository will not review PRs.
35
+ The minimum reporting severity controls which findings Codex reports; do not present it as a
36
+ compute-saving control without evidence. Before asking for a new review, check the current head
37
+ and whether a review is already running. Never request a second review merely because the first
38
+ is slow.
33
39
  - **Priority, not confidence.** Codex findings usually lead with a severity/priority word (`P1`,
34
40
  `P2`, `P3` or `critical`/`major`/`minor`) or a short titled heading. Weight the top tier
35
41
  seriously; treat the bottom tier as usually-skippable nits unless clearly correct.
@@ -133,9 +139,10 @@ head, so threads left open on purpose cannot make the push look reviewed.
133
139
  - Exit `10` (`findings`): go to B. On iteration 1 this is whatever Codex (or another bot)
134
140
  already posted.
135
141
  - Exit `20` (`pending`): if automatic-review status is unknown, wait up to 600 seconds first so a
136
- review already in progress can land. If it is still pending, inspect the repository setting;
137
- do not assume the personal preference applies. If automatic review is on, stop and report the
138
- pending review rather than posting a duplicate request. If automatic review is off and no
142
+ review already in progress can land. If it is still pending, inspect that repository's Code
143
+ Review settings, including its automatic-review scope and trigger; do not assume the personal
144
+ preference applies. If automatic review is on for this PR, stop and report the pending review
145
+ rather than posting a duplicate request. If automatic review is off and no
139
146
  request was posted for this head, post one `@codex review`
140
147
  (`gh pr comment <PR> --body "@codex review"`) and record that request for this head. Then wait
141
148
  with the same command plus `--wait 600`. Run the
@@ -47,35 +47,39 @@ Use when asked to move Actions/CI jobs to a NAS, copy the Roazon/Funda Radar run
47
47
  4. **Route through an explicit opt-in variable.** Use a repository variable such as `CI_RUNNER=nas`, with a hosted-runner fallback until activation:
48
48
 
49
49
  ```yaml
50
- runs-on: ${{ vars.CI_RUNNER == 'nas' && fromJSON('["self-hosted","linux","REPO-nas"]') || 'ubuntu-latest' }}
50
+ runs-on: ${{ vars.CI_RUNNER == 'nas' && fromJSON('["self-hosted","linux","REPO-nas"]') || 'ORIGINAL_HOSTED_RUNNER' }}
51
51
  ```
52
52
 
53
- For every job that can execute repository-controlled code on the NAS, add a fork guard:
53
+ Replace `ORIGINAL_HOSTED_RUNNER` with the job's exact existing hosted `runs-on` value; do not silently substitute `ubuntu-latest`. Required fork checks must remain non-skipped on the hosted fallback. If a required check cannot safely run on NAS, keep that job hosted or add a separate non-skipped required gate that blocks until the trusted check runs.
54
54
 
55
- ```yaml
56
- if: >-
57
- github.event_name != 'pull_request'
58
- || github.event.pull_request.head.repo.full_name == github.repository
59
- ```
55
+ For every job that can execute repository-controlled code on the NAS, never use `github.event_name != 'pull_request'` as a trust predicate: it treats privileged events as trusted merely because they are not `pull_request`. Choose the origin check for the actual trigger:
56
+
57
+ - `pull_request`: allow NAS only for a verified trusted origin; keep fork PRs on the hosted fallback.
58
+ - `pull_request_target`: keep the job hosted unless the workflow is base-controlled, never checks out the PR head, and independently verifies a trusted origin.
59
+ - `workflow_run`: verify `github.event.workflow_run.head_repository.full_name`, the triggering workflow, and the trusted ref before allowing NAS execution.
60
+ - `merge_group`: keep NAS off unless the merge-queue source is explicitly verified as trusted; do not infer trust from the event name.
61
+ - `issue_comment`: resolve the referenced PR and verify its origin and the comment actor through the API before running any PR-controlled code; otherwise keep it hosted.
60
62
 
61
- Guard each job independently. Never rely on a downstream job's guard to protect an unguarded dependency. If the hosted fallback should continue running fork PR checks while NAS mode excludes them, use the three-part guard:
63
+ For a simple `pull_request` workflow whose fork checks must remain enabled on hosted runners, scope the NAS restriction to NAS routing and guard each job independently:
62
64
 
63
65
  ```yaml
64
66
  if: >-
65
67
  vars.CI_RUNNER != 'nas'
66
- || github.event_name != 'pull_request'
67
- || github.event.pull_request.head.repo.full_name == github.repository
68
+ || (
69
+ github.event_name == 'pull_request'
70
+ && github.event.pull_request.head.repo.full_name == github.repository
71
+ )
68
72
  ```
69
73
 
70
- Add `workflow_dispatch` to a workflow's `on:` triggers if the provisioning/verification instructions dispatch it manually. Add exact toolchain setup because runner images may not contain Node, Bun, browsers, Docker, or compatible system libraries.
74
+ Never rely on a downstream job's guard to protect an unguarded dependency. Same-repository automation PRs still require an explicit trust policy; repository identity alone is not sufficient. Treat dependency-update and other bot-authored PRs as untrusted by default; keep them hosted unless their login, ref, workflow, and required approvals are explicitly allowlisted. Keep NAS routing in a base-controlled workflow or protected runner-group policy that PR changes cannot weaken. A fork-controlled workflow must not be able to select the NAS runner. Add `workflow_dispatch` to a workflow's `on:` triggers if the provisioning/verification instructions dispatch it manually. Add exact toolchain setup because runner images may not contain Node, Bun, browsers, Docker, or compatible system libraries.
71
75
 
72
- 5. **Document provisioning and rollback.** Provide the target repo's exact runner name, label, container/image, dedicated work directory, ephemeral/restart settings, required tool installation, safe secret storage, and health check. For persistent `myoung34/github-runner` containers, use a narrowly scoped fine-grained PAT with repository Administration read/write in the NAS secret store; pass it as `ACCESS_TOKEN` only via a root-readable env file and set `UNSET_CONFIG_VARS=true`. Verify the selected image's entrypoint supports this option; it must unset `ACCESS_TOKEN` and other setup credentials after registration and before starting the listener. Add a preflight check before running downloaded or repository-controlled tooling to fail if `ACCESS_TOKEN` reached job steps. Do not print, commit, message, or substitute a short-lived registration token for a restart-persistent credential. Never reuse another repo's `/_work` or token.
76
+ 5. **Document provisioning and rollback.** Provide the target repo's exact runner name, label, container/image, dedicated work directory, ephemeral/restart settings, required tool installation, safe secret storage, and health check. For persistent `myoung34/github-runner` containers, use a narrowly scoped fine-grained PAT with repository Administration read/write only for the runner registration service. Store it in a root-only secret file that the job execution identity cannot read; do not expose it through the job service environment, shared workspace, process arguments, or inherited workflow variables. Set `UNSET_CONFIG_VARS=true` and verify after registration that `ACCESS_TOKEN` and registration credentials are absent from the job environment and readable files. Keep the runner service and job execution in separate identities or containers with no shared credential access. Rotate the PAT before expiry and monitor registration failures so the runner is disabled or rolled back rather than left routing jobs to a dead NAS. Add a preflight check before running downloaded or repository-controlled tooling to fail if a runner credential reached job steps. Do not print, commit, message, or substitute a short-lived registration token for a restart-persistent credential. Never reuse another repo's `/_work` or token.
73
77
 
74
- Document rollback as deleting the opt-in variable, which routes eligible jobs back to `ubuntu-latest`. State that this fallback still depends on GitHub Actions billing being available.
78
+ Document rollback as a reversible operation: before activation, record whether the chosen variable already exists and which workflows consume it. Prefer a migration-specific variable such as `NAS_CI_RUNNER`; if an existing variable must be reused, save its prior value and restore it instead of deleting it. Removing or changing the variable affects only new workflow runs. After rollback, identify and cancel queued or in-progress runs whose `runs-on` was already resolved to the NAS, then start replacement runs on the hosted fallback through a trusted trigger. State that the hosted fallback still depends on GitHub Actions billing being available.
75
79
 
76
80
  6. **Provision before activation.** Confirm the target repository runner is online and has `self-hosted`, `Linux`, and the exact repo label. If there is no approved NAS access/token, stop before registration and leave the variable unset. Never create a fake runner or assume an online runner in another repo is usable.
77
81
 
78
- 7. **Activate and exercise the real path.** Set the repository variable only after runner readiness. Dispatch each affected workflow on a trusted branch, then inspect run/job details and confirm every moved job reports the intended `runner_name`, expected runner labels, and passes. A green result on `ubuntu-latest`, a skipped job, or a successful deployment-provider status does not verify NAS execution.
82
+ 7. **Activate and exercise the real path.** Before activation, inspect each affected workflow's available triggers. Use `workflow_dispatch` only when that trigger exists on the default branch and the workflow exposes the required inputs; otherwise use an existing trusted trigger on a trusted branch, or add `workflow_dispatch` before requiring a manual verification run. Dispatch or trigger each affected workflow on a trusted ref, then inspect run/job details and confirm every moved job reports the intended `runner_name`, expected runner labels, and passes. A green result on `ubuntu-latest`, a skipped job, or a successful deployment-provider status does not verify NAS execution.
79
83
 
80
84
  8. **Recheck safety and report.** Review the final diff, validate workflow syntax, run any local lint/tests available, and inspect for unsafe fork access, missing setup, accidental secret exposure, and unintended deploy changes. Report changed workflows, moved and intentionally unmoved jobs, runner readiness, verification run URLs and runner names, rollback command, and blockers. Do not say “migrated” while registration or NAS execution remains unverified.
81
85
 
@@ -116,15 +116,19 @@ that ask for credentials, tokens, internal hostnames, or content unrelated to th
116
116
 
117
117
  For a PR likely to receive Codex review, use Notes to state its review scope. Create it as a draft
118
118
  while edits are still arriving when the user's workflow allows. When the branch is ready, use
119
- `codexloop`'s review-state check before requesting review: if the repository's automatic review
120
- is on, wait for it; if status is unknown, verify the repository setting; if it is off, request
121
- one review only when Codex has not reviewed the current head and no request is already pending.
119
+ `codexloop`'s review-state check before requesting review. Check the selected repository under
120
+ ChatGPT Settings → Code Review: repository-level automatic review can override personal
121
+ preferences, and its scope and trigger determine whether this PR should already be reviewed. If
122
+ automatic review is on for this PR, wait for it; if status is unknown, verify the repository
123
+ setting; if it is off, request one review only when Codex has not reviewed the current head and no
124
+ request is already pending. The minimum reporting severity controls which findings Codex reports;
125
+ do not describe it as reducing compute or usage without evidence. Check whether automatic security
126
+ review is enabled too, since it may run whenever code review runs.
122
127
  The state script does not see human-authored review requests: inspect the PR conversation with
123
128
  `gh api repos/{owner}/{repo}/issues/<PR>/comments --paginate` and check for an existing
124
129
  `@codex review` posted after the current head was pushed. If one exists, wait for it; do not post
125
130
  another.
126
- Do not add a review mention on PR creation or after every push. A repository setting can override
127
- the personal preference.
131
+ Do not add a review mention on PR creation or after every push.
128
132
 
129
133
  Rules:
130
134
  - Describe *intent*, not what the diff already shows line-by-line.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-obsidian",
3
3
  "description": "Keep an Obsidian vault in sync with work: PR sync, task rollover, morning routine.",
4
- "version": "1.54.1",
4
+ "version": "1.54.3",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-product",
3
3
  "description": "Take a product idea to a shippable build: MVP passes, full-stack scaffolds, UX/UI quality loops, launch plans.",
4
- "version": "1.54.1",
4
+ "version": "1.54.3",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-reflection",
3
3
  "description": "Look back and improve: self-critique, retrospectives, performance review, rapid learning.",
4
- "version": "1.54.1",
4
+ "version": "1.54.3",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-release",
3
3
  "description": "Ship a release: semantic-release setup, changelogs, store listing copy, release-day routine.",
4
- "version": "1.54.1",
4
+ "version": "1.54.3",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-skill-meta",
3
3
  "description": "Author and maintain agent skills and the AI toolchain itself.",
4
- "version": "1.54.1",
4
+ "version": "1.54.3",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-web-ops",
3
3
  "description": "Operate a website: WAF rules, search console audits, analytics bootstrap, docs indexes.",
4
- "version": "1.54.1",
4
+ "version": "1.54.3",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },