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
29 changes: 29 additions & 0 deletions .github/workflows/agent-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Agent checks
on:
pull_request:
branches: [agents, main]
push:
branches: [agents]
permissions:
contents: read
concurrency:
group: agent-checks-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
core:
name: Windows core
runs-on: windows-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
with:
persist-credentials: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: '3.12'
- name: Validate syntax
run: python -m compileall -q scripts experiments/command_specialist
- name: Path binding and saved evidence invariants
run: python -m unittest discover -s experiments/command_specialist -p test_bindings.py -v
- name: Native and PowerShell contract invariants
run: python -m unittest discover -s experiments/command_specialist -p test_contract.py -v
64 changes: 64 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Agents and main

`agents` is the development integration branch. `main` is the stable installation
branch. Jon authorized agents-branch automation on September 10, 2026: agents may
prepare owned changes, verify them, open ready PRs against `agents`, and merge them
when the gates below pass. This replaces per-PR human merge requests for `agents`.
Merging into `main`, publication, deployments, model/weight changes, and production
data changes still require explicit approval for the concrete batch.

Start from fetched `agents` in an owned worktree. Preserve other sessions and reuse
existing PRs for the same work. Run commands from the repository root with Python
3.12. Required checks are:

```
python -m compileall -q scripts experiments/command_specialist
python -m unittest discover -s experiments/command_specialist -p test_bindings.py -v
python -m unittest discover -s experiments/command_specialist -p test_contract.py -v
```

Also verify the affected user operation through the public CLI and reopen its saved
artifact. Hosted CI has no private model, GPU, or transcripts; it supplements local
product verification. Do not run live model benchmarks concurrently or change the
shared Ollama service. Retain `shell-specialist-pilot` and its existing adapter.

`.github/workflows/agent-checks.yml` runs the required `Windows core` check on PRs
into both branches and pushes to `agents`. It runs on a hosted Windows runner with
read-only permissions and no persisted checkout credentials. PR code never receives
a privileged merge token. `agents` requires this GitHub Actions check and an up-to-date PR, prevents force
pushes/deletion, and applies protection to administrators. No approving review is
required for `agents`. Main protection is pending Jon's choice of GitHub review
enforcement versus explicit chat approval; do not claim it is server-enforced.

The local coordinator is `scripts/integrate_agents.py`. After reviewing the diff,
verifying the current head locally, and waiting for CI, run:

```
python scripts/integrate_agents.py --pr <number> --verified-head <verified-head>
```

It accepts only ready same-repository PRs authored by Noisemaker111 targeting
`agents`; checks the exact head, workflow identity/result, and mergeability; and
merges with GitHub's expected-head condition. It refuses `main`. `--check-only`
checks eligibility without merging. Invoke it from a trusted checkout; passing a
head is the agent's attestation of actual local verification, not proof supplied
by CI. This is agent-operated automation, not an installed unattended scheduler.
The agent continues through merge and merged-revision verification without asking
Jon for routine agents integration approval.

This repository is a local skill/CLI, with no hosted frontend, backend, database,
queue, production service, or deployment trigger configured here. Dev validation
runs the merged `agents` revision from an isolated worktree with fresh fixtures and
ignored `work/` artifacts. Stable users continue to install `main`; existing local
installations and sessions are not repointed. No automatic host integration is
claimed. Source revision, loaded CLI source, and saved artifact must agree when
reporting dev verification.

For stable promotion, branch a frozen release candidate from a verified agents
revision and open a ready PR into `main`. Include the full diff, user-facing notes,
verification evidence, and rollback target (the prior main revision). Later agents
changes must not join that candidate silently. Ask Jon to approve that concrete
batch before merging. The agents GitHub PR/check gates are enforced, but this account is shared
by Jon and agents: human authorization is a workflow rule, not an independently
verified GitHub reviewer identity. The coordinator cannot merge stable. No package
or runtime deployment is implied by either merge.
69 changes: 69 additions & 0 deletions scripts/integrate_agents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"""Integrate a locally verified, CI-green owner PR into agents; never main.

Run from a trusted agents checkout after inspecting the diff and completing the
real user-operation check. No PR code is downloaded or executed by this tool.
"""
import argparse
import json
import re
import subprocess

REPO = "Noisemaker111/shell-forensics"
OWNER = "Noisemaker111"


def gh(*args):
result = subprocess.run(["gh", *args], check=True, capture_output=True, text=True, encoding="utf-8", timeout=60)
return json.loads(result.stdout) if result.stdout.strip() else None


def eligible(pr, verified_head):
if pr["baseRefName"] != "agents":
raise ValueError("Only agents PRs may be integrated; main needs Jon's explicit batch approval")
if pr["state"] != "OPEN" or pr["isDraft"] or pr["isCrossRepository"] or pr["author"]["login"].lower() != OWNER.lower():
raise ValueError("Require an open, ready, same-repository owner PR")
if pr["headRefOid"] != verified_head:
raise ValueError("Head changed or was not locally verified; recheck the actual user operation")
if pr["mergeable"] != "MERGEABLE" or pr["mergeStateStatus"] != "CLEAN":
raise ValueError("PR must be up to date, mergeable, and pass branch protection")
checks = pr["statusCheckRollup"]
core = [c for c in checks if c.get("name") == "Windows core"]
if not core or any(c.get("status") != "COMPLETED" or c.get("conclusion") != "SUCCESS" for c in core):
raise ValueError("Windows core is missing, pending, or unsuccessful")
if any(c.get("conclusion") not in ("SUCCESS", "NEUTRAL", "SKIPPED") or c.get("status") != "COMPLETED" for c in checks):
raise ValueError("A check is incomplete or unsuccessful")
return core


def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--pr", type=int, required=True)
parser.add_argument("--verified-head", required=True, help="Exact head already reviewed and verified through the product")
parser.add_argument("--check-only", action="store_true")
args = parser.parse_args()
fields = "state,isDraft,isCrossRepository,author,baseRefName,headRefOid,mergeable,mergeStateStatus,statusCheckRollup"
pr = gh("pr", "view", str(args.pr), "--repo", REPO, "--json", fields)
checks = eligible(pr, args.verified_head)
for check in checks:
match = re.fullmatch(r"https://github\.com/Noisemaker111/shell-forensics/actions/runs/(\d+)/job/\d+", check.get("detailsUrl", ""))
if not match:
raise ValueError("Required check is not the repository Actions job")
run = gh("api", f"repos/{REPO}/actions/runs/{match[1]}")
if (run["path"] != ".github/workflows/agent-checks.yml" or run["event"] != "pull_request"
or run["head_sha"] != args.verified_head or run["conclusion"] != "success"):
raise ValueError("Required workflow does not validate this PR head")
# Server-side strict checks and the expected-head condition close update races.
latest = gh("pr", "view", str(args.pr), "--repo", REPO, "--json", fields)
eligible(latest, args.verified_head)
if args.check_only:
print(json.dumps({"eligible": True, "pr": args.pr, "base": "agents"}))
return
subprocess.run(["gh", "pr", "merge", str(args.pr), "--repo", REPO, "--squash", "--match-head-commit", args.verified_head], check=True, timeout=60)
receipt = gh("pr", "view", str(args.pr), "--repo", REPO, "--json", "state,baseRefName,mergeCommit,url")
if receipt["state"] != "MERGED" or receipt["baseRefName"] != "agents":
raise RuntimeError("Merge receipt did not confirm agents integration")
print(json.dumps(receipt))


if __name__ == "__main__":
main()
Loading