Skip to content

Initial plan#20

Open
blackboxprogramming wants to merge 49 commits intomainfrom
claude/merge-pull-requests-hw53C
Open

Initial plan#20
blackboxprogramming wants to merge 49 commits intomainfrom
claude/merge-pull-requests-hw53C

Conversation

@blackboxprogramming
Copy link
Contributor

No description provided.

Copilot AI and others added 30 commits January 27, 2026 18:50
- Add issue templates (bug report, feature request, org setup)
- Add PR template with BlackRoad-specific sections
- Add CODE_OF_CONDUCT.md (Contributor Covenant 2.1)
- Add CONTRIBUTING.md with org-specific guidelines
- Add SECURITY.md with vulnerability reporting process
- Add SUPPORT.md with help resources
- Add CODEOWNERS for code review assignments
- Add dependabot.yml for automated dependency updates
- Add FUNDING.yml placeholder
- Add .gitignore for common artifacts

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
- Add CONTRIBUTORS.md for recognizing contributors
- Add CHANGELOG.md with initial release notes
- Add .github/README.md explaining GitHub automation
- Add root README.md as main landing page

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
- Document Session 3: GitHub repository setup
- Add all new files to session history
- Mark GitHub repository setup as complete

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
- Add CLAUDE_CODE_API.md with best practices, examples, and guidelines
- Update INTEGRATIONS.md with detailed Anthropic/Claude API info
- Update MEMORY.md to explicitly reference Claude Code API
- Add Claude Code API badge to README.md
- Enhance AI stack information in README.md
- Update ai-router template with Claude Code API reference
- Add AI-assisted development section to CONTRIBUTING.md
- Update INDEX.md with Claude Code API link
- Document changes in CHANGELOG.md

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
- Add pytest configuration (pytest.ini)
- Add test dependencies (requirements-test.txt)
- Create tests/ directory with shared fixtures (conftest.py)
- Add 73 passing tests for Operator prototype:
  - 23 tests for parser.py (input parsing)
  - 24 tests for classifier.py (pattern matching)
  - 26 tests for router.py (routing logic)
- Achieve 75% code coverage for Operator
- All tests passing successfully

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
- Add GitHub Actions workflow for automated testing (tests.yml)
- Add comprehensive TESTING.md documentation
- Update .gitignore with test artifacts
- Update INDEX.md with TESTING.md link
- Update CHANGELOG.md with testing infrastructure
- All 73 tests passing with 75% coverage

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
- Document Session 4: Testing Infrastructure
- Mark testing infrastructure as complete in Active Threads
- Add details about 73 tests, 75% coverage, CI/CD

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
- Add GitHub Actions workflow (auto-merge.yml)
- Auto-merge PRs from copilot/** branches when checks pass
- Support auto-merge label for other branches
- Add eligibility checking (checks passed, no conflicts, not draft)
- Use squash merge strategy
- Add PR comments with merge status
- Create AUTO_MERGE.md comprehensive documentation
- Update README.md with auto-merge badge
- Update INDEX.md with AUTO_MERGE.md link
- Update CHANGELOG.md with auto-merge feature
- Update MEMORY.md with Session 5 details

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
- Add 24 comprehensive tests for Control Plane
- Test Bridge core functionality (state, status, routing)
- Test organization and template listing
- Test signal emission, search, and browsing
- Test lazy loading of components
- Fix Bridge.browse() to use correct Explorer API
- Fix Bridge.signal() to use simple format
- Fix Bridge.search() to return dict results directly
- All 97 tests passing (73 operator + 24 control plane)
- 73% overall code coverage

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
- Update MEMORY.md with Session 6 (Control Plane testing)
- Mark Control Plane as DONE in Active Threads
- Update CHANGELOG.md with Control Plane validation
- Update test count in README (97 tests passing)
- Update Active Threads numbering
- Document 73% overall coverage

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
…ocumentation

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
claude and others added 19 commits January 27, 2026 21:16
Sync Active Threads section with .STATUS - mark threads 7-12 as DONE:
- Control plane CLI (prototypes/control-plane)
- Node configs (all 7 nodes)
- GitHub Actions (8 workflows)
- Webhook handlers (prototypes/webhooks)
- MCP Server (prototypes/mcp-server)
- Dispatcher (prototypes/dispatcher)

https://claude.ai/code/session_01JzfHdbRffmyB7hY3Sagjyt
Pulled from BlackRoad-OS repos:
- agents/README.md - Registry of 1,050 agents across 20 types
- agents/types.yaml - Detailed type definitions with capabilities
- agents/ORCHESTRATION.md - Swarm coordination patterns
- EMOJI_DICTIONARY.md - Visual language reference from blackroad-docs

Updated INDEX.md with new Agents section and emoji dictionary link.

https://claude.ai/code/session_01JzfHdbRffmyB7hY3Sagjyt
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Provides a single-file reference covering repository structure,
development workflows, conventions, architecture, and session
startup checklist for any AI assistant working in The Bridge.

https://claude.ai/code/session_01JWYQzDR5tuCTFS2X3YPi5t
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
# Conflicts:
#	CODE_OF_CONDUCT.md
#	CONTRIBUTING.md
#	INDEX.md
#	README.md
#	SECURITY.md
# Conflicts:
#	.github/workflows/auto-merge.yml
#	README.md
Copilot AI review requested due to automatic review settings February 3, 2026 19:48
PR_NUMBER="${{ github.event.pull_request.number }}"
elif [ "${{ github.event_name }}" == "workflow_run" ]; then
# Extract PR number from workflow run
PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="${{ github.event.workflow_run.head_branch }}") | .number' | head -1)

Check failure

Code scanning / CodeQL

Code injection Critical

Potential code injection in
${ github.event.workflow_run.head_branch }
, which may be controlled by an external user (
workflow_run
).

Copilot Autofix

AI 11 days ago

In general, to fix this class of problem in GitHub Actions, untrusted expressions like ${{ github.* }} or ${{ inputs.* }} should not be injected directly into run: scripts where they will be interpreted by a shell or another language (jq, JavaScript, etc.). Instead, assign the expression to an environment variable via env: (or with.env:) and then reference it using the native variable syntax of the target interpreter ($VAR in bash, process.env.VAR in Node, etc.). This prevents the expression language from being evaluated again inside the script and reduces the risk of code injection.

For this workflow, the vulnerable use is on line 41 where ${{ github.event.workflow_run.head_branch }} is interpolated directly into the jq expression inside the shell script. The safest fix without changing functionality is:

  1. Define an environment variable (e.g., HEAD_BRANCH) for the job or at least for the “Get PR info” step, assigning it ${{ github.event.workflow_run.head_branch }}.
  2. Use standard shell variable expansion to insert $HEAD_BRANCH into the jq filter string, still within single quotes, so jq sees the correct branch name while the shell does not interpret its contents.
  3. Optionally handle the case where HEAD_BRANCH may be empty (for non-workflow_run events), but that can be left as-is since current logic only uses the jq command in the workflow_run branch.

Concretely, in .github/workflows/auto-merge.yml, update the “Get PR info” step to include HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} under env:. Then, replace the jq invocation on line 41 from:

PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="${{ github.event.workflow_run.head_branch }}") | .number' | head -1)

to:

PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="'"$HEAD_BRANCH"'") | .number' | head -1)

This uses shell-safe concatenation of single- and double-quoted strings so that $HEAD_BRANCH is expanded by the shell, but its contents are not reinterpreted by the shell, and jq still receives a proper string literal.

Suggested changeset 1
.github/workflows/auto-merge.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml
--- a/.github/workflows/auto-merge.yml
+++ b/.github/workflows/auto-merge.yml
@@ -32,13 +32,14 @@
         id: pr
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
         run: |
           # Get PR number from the event
           if [ "${{ github.event_name }}" == "pull_request_review" ]; then
             PR_NUMBER="${{ github.event.pull_request.number }}"
           elif [ "${{ github.event_name }}" == "workflow_run" ]; then
             # Extract PR number from workflow run
-            PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="${{ github.event.workflow_run.head_branch }}") | .number' | head -1)
+            PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="'"$HEAD_BRANCH"'") | .number' | head -1)
           else
             echo "No PR found for event type: ${{ github.event_name }}"
             exit 1
EOF
@@ -32,13 +32,14 @@
id: pr
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
run: |
# Get PR number from the event
if [ "${{ github.event_name }}" == "pull_request_review" ]; then
PR_NUMBER="${{ github.event.pull_request.number }}"
elif [ "${{ github.event_name }}" == "workflow_run" ]; then
# Extract PR number from workflow run
PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="${{ github.event.workflow_run.head_branch }}") | .number' | head -1)
PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="'"$HEAD_BRANCH"'") | .number' | head -1)
else
echo "No PR found for event type: ${{ github.event_name }}"
exit 1
Copilot is powered by AI and may make mistakes. Always verify output.
fi

if [ -z "$PR_NUMBER" ]; then
echo "No PR number found for branch ${{ github.event.workflow_run.head_branch }}"

Check failure

Code scanning / CodeQL

Code injection Critical

Potential code injection in
${ github.event.workflow_run.head_branch }
, which may be controlled by an external user (
workflow_run
).

Copilot Autofix

AI 11 days ago

To fix the problem, the untrusted value (github.event.workflow_run.head_branch) should not be interpolated directly into the shell within the run: block using ${{ ... }}. Instead, it should be passed into the step via env: and then referenced inside the script using normal shell variable syntax like $HEAD_BRANCH. This breaks the direct templating-to-shell path that enables code injection.

Concretely, for the “Get PR info” step in .github/workflows/auto-merge.yml, we should:

  • Add an environment variable, e.g. HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} under env:.
  • Replace usages of ${{ github.event.workflow_run.head_branch }} inside the run: script with $HEAD_BRANCH.
  • Keep existing behavior the same: the variable is only used to match PRs by head ref and to print an error message.

We must only edit within the shown snippet of .github/workflows/auto-merge.yml. Specifically:

  • Around lines 33–35, extend the env: mapping to include HEAD_BRANCH with the expression.
  • At line 41, change the gh pr list command so that select(.headRefName=="${{ github.event.workflow_run.head_branch }}") becomes select(.headRefName=="'$HEAD_BRANCH'") or equivalent safe quoting. The simplest is to replace the interpolated expression with $HEAD_BRANCH and keep the surrounding double quotes, resulting in select(.headRefName=="$HEAD_BRANCH").
  • At line 48, change the error message from branch ${{ github.event.workflow_run.head_branch }} to branch $HEAD_BRANCH.

No new methods or external libraries are needed; we only adjust YAML env: and shell variable usage in the existing step.

Suggested changeset 1
.github/workflows/auto-merge.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml
--- a/.github/workflows/auto-merge.yml
+++ b/.github/workflows/auto-merge.yml
@@ -32,20 +32,21 @@
         id: pr
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
         run: |
           # Get PR number from the event
           if [ "${{ github.event_name }}" == "pull_request_review" ]; then
             PR_NUMBER="${{ github.event.pull_request.number }}"
           elif [ "${{ github.event_name }}" == "workflow_run" ]; then
             # Extract PR number from workflow run
-            PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="${{ github.event.workflow_run.head_branch }}") | .number' | head -1)
+            PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="'"$HEAD_BRANCH"'") | .number' | head -1)
           else
             echo "No PR found for event type: ${{ github.event_name }}"
             exit 1
           fi
           
           if [ -z "$PR_NUMBER" ]; then
-            echo "No PR number found for branch ${{ github.event.workflow_run.head_branch }}"
+            echo "No PR number found for branch $HEAD_BRANCH"
             exit 1
           fi
           
EOF
@@ -32,20 +32,21 @@
id: pr
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
run: |
# Get PR number from the event
if [ "${{ github.event_name }}" == "pull_request_review" ]; then
PR_NUMBER="${{ github.event.pull_request.number }}"
elif [ "${{ github.event_name }}" == "workflow_run" ]; then
# Extract PR number from workflow run
PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="${{ github.event.workflow_run.head_branch }}") | .number' | head -1)
PR_NUMBER=$(gh pr list --json number,headRefName --jq '.[] | select(.headRefName=="'"$HEAD_BRANCH"'") | .number' | head -1)
else
echo "No PR found for event type: ${{ github.event_name }}"
exit 1
fi

if [ -z "$PR_NUMBER" ]; then
echo "No PR number found for branch ${{ github.event.workflow_run.head_branch }}"
echo "No PR number found for branch $HEAD_BRANCH"
exit 1
fi

Copilot is powered by AI and may make mistakes. Always verify output.
- name: Check merge conditions
id: check
run: |
STATE="${{ steps.pr.outputs.state }}"

Check failure

Code scanning / CodeQL

Code injection Critical

Potential code injection in
${ steps.pr.outputs.state }
, which may be controlled by an external user (
pull_request_review
).
Potential code injection in
${ steps.pr.outputs.state }
, which may be controlled by an external user (
workflow_run
).

Copilot Autofix

AI 11 days ago

General fix: Avoid inserting untrusted data into a shell script via GitHub expression interpolation inside run:. Instead, assign the untrusted value to an environment variable using ${{ ... }} in the env: block, and then reference it inside run: using the shell’s native variable syntax ($VAR), which prevents it from being parsed by the Actions expression engine within the script.

Concrete changes here:

  • In the Check merge conditions step (lines 68–76), move the three ${{ steps.pr.outputs.* }} expressions from the run: script into an env: block:
    • Add env: with STATE, MERGEABLE, and REVIEW_DECISION set from ${{ steps.pr.outputs.state }}, ${{ steps.pr.outputs.mergeable }}, ${{ steps.pr.outputs.review_decision }}.
  • Inside the run: block, replace:
    • STATE="${{ steps.pr.outputs.state }}"
    • MERGEABLE="${{ steps.pr.outputs.mergeable }}"
    • REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"
      with simple shell assignments from the environment:
    • STATE="$STATE"
    • MERGEABLE="$MERGEABLE"
    • REVIEW_DECISION="$REVIEW_DECISION"
  • No new methods or imports are required; all changes are confined to the YAML workflow and this single step.

This preserves the existing logic and behavior while following the recommended pattern to avoid code injection issues.


Suggested changeset 1
.github/workflows/auto-merge.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml
--- a/.github/workflows/auto-merge.yml
+++ b/.github/workflows/auto-merge.yml
@@ -66,10 +66,14 @@
 
       - name: Check merge conditions
         id: check
+        env:
+          STATE: ${{ steps.pr.outputs.state }}
+          MERGEABLE: ${{ steps.pr.outputs.mergeable }}
+          REVIEW_DECISION: ${{ steps.pr.outputs.review_decision }}
         run: |
-          STATE="${{ steps.pr.outputs.state }}"
-          MERGEABLE="${{ steps.pr.outputs.mergeable }}"
-          REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"
+          STATE="$STATE"
+          MERGEABLE="$MERGEABLE"
+          REVIEW_DECISION="$REVIEW_DECISION"
           
           echo "PR State: $STATE"
           echo "Mergeable: $MERGEABLE"
EOF
@@ -66,10 +66,14 @@

- name: Check merge conditions
id: check
env:
STATE: ${{ steps.pr.outputs.state }}
MERGEABLE: ${{ steps.pr.outputs.mergeable }}
REVIEW_DECISION: ${{ steps.pr.outputs.review_decision }}
run: |
STATE="${{ steps.pr.outputs.state }}"
MERGEABLE="${{ steps.pr.outputs.mergeable }}"
REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"
STATE="$STATE"
MERGEABLE="$MERGEABLE"
REVIEW_DECISION="$REVIEW_DECISION"

echo "PR State: $STATE"
echo "Mergeable: $MERGEABLE"
Copilot is powered by AI and may make mistakes. Always verify output.
id: check
run: |
STATE="${{ steps.pr.outputs.state }}"
MERGEABLE="${{ steps.pr.outputs.mergeable }}"

Check failure

Code scanning / CodeQL

Code injection Critical

Potential code injection in
${ steps.pr.outputs.mergeable }
, which may be controlled by an external user (
pull_request_review
).
Potential code injection in
${ steps.pr.outputs.mergeable }
, which may be controlled by an external user (
workflow_run
).

Copilot Autofix

AI 11 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

run: |
STATE="${{ steps.pr.outputs.state }}"
MERGEABLE="${{ steps.pr.outputs.mergeable }}"
REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"

Check failure

Code scanning / CodeQL

Code injection Critical

Potential code injection in
${ steps.pr.outputs.review_decision }
, which may be controlled by an external user (
pull_request_review
).
Potential code injection in
${ steps.pr.outputs.review_decision }
, which may be controlled by an external user (
workflow_run
).

Copilot Autofix

AI 11 days ago

General approach: Avoid using ${{ ... }} expressions directly inside shell scripts. Instead, set the potentially-untrusted value into an environment variable at the step level using GitHub expression syntax, and then reference that variable within the script using normal shell variable expansion ($VAR). This removes the direct interpolation path that CodeQL flags and follows GitHub’s recommended pattern.

Best concrete fix here:

  • In the "Check merge conditions" step (lines 68–73), move the three interpolations (${{ steps.pr.outputs.state }}, mergeable, and review_decision) from inside the run: script into an env: block.
  • Inside the script, simply read them as $STATE, $MERGEABLE, and $REVIEW_DECISION without any ${{ ... }} usage.
  • This addresses the flagged review_decision usage and, for consistency, hardens the other two values in the same way.
  • No new imports or external dependencies are required; this is purely a YAML/workflow change inside .github/workflows/auto-merge.yml.

Concretely:

  • Edit the Check merge conditions step starting at line 68.
  • Add an env: section under that step with:
    • STATE: ${{ steps.pr.outputs.state }}
    • MERGEABLE: ${{ steps.pr.outputs.mergeable }}
    • REVIEW_DECISION: ${{ steps.pr.outputs.review_decision }}
  • Replace the first three lines of the script body (70–72) with simple shell assignments that copy from the environment (STATE="$STATE" etc.), or even just rely directly on the environment variables without reassigning; to keep minimal logic change, we’ll keep explicit assignments that no longer use ${{ ... }}.

No other parts of the file need to change for this alert.


Suggested changeset 1
.github/workflows/auto-merge.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml
--- a/.github/workflows/auto-merge.yml
+++ b/.github/workflows/auto-merge.yml
@@ -66,10 +66,14 @@
 
       - name: Check merge conditions
         id: check
+        env:
+          STATE: ${{ steps.pr.outputs.state }}
+          MERGEABLE: ${{ steps.pr.outputs.mergeable }}
+          REVIEW_DECISION: ${{ steps.pr.outputs.review_decision }}
         run: |
-          STATE="${{ steps.pr.outputs.state }}"
-          MERGEABLE="${{ steps.pr.outputs.mergeable }}"
-          REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"
+          STATE="$STATE"
+          MERGEABLE="$MERGEABLE"
+          REVIEW_DECISION="$REVIEW_DECISION"
           
           echo "PR State: $STATE"
           echo "Mergeable: $MERGEABLE"
EOF
@@ -66,10 +66,14 @@

- name: Check merge conditions
id: check
env:
STATE: ${{ steps.pr.outputs.state }}
MERGEABLE: ${{ steps.pr.outputs.mergeable }}
REVIEW_DECISION: ${{ steps.pr.outputs.review_decision }}
run: |
STATE="${{ steps.pr.outputs.state }}"
MERGEABLE="${{ steps.pr.outputs.mergeable }}"
REVIEW_DECISION="${{ steps.pr.outputs.review_decision }}"
STATE="$STATE"
MERGEABLE="$MERGEABLE"
REVIEW_DECISION="$REVIEW_DECISION"

echo "PR State: $STATE"
echo "Mergeable: $MERGEABLE"
Copilot is powered by AI and may make mistakes. Always verify output.
echo "🎯 Auto-merge Summary"
echo ""
echo "PR: #${{ steps.pr.outputs.pr_number }}"
echo "State: ${{ steps.pr.outputs.state }}"

Check failure

Code scanning / CodeQL

Code injection Critical

Potential code injection in
${ steps.pr.outputs.state }
, which may be controlled by an external user (
pull_request_review
).
Potential code injection in
${ steps.pr.outputs.state }
, which may be controlled by an external user (
workflow_run
).

Copilot Autofix

AI 11 days ago

To fix this, avoid using ${{ steps.pr.outputs.state }} directly inside the run: script. Instead, assign the potentially tainted expression to an environment variable via the env: section of the step, and then reference it using native shell syntax ($PR_STATE) inside the script. This is the recommended pattern to prevent code injection in GitHub Actions, because the shell never sees the ${{ ... }} interpolation and only receives values as regular environment variables.

Concretely, in the Summary step (lines 121–129), add an env: block that exposes the needed outputs as environment variables: PR_NUMBER, PR_STATE, and CAN_MERGE. Then, in the run: block, replace echo "PR: #${{ steps.pr.outputs.pr_number }}", echo "State: ${{ steps.pr.outputs.state }}", and echo "Can merge: ${{ steps.check.outputs.can_merge }}" with shell variable references: echo "PR: #$PR_NUMBER", echo "State: $PR_STATE", and echo "Can merge: $CAN_MERGE". This change is local to .github/workflows/auto-merge.yml, preserves the existing functionality and output format, and removes the direct use of the tainted expression inside the script.

Suggested changeset 1
.github/workflows/auto-merge.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml
--- a/.github/workflows/auto-merge.yml
+++ b/.github/workflows/auto-merge.yml
@@ -120,10 +120,15 @@
 
       - name: Summary
         if: always()
+        env:
+          PR_NUMBER: ${{ steps.pr.outputs.pr_number }}
+          PR_STATE: ${{ steps.pr.outputs.state }}
+          CAN_MERGE: ${{ steps.check.outputs.can_merge }}
+          JOB_STATUS: ${{ job.status }}
         run: |
           echo "🎯 Auto-merge Summary"
           echo ""
-          echo "PR: #${{ steps.pr.outputs.pr_number }}"
-          echo "State: ${{ steps.pr.outputs.state }}"
-          echo "Can merge: ${{ steps.check.outputs.can_merge }}"
-          echo "Status: ${{ job.status }}"
+          echo "PR: #$PR_NUMBER"
+          echo "State: $PR_STATE"
+          echo "Can merge: $CAN_MERGE"
+          echo "Status: $JOB_STATUS"
EOF
@@ -120,10 +120,15 @@

- name: Summary
if: always()
env:
PR_NUMBER: ${{ steps.pr.outputs.pr_number }}
PR_STATE: ${{ steps.pr.outputs.state }}
CAN_MERGE: ${{ steps.check.outputs.can_merge }}
JOB_STATUS: ${{ job.status }}
run: |
echo "🎯 Auto-merge Summary"
echo ""
echo "PR: #${{ steps.pr.outputs.pr_number }}"
echo "State: ${{ steps.pr.outputs.state }}"
echo "Can merge: ${{ steps.check.outputs.can_merge }}"
echo "Status: ${{ job.status }}"
echo "PR: #$PR_NUMBER"
echo "State: $PR_STATE"
echo "Can merge: $CAN_MERGE"
echo "Status: $JOB_STATUS"
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +23 to +82
name: Run Tests
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.11', '3.12']

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-test.txt

- name: Run pytest
run: |
python -m pytest tests/ \
--verbose \
--cov=prototypes \
--cov-report=term-missing \
--cov-report=xml \
--cov-report=html \
-ra

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
if: matrix.python-version == '3.12'
with:
files: ./coverage.xml
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false

- name: Archive coverage results
uses: actions/upload-artifact@v4
if: matrix.python-version == '3.12'
with:
name: coverage-report
path: htmlcov/
retention-days: 30

- name: Test Summary
if: always()
run: |
echo "## Test Results 🧪" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Python ${{ matrix.python-version }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
python -m pytest tests/ --quiet --tb=no || true
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY

lint:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 11 days ago

In general, the fix is to explicitly declare a permissions block that limits the GITHUB_TOKEN to only the scopes needed. For a CI workflow that only needs to read the repository contents and upload artifacts/coverage, contents: read is usually sufficient. This can be set at the root of the workflow (affecting all jobs) or per-job; here, a single root-level permissions block is cleaner since both jobs have the same needs.

For this specific workflow, no step performs write operations to the repository, issues, or pull requests. actions/checkout, codecov/codecov-action, and actions/upload-artifact work with a read-only contents permission when they only need to read the code and upload data to external or GitHub-managed storage. Therefore, the best minimal change is to add:

permissions:
  contents: read

at the top level, between name: Tests and on:. This documents and enforces read-only repository access for all jobs without altering any existing steps or behavior.

Changes needed:

  • Edit .github/workflows/tests.yml.
  • Insert a new permissions block after line 2 (name: Tests) and before line 4 (on:).
  • No new imports or methods are required; this is purely a YAML workflow configuration change.

Suggested changeset 1
.github/workflows/tests.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -1,5 +1,7 @@
 # Run BlackRoad tests on pull requests and pushes
 name: Tests
+permissions:
+  contents: read
 
 on:
   push:
EOF
@@ -1,5 +1,7 @@
# Run BlackRoad tests on pull requests and pushes
name: Tests
permissions:
contents: read

on:
push:
Copilot is powered by AI and may make mistakes. Always verify output.
-ra

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium test

Unpinned 3rd party Action 'Tests' step
Uses Step
uses 'codecov/codecov-action' with ref 'v4', not a pinned commit hash
Comment on lines +83 to +113
name: Code Quality
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'

- name: Install linting tools
run: |
python -m pip install --upgrade pip
pip install black ruff mypy

- name: Check code formatting with Black
run: |
black --check --diff prototypes/ tests/ || true

- name: Lint with Ruff
run: |
ruff check prototypes/ tests/ || true
continue-on-error: true

- name: Type check with mypy
run: |
mypy prototypes/ --ignore-missing-imports || true
continue-on-error: true

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 11 days ago

In general, fix this by adding an explicit permissions: block that grants only the minimal needed scopes. Since this workflow only checks out code, installs dependencies, runs tests, uploads coverage to Codecov, and uploads artifacts, it only needs read access to repository contents. It does not need to write to contents, pull requests, or issues.

The best fix without changing existing functionality is to add a permissions: block at the workflow root (right after name: Tests). This will apply to both test and lint jobs, satisfying the CodeQL recommendation and documenting required permissions. Set contents: read, which is the standard minimal scope for typical CI jobs that only need to read the repository.

Concretely, in .github/workflows/tests.yml, between line 2 (name: Tests) and line 4 (on:), insert:

permissions:
  contents: read

No additional methods, imports, or other definitions are needed.

Suggested changeset 1
.github/workflows/tests.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -1,5 +1,7 @@
 # Run BlackRoad tests on pull requests and pushes
 name: Tests
+permissions:
+  contents: read
 
 on:
   push:
EOF
@@ -1,5 +1,7 @@
# Run BlackRoad tests on pull requests and pushes
name: Tests
permissions:
contents: read

on:
push:
Copilot is powered by AI and may make mistakes. Always verify output.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR establishes the initial project structure and testing infrastructure for the BlackRoad ecosystem. The changes include comprehensive test suites for core components, workflow automation for syncing updates across organizations, and an extensive agent-based development environment with 5 specialized AI agents using open-source models.

Changes:

  • Added comprehensive testing infrastructure with 97 passing tests across operator and control plane prototypes
  • Implemented sync-to-orgs workflow for automatically distributing updates to target repositories
  • Created auto-merge workflow for approved PRs after CI passes
  • Added agent-based codespace with 5 AI agents (coder, designer, ops, docs, analyst) using 7 open-source models
  • Established session management system for agent collaboration and shared memory

Reviewed changes

Copilot reviewed 95 out of 122 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/test_sync.py Test suite validating sync workflow functionality and registry configuration
tests/test_integration.py Integration tests simulating complete sync flow without actual dispatch
tests/operator/test_parser.py Comprehensive parser tests for various input types (text, HTTP, webhook, signal, CLI)
tests/operator/test_classifier.py Classification tests for routing queries to appropriate organizations
tests/conftest.py Shared pytest fixtures and test configuration
.github/workflows/sync-to-orgs.yml Workflow for dispatching updates to active organization repositories
.github/workflows/auto-merge.yml Automated PR merging after approval and CI success
.github/workflows/ci.yml Enhanced CI with sync testing
pytest.ini Pytest configuration with coverage and markers
requirements-test.txt Testing infrastructure dependencies
docs/SYNC.md Comprehensive documentation for sync functionality
codespace-agents/* Agent orchestration, configuration, and deployment files
prototypes/sessions/* Session management, collaboration, and shared memory implementations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +167 to 168
# Explorer just has tree() method
return self.explorer.tree()
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment states that Explorer 'just has tree() method', but this contradicts the removed code which was calling show(path). If the Explorer API was intentionally changed to only support tree() without path-based navigation, this should be documented in the Explorer module itself or in a changelog to help other developers understand why the functionality was removed.

Copilot uses AI. Check for mistakes.
Comment on lines +172 to +173
# Use simple fallback format since SignalEmitter needs different args
return f"📡 OS → {target} : {message}"
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment indicates that SignalEmitter exists but requires different arguments than what's available here. This hardcoded fallback format bypasses the actual SignalEmitter implementation, creating potential inconsistency in signal formatting across the codebase. Consider either: 1) updating SignalEmitter to accept these arguments, or 2) documenting the expected SignalEmitter interface so callers can provide the correct arguments.

Copilot uses AI. Check for mistakes.
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

else:
# Use default service
service_name = self.registry.defaults.get("default_services", {}).get(org_code)

P1 Badge Route matched-rule traffic to default service

When classification is missing, the dispatcher always falls back to default_services (here, crm for FND) and ignores the matched_service returned by Registry.match. That means queries that match explicit routing rules (e.g., salesforce → service salesforce, stripe|billing|payment → service stripe in routes/registry.yaml lines 542-550) will be sent to the org’s default service instead of the rule’s service whenever the operator is unavailable or classification fails. This breaks the rule-based routing that the registry is defining and will misroute requests to the wrong endpoint.


cd prototypes/operator
python -m pytest tests/ -v || echo "No tests yet"

P2 Badge Do not mask operator test failures in CI

The Run operator tests step appends || echo "No tests yet", which converts any pytest failure into a success. That means legitimate test failures (not just “no tests collected”) will still allow the CI workflow to pass, enabling merges with broken operator behavior. If the intent is only to tolerate empty test suites, you’ll need a conditional that distinguishes pytest’s "no tests" exit code from real failures.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants