Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 4 additions & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ Use the narrowest relevant validation first:
- Bash command changes: run the focused BATS tests;
- general Base changes: run `env -u BASE_HOME ./bin/base-test` when practical.

Copilot cloud-agent sessions may run `.github/workflows/copilot-setup-steps.yml`
before work starts. That workflow is only a lightweight environment guardrail;
pull requests still need the focused validation above and normal CI review.

Do not require GitHub Copilot for Base development, add personal Copilot or
Codex settings, store credentials, or introduce third-party agent methodology as
a repo requirement. Translate useful external workflow ideas into smaller
Base-native guidance.

43 changes: 43 additions & 0 deletions .github/workflows/copilot-setup-steps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Copilot setup steps

on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
copilot-setup-steps:
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5

- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: "3.13"

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

- name: Run lightweight Base validation
env:
PYTHONPATH: lib/python:cli/python
run: |
python -m compileall -q cli/python lib/python tests
python -m pytest tests/test_github_workflows.py tests/test_bootstrap_docs.py -q
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ and Base versions are tracked in the repo-root `VERSION` file.
- Added `basectl history --report` to generate local Markdown or JSON activity
summaries from recent command history and log metadata without dumping raw
logs or uploading telemetry.
- Added a bounded `copilot-setup-steps` workflow and documentation for optional
GitHub Copilot cloud-agent setup without changing normal local development or
CI behavior.

### Changed

Expand Down
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ reference. The filename should answer "what is this about?"
`basectl repo check`, `basectl repo configure`, and the optional
`basectl repo agent-guidance` layer for standardizing new Base-managed
repositories.
- [Copilot Cloud-Agent Guardrails](copilot-cloud-agent.md) records the optional
GitHub Copilot setup workflow and why repository hooks are deferred.
- [`basectl repo` Ownership Map](repo-command-ownership.md) maps the current
`repo.sh` responsibility boundaries and records the safe split direction.
- [Remote Installer Policy](remote-installer-policy.md) defines the allowed
Expand Down
47 changes: 47 additions & 0 deletions docs/copilot-cloud-agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copilot Cloud-Agent Guardrails

Base supports GitHub Copilot cloud-agent work as an optional hosted agent
surface. It does not require Copilot for local development, does not store
personal credentials for agents, and does not replace normal CI or human review.

## Setup Workflow

`.github/workflows/copilot-setup-steps.yml` follows GitHub's special
`copilot-setup-steps` workflow shape. Copilot cloud agent runs the job before
starting work, while GitHub Actions also runs it when the workflow file changes
so the setup can be reviewed like normal CI.

The Base workflow is intentionally small:

- checks out the repository
- installs Python development dependencies from `requirements-dev.txt`
- compiles Python sources and tests
- runs the workflow-policy and bootstrap-doc tests

It does not install Homebrew packages, clone sibling repositories, use personal
tokens, or run Base's full Bats suite. Those checks remain normal CI and review
responsibilities for the pull request.

## Hooks Decision

Base does not add `.github/hooks/*` in this slice. GitHub Copilot hooks can run
custom shell commands at agent lifecycle points, but Base does not yet have a
repository policy for which hook triggers are appropriate, how hook output
should be interpreted, or how hook failures should guide hosted agents.

Until that policy exists, the safer guardrail is the bounded setup workflow plus
the existing repository instructions in `.github/copilot-instructions.md`.

## Verification

For Copilot-created pull requests:

1. Review the draft PR like any other Base PR.
2. Check that normal CI still runs and passes.
3. Look for the `Copilot setup steps` workflow result when the setup workflow
itself changes or when manually testing it from the Actions tab.
4. Confirm the PR body lists the focused local validation the agent ran.

If Copilot cloud-agent setup fails, the agent still starts with the environment
state available at that point. Treat setup failure as a signal to inspect the
PR more carefully, not as a merge decision by itself.
30 changes: 30 additions & 0 deletions tests/test_github_workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
REPO_ROOT = Path(__file__).resolve().parents[1]
WORKFLOW_DIR = REPO_ROOT / ".github" / "workflows"
COPILOT_INSTRUCTIONS = REPO_ROOT / ".github" / "copilot-instructions.md"
COPILOT_SETUP_WORKFLOW = WORKFLOW_DIR / "copilot-setup-steps.yml"
BASE_PROJECT_CONFIG = REPO_ROOT / ".github" / "base-project.yml"
IMPLEMENTATION_ISSUE_TEMPLATE = REPO_ROOT / ".github" / "ISSUE_TEMPLATE" / "implementation.yml"
FULL_COMMIT_SHA_ACTION_REF = re.compile(r"^[^@]+@[0-9a-f]{40}$")
Expand Down Expand Up @@ -258,6 +259,35 @@ def test_copilot_repository_instructions_stay_anchored_to_base_guidance() -> Non
assert "Do not require GitHub Copilot" in text


def test_copilot_setup_steps_are_bounded_to_cloud_agent_setup() -> None:
workflow = load_workflow(COPILOT_SETUP_WORKFLOW)
triggers = workflow.get("on") or workflow.get(True)
jobs = workflow["jobs"]
setup_job = jobs["copilot-setup-steps"]

assert workflow["name"] == "Copilot setup steps"
assert triggers == {
"workflow_dispatch": None,
"push": {"paths": [".github/workflows/copilot-setup-steps.yml"]},
"pull_request": {"paths": [".github/workflows/copilot-setup-steps.yml"]},
}
assert workflow["permissions"] == {"contents": "read"}
assert set(jobs) == {"copilot-setup-steps"}
assert setup_job["runs-on"] == "ubuntu-latest"
assert setup_job["timeout-minutes"] == 15

run_commands = "\n".join(
step.get("run", "")
for step in setup_job["steps"]
if isinstance(step, dict)
)
assert "python -m pip install -r requirements-dev.txt" in run_commands
assert "python -m compileall -q cli/python lib/python tests" in run_commands
assert "python -m pytest tests/test_github_workflows.py tests/test_bootstrap_docs.py -q" in run_commands
assert "BASE_BASH_LIBS_DIR" not in run_commands
assert "secrets." not in run_commands


def test_implementation_issue_template_is_copilot_ready_and_project_aligned() -> None:
template = load_yaml_mapping(IMPLEMENTATION_ISSUE_TEMPLATE)
project_config = load_yaml_mapping(BASE_PROJECT_CONFIG)["project"]
Expand Down
Loading