Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
bf16d27
feat(ci): route PR comment agent mentions
seonghobae Aug 4, 2026
44a3afa
feat(ci): respond to review-agent mentions
seonghobae Aug 4, 2026
e9f223e
test(ci): cover review-agent mention routing
seonghobae Aug 4, 2026
185d5ba
test(ci): load router module safely
seonghobae Aug 4, 2026
225b266
test(ci): specify trusted comment routing contract
seonghobae Aug 4, 2026
c8e6ec1
test(ci): cover organization mention sweep
seonghobae Aug 4, 2026
26ef319
test(ci): enforce mention workflow security contract
seonghobae Aug 4, 2026
57e6291
feat(ci): route trusted mentions through central review events
seonghobae Aug 4, 2026
d3868f5
feat(ci): sweep organization PR comments for agent mentions
seonghobae Aug 4, 2026
6f46a64
feat(ci): route local and organization-wide agent mentions
seonghobae Aug 4, 2026
0db74c7
docs(ci): document review-agent comment invocation
seonghobae Aug 4, 2026
af29c2c
fix(ci): restore review and security baseline for comment routing
seonghobae Aug 4, 2026
7dda47d
fix(ci): install validated Python locks atomically
seonghobae Aug 4, 2026
17c196d
fix(ci): preserve lock preflight contract
seonghobae Aug 4, 2026
1a29496
fix(ci): trust only automation receipt markers
seonghobae Aug 4, 2026
0a838ec
fix(ci): bound and validate organization mention sweep
seonghobae Aug 4, 2026
bb9cc61
docs(ci): correct retrieval dates
seonghobae Aug 4, 2026
0e62b10
fix(ci): scope local mention routing to central repository
seonghobae Aug 4, 2026
437f054
test(ci): cover trusted receipt authorship
seonghobae Aug 4, 2026
5d2b81b
test(ci): cover lazy and fail-closed mention sweep
seonghobae Aug 4, 2026
4cd8ef3
test(ci): pin central repository gate
seonghobae Aug 4, 2026
e84486c
test(ci): prove aggregate Python lock installation
seonghobae Aug 4, 2026
82c857a
fix(ci): redact subprocess commands and output
seonghobae Aug 5, 2026
6bf63ed
fix(ci): redact sandbox verification evidence
seonghobae Aug 5, 2026
ba54e95
fix(ci): redact sandboxed web E2E evidence
seonghobae Aug 5, 2026
3f81971
test(ci): cover sandbox evidence redaction
seonghobae Aug 5, 2026
c994f4e
docs(ci): document sandbox output redaction
seonghobae Aug 5, 2026
a2d6c13
fix(ci): consolidate runtime coverage and redaction boundaries
seonghobae Aug 5, 2026
4508edf
docs(doctoring): replace superseded sandbox redaction record
seonghobae Aug 5, 2026
8782eec
docs(changelog): record consolidated control-plane fixes
seonghobae Aug 5, 2026
7913121
docs(doctoring): pin coverage semantics to Vitest 3.2.7
seonghobae Aug 5, 2026
a908eb0
fix(security): bound deeply nested JSON redaction
seonghobae Aug 5, 2026
c525596
test(security): prove fail-closed nested JSON redaction
seonghobae Aug 5, 2026
9493a7d
docs(doctoring): record bounded deep JSON redaction
seonghobae Aug 5, 2026
aa1e0c9
docs(changelog): record fail-closed JSON depth handling
seonghobae Aug 5, 2026
41e9253
fix(security): classify long assignments in one pass
seonghobae Aug 5, 2026
5f3a4c4
test(security): verify one-pass long assignment handling
seonghobae Aug 5, 2026
59b4f82
test(redaction): cover echoed separate secret options
seonghobae Aug 5, 2026
f39af5e
fix(security): redact concatenated credential key names
seonghobae Aug 5, 2026
72a9ef6
test(security): cover concatenated sensitive JSON keys
seonghobae Aug 5, 2026
538cd06
fix(redaction): scrub echoed separate secret options
seonghobae Aug 5, 2026
84d2a1c
fix(security): fail closed for JSON-like diagnostic parse errors
seonghobae Aug 5, 2026
f295e5f
test(security): cover JSON-like and echoed option boundaries
seonghobae Aug 5, 2026
6a05c29
docs(doctoring): fail closed on malformed JSON-like evidence
seonghobae Aug 5, 2026
6153069
docs(changelog): record malformed structured evidence handling
seonghobae Aug 5, 2026
50f75c6
test(ci): define exact-head control-plane quality contract
seonghobae Aug 5, 2026
f69b5b6
ci: add exact-head control-plane quality gate
seonghobae Aug 5, 2026
f664ac3
docs(doctoring): require exact-head control-plane quality evidence
seonghobae Aug 5, 2026
0363abe
docs(changelog): add exact-head quality gate
seonghobae Aug 5, 2026
7265fee
test(security): assert explicit non-shell subprocess execution
seonghobae Aug 5, 2026
1bffbd7
fix(security): redact quoted echoed option values
seonghobae Aug 5, 2026
25a929f
test(ci): require path-bounded dynamic coverage evidence
seonghobae Aug 5, 2026
4127255
ci: measure dynamically loaded control-plane modules
seonghobae Aug 5, 2026
da65c18
test(ci): require isolated coverage configuration
seonghobae Aug 5, 2026
bafc089
ci: isolate exact-head coverage configuration
seonghobae Aug 5, 2026
c651531
test(ci): close exact-head branch coverage gaps
seonghobae Aug 5, 2026
a474985
fix(ci): execute complete control-plane coverage contracts
seonghobae Aug 5, 2026
5a95ff2
test(ci): close central control-plane coverage edges
seonghobae Aug 5, 2026
e15356e
ci: execute complete control-plane coverage closure
seonghobae Aug 5, 2026
c01d1cd
fix(security): redact deep fallback credential assignments
seonghobae Aug 5, 2026
5cdbc36
ci: diagnose exact-head control-plane coverage
seonghobae Aug 5, 2026
d12bd08
test(control-plane): capture exact-head coverage gaps
github-actions[bot] Aug 5, 2026
d66c2c2
ci: verify PR 757 exact-head quality repair
seonghobae Aug 5, 2026
e73c2e2
fix(control-plane): remove branch-selected manual router entrypoint
seonghobae Aug 5, 2026
db243a1
test(control-plane): cover package-qualified scheduler import fallback
seonghobae Aug 5, 2026
59120ed
test(control-plane): require operable manual mention sweep
seonghobae Aug 5, 2026
48cdc28
fix(control-plane): close credential redaction parser gaps
seonghobae Aug 5, 2026
c22f614
test(control-plane): isolate ownership-boundary fixture
seonghobae Aug 5, 2026
40b4a92
fix(control-plane): restore manual mention sweep
seonghobae Aug 5, 2026
47f6ba5
test(control-plane): distinguish trusted manual sweep from branch sel…
seonghobae Aug 5, 2026
29b1fd4
chore(control-plane): remove transient coverage diagnosis
seonghobae Aug 5, 2026
0a5501e
chore(control-plane): remove unused one-shot repair workflow
seonghobae Aug 5, 2026
337f426
test(control-plane): close redaction and import fallback coverage
seonghobae Aug 5, 2026
8d9232a
ci(pr757): focus agent mention router on current main
seonghobae Aug 5, 2026
548bb41
chore(ci): remove write-capable PR 757 focus workflow
seonghobae Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 187 additions & 0 deletions .github/workflows/agent-mention-router.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
name: Review Agent Mention Router

on:
issue_comment:
types: [created]
schedule:
- cron: "*/5 * * * *"
workflow_dispatch:

concurrency:
group: review-agent-mention-router-${{ github.repository }}
cancel-in-progress: false

# Organization required-workflow rules do not propagate issue_comment events
# into sibling repositories. Keep the workflow default read-only; each bounded
# job declares only the writes it actually needs.
permissions:
contents: read

jobs:
route-local-agent-mention:
if: >-
github.repository == 'ContextualWisdomLab/.github'
&& github.event_name == 'issue_comment'
&& github.event.issue.pull_request
&& github.event.comment.user.type != 'Bot'
&& contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)
&& (
contains(github.event.comment.body, '@cwl-noema-review')
|| contains(github.event.comment.body, '@opencode-agent')
)
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: write
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
issues: write
pull-requests: read
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
GH_TOKEN: ${{ github.token }}
TARGET_REPOSITORY_TOKEN: ${{ github.token }}
AGENT_DISPATCH_TOKEN: ${{ github.token }}
OPENCODE_REPOSITORY_DISPATCH_TARGETS: ${{ vars.OPENCODE_REPOSITORY_DISPATCH_TARGETS }}
steps:
- name: Check out trusted default-branch router
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
ref: ${{ github.event.repository.default_branch }}
persist-credentials: false

- name: Resolve immutable pull-request head and prior receipts
env:
REPOSITORY: ${{ github.repository }}
PR_NUMBER: ${{ github.event.issue.number }}
SOURCE_EVENT_PATH: ${{ github.event_path }}
run: |
set -euo pipefail
pr_json="$(gh api "repos/${REPOSITORY}/pulls/${PR_NUMBER}")"
comments_json="$(
gh api --paginate --slurp \
"repos/${REPOSITORY}/issues/${PR_NUMBER}/comments?per_page=100" \
| jq -c 'add // []'
)"
jq \
--argjson pull_request "$pr_json" \
--argjson conversation_comments "$comments_json" \
'. + {
pull_request: $pull_request,
conversation_comments: $conversation_comments
}' \
"$SOURCE_EVENT_PATH" >"${RUNNER_TEMP}/agent-mention-event.json"

- name: Route trusted local agent mention
run: >-
python3 scripts/ci/agent_mention_router.py
--event-path "${RUNNER_TEMP}/agent-mention-event.json"

sweep-organization-agent-mentions:
if: >-
github.repository == 'ContextualWisdomLab/.github'
&& (
github.event_name == 'schedule'
|| github.event_name == 'workflow_dispatch'
)
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: write
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
id-token: write
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
OPENCODE_REPOSITORY_DISPATCH_TARGETS: ${{ vars.OPENCODE_REPOSITORY_DISPATCH_TARGETS }}
LOOKBACK_HOURS: ${{ vars.AGENT_MENTION_LOOKBACK_HOURS || '168' }}
MAX_DISPATCHES: ${{ vars.AGENT_MENTION_MAX_DISPATCHES || '20' }}
DRY_RUN: "false"
steps:
- name: Exchange OpenCode app token for sibling-repository comments
id: sweep_app_token
env:
OIDC_AUDIENCE: opencode-github-action
OPENCODE_API_BASE_URL: https://api.opencode.ai
USER_TOKEN_CONFIGURED: ${{ secrets.PR_REVIEW_MERGE_TOKEN != '' || secrets.OPENCODE_APPROVE_TOKEN != '' }}
run: |
set -euo pipefail
mark_unavailable() {
echo "available=false" >>"$GITHUB_OUTPUT"
}
if [ "$USER_TOKEN_CONFIGURED" = "true" ]; then
echo "A configured cross-repository user token takes precedence."
mark_unavailable
exit 0
fi
if [ -z "${ACTIONS_ID_TOKEN_REQUEST_TOKEN:-}" ] || [ -z "${ACTIONS_ID_TOKEN_REQUEST_URL:-}" ]; then
echo "OpenCode app token exchange unavailable: OIDC request environment is missing."
mark_unavailable
exit 0
fi
request_url="${ACTIONS_ID_TOKEN_REQUEST_URL}"
separator="&"
case "$request_url" in
*\?*) ;;
*) separator="?" ;;
esac
if ! oidc_response="$(
curl -fsS \
-H "Authorization: Bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \
"${request_url}${separator}audience=${OIDC_AUDIENCE}"
)"; then
echo "OpenCode app token exchange unavailable: OIDC token request did not complete."
mark_unavailable
exit 0
fi
oidc_token="$(jq -r '.value // empty' <<<"$oidc_response")"
if [ -z "$oidc_token" ]; then
echo "OpenCode app token exchange unavailable: OIDC token response was empty."
mark_unavailable
exit 0
fi
if ! token_response="$(
curl -fsS \
-X POST \
-H "Authorization: Bearer ${oidc_token}" \
"${OPENCODE_API_BASE_URL}/exchange_github_app_token"
)"; then
echo "OpenCode app token exchange unavailable: app token request did not complete."
mark_unavailable
exit 0
fi
app_token="$(jq -r '.token // empty' <<<"$token_response")"
if [ -z "$app_token" ]; then
echo "OpenCode app token exchange unavailable: app token response was empty."
mark_unavailable
exit 0
fi
echo "::add-mask::$app_token"
{
echo "available=true"
echo "token=$app_token"
} >>"$GITHUB_OUTPUT"

- name: Check out trusted central router
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
ref: ${{ github.event.repository.default_branch }}
persist-credentials: false

- name: Sweep recent organization PR comments
env:
TARGET_REPOSITORY_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN || secrets.OPENCODE_APPROVE_TOKEN || steps.sweep_app_token.outputs.token }}
TARGET_REPOSITORY_SOURCE: ${{ (secrets.PR_REVIEW_MERGE_TOKEN != '' || secrets.OPENCODE_APPROVE_TOKEN != '') && 'organization' || steps.sweep_app_token.outputs.available == 'true' && 'installation' || '' }}
AGENT_DISPATCH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
if [ -z "${TARGET_REPOSITORY_TOKEN:-}" ] || [ -z "${TARGET_REPOSITORY_SOURCE:-}" ]; then
echo "::error::Agent mention sweep requires PR_REVIEW_MERGE_TOKEN, OPENCODE_APPROVE_TOKEN, or the OpenCode app token exchange."
exit 1
fi
args=(
--organization ContextualWisdomLab
--repository-source "$TARGET_REPOSITORY_SOURCE"
--lookback-hours "$LOOKBACK_HOURS"
--max-dispatches "$MAX_DISPATCHES"
)
if [ "$DRY_RUN" = "true" ]; then
args+=(--dry-run)
fi
python3 scripts/ci/agent_mention_sweep.py "${args[@]}"
8 changes: 4 additions & 4 deletions .github/workflows/codeql-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}

- name: Initialize CodeQL
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/init@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/analyze@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
with:
category: "/language:${{ matrix.language }}"
upload: false
Expand Down Expand Up @@ -197,13 +197,13 @@ jobs:
ref: ${{ format('refs/pull/{0}/merge', github.event.pull_request.number) }}

- name: Initialize CodeQL
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/init@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/analyze@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
with:
category: "/language:${{ matrix.language }}-merge"
upload: false
Expand Down
Loading
Loading