From 60f6f2c5d91cfb0dc66c78b4f6d93cff69881f31 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:34:44 +0900 Subject: [PATCH 01/36] test(automation): specify organization writer lease --- ..._organization_commercial_readiness_loop.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/test_organization_commercial_readiness_loop.py diff --git a/tests/test_organization_commercial_readiness_loop.py b/tests/test_organization_commercial_readiness_loop.py new file mode 100644 index 000000000..f10aef2af --- /dev/null +++ b/tests/test_organization_commercial_readiness_loop.py @@ -0,0 +1,20 @@ +from __future__ import annotations + +from scripts.ci.organization_commercial_readiness_loop import ( + WorkflowRecord, + is_dedicated_writer_workflow, +) + + +def test_active_scheduled_writer_claims_the_repository_lease() -> None: + """An enabled scheduled product writer excludes the generic coordinator.""" + workflow = WorkflowRecord( + workflow_id=1, + name="Hourly Product Development", + path=".github/workflows/hourly-product-development.yml", + state="active", + content_sha="sha-1", + content='on:\n schedule:\n - cron: "37 * * * *"\n', + ) + + assert is_dedicated_writer_workflow(workflow) From aade0501fa0c91604ab5894661fd3e61e23f7ad0 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:38:41 +0900 Subject: [PATCH 02/36] feat(automation): add lease-aware fleet coordinator --- .../organization_commercial_readiness_loop.py | 790 ++++++++++++++++++ 1 file changed, 790 insertions(+) create mode 100644 scripts/ci/organization_commercial_readiness_loop.py diff --git a/scripts/ci/organization_commercial_readiness_loop.py b/scripts/ci/organization_commercial_readiness_loop.py new file mode 100644 index 000000000..07ab48f8a --- /dev/null +++ b/scripts/ci/organization_commercial_readiness_loop.py @@ -0,0 +1,790 @@ +#!/usr/bin/env python3 +"""Coordinate bounded commercial-readiness work across an organization. + +The coordinator deliberately does not implement code review, branch repair, or +product development itself. It discovers repositories that do not already have +an active writer, revalidates their exact live state immediately before a +mutation, and dispatches at most one central review-repair run and one +repository-local product-development run per invocation. +""" + +from __future__ import annotations + +import argparse +import base64 +import dataclasses +import enum +import hashlib +import json +import os +import re +import subprocess +import sys +from pathlib import Path +from typing import Any, Callable, Iterable, Mapping, Sequence +from urllib.parse import quote + + +ORGANIZATION_RE = re.compile(r"^[A-Za-z0-9_.-]+$") +ENTRYPOINT_MARKER = "# cwl-org-commercial-entrypoint: v1" +CENTRAL_REPOSITORY = "ContextualWisdomLab/.github" +CENTRAL_REPAIR_EVENT = "pr-review-fix-scheduler" +ACTIVE_RUN_STATES = frozenset({"queued", "in_progress", "waiting", "pending", "requested"}) +WRITER_SIGNAL_RE = re.compile( + r"(?:hourly|commercial|product[ _-]*development|autonomous|readiness|" + r"maintenance|review[ _-]*repair|review[ _-]*fix|maintainer|pr[ _-]*disposition)", + re.IGNORECASE, +) +MERGE_SCHEDULER_RE = re.compile( + r"(?:required[ _-]*pr[ _-]*review[ _-]*merge[ _-]*scheduler|" + r"pr-review-merge-scheduler)", + re.IGNORECASE, +) +SCHEDULE_RE = re.compile(r"(?m)^\s*schedule\s*:") +WORKFLOW_DISPATCH_RE = re.compile(r"(?m)^\s*workflow_dispatch\s*:") + + +class GitHubError(RuntimeError): + """Represent a bounded GitHub API or authentication failure.""" + + +class SnapshotChanged(RuntimeError): + """Signal that a repository moved while one snapshot was materialized.""" + + +class ActionKind(str, enum.Enum): + """Supported coordinator mutation classes.""" + + REVIEW_REPAIR = "review_repair" + PRODUCT_DEVELOPMENT = "product_development" + + +@dataclasses.dataclass(frozen=True) +class WorkflowRecord: + """Describe one repository workflow and its exact inspected source.""" + + workflow_id: int + name: str + path: str + state: str + content_sha: str + content: str | None + + +@dataclasses.dataclass(frozen=True) +class RunRecord: + """Describe one workflow run that may hold a live writer lease.""" + + run_id: int + name: str + path: str + status: str + head_sha: str + + +@dataclasses.dataclass(frozen=True) +class PullRequestRecord: + """Describe the exact pull-request fields used by the selection policy.""" + + number: int + draft: bool + base_ref: str + head_sha: str + updated_at: str + + +@dataclasses.dataclass(frozen=True) +class RepositorySnapshot: + """Bind repository selection evidence to one stable default-branch state.""" + + full_name: str + default_branch: str + default_sha: str + workflows: tuple[WorkflowRecord, ...] + active_runs: tuple[RunRecord, ...] + open_pulls: tuple[PullRequestRecord, ...] + + @property + def fingerprint(self) -> str: + """Return a deterministic digest independent of API result ordering.""" + payload = { + "full_name": self.full_name, + "default_branch": self.default_branch, + "default_sha": self.default_sha, + "workflows": sorted( + ( + item.workflow_id, + item.name, + item.path, + item.state, + item.content_sha, + ) + for item in self.workflows + ), + "active_runs": sorted( + (item.run_id, item.name, item.path, item.status, item.head_sha) + for item in self.active_runs + ), + "open_pulls": sorted( + ( + item.number, + item.draft, + item.base_ref, + item.head_sha, + item.updated_at, + ) + for item in self.open_pulls + ), + } + canonical = json.dumps(payload, sort_keys=True, separators=(",", ":")) + return hashlib.sha256(canonical.encode("utf-8")).hexdigest() + + +@dataclasses.dataclass(frozen=True) +class PlanItem: + """Describe one bounded mutation selected from an initial snapshot.""" + + kind: ActionKind + repository: str + default_branch: str + expected_fingerprint: str + workflow_id: int | None = None + + +@dataclasses.dataclass(frozen=True) +class ActionResult: + """Record the outcome of one revalidated coordinator action.""" + + kind: ActionKind + repository: str + status: str + detail: str + + +@dataclasses.dataclass(frozen=True) +class RunReport: + """Provide machine-readable and operator-readable evidence for one run.""" + + organization: str + inspected_repositories: int + leased_repositories: tuple[str, ...] + inspection_errors: tuple[tuple[str, str], ...] + actions: tuple[ActionResult, ...] + dry_run: bool + + def to_dict(self) -> dict[str, Any]: + """Return a JSON-serializable representation of this report.""" + return { + "organization": self.organization, + "inspected_repositories": self.inspected_repositories, + "leased_repositories": list(self.leased_repositories), + "inspection_errors": [ + {"repository": repository, "error": error} + for repository, error in self.inspection_errors + ], + "actions": [ + { + "kind": action.kind.value, + "repository": action.repository, + "status": action.status, + "detail": action.detail, + } + for action in self.actions + ], + "dry_run": self.dry_run, + } + + def to_json(self) -> str: + """Serialize this report as stable UTF-8 JSON text.""" + return json.dumps(self.to_dict(), ensure_ascii=False, indent=2, sort_keys=True) + + def to_markdown(self) -> str: + """Render a concise GitHub Actions job summary.""" + lines = [ + "# Organization commercial-readiness coordinator", + "", + f"- Organization: `{self.organization}`", + f"- Repositories inspected: **{self.inspected_repositories}**", + f"- Repositories leased to dedicated writers: **{len(self.leased_repositories)}**", + f"- Inspection errors: **{len(self.inspection_errors)}**", + f"- Dry run: **{'yes' if self.dry_run else 'no'}**", + "", + "## Actions", + "", + "| Kind | Repository | Status | Detail |", + "|---|---|---|---|", + ] + if self.actions: + for action in self.actions: + detail = action.detail.replace("|", "\\|").replace("\n", " ") + lines.append( + f"| `{action.kind.value}` | `{action.repository}` | " + f"`{action.status}` | {detail} |" + ) + else: + lines.append("| — | — | `no_action` | No safe target was selected. |") + if self.inspection_errors: + lines.extend(["", "## Inspection errors", ""]) + for repository, error in self.inspection_errors: + lines.append(f"- `{repository}`: {error}") + return "\n".join(lines) + "\n" + + +class GitHubClient: + """Use the GitHub CLI as an authenticated, bounded REST transport.""" + + def __init__(self, token: str, *, timeout_seconds: int = 60) -> None: + if not token: + raise GitHubError("GH_TOKEN is required for organization coordination") + self._token = token + self._timeout_seconds = timeout_seconds + + @classmethod + def from_environment(cls, environ: Mapping[str, str] | None = None) -> GitHubClient: + """Build a client without accepting the repository-scoped GITHUB_TOKEN.""" + values = os.environ if environ is None else environ + token = str(values.get("GH_TOKEN") or "").strip() + if not token: + raise GitHubError("GH_TOKEN is required; no GITHUB_TOKEN fallback is permitted") + return cls(token) + + def request( + self, + path: str, + *, + method: str = "GET", + payload: Any = None, + ) -> Any: + """Call one GitHub REST endpoint and decode a bounded JSON response.""" + normalized_method = method.upper() + args = ["gh", "api"] + if normalized_method != "GET": + args.extend(["--method", normalized_method]) + args.append(path) + input_text: str | None = None + if payload is not None: + args.extend(["--input", "-"]) + input_text = json.dumps(payload, separators=(",", ":")) + try: + completed = subprocess.run( + args, + input=input_text, + capture_output=True, + text=True, + timeout=self._timeout_seconds, + env={**os.environ, "GH_TOKEN": self._token}, + check=False, + ) + except (OSError, subprocess.TimeoutExpired) as exc: + raise GitHubError(f"GitHub API transport failed: {type(exc).__name__}") from exc + if completed.returncode != 0: + raw = (completed.stderr or completed.stdout or "GitHub API request failed").strip() + bounded = raw[-900:].replace(self._token, "[REDACTED]") + raise GitHubError(f"GitHub API {normalized_method} {path} failed: {bounded}") + text = completed.stdout.strip() + if not text: + return None + try: + return json.loads(text) + except json.JSONDecodeError as exc: + raise GitHubError(f"GitHub API returned invalid JSON for {path}") from exc + + def list_repositories(self, organization: str) -> list[dict[str, Any]]: + """Return every repository visible to the coordinator installation.""" + repositories: list[dict[str, Any]] = [] + page = 1 + while True: + result = self.request( + f"/orgs/{organization}/repos?type=all&sort=full_name&per_page=100&page={page}" + ) + batch = list(result or []) + repositories.extend(batch) + if len(batch) < 100: + return repositories + page += 1 + + def default_branch_sha(self, repository: str, default_branch: str) -> str: + """Resolve one exact commit for the repository default branch.""" + branch_ref = quote(default_branch, safe="") + result = self.request(f"/repos/{repository}/commits/{branch_ref}") + sha = str((result or {}).get("sha") or "") + if not re.fullmatch(r"[0-9a-fA-F]{40}", sha): + raise GitHubError(f"repository {repository} returned an invalid default-branch SHA") + return sha.lower() + + def list_workflows(self, repository: str, exact_ref: str) -> tuple[WorkflowRecord, ...]: + """Return active and disabled workflow metadata with exact-ref source evidence.""" + workflows: list[WorkflowRecord] = [] + page = 1 + while True: + result = self.request( + f"/repos/{repository}/actions/workflows?per_page=100&page={page}" + ) + batch = list((result or {}).get("workflows") or []) + for raw in batch: + workflow_id = int(raw.get("id") or 0) + path = str(raw.get("path") or "") + name = str(raw.get("name") or path) + state = str(raw.get("state") or "unknown") + content: str | None = None + content_sha = "" + if path and not path.startswith("dynamic/"): + encoded_path = quote(path, safe="/") + try: + source = self.request( + f"/repos/{repository}/contents/{encoded_path}?ref={exact_ref}" + ) + if ( + isinstance(source, dict) + and source.get("type") == "file" + and int(source.get("size") or 0) <= 1_048_576 + and source.get("encoding") == "base64" + ): + decoded = base64.b64decode( + str(source.get("content") or ""), validate=True + ) + content = decoded.decode("utf-8") + content_sha = str(source.get("sha") or "") + except (GitHubError, ValueError, UnicodeDecodeError): + content = None + content_sha = "" + workflows.append( + WorkflowRecord( + workflow_id=workflow_id, + name=name, + path=path, + state=state, + content_sha=content_sha, + content=content, + ) + ) + if len(batch) < 100: + return tuple(workflows) + page += 1 + + def list_active_runs(self, repository: str) -> tuple[RunRecord, ...]: + """Return queued and running workflow evidence for writer lease detection.""" + records: list[RunRecord] = [] + for status in ("queued", "in_progress", "waiting", "pending", "requested"): + result = self.request( + f"/repos/{repository}/actions/runs?status={status}&per_page=100&page=1" + ) + for raw in list((result or {}).get("workflow_runs") or []): + records.append( + RunRecord( + run_id=int(raw.get("id") or 0), + name=str(raw.get("name") or ""), + path=str(raw.get("path") or ""), + status=str(raw.get("status") or status), + head_sha=str(raw.get("head_sha") or ""), + ) + ) + return tuple(records) + + def list_open_pulls(self, repository: str) -> tuple[PullRequestRecord, ...]: + """Return all open pull requests with exact stack and head identity.""" + records: list[PullRequestRecord] = [] + page = 1 + while True: + result = self.request( + f"/repos/{repository}/pulls?state=open&per_page=100&page={page}" + ) + batch = list(result or []) + for raw in batch: + records.append( + PullRequestRecord( + number=int(raw.get("number") or 0), + draft=bool(raw.get("draft")), + base_ref=str((raw.get("base") or {}).get("ref") or ""), + head_sha=str((raw.get("head") or {}).get("sha") or ""), + updated_at=str(raw.get("updated_at") or ""), + ) + ) + if len(batch) < 100: + return tuple(records) + page += 1 + + def snapshot(self, repository: str, default_branch: str) -> RepositorySnapshot: + """Materialize one snapshot and reject concurrent default-branch movement.""" + before = self.default_branch_sha(repository, default_branch) + workflows = self.list_workflows(repository, before) + runs = self.list_active_runs(repository) + pulls = self.list_open_pulls(repository) + after = self.default_branch_sha(repository, default_branch) + if before != after: + raise SnapshotChanged( + f"default branch moved while inspecting {repository}: {before} -> {after}" + ) + return RepositorySnapshot( + full_name=repository, + default_branch=default_branch, + default_sha=before, + workflows=workflows, + active_runs=runs, + open_pulls=pulls, + ) + + def dispatch_review_repair(self, repository: str, base_branch: str) -> None: + """Ask the established central scheduler for one bounded repair attempt.""" + self.request( + f"/repos/{CENTRAL_REPOSITORY}/dispatches", + method="POST", + payload={ + "event_type": CENTRAL_REPAIR_EVENT, + "client_payload": { + "target_repository": repository, + "base_branch": base_branch, + "max_prs": "50", + "max_dispatches": "1", + "retry_hours": "1", + "dry_run": False, + }, + }, + ) + + def dispatch_product_workflow( + self, repository: str, workflow_id: int, default_branch: str + ) -> None: + """Dispatch an explicitly opted-in repository-local development entrypoint.""" + self.request( + f"/repos/{repository}/actions/workflows/{workflow_id}/dispatches", + method="POST", + payload={"ref": default_branch}, + ) + + +def _writer_signal(name: str, path: str) -> bool: + """Return whether workflow identity indicates a repository writer.""" + identity = f"{name}\n{path}" + return bool(WRITER_SIGNAL_RE.search(identity)) and not bool( + MERGE_SCHEDULER_RE.search(identity) + ) + + +def is_dedicated_writer_workflow(workflow: WorkflowRecord) -> bool: + """Return whether an active scheduled workflow owns the repository writer lease.""" + if workflow.state != "active" or not _writer_signal(workflow.name, workflow.path): + return False + if workflow.content is None: + return True + return bool(SCHEDULE_RE.search(workflow.content)) + + +def is_live_writer_run(run: RunRecord) -> bool: + """Return whether a queued or running high-signal workflow owns a live lease.""" + return run.status in ACTIVE_RUN_STATES and _writer_signal(run.name, run.path) + + +def is_manual_product_entrypoint(workflow: WorkflowRecord) -> bool: + """Return whether a workflow explicitly opts in to central product dispatch.""" + source = workflow.content + if workflow.state != "active" or source is None: + return False + return all( + ( + ENTRYPOINT_MARKER in source, + bool(WORKFLOW_DISPATCH_RE.search(source)), + not bool(SCHEDULE_RE.search(source)), + "NVIDIA_NIM_API_KEY" in source, + "COPILOT_GITHUB_TOKEN" not in source, + "concurrency:" in source, + _writer_signal(workflow.name, workflow.path), + ) + ) + + +def repository_is_eligible(repository: Mapping[str, Any], organization: str) -> bool: + """Return whether one owned repository can participate in organization coordination.""" + full_name = str(repository.get("full_name") or "") + permissions = repository.get("permissions") or {} + write_capable = any(bool(permissions.get(key)) for key in ("push", "maintain", "admin")) + return all( + ( + full_name.startswith(f"{organization}/"), + full_name != f"{organization}/.github", + not bool(repository.get("archived")), + not bool(repository.get("disabled")), + not bool(repository.get("fork")), + bool(repository.get("default_branch")), + write_capable, + ) + ) + + +def choose_rotating(items: Sequence[Any], seed: int, limit: int) -> tuple[Any, ...]: + """Choose a bounded cyclic window so later repositories are not starved.""" + if not items or limit <= 0: + return () + count = min(limit, len(items)) + start = seed % len(items) + return tuple(items[(start + offset) % len(items)] for offset in range(count)) + + +def _has_writer_lease(snapshot: RepositorySnapshot) -> bool: + """Return whether static or live evidence assigns this repository elsewhere.""" + return any(is_dedicated_writer_workflow(item) for item in snapshot.workflows) or any( + is_live_writer_run(item) for item in snapshot.active_runs + ) + + +def _eligible_review_snapshot(snapshot: RepositorySnapshot) -> bool: + """Return whether generic review repair is safe for at least one direct PR.""" + return any( + not pull.draft and pull.base_ref == snapshot.default_branch + for pull in snapshot.open_pulls + ) + + +def _manual_product_workflow(snapshot: RepositorySnapshot) -> WorkflowRecord | None: + """Return the first deterministic opted-in manual development entrypoint.""" + matches = sorted( + (item for item in snapshot.workflows if is_manual_product_entrypoint(item)), + key=lambda item: (item.path, item.workflow_id), + ) + return matches[0] if matches else None + + +def build_plan( + snapshots: Iterable[RepositorySnapshot], + *, + rotation_seed: int, + max_review_dispatches: int = 1, + max_development_dispatches: int = 1, +) -> tuple[PlanItem, ...]: + """Select independent bounded review and product targets from exact snapshots.""" + usable = tuple( + sorted( + ( + item + for item in snapshots + if item.full_name != CENTRAL_REPOSITORY and not _has_writer_lease(item) + ), + key=lambda item: item.full_name, + ) + ) + review_candidates = tuple(item for item in usable if _eligible_review_snapshot(item)) + development_candidates = tuple( + (item, workflow) + for item in usable + if not item.open_pulls + for workflow in (_manual_product_workflow(item),) + if workflow is not None + ) + plan: list[PlanItem] = [] + for item in choose_rotating(review_candidates, rotation_seed, max_review_dispatches): + plan.append( + PlanItem( + kind=ActionKind.REVIEW_REPAIR, + repository=item.full_name, + default_branch=item.default_branch, + expected_fingerprint=item.fingerprint, + ) + ) + for item, workflow in choose_rotating( + development_candidates, rotation_seed, max_development_dispatches + ): + plan.append( + PlanItem( + kind=ActionKind.PRODUCT_DEVELOPMENT, + repository=item.full_name, + default_branch=item.default_branch, + expected_fingerprint=item.fingerprint, + workflow_id=workflow.workflow_id, + ) + ) + return tuple(plan) + + +def _bounded_error(exc: BaseException) -> str: + """Return a stable, bounded error description without stack or credential data.""" + text = f"{type(exc).__name__}: {exc}".replace("\n", " ") + return text[:1000] + + +def run_once( + client: Any, + *, + organization: str, + rotation_seed: int, + max_repositories: int = 200, + max_review_dispatches: int = 1, + max_development_dispatches: int = 1, + dry_run: bool = False, +) -> RunReport: + """Inspect the organization, revalidate targets, and dispatch bounded work.""" + raw_repositories = client.list_repositories(organization) + eligible = sorted( + ( + item + for item in raw_repositories + if repository_is_eligible(item, organization) + ), + key=lambda item: str(item.get("full_name") or ""), + ) + selected_repositories = choose_rotating(eligible, rotation_seed, max_repositories) + snapshots: list[RepositorySnapshot] = [] + errors: list[tuple[str, str]] = [] + leased: list[str] = [] + for repository in selected_repositories: + full_name = str(repository["full_name"]) + default_branch = str(repository["default_branch"]) + try: + current = client.snapshot(full_name, default_branch) + except (GitHubError, SnapshotChanged) as exc: + errors.append((full_name, _bounded_error(exc))) + continue + snapshots.append(current) + if _has_writer_lease(current): + leased.append(full_name) + plan = build_plan( + snapshots, + rotation_seed=rotation_seed, + max_review_dispatches=max_review_dispatches, + max_development_dispatches=max_development_dispatches, + ) + actions: list[ActionResult] = [] + for item in plan: + try: + live = client.snapshot(item.repository, item.default_branch) + except (GitHubError, SnapshotChanged) as exc: + actions.append( + ActionResult( + kind=item.kind, + repository=item.repository, + status="skipped_refetch_error", + detail=_bounded_error(exc), + ) + ) + continue + if _has_writer_lease(live): + actions.append( + ActionResult( + kind=item.kind, + repository=item.repository, + status="skipped_writer_lease", + detail="a dedicated or live writer appeared before dispatch", + ) + ) + continue + if live.fingerprint != item.expected_fingerprint: + actions.append( + ActionResult( + kind=item.kind, + repository=item.repository, + status="skipped_state_changed", + detail="repository, workflow, run, or pull-request state moved before dispatch", + ) + ) + continue + if dry_run: + actions.append( + ActionResult( + kind=item.kind, + repository=item.repository, + status="dry_run", + detail="exact state revalidated; mutation intentionally suppressed", + ) + ) + continue + try: + if item.kind is ActionKind.REVIEW_REPAIR: + client.dispatch_review_repair(item.repository, item.default_branch) + else: + if item.workflow_id is None: + raise GitHubError("product-development plan omitted workflow identity") + client.dispatch_product_workflow( + item.repository, item.workflow_id, item.default_branch + ) + except GitHubError as exc: + actions.append( + ActionResult( + kind=item.kind, + repository=item.repository, + status="dispatch_failed", + detail=_bounded_error(exc), + ) + ) + else: + actions.append( + ActionResult( + kind=item.kind, + repository=item.repository, + status="dispatched", + detail="exact state revalidated and bounded workflow dispatched", + ) + ) + return RunReport( + organization=organization, + inspected_repositories=len(snapshots), + leased_repositories=tuple(sorted(leased)), + inspection_errors=tuple(errors), + actions=tuple(actions), + dry_run=dry_run, + ) + + +def _positive_int(value: str) -> int: + """Parse one positive integer command-line bound.""" + parsed = int(value) + if parsed < 0: + raise argparse.ArgumentTypeError("value must be zero or greater") + return parsed + + +def _parser() -> argparse.ArgumentParser: + """Build the command-line parser used by workflow and local dry runs.""" + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--organization", default="ContextualWisdomLab") + parser.add_argument("--rotation-seed", type=int, default=0) + parser.add_argument("--max-repositories", type=_positive_int, default=200) + parser.add_argument("--max-review-dispatches", type=_positive_int, default=1) + parser.add_argument("--max-development-dispatches", type=_positive_int, default=1) + parser.add_argument("--dry-run", action="store_true") + parser.add_argument("--json-output", type=Path) + return parser + + +def main( + argv: Sequence[str] | None = None, + *, + client_factory: Callable[[], Any] | None = None, +) -> int: + """Run the coordinator CLI and persist auditable receipts.""" + parser = _parser() + try: + args = parser.parse_args(argv) + except SystemExit: + return 2 + if not ORGANIZATION_RE.fullmatch(args.organization): + print("invalid organization", file=sys.stderr) + return 2 + factory = client_factory or GitHubClient.from_environment + try: + client = factory() + report = run_once( + client, + organization=args.organization, + rotation_seed=args.rotation_seed, + max_repositories=args.max_repositories, + max_review_dispatches=args.max_review_dispatches, + max_development_dispatches=args.max_development_dispatches, + dry_run=args.dry_run, + ) + except (GitHubError, SnapshotChanged, ValueError) as exc: + print(_bounded_error(exc), file=sys.stderr) + return 2 + text = report.to_json() + "\n" + if args.json_output is not None: + args.json_output.parent.mkdir(parents=True, exist_ok=True) + args.json_output.write_text(text, encoding="utf-8") + else: + sys.stdout.write(text) + summary_path = os.environ.get("GITHUB_STEP_SUMMARY") + if summary_path: + with Path(summary_path).open("a", encoding="utf-8") as handle: + handle.write(report.to_markdown()) + return 0 + + +if __name__ == "__main__": # pragma: no cover - exercised through main() + raise SystemExit(main()) From 9ad66be3c013a8e7977823cadf8258918baa4ed7 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:39:14 +0900 Subject: [PATCH 03/36] ci(automation): schedule bounded organization coordination --- ...organization-commercial-readiness-loop.yml | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 .github/workflows/organization-commercial-readiness-loop.yml diff --git a/.github/workflows/organization-commercial-readiness-loop.yml b/.github/workflows/organization-commercial-readiness-loop.yml new file mode 100644 index 000000000..c277c3e6d --- /dev/null +++ b/.github/workflows/organization-commercial-readiness-loop.yml @@ -0,0 +1,81 @@ +name: Organization Commercial Readiness Loop + +on: + workflow_dispatch: + inputs: + dry_run: + description: Revalidate the fleet and report actions without dispatching work + required: false + default: false + type: boolean + schedule: + - cron: "7 * * * *" + +concurrency: + group: organization-commercial-readiness-loop + cancel-in-progress: false + +permissions: + contents: read + +jobs: + coordinate: + if: >- + github.repository == 'ContextualWisdomLab/.github' && + github.ref == format('refs/heads/{0}', github.event.repository.default_branch) + runs-on: ubuntu-24.04 + timeout-minutes: 25 + env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" + ORGANIZATION: ContextualWisdomLab + GH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN || secrets.OPENCODE_APPROVE_TOKEN }} + ROTATION_SEED: ${{ github.run_number }} + MAX_REPOSITORIES: "200" + MAX_REVIEW_DISPATCHES: "1" + MAX_DEVELOPMENT_DISPATCHES: "1" + DRY_RUN: ${{ inputs.dry_run || false }} + steps: + - name: Harden runner + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.13.2 + with: + egress-policy: block + allowed-endpoints: >- + api.github.com:443 + github.com:443 + objects.githubusercontent.com:443 + release-assets.githubusercontent.com:443 + + - name: Checkout exact trusted coordinator source + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + ref: ${{ github.sha }} + persist-credentials: false + + - name: Set up Python + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: "3.14" + + - name: Coordinate one bounded fleet pass + shell: bash --noprofile --norc -e -o pipefail {0} + run: | + if [ -z "${GH_TOKEN:-}" ]; then + echo "::error::PR_REVIEW_MERGE_TOKEN or OPENCODE_APPROVE_TOKEN is required; the repository-scoped GITHUB_TOKEN is not accepted." + exit 1 + fi + echo "::add-mask::$GH_TOKEN" + test "$(git rev-parse HEAD)" = "${GITHUB_SHA}" + + args=( + --organization "$ORGANIZATION" + --rotation-seed "$ROTATION_SEED" + --max-repositories "$MAX_REPOSITORIES" + --max-review-dispatches "$MAX_REVIEW_DISPATCHES" + --max-development-dispatches "$MAX_DEVELOPMENT_DISPATCHES" + --json-output "$RUNNER_TEMP/organization-commercial-readiness-loop.json" + ) + if [ "$DRY_RUN" = "true" ]; then + args+=(--dry-run) + fi + python scripts/ci/organization_commercial_readiness_loop.py "${args[@]}" + python -m json.tool "$RUNNER_TEMP/organization-commercial-readiness-loop.json" >/dev/null From 970c052a39bd4706ca3d0a483f67a42413ef266b Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:39:38 +0900 Subject: [PATCH 04/36] ci(automation): require exact-head fleet policy coverage --- ...n-commercial-readiness-loop-quality-ci.yml | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 .github/workflows/organization-commercial-readiness-loop-quality-ci.yml diff --git a/.github/workflows/organization-commercial-readiness-loop-quality-ci.yml b/.github/workflows/organization-commercial-readiness-loop-quality-ci.yml new file mode 100644 index 000000000..b460c3987 --- /dev/null +++ b/.github/workflows/organization-commercial-readiness-loop-quality-ci.yml @@ -0,0 +1,71 @@ +name: Organization Commercial Readiness Loop Quality CI + +on: + pull_request: + branches: [main] + paths: + - ".github/workflows/organization-commercial-readiness-loop.yml" + - ".github/workflows/organization-commercial-readiness-loop-quality-ci.yml" + - "scripts/ci/organization_commercial_readiness_loop.py" + - "tests/test_organization_commercial_readiness_loop.py" + - "docs/doctoring/organization-commercial-readiness-loop.md" + - "CHANGELOG.md" + +permissions: + contents: read + +concurrency: + group: organization-commercial-readiness-loop-quality-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + exact-head-policy: + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - name: Checkout exact source revision + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + ref: ${{ github.event.pull_request.head.sha }} + persist-credentials: false + + - name: Set up Python + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: "3.14" + + - name: Install exact hash-verified quality dependencies + env: + PIP_DISABLE_PIP_VERSION_CHECK: "1" + PIP_NO_INPUT: "1" + shell: bash --noprofile --norc -e -o pipefail {0} + run: | + cat >"${RUNNER_TEMP}/organization-loop-quality-requirements.txt" <<'EOF' + coverage==7.15.2 --hash=sha256:b9a6367e4aff723e8ee8190836836124284e8fcd4265e307c844010cfa074f3f + iniconfig==2.1.0 --hash=sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760 + packaging==26.2 --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e + pluggy==1.6.0 --hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 + pygments==2.20.0 --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 + pytest==9.1.1 --hash=sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c + EOF + python -m pip install \ + --only-binary=:all: \ + --require-hashes \ + -r "${RUNNER_TEMP}/organization-loop-quality-requirements.txt" + + - name: Prove exact-head policy and full branch coverage + shell: bash --noprofile --norc -e -o pipefail {0} + run: | + test "$(git rev-parse HEAD)" = "${{ github.event.pull_request.head.sha }}" + python -m coverage run \ + --branch \ + --include='scripts/ci/organization_commercial_readiness_loop.py' \ + -m pytest tests/test_organization_commercial_readiness_loop.py -q + python -m coverage report \ + --include='scripts/ci/organization_commercial_readiness_loop.py' \ + --show-missing \ + --fail-under=100 + python -m compileall -q \ + scripts/ci/organization_commercial_readiness_loop.py \ + tests/test_organization_commercial_readiness_loop.py + git diff --exit-code From 6b2d98b253e704908901b766c5bf4afcd53561d7 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:40:28 +0900 Subject: [PATCH 05/36] docs(automation): record organization lease boundary --- .../organization-commercial-readiness-loop.md | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 docs/doctoring/organization-commercial-readiness-loop.md diff --git a/docs/doctoring/organization-commercial-readiness-loop.md b/docs/doctoring/organization-commercial-readiness-loop.md new file mode 100644 index 000000000..08d3a3823 --- /dev/null +++ b/docs/doctoring/organization-commercial-readiness-loop.md @@ -0,0 +1,61 @@ +# Organization commercial-readiness coordinator + +## Decision + +ContextualWisdomLab uses one organization-central hourly coordinator for repositories that do not already have an enabled dedicated commercial, maintenance, review-repair, or product-development writer. The coordinator complements rather than duplicates the existing 15-minute organization merge scheduler. + +The coordinator may dispatch at most one review-repair workflow and one product-development workflow per hour. These may target different repositories, so review or check latency in one repository does not stop useful work in another. The coordinator never approves, merges, releases, edits source, or interprets a failed check as success by itself. + +## Why this is realistic + +A single workflow cannot safely write every repository merely because it runs in the organization `.github` repository. GitHub's default `GITHUB_TOKEN` is scoped to the repository containing the workflow; cross-repository Actions dispatch therefore requires an explicitly provisioned user or GitHub App credential with the required repository and Actions permissions. This control does not make every repository directly writable. It only considers repositories the live API reports as organization-owned, non-fork, enabled, non-archived, default-branch-bearing, and writable by the authenticated installation. + +The central job therefore refuses a repository-scoped token fallback. It requires `PR_REVIEW_MERGE_TOKEN` or `OPENCODE_APPROVE_TOKEN`, while the coordinator itself receives neither `NVIDIA_NIM_API_KEY` nor `COPILOT_GITHUB_TOKEN`. Model credentials remain inside separately reviewed repository-local or central workers. + +## Dynamic repository-writer lease + +An active workflow with a scheduled high-signal commercial/development/maintenance/review-repair identity owns the repository writer lease. A queued or in-progress run with the same identity also owns a live lease. The organization coordinator skips that repository for the entire pass. + +A disabled workflow does not hold a lease. A manual-only workflow does not hold a lease unless it is already running. If an active high-signal workflow exists but its source cannot be read, the coordinator fails closed and treats the repository as leased. The organization-required merge scheduler is explicitly excluded from this classification because it is a governance gate rather than a product-code writer. + +Before every dispatch, the coordinator refetches the exact default-branch SHA, active workflow identities and source blobs, active runs, and open pull-request heads, bases, draft states, and update timestamps. Any change invalidates the predecessor snapshot. A newly appearing writer causes `skipped_writer_lease`; any other movement causes `skipped_state_changed`. + +## Review-repair boundary + +A repository with at least one non-draft pull request targeting its default branch may receive one `pr-review-fix-scheduler` repository dispatch. Draft and stacked pull requests are not treated as generic repair targets because the coordinator cannot safely infer their dependency order. The established central scheduler and autofix worker remain responsible for thread classification, current-head checks, path bounds, credential isolation, and whether a repair is actually warranted. + +The existing organization merge scheduler continues to own review dispatch, branch updates, exact-head approval evaluation, direct or automatic merge, and branch-protection compliance. The hourly coordinator does not create a second merge implementation. + +## Product-development boundary + +Product development is dispatched only when a repository has zero open pull requests and exposes one active, manual-only, explicitly marked workflow: + +```yaml +# cwl-org-commercial-entrypoint: v1 +on: + workflow_dispatch: +``` + +The entrypoint must contain an explicit `concurrency` contract, use `NVIDIA_NIM_API_KEY`, omit `COPILOT_GITHUB_TOKEN`, have no schedule of its own, and carry a commercial/product-development identity. This opt-in prevents the central coordinator from guessing that an unrelated manual workflow can safely modify product source. Repositories with an existing schedule keep their own lease and are never double-dispatched. + +The repository-local entrypoint remains responsible for its own bounded editable paths, tests, 100% production statement and branch coverage, public docstrings, package and security verification, exact-head publication, and pull-request creation. A missing compliant entrypoint is a deliberate no-op, not permission to inject a generic writer into that repository. + +## Failure and operations + +The schedule runs at minute 7 rather than minute 0 to reduce exposure to the documented start-of-hour GitHub Actions load spike. Scheduled execution occurs only from the default branch. Organization and repository inventories are paginated. One inaccessible repository is recorded as an inspection error while other independently safe repositories continue. + +No queued, pending, skipped-required, cancelled, absent, stale-head, predecessor-head, synthetic-merge-only, or failed check is converted to passing evidence. The coordinator's successful dispatch means only that exact state was revalidated and a bounded downstream workflow was accepted by GitHub. + +Rollback is removal or disabling of `.github/workflows/organization-commercial-readiness-loop.yml`. Repository-local dedicated loops and the existing 15-minute merge scheduler remain independently operational. + +## APA 7 references + +GitHub. (n.d.). *Automatic token authentication*. GitHub Docs. Retrieved August 8, 2026, from https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication + +GitHub. (n.d.). *Events that trigger workflows*. GitHub Docs. Retrieved August 8, 2026, from https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows + +GitHub. (n.d.). *REST API endpoints for workflows*. GitHub Docs. Retrieved August 8, 2026, from https://docs.github.com/en/rest/actions/workflows + +GitHub. (n.d.). *REST API endpoints for workflow runs*. GitHub Docs. Retrieved August 8, 2026, from https://docs.github.com/en/rest/actions/workflow-runs + +National Institute of Standards and Technology. (2022). *Secure software development framework (SSDF) version 1.1: Recommendations for mitigating the risk of software vulnerabilities* (NIST Special Publication 800-218). https://doi.org/10.6028/NIST.SP.800-218 From 869f0a6573b513fe47eb31ee0e69b24e62d5a73e Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:42:44 +0900 Subject: [PATCH 06/36] test(automation): add fleet coordinator fixtures --- ...anization_commercial_readiness_fixtures.py | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 tests/organization_commercial_readiness_fixtures.py diff --git a/tests/organization_commercial_readiness_fixtures.py b/tests/organization_commercial_readiness_fixtures.py new file mode 100644 index 000000000..d86596196 --- /dev/null +++ b/tests/organization_commercial_readiness_fixtures.py @@ -0,0 +1,128 @@ +"""Test fixtures for the organization commercial-readiness coordinator.""" + +from __future__ import annotations + +from typing import Any + +from scripts.ci.organization_commercial_readiness_loop import ( + GitHubError, + PullRequestRecord, + RepositorySnapshot, + RunRecord, + WorkflowRecord, +) + + +def workflow( + *, + workflow_id: int = 1, + name: str = "Hourly Product Development", + path: str = ".github/workflows/hourly-product-development.yml", + state: str = "active", + content: str | None = None, +) -> WorkflowRecord: + """Build one workflow record.""" + return WorkflowRecord(workflow_id, name, path, state, f"sha-{workflow_id}", content) + + +def pull( + number: int, + *, + draft: bool = False, + base_ref: str = "main", + head_sha: str | None = None, + updated_at: str = "2026-08-08T00:00:00Z", +) -> PullRequestRecord: + """Build one pull-request record.""" + return PullRequestRecord( + number, draft, base_ref, head_sha or f"{number:040x}", updated_at + ) + + +def snapshot( + repository: str, + *, + default_branch: str = "main", + default_sha: str = "a" * 40, + workflows: tuple[WorkflowRecord, ...] = (), + runs: tuple[RunRecord, ...] = (), + pulls: tuple[PullRequestRecord, ...] = (), +) -> RepositorySnapshot: + """Build one repository snapshot.""" + return RepositorySnapshot( + repository, default_branch, default_sha, workflows, runs, pulls + ) + + +def repository_payload(name: str) -> dict[str, Any]: + """Return one eligible repository response.""" + return { + "full_name": f"ContextualWisdomLab/{name}", + "default_branch": "main", + "archived": False, + "disabled": False, + "fork": False, + "permissions": {"maintain": True}, + } + + +def manual_workflow(*, workflow_id: int = 9) -> WorkflowRecord: + """Return one safe organization-dispatch product entrypoint.""" + return workflow( + workflow_id=workflow_id, + name="Commercial Product Development", + path=".github/workflows/commercial-product-development.yml", + content=( + "# cwl-org-commercial-entrypoint: v1\n" + "on:\n workflow_dispatch:\n" + "concurrency:\n group: product-development\n" + "permissions:\n contents: write\n" + "NVIDIA_API_KEY: ${{ secrets.NVIDIA_NIM_API_KEY }}\n" + ), + ) + + +class FakeClient: + """Deterministic GitHub boundary.""" + + def __init__( + self, + repositories: list[dict[str, Any]], + snapshots: dict[str, list[RepositorySnapshot | Exception]], + ) -> None: + self.repositories = repositories + self.snapshots = snapshots + self.dispatched_repairs: list[tuple[str, str]] = [] + self.dispatched_products: list[tuple[str, int, str]] = [] + + def list_repositories(self, organization: str) -> list[dict[str, Any]]: + """Return configured repositories.""" + assert organization == "ContextualWisdomLab" + return self.repositories + + def snapshot(self, repository: str, default_branch: str) -> RepositorySnapshot: + """Return or raise the next configured snapshot value.""" + value = self.snapshots[repository].pop(0) + if isinstance(value, Exception): + raise value + assert value.default_branch == default_branch + return value + + def dispatch_review_repair(self, repository: str, base_branch: str) -> None: + """Record one repair dispatch.""" + self.dispatched_repairs.append((repository, base_branch)) + + def dispatch_product_workflow( + self, repository: str, workflow_id: int, default_branch: str + ) -> None: + """Record one product dispatch.""" + self.dispatched_products.append((repository, workflow_id, default_branch)) + + +class FailingDispatchClient(FakeClient): + """Reject review dispatches for failure-path tests.""" + + def dispatch_review_repair(self, repository: str, base_branch: str) -> None: + """Raise a bounded API failure.""" + del repository, base_branch + raise GitHubError("dispatch rejected") From c546484967439f19a591c9d5ef9826d5c6da083a Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:43:12 +0900 Subject: [PATCH 07/36] test(automation): cover lease and workflow policy --- ...zation_commercial_readiness_loop_policy.py | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 tests/test_organization_commercial_readiness_loop_policy.py diff --git a/tests/test_organization_commercial_readiness_loop_policy.py b/tests/test_organization_commercial_readiness_loop_policy.py new file mode 100644 index 000000000..84dab7868 --- /dev/null +++ b/tests/test_organization_commercial_readiness_loop_policy.py @@ -0,0 +1,173 @@ +from __future__ import annotations + +from pathlib import Path +from typing import Any + +from organization_commercial_readiness_fixtures import ( + manual_workflow, + pull, + snapshot, + workflow, +) +from scripts.ci.organization_commercial_readiness_loop import ( + ActionKind, + ActionResult, + RunRecord, + RunReport, + build_plan, + choose_rotating, + is_dedicated_writer_workflow, + is_live_writer_run, + is_manual_product_entrypoint, + repository_is_eligible, +) + +ROOT = Path(__file__).resolve().parents[1] + + +def test_static_and_live_writer_lease_policy() -> None: + """Only active high-signal writers, including unreadable ones, hold leases.""" + scheduled = workflow(content='on:\n schedule:\n - cron: "1 * * * *"\n') + disabled = workflow(state="disabled_manually", content=scheduled.content) + manual = workflow(content="on:\n workflow_dispatch:\n") + merge = workflow( + name="Required PR Review Merge Scheduler", + path=".github/workflows/pr-review-merge-scheduler.yml", + content='on:\n schedule:\n - cron: "*/15 * * * *"\n', + ) + assert is_dedicated_writer_workflow(scheduled) + assert is_dedicated_writer_workflow(workflow(content=None)) + assert not is_dedicated_writer_workflow(disabled) + assert not is_dedicated_writer_workflow(manual) + assert not is_dedicated_writer_workflow(merge) + + active = RunRecord(1, scheduled.name, scheduled.path, "in_progress", "a" * 40) + complete = RunRecord(2, scheduled.name, scheduled.path, "completed", "b" * 40) + assert is_live_writer_run(active) + assert not is_live_writer_run(complete) + + +def test_product_entrypoint_requires_manual_nvidia_opt_in() -> None: + """Product dispatch requires a marked, unscheduled, credential-isolated workflow.""" + safe = manual_workflow() + assert is_manual_product_entrypoint(safe) + assert not is_manual_product_entrypoint(workflow(state="disabled_manually", content="x")) + assert not is_manual_product_entrypoint(workflow(content=None)) + for changed in ( + (safe.content or "") + 'schedule:\n - cron: "1 * * * *"\n', + (safe.content or "") + "COPILOT_GITHUB_TOKEN: forbidden\n", + (safe.content or "").replace("# cwl-org-commercial-entrypoint: v1\n", ""), + (safe.content or "").replace("concurrency:\n", ""), + ): + assert not is_manual_product_entrypoint(workflow(content=changed)) + + +def test_repository_eligibility_is_owned_and_write_capable() -> None: + """Archived, forked, disabled, foreign, central, and read-only repos are excluded.""" + base: dict[str, Any] = { + "full_name": "ContextualWisdomLab/example", + "default_branch": "main", + "archived": False, + "disabled": False, + "fork": False, + "permissions": {"push": True}, + } + assert repository_is_eligible(base, "ContextualWisdomLab") + variants = ( + {**base, "archived": True}, + {**base, "disabled": True}, + {**base, "fork": True}, + {**base, "default_branch": None}, + {**base, "full_name": "Other/example"}, + {**base, "full_name": "ContextualWisdomLab/.github"}, + {**base, "permissions": {"pull": True}}, + ) + assert all(not repository_is_eligible(item, "ContextualWisdomLab") for item in variants) + + +def test_rotation_and_plan_are_bounded_and_dependency_safe() -> None: + """Review and development rotate independently without drafts, stacks, or leases.""" + assert choose_rotating(("a", "b", "c"), 1, 2) == ("b", "c") + assert choose_rotating(("a", "b", "c"), 2, 4) == ("c", "a", "b") + assert choose_rotating((), 1, 1) == () + assert choose_rotating(("a",), 1, 0) == () + + records = ( + snapshot("ContextualWisdomLab/review-a", pulls=(pull(1),)), + snapshot("ContextualWisdomLab/review-b", pulls=(pull(2),)), + snapshot("ContextualWisdomLab/product", workflows=(manual_workflow(),)), + snapshot("ContextualWisdomLab/draft", pulls=(pull(3, draft=True),)), + snapshot("ContextualWisdomLab/stack", pulls=(pull(4, base_ref="feature/base"),)), + snapshot( + "ContextualWisdomLab/leased", + workflows=(workflow(content='on:\n schedule:\n - cron: "1 * * * *"\n'),), + pulls=(pull(5),), + ), + ) + plan = build_plan(records, rotation_seed=1) + assert [(item.kind, item.repository) for item in plan] == [ + (ActionKind.REVIEW_REPAIR, "ContextualWisdomLab/review-b"), + (ActionKind.PRODUCT_DEVELOPMENT, "ContextualWisdomLab/product"), + ] + assert plan[1].workflow_id == 9 + + +def test_snapshot_fingerprint_ignores_api_order_only() -> None: + """Reordered workflow and PR lists retain one exact-state fingerprint.""" + a = snapshot( + "ContextualWisdomLab/example", + workflows=(workflow(workflow_id=2), workflow(workflow_id=1)), + pulls=(pull(2), pull(1)), + ) + b = snapshot( + "ContextualWisdomLab/example", + workflows=(workflow(workflow_id=1), workflow(workflow_id=2)), + pulls=(pull(1), pull(2)), + ) + assert a.fingerprint == b.fingerprint + + +def test_report_formats_actions_empty_state_and_errors() -> None: + """JSON and Markdown receipts preserve bounded action and failure evidence.""" + report = RunReport( + "ContextualWisdomLab", + 1, + ("ContextualWisdomLab/leased",), + (("ContextualWisdomLab/broken", "error|detail\nnext"),), + (ActionResult(ActionKind.REVIEW_REPAIR, "ContextualWisdomLab/a", "dry_run", "a|b"),), + True, + ) + assert '"dry_run": true' in report.to_json() + assert "a\\|b" in report.to_markdown() + empty = RunReport("ContextualWisdomLab", 0, (), (), (), False) + assert "No safe target" in empty.to_markdown() + + +def test_workflow_and_doctoring_contracts() -> None: + """Permanent files retain cadence, token, coverage, and realistic-scope controls.""" + workflow_source = ( + ROOT / ".github/workflows/organization-commercial-readiness-loop.yml" + ).read_text() + quality = ( + ROOT + / ".github/workflows/organization-commercial-readiness-loop-quality-ci.yml" + ).read_text() + doctoring = ( + ROOT / "docs/doctoring/organization-commercial-readiness-loop.md" + ).read_text() + assert 'cron: "7 * * * *"' in workflow_source + assert "cancel-in-progress: false" in workflow_source + assert 'MAX_REVIEW_DISPATCHES: "1"' in workflow_source + assert 'MAX_DEVELOPMENT_DISPATCHES: "1"' in workflow_source + assert "PR_REVIEW_MERGE_TOKEN || secrets.OPENCODE_APPROVE_TOKEN" in workflow_source + assert "|| github.token" not in workflow_source + assert "NVIDIA_NIM_API_KEY" not in workflow_source + assert "COPILOT_GITHUB_TOKEN" not in workflow_source + assert "github.run_number" in workflow_source + assert "persist-credentials: false" in workflow_source + assert "--branch" in quality and "--fail-under=100" in quality + assert "github.event.pull_request.head.sha" in quality + assert "disabled workflow does not hold a lease" in doctoring + assert "manual-only, explicitly marked" in doctoring + assert "does not make every repository directly writable" in doctoring + assert "GITHUB_TOKEN" in doctoring and "APA 7" in doctoring From 25a362dc40aa3c1549c209444379370e77a79c76 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:43:52 +0900 Subject: [PATCH 08/36] test(automation): cover GitHub fleet boundary --- ...zation_commercial_readiness_loop_github.py | 223 ++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 tests/test_organization_commercial_readiness_loop_github.py diff --git a/tests/test_organization_commercial_readiness_loop_github.py b/tests/test_organization_commercial_readiness_loop_github.py new file mode 100644 index 000000000..ccdee2dba --- /dev/null +++ b/tests/test_organization_commercial_readiness_loop_github.py @@ -0,0 +1,223 @@ +from __future__ import annotations + +import base64 +from typing import Any + +import pytest + +from organization_commercial_readiness_fixtures import repository_payload +from scripts.ci.organization_commercial_readiness_loop import ( + GitHubClient, + GitHubError, + SnapshotChanged, +) + + +def test_client_requires_explicit_token_and_decodes_requests( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Organization access never falls back and JSON/empty/error responses stay distinct.""" + with pytest.raises(GitHubError, match="GH_TOKEN"): + GitHubClient("") + with pytest.raises(GitHubError, match="GH_TOKEN"): + GitHubClient.from_environment({}) + assert isinstance(GitHubClient.from_environment({"GH_TOKEN": " token "}), GitHubClient) + monkeypatch.setenv("GH_TOKEN", "live") + assert isinstance(GitHubClient.from_environment(), GitHubClient) + + class Completed: + def __init__(self, code: int, out: str = "", err: str = "") -> None: + self.returncode, self.stdout, self.stderr = code, out, err + + responses = [Completed(0, '{"ok":true}'), Completed(0), Completed(1, err="x" * 2000)] + calls: list[list[str]] = [] + + def fake_run(args: list[str], **kwargs: Any) -> Completed: + calls.append(args) + assert kwargs["env"]["GH_TOKEN"] == "token" + return responses.pop(0) + + monkeypatch.setattr("subprocess.run", fake_run) + client = GitHubClient("token") + assert client.request("/ok") == {"ok": True} + assert client.request("/empty", method="POST", payload={"a": 1}) is None + with pytest.raises(GitHubError) as error: + client.request("/fail") + assert len(str(error.value)) < 1200 + assert calls[1][:4] == ["gh", "api", "--method", "POST"] + + +def test_client_transport_and_invalid_json_fail_closed( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Transport and JSON failures never become empty successful evidence.""" + client = GitHubClient("secret") + monkeypatch.setattr( + "subprocess.run", + lambda *_args, **_kwargs: (_ for _ in ()).throw(OSError("network")), + ) + with pytest.raises(GitHubError, match="transport failed"): + client.request("/transport") + + class Completed: + returncode, stdout, stderr = 0, "not-json", "" + + monkeypatch.setattr("subprocess.run", lambda *_args, **_kwargs: Completed()) + with pytest.raises(GitHubError, match="invalid JSON"): + client.request("/invalid") + + +def test_repository_pagination_and_default_sha_validation( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Fleet discovery spans pages and exact default evidence is mandatory.""" + client = GitHubClient("token") + pages = [ + [repository_payload(f"repo-{index}") for index in range(100)], + [repository_payload("last")], + ] + monkeypatch.setattr(client, "request", lambda _path: pages.pop(0)) + assert len(client.list_repositories("ContextualWisdomLab")) == 101 + monkeypatch.setattr(client, "request", lambda _path: {"sha": "bad"}) + with pytest.raises(GitHubError, match="invalid default-branch SHA"): + client.default_branch_sha("ContextualWisdomLab/example", "release/v1") + + +def test_workflow_source_materialization_and_pagination( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Exact workflow source is decoded while unsafe source shapes remain unreadable.""" + client = GitHubClient("token") + page = [ + { + "id": index + 1, + "name": "Hourly Product Development", + "path": "" if index == 0 else "dynamic/x" if index == 1 else f".github/workflows/{index}.yml", + "state": "active", + } + for index in range(100) + ] + workflow_calls = 0 + + def fake(path: str, *, method: str = "GET", payload: Any = None) -> Any: + nonlocal workflow_calls + del method, payload + if "actions/workflows" in path: + workflow_calls += 1 + return {"workflows": page if workflow_calls == 1 else []} + if "/contents/" in path: + index = int(path.split("/")[-1].split(".")[0]) + if index == 2: + data = b"on:\n workflow_dispatch:\n" + return { + "type": "file", + "size": len(data), + "sha": "good", + "encoding": "base64", + "content": base64.b64encode(data).decode(), + } + if index == 8: + raise GitHubError("forbidden") + variants: list[Any] = [ + None, + {"type": "dir", "size": 0, "encoding": "base64"}, + {"type": "file", "size": 1_048_577, "encoding": "base64"}, + {"type": "file", "size": 1, "encoding": "utf-8"}, + {"type": "file", "size": 1, "encoding": "base64", "content": "%%%"}, + {"type": "file", "size": 1, "encoding": "base64", "content": "/w=="}, + ] + return variants[(index - 3) % len(variants)] + raise AssertionError(path) + + monkeypatch.setattr(client, "request", fake) + records = client.list_workflows("ContextualWisdomLab/example", "a" * 40) + assert len(records) == 100 and workflow_calls == 2 + assert records[2].content_sha == "good" + assert sum(item.content is not None for item in records) == 1 + + +def test_run_and_pull_inventories_cover_live_fields_and_pages( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Live-run and pull inventories preserve exact identity across pages.""" + client = GitHubClient("token") + pull_calls = 0 + + def fake(path: str, *, method: str = "GET", payload: Any = None) -> Any: + nonlocal pull_calls + del method, payload + if "actions/runs" in path: + status = path.split("status=")[1].split("&")[0] + return { + "workflow_runs": [{ + "id": len(status), + "name": "Hourly Product Development", + "path": ".github/workflows/hourly-product-development.yml", + "status": "" if status == "queued" else status, + "head_sha": "a" * 40, + }] + } + if "/pulls?" in path: + pull_calls += 1 + size = 100 if pull_calls == 1 else 1 + return [{ + "number": index + 1, + "draft": False, + "base": {"ref": "main"}, + "head": {"sha": f"{index + 1:040x}"}, + "updated_at": "2026-08-08T00:00:00Z", + } for index in range(size)] + raise AssertionError(path) + + monkeypatch.setattr(client, "request", fake) + runs = client.list_active_runs("ContextualWisdomLab/example") + assert len(runs) == 5 and runs[0].status == "queued" + assert len(client.list_open_pulls("ContextualWisdomLab/example")) == 101 + + +def test_snapshot_movement_and_dispatch_payloads(monkeypatch: pytest.MonkeyPatch) -> None: + """Snapshots reject movement and dispatches retain the reviewed bounded payloads.""" + client = GitHubClient("token") + shas = iter(("a" * 40, "b" * 40)) + monkeypatch.setattr(client, "default_branch_sha", lambda _repo, _branch: next(shas)) + monkeypatch.setattr(client, "list_workflows", lambda _repo, _ref: ()) + monkeypatch.setattr(client, "list_active_runs", lambda _repo: ()) + monkeypatch.setattr(client, "list_open_pulls", lambda _repo: ()) + with pytest.raises(SnapshotChanged): + client.snapshot("ContextualWisdomLab/example", "main") + + calls: list[tuple[str, str, Any]] = [] + + def capture(path: str, *, method: str = "GET", payload: Any = None) -> None: + calls.append((path, method, payload)) + + monkeypatch.setattr(client, "request", capture) + client.dispatch_review_repair("ContextualWisdomLab/example", "develop") + client.dispatch_product_workflow("ContextualWisdomLab/example", 91, "develop") + assert calls[0][2]["client_payload"] == { + "target_repository": "ContextualWisdomLab/example", + "base_branch": "develop", + "max_prs": "50", + "max_dispatches": "1", + "retry_hours": "1", + "dry_run": False, + } + assert calls[1][2] == {"ref": "develop"} + + +def test_complete_snapshot_materialization(monkeypatch: pytest.MonkeyPatch) -> None: + """One stable default head yields workflows, runs, and pull records together.""" + client = GitHubClient("token") + monkeypatch.setattr(client, "default_branch_sha", lambda _repo, _branch: "a" * 40) + monkeypatch.setattr(client, "list_workflows", lambda _repo, _ref: ()) + monkeypatch.setattr(client, "list_active_runs", lambda _repo: ()) + monkeypatch.setattr(client, "list_open_pulls", lambda _repo: ()) + result = client.snapshot("ContextualWisdomLab/example", "main") + assert result.default_sha == "a" * 40 + + +def test_default_branch_sha_normalizes_valid_hex(monkeypatch: pytest.MonkeyPatch) -> None: + """Valid exact branch identity is normalized before fingerprinting.""" + client = GitHubClient("token") + monkeypatch.setattr(client, "request", lambda _path: {"sha": "A" * 40}) + assert client.default_branch_sha("ContextualWisdomLab/example", "main") == "a" * 40 From 255b4b9daef1f8160b5d311506e82a315d70a60e Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:44:23 +0900 Subject: [PATCH 09/36] test(automation): cover fleet coordination outcomes --- ...n_commercial_readiness_loop_coordinator.py | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 tests/test_organization_commercial_readiness_loop_coordinator.py diff --git a/tests/test_organization_commercial_readiness_loop_coordinator.py b/tests/test_organization_commercial_readiness_loop_coordinator.py new file mode 100644 index 000000000..0bd601d26 --- /dev/null +++ b/tests/test_organization_commercial_readiness_loop_coordinator.py @@ -0,0 +1,187 @@ +from __future__ import annotations + +import json +from pathlib import Path + +import pytest + +from organization_commercial_readiness_fixtures import ( + FailingDispatchClient, + FakeClient, + manual_workflow, + pull, + repository_payload, + snapshot, + workflow, +) +from scripts.ci.organization_commercial_readiness_loop import ( + ActionKind, + GitHubError, + PlanItem, + SnapshotChanged, + main, + run_once, +) + + +def test_run_dispatches_one_repair_and_one_independent_product() -> None: + """Unchanged exact state authorizes one bounded action of each class.""" + review = snapshot("ContextualWisdomLab/review", pulls=(pull(1),)) + product = snapshot( + "ContextualWisdomLab/product", workflows=(manual_workflow(workflow_id=17),) + ) + client = FakeClient( + [repository_payload("review"), repository_payload("product")], + {review.full_name: [review, review], product.full_name: [product, product]}, + ) + report = run_once(client, organization="ContextualWisdomLab", rotation_seed=0) + assert client.dispatched_repairs == [(review.full_name, "main")] + assert client.dispatched_products == [(product.full_name, 17, "main")] + assert [action.status for action in report.actions] == ["dispatched", "dispatched"] + assert json.loads(report.to_json())["inspected_repositories"] == 2 + + +def test_drift_new_lease_and_refetch_error_skip_only_the_target() -> None: + """Pre-dispatch movement invalidates selection without reusing old evidence.""" + review = snapshot("ContextualWisdomLab/review", pulls=(pull(1),)) + moved = snapshot( + review.full_name, default_sha="b" * 40, pulls=(pull(1, head_sha="c" * 40),) + ) + product = snapshot("ContextualWisdomLab/product", workflows=(manual_workflow(),)) + newly_leased = snapshot( + product.full_name, + workflows=( + manual_workflow(), + workflow( + workflow_id=8, + content='on:\n schedule:\n - cron: "9 * * * *"\n', + ), + ), + ) + broken = snapshot("ContextualWisdomLab/broken", pulls=(pull(2),)) + client = FakeClient( + [ + repository_payload("review"), + repository_payload("product"), + repository_payload("broken"), + ], + { + review.full_name: [review, moved], + product.full_name: [product, newly_leased], + broken.full_name: [broken, SnapshotChanged("moved")], + }, + ) + report = run_once( + client, + organization="ContextualWisdomLab", + rotation_seed=0, + max_review_dispatches=2, + ) + assert [item.status for item in report.actions] == [ + "skipped_refetch_error", + "skipped_state_changed", + "skipped_writer_lease", + ] + + +def test_initial_errors_leases_and_dry_run_are_reported() -> None: + """An inaccessible repo is contained; initial leases and dry-run stay explicit.""" + leased = snapshot( + "ContextualWisdomLab/leased", + workflows=(workflow(content='on:\n schedule:\n - cron: "7 * * * *"\n'),), + ) + review = snapshot("ContextualWisdomLab/review", pulls=(pull(1),)) + client = FakeClient( + [ + repository_payload("broken"), + repository_payload("leased"), + repository_payload("review"), + ], + { + "ContextualWisdomLab/broken": [GitHubError("forbidden")], + leased.full_name: [leased], + review.full_name: [review, review], + }, + ) + report = run_once( + client, + organization="ContextualWisdomLab", + rotation_seed=0, + dry_run=True, + ) + assert report.inspection_errors == ( + ("ContextualWisdomLab/broken", "GitHubError: forbidden"), + ) + assert report.leased_repositories == (leased.full_name,) + assert report.actions[0].status == "dry_run" + assert not client.dispatched_repairs + + +def test_dispatch_failures_and_invalid_internal_product_plan( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """API rejection and an impossible product plan both fail closed per action.""" + review = snapshot("ContextualWisdomLab/review", pulls=(pull(1),)) + failing = FailingDispatchClient( + [repository_payload("review")], {review.full_name: [review, review]} + ) + assert run_once( + failing, organization="ContextualWisdomLab", rotation_seed=0 + ).actions[0].status == "dispatch_failed" + + product = snapshot("ContextualWisdomLab/product") + invalid = PlanItem( + ActionKind.PRODUCT_DEVELOPMENT, + product.full_name, + "main", + product.fingerprint, + None, + ) + monkeypatch.setattr( + "scripts.ci.organization_commercial_readiness_loop.build_plan", + lambda *_args, **_kwargs: (invalid,), + ) + client = FakeClient( + [repository_payload("product")], {product.full_name: [product, product]} + ) + assert run_once( + client, organization="ContextualWisdomLab", rotation_seed=0 + ).actions[0].status == "dispatch_failed" + + +def test_main_writes_file_summary_stdout_and_failure_paths( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, + capsys: pytest.CaptureFixture[str], +) -> None: + """CLI output and invalid configuration have deterministic exit behavior.""" + review = snapshot("ContextualWisdomLab/review", pulls=(pull(1),)) + client = FakeClient( + [repository_payload("review")], {review.full_name: [review, review]} + ) + output, summary = tmp_path / "report.json", tmp_path / "summary.md" + monkeypatch.setenv("GITHUB_STEP_SUMMARY", str(summary)) + assert main( + ["--rotation-seed", "2", "--json-output", str(output)], + client_factory=lambda: client, + ) == 0 + assert json.loads(output.read_text())["actions"][0]["status"] == "dispatched" + assert "ContextualWisdomLab/review" in summary.read_text() + + empty = FakeClient([], {}) + monkeypatch.delenv("GITHUB_STEP_SUMMARY") + assert main( + ["--max-repositories", "0", "--max-review-dispatches", "0"], + client_factory=lambda: empty, + ) == 0 + assert '"inspected_repositories": 0' in capsys.readouterr().out + + assert main( + ["--organization", "bad organization"], client_factory=lambda: empty + ) == 2 + assert "invalid organization" in capsys.readouterr().err + assert main( + [], client_factory=lambda: (_ for _ in ()).throw(GitHubError("auth")) + ) == 2 + assert "GitHubError: auth" in capsys.readouterr().err + assert main(["--max-repositories", "-1"], client_factory=lambda: empty) == 2 From 8afd0fcc8a28a29a413511eeee2f3f3669fa8d97 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:44:48 +0900 Subject: [PATCH 10/36] ci(automation): cover complete coordinator suite --- .../organization-commercial-readiness-loop-quality-ci.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/organization-commercial-readiness-loop-quality-ci.yml b/.github/workflows/organization-commercial-readiness-loop-quality-ci.yml index b460c3987..2e8d431d2 100644 --- a/.github/workflows/organization-commercial-readiness-loop-quality-ci.yml +++ b/.github/workflows/organization-commercial-readiness-loop-quality-ci.yml @@ -7,7 +7,8 @@ on: - ".github/workflows/organization-commercial-readiness-loop.yml" - ".github/workflows/organization-commercial-readiness-loop-quality-ci.yml" - "scripts/ci/organization_commercial_readiness_loop.py" - - "tests/test_organization_commercial_readiness_loop.py" + - "tests/organization_commercial_readiness_fixtures.py" + - "tests/test_organization_commercial_readiness_loop*.py" - "docs/doctoring/organization-commercial-readiness-loop.md" - "CHANGELOG.md" @@ -60,12 +61,13 @@ jobs: python -m coverage run \ --branch \ --include='scripts/ci/organization_commercial_readiness_loop.py' \ - -m pytest tests/test_organization_commercial_readiness_loop.py -q + -m pytest tests/test_organization_commercial_readiness_loop*.py -q python -m coverage report \ --include='scripts/ci/organization_commercial_readiness_loop.py' \ --show-missing \ --fail-under=100 python -m compileall -q \ scripts/ci/organization_commercial_readiness_loop.py \ - tests/test_organization_commercial_readiness_loop.py + tests/organization_commercial_readiness_fixtures.py \ + tests/test_organization_commercial_readiness_loop*.py git diff --exit-code From 923926abf3bb8d3868d5b194efd2777a4afd8d3c Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:45:40 +0900 Subject: [PATCH 11/36] docs(changelog): record fleet coordinator --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf30091dd..a6a5bf2a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Semantic Versioning where the repository publishes a release. ### Added +- Added an hourly organization commercial-readiness coordinator that discovers writable repositories, honors enabled dedicated writer leases and live writer runs, refetches exact repository/workflow/run/PR state before dispatch, rotates bounded review-repair and opt-in NVIDIA OpenCode product-development targets, and keeps the existing 15-minute merge scheduler authoritative. - Added a trusted pull-request comment router for `@cwl-noema-review` and review-only `@opencode-agent` dispatches, with an organization sweep, exact-head receipts, repository allowlisting, fixed runners, immutable checkout pins, and a permanent 100% statement/branch/docstring quality gate. - Added exact-base `uv.lock` materialization that reconstructs standalone nested projects with a checksum-pinned official `uv` exporter, isolated frozen/offline execution, strict exact-pin and SHA-256 output validation, and complete Python 3.10/3.14 quality evidence. From e6583cfe1c667cf3d7b77d4fe078ba952c135c64 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:51:44 +0900 Subject: [PATCH 12/36] test(automation): make coordinator fixtures import-stable --- organization_commercial_readiness_fixtures.py | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 organization_commercial_readiness_fixtures.py diff --git a/organization_commercial_readiness_fixtures.py b/organization_commercial_readiness_fixtures.py new file mode 100644 index 000000000..d86596196 --- /dev/null +++ b/organization_commercial_readiness_fixtures.py @@ -0,0 +1,128 @@ +"""Test fixtures for the organization commercial-readiness coordinator.""" + +from __future__ import annotations + +from typing import Any + +from scripts.ci.organization_commercial_readiness_loop import ( + GitHubError, + PullRequestRecord, + RepositorySnapshot, + RunRecord, + WorkflowRecord, +) + + +def workflow( + *, + workflow_id: int = 1, + name: str = "Hourly Product Development", + path: str = ".github/workflows/hourly-product-development.yml", + state: str = "active", + content: str | None = None, +) -> WorkflowRecord: + """Build one workflow record.""" + return WorkflowRecord(workflow_id, name, path, state, f"sha-{workflow_id}", content) + + +def pull( + number: int, + *, + draft: bool = False, + base_ref: str = "main", + head_sha: str | None = None, + updated_at: str = "2026-08-08T00:00:00Z", +) -> PullRequestRecord: + """Build one pull-request record.""" + return PullRequestRecord( + number, draft, base_ref, head_sha or f"{number:040x}", updated_at + ) + + +def snapshot( + repository: str, + *, + default_branch: str = "main", + default_sha: str = "a" * 40, + workflows: tuple[WorkflowRecord, ...] = (), + runs: tuple[RunRecord, ...] = (), + pulls: tuple[PullRequestRecord, ...] = (), +) -> RepositorySnapshot: + """Build one repository snapshot.""" + return RepositorySnapshot( + repository, default_branch, default_sha, workflows, runs, pulls + ) + + +def repository_payload(name: str) -> dict[str, Any]: + """Return one eligible repository response.""" + return { + "full_name": f"ContextualWisdomLab/{name}", + "default_branch": "main", + "archived": False, + "disabled": False, + "fork": False, + "permissions": {"maintain": True}, + } + + +def manual_workflow(*, workflow_id: int = 9) -> WorkflowRecord: + """Return one safe organization-dispatch product entrypoint.""" + return workflow( + workflow_id=workflow_id, + name="Commercial Product Development", + path=".github/workflows/commercial-product-development.yml", + content=( + "# cwl-org-commercial-entrypoint: v1\n" + "on:\n workflow_dispatch:\n" + "concurrency:\n group: product-development\n" + "permissions:\n contents: write\n" + "NVIDIA_API_KEY: ${{ secrets.NVIDIA_NIM_API_KEY }}\n" + ), + ) + + +class FakeClient: + """Deterministic GitHub boundary.""" + + def __init__( + self, + repositories: list[dict[str, Any]], + snapshots: dict[str, list[RepositorySnapshot | Exception]], + ) -> None: + self.repositories = repositories + self.snapshots = snapshots + self.dispatched_repairs: list[tuple[str, str]] = [] + self.dispatched_products: list[tuple[str, int, str]] = [] + + def list_repositories(self, organization: str) -> list[dict[str, Any]]: + """Return configured repositories.""" + assert organization == "ContextualWisdomLab" + return self.repositories + + def snapshot(self, repository: str, default_branch: str) -> RepositorySnapshot: + """Return or raise the next configured snapshot value.""" + value = self.snapshots[repository].pop(0) + if isinstance(value, Exception): + raise value + assert value.default_branch == default_branch + return value + + def dispatch_review_repair(self, repository: str, base_branch: str) -> None: + """Record one repair dispatch.""" + self.dispatched_repairs.append((repository, base_branch)) + + def dispatch_product_workflow( + self, repository: str, workflow_id: int, default_branch: str + ) -> None: + """Record one product dispatch.""" + self.dispatched_products.append((repository, workflow_id, default_branch)) + + +class FailingDispatchClient(FakeClient): + """Reject review dispatches for failure-path tests.""" + + def dispatch_review_repair(self, repository: str, base_branch: str) -> None: + """Raise a bounded API failure.""" + del repository, base_branch + raise GitHubError("dispatch rejected") From 1f558bcc08027ba7a1dec2572e65a64fbba55064 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:51:59 +0900 Subject: [PATCH 13/36] test(automation): specify hosted fixture import contract --- ...mmercial_readiness_loop_import_contract.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/test_organization_commercial_readiness_loop_import_contract.py diff --git a/tests/test_organization_commercial_readiness_loop_import_contract.py b/tests/test_organization_commercial_readiness_loop_import_contract.py new file mode 100644 index 000000000..43c3c71ac --- /dev/null +++ b/tests/test_organization_commercial_readiness_loop_import_contract.py @@ -0,0 +1,20 @@ +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[1] +QUALITY_WORKFLOW = ( + REPO_ROOT + / ".github" + / "workflows" + / "organization-commercial-readiness-loop-quality-ci.yml" +) + + +def test_quality_gate_uses_import_stable_test_support() -> None: + """Hosted and complete-suite collection must resolve the same helper module.""" + source = QUALITY_WORKFLOW.read_text(encoding="utf-8") + + assert "--import-mode=importlib" in source + assert '"organization_commercial_readiness_fixtures.py"' in source + assert "tests/organization_commercial_readiness_fixtures.py" not in source + assert "--include='scripts/ci/organization_commercial_readiness_loop.py' \\\n -m pytest" not in source From 552489e82eb6caf2a571b7a9433ac8a6bdcb1159 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:52:19 +0900 Subject: [PATCH 14/36] fix(automation): make hosted coordinator tests import-stable --- .../organization-commercial-readiness-loop-quality-ci.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/organization-commercial-readiness-loop-quality-ci.yml b/.github/workflows/organization-commercial-readiness-loop-quality-ci.yml index 2e8d431d2..50729db47 100644 --- a/.github/workflows/organization-commercial-readiness-loop-quality-ci.yml +++ b/.github/workflows/organization-commercial-readiness-loop-quality-ci.yml @@ -7,7 +7,7 @@ on: - ".github/workflows/organization-commercial-readiness-loop.yml" - ".github/workflows/organization-commercial-readiness-loop-quality-ci.yml" - "scripts/ci/organization_commercial_readiness_loop.py" - - "tests/organization_commercial_readiness_fixtures.py" + - "organization_commercial_readiness_fixtures.py" - "tests/test_organization_commercial_readiness_loop*.py" - "docs/doctoring/organization-commercial-readiness-loop.md" - "CHANGELOG.md" @@ -60,14 +60,13 @@ jobs: test "$(git rev-parse HEAD)" = "${{ github.event.pull_request.head.sha }}" python -m coverage run \ --branch \ - --include='scripts/ci/organization_commercial_readiness_loop.py' \ - -m pytest tests/test_organization_commercial_readiness_loop*.py -q + -m pytest --import-mode=importlib tests/test_organization_commercial_readiness_loop*.py -q python -m coverage report \ --include='scripts/ci/organization_commercial_readiness_loop.py' \ --show-missing \ --fail-under=100 python -m compileall -q \ scripts/ci/organization_commercial_readiness_loop.py \ - tests/organization_commercial_readiness_fixtures.py \ + organization_commercial_readiness_fixtures.py \ tests/test_organization_commercial_readiness_loop*.py git diff --exit-code From 03a9124322c4f80d91eb4ccc4742821fcf11c304 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:52:26 +0900 Subject: [PATCH 15/36] test(automation): remove path-sensitive fixture module --- ...anization_commercial_readiness_fixtures.py | 128 ------------------ 1 file changed, 128 deletions(-) delete mode 100644 tests/organization_commercial_readiness_fixtures.py diff --git a/tests/organization_commercial_readiness_fixtures.py b/tests/organization_commercial_readiness_fixtures.py deleted file mode 100644 index d86596196..000000000 --- a/tests/organization_commercial_readiness_fixtures.py +++ /dev/null @@ -1,128 +0,0 @@ -"""Test fixtures for the organization commercial-readiness coordinator.""" - -from __future__ import annotations - -from typing import Any - -from scripts.ci.organization_commercial_readiness_loop import ( - GitHubError, - PullRequestRecord, - RepositorySnapshot, - RunRecord, - WorkflowRecord, -) - - -def workflow( - *, - workflow_id: int = 1, - name: str = "Hourly Product Development", - path: str = ".github/workflows/hourly-product-development.yml", - state: str = "active", - content: str | None = None, -) -> WorkflowRecord: - """Build one workflow record.""" - return WorkflowRecord(workflow_id, name, path, state, f"sha-{workflow_id}", content) - - -def pull( - number: int, - *, - draft: bool = False, - base_ref: str = "main", - head_sha: str | None = None, - updated_at: str = "2026-08-08T00:00:00Z", -) -> PullRequestRecord: - """Build one pull-request record.""" - return PullRequestRecord( - number, draft, base_ref, head_sha or f"{number:040x}", updated_at - ) - - -def snapshot( - repository: str, - *, - default_branch: str = "main", - default_sha: str = "a" * 40, - workflows: tuple[WorkflowRecord, ...] = (), - runs: tuple[RunRecord, ...] = (), - pulls: tuple[PullRequestRecord, ...] = (), -) -> RepositorySnapshot: - """Build one repository snapshot.""" - return RepositorySnapshot( - repository, default_branch, default_sha, workflows, runs, pulls - ) - - -def repository_payload(name: str) -> dict[str, Any]: - """Return one eligible repository response.""" - return { - "full_name": f"ContextualWisdomLab/{name}", - "default_branch": "main", - "archived": False, - "disabled": False, - "fork": False, - "permissions": {"maintain": True}, - } - - -def manual_workflow(*, workflow_id: int = 9) -> WorkflowRecord: - """Return one safe organization-dispatch product entrypoint.""" - return workflow( - workflow_id=workflow_id, - name="Commercial Product Development", - path=".github/workflows/commercial-product-development.yml", - content=( - "# cwl-org-commercial-entrypoint: v1\n" - "on:\n workflow_dispatch:\n" - "concurrency:\n group: product-development\n" - "permissions:\n contents: write\n" - "NVIDIA_API_KEY: ${{ secrets.NVIDIA_NIM_API_KEY }}\n" - ), - ) - - -class FakeClient: - """Deterministic GitHub boundary.""" - - def __init__( - self, - repositories: list[dict[str, Any]], - snapshots: dict[str, list[RepositorySnapshot | Exception]], - ) -> None: - self.repositories = repositories - self.snapshots = snapshots - self.dispatched_repairs: list[tuple[str, str]] = [] - self.dispatched_products: list[tuple[str, int, str]] = [] - - def list_repositories(self, organization: str) -> list[dict[str, Any]]: - """Return configured repositories.""" - assert organization == "ContextualWisdomLab" - return self.repositories - - def snapshot(self, repository: str, default_branch: str) -> RepositorySnapshot: - """Return or raise the next configured snapshot value.""" - value = self.snapshots[repository].pop(0) - if isinstance(value, Exception): - raise value - assert value.default_branch == default_branch - return value - - def dispatch_review_repair(self, repository: str, base_branch: str) -> None: - """Record one repair dispatch.""" - self.dispatched_repairs.append((repository, base_branch)) - - def dispatch_product_workflow( - self, repository: str, workflow_id: int, default_branch: str - ) -> None: - """Record one product dispatch.""" - self.dispatched_products.append((repository, workflow_id, default_branch)) - - -class FailingDispatchClient(FakeClient): - """Reject review dispatches for failure-path tests.""" - - def dispatch_review_repair(self, repository: str, base_branch: str) -> None: - """Raise a bounded API failure.""" - del repository, base_branch - raise GitHubError("dispatch rejected") From 5867e8a119324732f159e1f94e215f7bffac2f87 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:54:58 +0900 Subject: [PATCH 16/36] test(automation): specify schedule-only credential separation --- ...cial_readiness_loop_credential_contract.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/test_organization_commercial_readiness_loop_credential_contract.py diff --git a/tests/test_organization_commercial_readiness_loop_credential_contract.py b/tests/test_organization_commercial_readiness_loop_credential_contract.py new file mode 100644 index 000000000..ad8ee85d6 --- /dev/null +++ b/tests/test_organization_commercial_readiness_loop_credential_contract.py @@ -0,0 +1,20 @@ +from pathlib import Path + + +WORKFLOW_PATH = ( + Path(__file__).resolve().parents[1] + / ".github" + / "workflows" + / "organization-commercial-readiness-loop.yml" +) + + +def test_central_schedule_has_no_branch_selected_or_reviewer_credential_path() -> None: + """The fleet coordinator must be schedule-only and use maintainer authority.""" + source = WORKFLOW_PATH.read_text(encoding="utf-8") + + assert "workflow_dispatch:" not in source + assert "GH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN }}" in source + assert "OPENCODE_APPROVE_TOKEN" not in source + assert "DRY_RUN" not in source + assert "inputs.dry_run" not in source From a3682b740d8dc1f5f5534636ed7472bd4699602a Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:55:21 +0900 Subject: [PATCH 17/36] fix(automation): keep fleet coordinator schedule-only --- ...organization-commercial-readiness-loop.yml | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/.github/workflows/organization-commercial-readiness-loop.yml b/.github/workflows/organization-commercial-readiness-loop.yml index c277c3e6d..a6a94604f 100644 --- a/.github/workflows/organization-commercial-readiness-loop.yml +++ b/.github/workflows/organization-commercial-readiness-loop.yml @@ -1,13 +1,6 @@ name: Organization Commercial Readiness Loop on: - workflow_dispatch: - inputs: - dry_run: - description: Revalidate the fleet and report actions without dispatching work - required: false - default: false - type: boolean schedule: - cron: "7 * * * *" @@ -28,12 +21,11 @@ jobs: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" ORGANIZATION: ContextualWisdomLab - GH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN || secrets.OPENCODE_APPROVE_TOKEN }} + GH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN }} ROTATION_SEED: ${{ github.run_number }} MAX_REPOSITORIES: "200" MAX_REVIEW_DISPATCHES: "1" MAX_DEVELOPMENT_DISPATCHES: "1" - DRY_RUN: ${{ inputs.dry_run || false }} steps: - name: Harden runner uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.13.2 @@ -60,22 +52,17 @@ jobs: shell: bash --noprofile --norc -e -o pipefail {0} run: | if [ -z "${GH_TOKEN:-}" ]; then - echo "::error::PR_REVIEW_MERGE_TOKEN or OPENCODE_APPROVE_TOKEN is required; the repository-scoped GITHUB_TOKEN is not accepted." + echo "::error::PR_REVIEW_MERGE_TOKEN is required; neither the reviewer credential nor repository-scoped GITHUB_TOKEN is accepted." exit 1 fi echo "::add-mask::$GH_TOKEN" test "$(git rev-parse HEAD)" = "${GITHUB_SHA}" - args=( - --organization "$ORGANIZATION" - --rotation-seed "$ROTATION_SEED" - --max-repositories "$MAX_REPOSITORIES" - --max-review-dispatches "$MAX_REVIEW_DISPATCHES" - --max-development-dispatches "$MAX_DEVELOPMENT_DISPATCHES" + python scripts/ci/organization_commercial_readiness_loop.py \ + --organization "$ORGANIZATION" \ + --rotation-seed "$ROTATION_SEED" \ + --max-repositories "$MAX_REPOSITORIES" \ + --max-review-dispatches "$MAX_REVIEW_DISPATCHES" \ + --max-development-dispatches "$MAX_DEVELOPMENT_DISPATCHES" \ --json-output "$RUNNER_TEMP/organization-commercial-readiness-loop.json" - ) - if [ "$DRY_RUN" = "true" ]; then - args+=(--dry-run) - fi - python scripts/ci/organization_commercial_readiness_loop.py "${args[@]}" python -m json.tool "$RUNNER_TEMP/organization-commercial-readiness-loop.json" >/dev/null From 2b0a74bdcc230789eec032a50dca7d58f36f134f Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:56:48 +0900 Subject: [PATCH 18/36] test(automation): align fleet credential contract --- tests/test_organization_commercial_readiness_loop_policy.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_organization_commercial_readiness_loop_policy.py b/tests/test_organization_commercial_readiness_loop_policy.py index 84dab7868..920f8072f 100644 --- a/tests/test_organization_commercial_readiness_loop_policy.py +++ b/tests/test_organization_commercial_readiness_loop_policy.py @@ -159,13 +159,17 @@ def test_workflow_and_doctoring_contracts() -> None: assert "cancel-in-progress: false" in workflow_source assert 'MAX_REVIEW_DISPATCHES: "1"' in workflow_source assert 'MAX_DEVELOPMENT_DISPATCHES: "1"' in workflow_source - assert "PR_REVIEW_MERGE_TOKEN || secrets.OPENCODE_APPROVE_TOKEN" in workflow_source + assert "GH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN }}" in workflow_source + assert "OPENCODE_APPROVE_TOKEN" not in workflow_source + assert "workflow_dispatch:" not in workflow_source assert "|| github.token" not in workflow_source assert "NVIDIA_NIM_API_KEY" not in workflow_source assert "COPILOT_GITHUB_TOKEN" not in workflow_source assert "github.run_number" in workflow_source assert "persist-credentials: false" in workflow_source assert "--branch" in quality and "--fail-under=100" in quality + assert "--import-mode=importlib" in quality + assert "organization_commercial_readiness_fixtures.py" in quality assert "github.event.pull_request.head.sha" in quality assert "disabled workflow does not hold a lease" in doctoring assert "manual-only, explicitly marked" in doctoring From cdc30199947186c5e72550dcd98fdbaf07d28d0d Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 21:57:22 +0900 Subject: [PATCH 19/36] docs(automation): separate coordinator and reviewer authority --- docs/doctoring/organization-commercial-readiness-loop.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/doctoring/organization-commercial-readiness-loop.md b/docs/doctoring/organization-commercial-readiness-loop.md index 08d3a3823..f7adf0c02 100644 --- a/docs/doctoring/organization-commercial-readiness-loop.md +++ b/docs/doctoring/organization-commercial-readiness-loop.md @@ -10,7 +10,7 @@ The coordinator may dispatch at most one review-repair workflow and one product- A single workflow cannot safely write every repository merely because it runs in the organization `.github` repository. GitHub's default `GITHUB_TOKEN` is scoped to the repository containing the workflow; cross-repository Actions dispatch therefore requires an explicitly provisioned user or GitHub App credential with the required repository and Actions permissions. This control does not make every repository directly writable. It only considers repositories the live API reports as organization-owned, non-fork, enabled, non-archived, default-branch-bearing, and writable by the authenticated installation. -The central job therefore refuses a repository-scoped token fallback. It requires `PR_REVIEW_MERGE_TOKEN` or `OPENCODE_APPROVE_TOKEN`, while the coordinator itself receives neither `NVIDIA_NIM_API_KEY` nor `COPILOT_GITHUB_TOKEN`. Model credentials remain inside separately reviewed repository-local or central workers. +The central job therefore refuses both repository-scoped and reviewer-scoped token fallbacks. It requires the maintainer-scoped `PR_REVIEW_MERGE_TOKEN`; `OPENCODE_APPROVE_TOKEN` remains isolated to the reviewer credential chain and `GITHUB_TOKEN` is not accepted for cross-repository coordination. The coordinator itself receives neither `NVIDIA_NIM_API_KEY` nor `COPILOT_GITHUB_TOKEN`. Model credentials remain inside separately reviewed repository-local or central workers. ## Dynamic repository-writer lease @@ -42,7 +42,9 @@ The repository-local entrypoint remains responsible for its own bounded editable ## Failure and operations -The schedule runs at minute 7 rather than minute 0 to reduce exposure to the documented start-of-hour GitHub Actions load spike. Scheduled execution occurs only from the default branch. Organization and repository inventories are paginated. One inaccessible repository is recorded as an inspection error while other independently safe repositories continue. +The schedule runs at minute 7 rather than minute 0 to reduce exposure to the documented start-of-hour GitHub Actions load spike. The central workflow has no `workflow_dispatch` entrypoint, so branch-selected coordinator source cannot be executed; scheduled execution occurs only from protected default `main`. Local operators may use the script's `--dry-run` mode from a reviewed checkout without adding a central manual workflow entrypoint. + +Organization and repository inventories are paginated. One inaccessible repository is recorded as an inspection error while other independently safe repositories continue. No queued, pending, skipped-required, cancelled, absent, stale-head, predecessor-head, synthetic-merge-only, or failed check is converted to passing evidence. The coordinator's successful dispatch means only that exact state was revalidated and a bounded downstream workflow was accepted by GitHub. From 6647b235d144946ac173aba0bda96851c0fb3549 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:10:15 +0900 Subject: [PATCH 20/36] test(automation): require complete active-writer pagination --- ...ommercial_readiness_loop_run_pagination.py | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tests/test_organization_commercial_readiness_loop_run_pagination.py diff --git a/tests/test_organization_commercial_readiness_loop_run_pagination.py b/tests/test_organization_commercial_readiness_loop_run_pagination.py new file mode 100644 index 000000000..f1aefbce0 --- /dev/null +++ b/tests/test_organization_commercial_readiness_loop_run_pagination.py @@ -0,0 +1,55 @@ +from __future__ import annotations + +from typing import Any + +import pytest + +from scripts.ci.organization_commercial_readiness_loop import GitHubClient + + +def test_active_writer_inventory_paginates_every_status( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """A writer beyond the first 100 active runs must still hold the lease.""" + client = GitHubClient("token") + requested_paths: list[str] = [] + + def fake(path: str, *, method: str = "GET", payload: Any = None) -> Any: + del method, payload + requested_paths.append(path) + status = path.split("status=")[1].split("&")[0] + page = int(path.split("page=")[1]) + if status == "queued" and page == 1: + return { + "workflow_runs": [ + { + "id": index + 1, + "name": "Ordinary CI", + "path": ".github/workflows/ci.yml", + "status": "queued", + "head_sha": "a" * 40, + } + for index in range(100) + ] + } + if status == "queued" and page == 2: + return { + "workflow_runs": [ + { + "id": 101, + "name": "Hourly Product Development", + "path": ".github/workflows/hourly-product-development.yml", + "status": "queued", + "head_sha": "b" * 40, + } + ] + } + return {"workflow_runs": []} + + monkeypatch.setattr(client, "request", fake) + + records = client.list_active_runs("ContextualWisdomLab/example") + + assert len(records) == 101 + assert records[-1].name == "Hourly Product Development" + assert any("status=queued&per_page=100&page=2" in path for path in requested_paths) From a6bbee1f0623a31e595fef73e97e103709c8ab21 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:16:10 +0900 Subject: [PATCH 21/36] fix(automation): paginate complete active writer inventory --- .../organization_commercial_readiness_loop.py | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/scripts/ci/organization_commercial_readiness_loop.py b/scripts/ci/organization_commercial_readiness_loop.py index 07ab48f8a..14300f343 100644 --- a/scripts/ci/organization_commercial_readiness_loop.py +++ b/scripts/ci/organization_commercial_readiness_loop.py @@ -363,22 +363,28 @@ def list_workflows(self, repository: str, exact_ref: str) -> tuple[WorkflowRecor page += 1 def list_active_runs(self, repository: str) -> tuple[RunRecord, ...]: - """Return queued and running workflow evidence for writer lease detection.""" + """Return all queued and running workflow evidence for writer lease detection.""" records: list[RunRecord] = [] for status in ("queued", "in_progress", "waiting", "pending", "requested"): - result = self.request( - f"/repos/{repository}/actions/runs?status={status}&per_page=100&page=1" - ) - for raw in list((result or {}).get("workflow_runs") or []): - records.append( - RunRecord( - run_id=int(raw.get("id") or 0), - name=str(raw.get("name") or ""), - path=str(raw.get("path") or ""), - status=str(raw.get("status") or status), - head_sha=str(raw.get("head_sha") or ""), - ) + page = 1 + while True: + result = self.request( + f"/repos/{repository}/actions/runs?status={status}&per_page=100&page={page}" ) + batch = list((result or {}).get("workflow_runs") or []) + for raw in batch: + records.append( + RunRecord( + run_id=int(raw.get("id") or 0), + name=str(raw.get("name") or ""), + path=str(raw.get("path") or ""), + status=str(raw.get("status") or status), + head_sha=str(raw.get("head_sha") or ""), + ) + ) + if len(batch) < 100: + break + page += 1 return tuple(records) def list_open_pulls(self, repository: str) -> tuple[PullRequestRecord, ...]: From 8713755b1223fb3f88028e2fedac73db050fbe0c Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:16:52 +0900 Subject: [PATCH 22/36] test(automation): require step-scoped maintainer token --- ..._commercial_readiness_loop_secret_scope.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/test_organization_commercial_readiness_loop_secret_scope.py diff --git a/tests/test_organization_commercial_readiness_loop_secret_scope.py b/tests/test_organization_commercial_readiness_loop_secret_scope.py new file mode 100644 index 000000000..b47c2cadc --- /dev/null +++ b/tests/test_organization_commercial_readiness_loop_secret_scope.py @@ -0,0 +1,21 @@ +from pathlib import Path + + +WORKFLOW_PATH = ( + Path(__file__).resolve().parents[1] + / ".github" + / "workflows" + / "organization-commercial-readiness-loop.yml" +) + + +def test_maintainer_token_is_scoped_only_to_the_dispatch_step() -> None: + """Third-party setup actions must never receive the cross-repository token.""" + source = WORKFLOW_PATH.read_text(encoding="utf-8") + before_dispatch, dispatch_step = source.split( + " - name: Coordinate one bounded fleet pass\n", maxsplit=1 + ) + + assert "PR_REVIEW_MERGE_TOKEN" not in before_dispatch + assert "GH_TOKEN:" not in before_dispatch + assert "env:\n GH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN }}" in dispatch_step From 8cb065616ed0381c4e25ed15c4a9e8bd754093e0 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:17:29 +0900 Subject: [PATCH 23/36] fix(automation): scope maintainer token to dispatch step --- .github/workflows/organization-commercial-readiness-loop.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/organization-commercial-readiness-loop.yml b/.github/workflows/organization-commercial-readiness-loop.yml index a6a94604f..42f2b90b6 100644 --- a/.github/workflows/organization-commercial-readiness-loop.yml +++ b/.github/workflows/organization-commercial-readiness-loop.yml @@ -21,7 +21,6 @@ jobs: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" ORGANIZATION: ContextualWisdomLab - GH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN }} ROTATION_SEED: ${{ github.run_number }} MAX_REPOSITORIES: "200" MAX_REVIEW_DISPATCHES: "1" @@ -49,6 +48,8 @@ jobs: python-version: "3.14" - name: Coordinate one bounded fleet pass + env: + GH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN }} shell: bash --noprofile --norc -e -o pipefail {0} run: | if [ -z "${GH_TOKEN:-}" ]; then From acd434b876517a6bbe3d9069de25ada78df70874 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:18:01 +0900 Subject: [PATCH 24/36] test(automation): parse active-run page unambiguously --- ...est_organization_commercial_readiness_loop_run_pagination.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_organization_commercial_readiness_loop_run_pagination.py b/tests/test_organization_commercial_readiness_loop_run_pagination.py index f1aefbce0..fc16ea669 100644 --- a/tests/test_organization_commercial_readiness_loop_run_pagination.py +++ b/tests/test_organization_commercial_readiness_loop_run_pagination.py @@ -18,7 +18,7 @@ def fake(path: str, *, method: str = "GET", payload: Any = None) -> Any: del method, payload requested_paths.append(path) status = path.split("status=")[1].split("&")[0] - page = int(path.split("page=")[1]) + page = int(path.rsplit("page=", maxsplit=1)[1]) if status == "queued" and page == 1: return { "workflow_runs": [ From 50e9ceed3aa44b10966054fc2f6f20375e68957b Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:19:44 +0900 Subject: [PATCH 25/36] test(automation): bind coordinator to CWL control plane --- ...rcial_readiness_loop_organization_scope.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tests/test_organization_commercial_readiness_loop_organization_scope.py diff --git a/tests/test_organization_commercial_readiness_loop_organization_scope.py b/tests/test_organization_commercial_readiness_loop_organization_scope.py new file mode 100644 index 000000000..5b20bfe5e --- /dev/null +++ b/tests/test_organization_commercial_readiness_loop_organization_scope.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +import pytest + +from organization_commercial_readiness_fixtures import FakeClient +from scripts.ci.organization_commercial_readiness_loop import GitHubError, main, run_once + + +def test_runtime_rejects_a_foreign_organization_before_inventory() -> None: + """A variable org must never dispatch through the fixed CWL control plane.""" + client = FakeClient([], {}) + + with pytest.raises(GitHubError, match="ContextualWisdomLab"): + run_once(client, organization="OtherOrganization", rotation_seed=0) + + +def test_cli_rejects_a_well_formed_foreign_organization() -> None: + """A syntactically valid foreign org is still outside this scheduler's scope.""" + client = FakeClient([], {}) + + assert main( + ["--organization", "OtherOrganization"], client_factory=lambda: client + ) == 2 From 006bcd78e1e447f573e88f0e75e2a3d20904ab16 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:23:05 +0900 Subject: [PATCH 26/36] fix(automation): bind coordinator to CWL control plane --- scripts/ci/organization_commercial_readiness_loop.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/ci/organization_commercial_readiness_loop.py b/scripts/ci/organization_commercial_readiness_loop.py index 14300f343..324e1a067 100644 --- a/scripts/ci/organization_commercial_readiness_loop.py +++ b/scripts/ci/organization_commercial_readiness_loop.py @@ -25,9 +25,10 @@ from urllib.parse import quote +DEFAULT_ORGANIZATION = "ContextualWisdomLab" ORGANIZATION_RE = re.compile(r"^[A-Za-z0-9_.-]+$") ENTRYPOINT_MARKER = "# cwl-org-commercial-entrypoint: v1" -CENTRAL_REPOSITORY = "ContextualWisdomLab/.github" +CENTRAL_REPOSITORY = f"{DEFAULT_ORGANIZATION}/.github" CENTRAL_REPAIR_EVENT = "pr-review-fix-scheduler" ACTIVE_RUN_STATES = frozenset({"queued", "in_progress", "waiting", "pending", "requested"}) WRITER_SIGNAL_RE = re.compile( @@ -618,6 +619,10 @@ def run_once( dry_run: bool = False, ) -> RunReport: """Inspect the organization, revalidate targets, and dispatch bounded work.""" + if organization != DEFAULT_ORGANIZATION: + raise GitHubError( + f"organization must be {DEFAULT_ORGANIZATION}; foreign control planes are not supported" + ) raw_repositories = client.list_repositories(organization) eligible = sorted( ( @@ -740,7 +745,7 @@ def _positive_int(value: str) -> int: def _parser() -> argparse.ArgumentParser: """Build the command-line parser used by workflow and local dry runs.""" parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("--organization", default="ContextualWisdomLab") + parser.add_argument("--organization", default=DEFAULT_ORGANIZATION) parser.add_argument("--rotation-seed", type=int, default=0) parser.add_argument("--max-repositories", type=_positive_int, default=200) parser.add_argument("--max-review-dispatches", type=_positive_int, default=1) From e167c554ba3ee671e9fcd8ae0cff829ad231233f Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:24:49 +0900 Subject: [PATCH 27/36] test(automation): retain checkout credential isolation --- ...organization_commercial_readiness_loop_credential_contract.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_organization_commercial_readiness_loop_credential_contract.py b/tests/test_organization_commercial_readiness_loop_credential_contract.py index ad8ee85d6..3225d5832 100644 --- a/tests/test_organization_commercial_readiness_loop_credential_contract.py +++ b/tests/test_organization_commercial_readiness_loop_credential_contract.py @@ -15,6 +15,7 @@ def test_central_schedule_has_no_branch_selected_or_reviewer_credential_path() - assert "workflow_dispatch:" not in source assert "GH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN }}" in source + assert "persist-credentials: false" in source assert "OPENCODE_APPROVE_TOKEN" not in source assert "DRY_RUN" not in source assert "inputs.dry_run" not in source From 9c6f3fe77a91a0a2e4521cd89df3adbd7cc478e3 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:26:18 +0900 Subject: [PATCH 28/36] test(automation): address credential and pagination review --- tests/test_organization_commercial_readiness_loop_github.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_organization_commercial_readiness_loop_github.py b/tests/test_organization_commercial_readiness_loop_github.py index ccdee2dba..aa4bfa576 100644 --- a/tests/test_organization_commercial_readiness_loop_github.py +++ b/tests/test_organization_commercial_readiness_loop_github.py @@ -34,7 +34,7 @@ def __init__(self, code: int, out: str = "", err: str = "") -> None: def fake_run(args: list[str], **kwargs: Any) -> Completed: calls.append(args) - assert kwargs["env"]["GH_TOKEN"] == "token" + assert kwargs["env"]["GH_TOKEN"] == "token" # noqa: S105 return responses.pop(0) monkeypatch.setattr("subprocess.run", fake_run) @@ -148,6 +148,9 @@ def fake(path: str, *, method: str = "GET", payload: Any = None) -> Any: del method, payload if "actions/runs" in path: status = path.split("status=")[1].split("&")[0] + page = int(path.split("&page=")[1].split("&")[0]) + if page > 1: + return {"workflow_runs": []} return { "workflow_runs": [{ "id": len(status), From fb7b847e65058fd473845717080a8c1cb1c65207 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:30:33 +0900 Subject: [PATCH 29/36] test(automation): require fleet-wide failures to fail the job --- ...ial_readiness_loop_operational_failures.py | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/test_organization_commercial_readiness_loop_operational_failures.py diff --git a/tests/test_organization_commercial_readiness_loop_operational_failures.py b/tests/test_organization_commercial_readiness_loop_operational_failures.py new file mode 100644 index 000000000..ae70d088d --- /dev/null +++ b/tests/test_organization_commercial_readiness_loop_operational_failures.py @@ -0,0 +1,39 @@ +from __future__ import annotations + +import pytest + +from organization_commercial_readiness_fixtures import ( + FailingDispatchClient, + FakeClient, + pull, + repository_payload, + snapshot, +) +from scripts.ci.organization_commercial_readiness_loop import GitHubError, main + + +def test_cli_fails_when_every_selected_repository_inspection_fails( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """A fleet-wide inspection outage must make the scheduled job non-green.""" + monkeypatch.delenv("GITHUB_STEP_SUMMARY", raising=False) + client = FakeClient( + [repository_payload("broken")], + {"ContextualWisdomLab/broken": [GitHubError("forbidden")]}, + ) + + assert main([], client_factory=lambda: client) == 1 + + +def test_cli_fails_when_every_planned_dispatch_fails( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """A run that cannot start any selected work must make the job non-green.""" + monkeypatch.delenv("GITHUB_STEP_SUMMARY", raising=False) + review = snapshot("ContextualWisdomLab/review", pulls=(pull(1),)) + client = FailingDispatchClient( + [repository_payload("review")], + {review.full_name: [review, review]}, + ) + + assert main([], client_factory=lambda: client) == 1 From 4b9c4ee1f5073ecf6356c53ce6f39068d9878606 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:30:53 +0900 Subject: [PATCH 30/36] test(automation): bound workflow source API calls --- ...al_readiness_loop_workflow_source_scope.py | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 tests/test_organization_commercial_readiness_loop_workflow_source_scope.py diff --git a/tests/test_organization_commercial_readiness_loop_workflow_source_scope.py b/tests/test_organization_commercial_readiness_loop_workflow_source_scope.py new file mode 100644 index 000000000..2cd3386ad --- /dev/null +++ b/tests/test_organization_commercial_readiness_loop_workflow_source_scope.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +import base64 +from typing import Any + +import pytest + +from scripts.ci.organization_commercial_readiness_loop import GitHubClient + + +def test_workflow_source_fetch_is_limited_to_writer_candidates( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Ordinary CI workflows must not consume one contents request each.""" + client = GitHubClient("token") + content_paths: list[str] = [] + + def fake(path: str, *, method: str = "GET", payload: Any = None) -> Any: + del method, payload + if "actions/workflows" in path: + return { + "workflows": [ + { + "id": 1, + "name": "Ordinary CI", + "path": ".github/workflows/ci.yml", + "state": "active", + }, + { + "id": 2, + "name": "Hourly Product Development", + "path": ".github/workflows/hourly-product-development.yml", + "state": "active", + }, + ] + } + if "/contents/" in path: + content_paths.append(path) + data = b'on:\n schedule:\n - cron: "7 * * * *"\n' + return { + "type": "file", + "size": len(data), + "sha": "source-sha", + "encoding": "base64", + "content": base64.b64encode(data).decode(), + } + raise AssertionError(path) + + monkeypatch.setattr(client, "request", fake) + + records = client.list_workflows("ContextualWisdomLab/example", "a" * 40) + + assert records[0].content is None + assert records[0].content_sha == "" + assert records[1].content is not None + assert len(content_paths) == 1 + assert "hourly-product-development.yml" in content_paths[0] From a09810264a543e829ec48f9740f1c849e2fb9680 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:31:17 +0900 Subject: [PATCH 31/36] test(automation): require durable fleet receipt and strict product opt-in --- ...mercial_readiness_loop_receipt_contract.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 tests/test_organization_commercial_readiness_loop_receipt_contract.py diff --git a/tests/test_organization_commercial_readiness_loop_receipt_contract.py b/tests/test_organization_commercial_readiness_loop_receipt_contract.py new file mode 100644 index 000000000..ce0956bba --- /dev/null +++ b/tests/test_organization_commercial_readiness_loop_receipt_contract.py @@ -0,0 +1,45 @@ +from pathlib import Path + +from organization_commercial_readiness_fixtures import manual_workflow, workflow +from scripts.ci.organization_commercial_readiness_loop import ( + is_manual_product_entrypoint, +) + + +WORKFLOW_PATH = ( + Path(__file__).resolve().parents[1] + / ".github" + / "workflows" + / "organization-commercial-readiness-loop.yml" +) + + +def test_product_entrypoint_rejects_missing_model_key_or_manual_trigger() -> None: + """Both the NVIDIA model boundary and manual opt-in trigger are mandatory.""" + safe = manual_workflow() + without_nvidia = (safe.content or "").replace( + "NVIDIA_NIM_API_KEY", "OTHER_API_KEY" + ) + without_dispatch = (safe.content or "").replace( + "on:\n workflow_dispatch:\n", "on:\n push:\n" + ) + + assert not is_manual_product_entrypoint(workflow(content=without_nvidia)) + assert not is_manual_product_entrypoint(workflow(content=without_dispatch)) + + +def test_json_receipt_is_retained_as_an_immutable_short_lived_artifact() -> None: + """The machine-readable fleet receipt must outlive ephemeral runner storage.""" + source = WORKFLOW_PATH.read_text(encoding="utf-8") + + assert ( + "uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a" + in source + ) + assert "name: organization-commercial-readiness-${{ github.run_id }}-${{ github.run_attempt }}" in source + assert "path: ${{ runner.temp }}/organization-commercial-readiness-loop.json" in source + assert "if-no-files-found: error" in source + assert "retention-days: 3" in source + assert "results-receiver.actions.githubusercontent.com:443" in source + assert "*.actions.githubusercontent.com:443" in source + assert "*.blob.core.windows.net:443" in source From 55f0b7373ab11d71a18cb6ed780c388908296697 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:34:11 +0900 Subject: [PATCH 32/36] fix(automation): retain bounded fleet receipts --- .../organization-commercial-readiness-loop.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/organization-commercial-readiness-loop.yml b/.github/workflows/organization-commercial-readiness-loop.yml index 42f2b90b6..521495617 100644 --- a/.github/workflows/organization-commercial-readiness-loop.yml +++ b/.github/workflows/organization-commercial-readiness-loop.yml @@ -35,6 +35,9 @@ jobs: github.com:443 objects.githubusercontent.com:443 release-assets.githubusercontent.com:443 + results-receiver.actions.githubusercontent.com:443 + *.actions.githubusercontent.com:443 + *.blob.core.windows.net:443 - name: Checkout exact trusted coordinator source uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -67,3 +70,12 @@ jobs: --max-development-dispatches "$MAX_DEVELOPMENT_DISPATCHES" \ --json-output "$RUNNER_TEMP/organization-commercial-readiness-loop.json" python -m json.tool "$RUNNER_TEMP/organization-commercial-readiness-loop.json" >/dev/null + + - name: Preserve the exact fleet receipt + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: organization-commercial-readiness-${{ github.run_id }}-${{ github.run_attempt }} + path: ${{ runner.temp }}/organization-commercial-readiness-loop.json + if-no-files-found: error + retention-days: 3 From 83f93318dbf3f302ab1321e813d6117326164ad7 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:37:36 +0900 Subject: [PATCH 33/36] fix(automation): fail closed on fleet-wide outages --- .../organization_commercial_readiness_loop.py | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/scripts/ci/organization_commercial_readiness_loop.py b/scripts/ci/organization_commercial_readiness_loop.py index 324e1a067..14eeffeab 100644 --- a/scripts/ci/organization_commercial_readiness_loop.py +++ b/scripts/ci/organization_commercial_readiness_loop.py @@ -314,7 +314,7 @@ def default_branch_sha(self, repository: str, default_branch: str) -> str: return sha.lower() def list_workflows(self, repository: str, exact_ref: str) -> tuple[WorkflowRecord, ...]: - """Return active and disabled workflow metadata with exact-ref source evidence.""" + """Return workflow metadata and exact source only for writer candidates.""" workflows: list[WorkflowRecord] = [] page = 1 while True: @@ -329,7 +329,11 @@ def list_workflows(self, repository: str, exact_ref: str) -> tuple[WorkflowRecor state = str(raw.get("state") or "unknown") content: str | None = None content_sha = "" - if path and not path.startswith("dynamic/"): + if ( + path + and not path.startswith("dynamic/") + and _writer_signal(name, path) + ): encoded_path = quote(path, safe="/") try: source = self.request( @@ -734,8 +738,8 @@ def run_once( ) -def _positive_int(value: str) -> int: - """Parse one positive integer command-line bound.""" +def _non_negative_int(value: str) -> int: + """Parse one non-negative integer command-line bound.""" parsed = int(value) if parsed < 0: raise argparse.ArgumentTypeError("value must be zero or greater") @@ -747,9 +751,9 @@ def _parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--organization", default=DEFAULT_ORGANIZATION) parser.add_argument("--rotation-seed", type=int, default=0) - parser.add_argument("--max-repositories", type=_positive_int, default=200) - parser.add_argument("--max-review-dispatches", type=_positive_int, default=1) - parser.add_argument("--max-development-dispatches", type=_positive_int, default=1) + parser.add_argument("--max-repositories", type=_non_negative_int, default=200) + parser.add_argument("--max-review-dispatches", type=_non_negative_int, default=1) + parser.add_argument("--max-development-dispatches", type=_non_negative_int, default=1) parser.add_argument("--dry-run", action="store_true") parser.add_argument("--json-output", type=Path) return parser @@ -794,7 +798,13 @@ def main( if summary_path: with Path(summary_path).open("a", encoding="utf-8") as handle: handle.write(report.to_markdown()) - return 0 + all_selected_inspections_failed = ( + report.inspected_repositories == 0 and bool(report.inspection_errors) + ) + all_planned_dispatches_failed = bool(report.actions) and all( + action.status == "dispatch_failed" for action in report.actions + ) + return 1 if all_selected_inspections_failed or all_planned_dispatches_failed else 0 if __name__ == "__main__": # pragma: no cover - exercised through main() From 77708c9138e5523d8d98d3e300cce9e06b7fb8d0 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:38:01 +0900 Subject: [PATCH 34/36] test(automation): remove duplicated lease assertion --- ..._organization_commercial_readiness_loop.py | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 tests/test_organization_commercial_readiness_loop.py diff --git a/tests/test_organization_commercial_readiness_loop.py b/tests/test_organization_commercial_readiness_loop.py deleted file mode 100644 index f10aef2af..000000000 --- a/tests/test_organization_commercial_readiness_loop.py +++ /dev/null @@ -1,20 +0,0 @@ -from __future__ import annotations - -from scripts.ci.organization_commercial_readiness_loop import ( - WorkflowRecord, - is_dedicated_writer_workflow, -) - - -def test_active_scheduled_writer_claims_the_repository_lease() -> None: - """An enabled scheduled product writer excludes the generic coordinator.""" - workflow = WorkflowRecord( - workflow_id=1, - name="Hourly Product Development", - path=".github/workflows/hourly-product-development.yml", - state="active", - content_sha="sha-1", - content='on:\n schedule:\n - cron: "37 * * * *"\n', - ) - - assert is_dedicated_writer_workflow(workflow) From 002723b6ef2a9b0bf4e94690842a96c4a8eeb554 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:39:06 +0900 Subject: [PATCH 35/36] docs(automation): record fail-closed fleet operations --- .../organization-commercial-readiness-loop.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/doctoring/organization-commercial-readiness-loop.md b/docs/doctoring/organization-commercial-readiness-loop.md index f7adf0c02..76ef1fce5 100644 --- a/docs/doctoring/organization-commercial-readiness-loop.md +++ b/docs/doctoring/organization-commercial-readiness-loop.md @@ -10,14 +10,16 @@ The coordinator may dispatch at most one review-repair workflow and one product- A single workflow cannot safely write every repository merely because it runs in the organization `.github` repository. GitHub's default `GITHUB_TOKEN` is scoped to the repository containing the workflow; cross-repository Actions dispatch therefore requires an explicitly provisioned user or GitHub App credential with the required repository and Actions permissions. This control does not make every repository directly writable. It only considers repositories the live API reports as organization-owned, non-fork, enabled, non-archived, default-branch-bearing, and writable by the authenticated installation. -The central job therefore refuses both repository-scoped and reviewer-scoped token fallbacks. It requires the maintainer-scoped `PR_REVIEW_MERGE_TOKEN`; `OPENCODE_APPROVE_TOKEN` remains isolated to the reviewer credential chain and `GITHUB_TOKEN` is not accepted for cross-repository coordination. The coordinator itself receives neither `NVIDIA_NIM_API_KEY` nor `COPILOT_GITHUB_TOKEN`. Model credentials remain inside separately reviewed repository-local or central workers. +The central job therefore refuses both repository-scoped and reviewer-scoped token fallbacks. It requires the maintainer-scoped `PR_REVIEW_MERGE_TOKEN`; `OPENCODE_APPROVE_TOKEN` remains isolated to the reviewer credential chain and `GITHUB_TOKEN` is not accepted for cross-repository coordination. The maintainer token is exposed only to the final dispatch shell step, not checkout, setup, artifact upload, or other third-party actions. The coordinator itself receives neither `NVIDIA_NIM_API_KEY` nor `COPILOT_GITHUB_TOKEN`. Model credentials remain inside separately reviewed repository-local or central workers. ## Dynamic repository-writer lease -An active workflow with a scheduled high-signal commercial/development/maintenance/review-repair identity owns the repository writer lease. A queued or in-progress run with the same identity also owns a live lease. The organization coordinator skips that repository for the entire pass. +An active workflow with a scheduled high-signal commercial/development/maintenance/review-repair identity owns the repository writer lease. A queued, in-progress, waiting, pending, or requested run with the same identity also owns a live lease. The organization coordinator skips that repository for the entire pass. A disabled workflow does not hold a lease. A manual-only workflow does not hold a lease unless it is already running. If an active high-signal workflow exists but its source cannot be read, the coordinator fails closed and treats the repository as leased. The organization-required merge scheduler is explicitly excluded from this classification because it is a governance gate rather than a product-code writer. +The coordinator lists workflow metadata for every repository but fetches exact workflow source only for identities that can plausibly be a repository writer. This keeps API use proportional to writer candidates rather than every ordinary CI, packaging, or security workflow. Active-run and pull-request inventories remain fully paginated, including writers beyond the first 100 queued or running executions. + Before every dispatch, the coordinator refetches the exact default-branch SHA, active workflow identities and source blobs, active runs, and open pull-request heads, bases, draft states, and update timestamps. Any change invalidates the predecessor snapshot. A newly appearing writer causes `skipped_writer_lease`; any other movement causes `skipped_state_changed`. ## Review-repair boundary @@ -40,11 +42,13 @@ The entrypoint must contain an explicit `concurrency` contract, use `NVIDIA_NIM_ The repository-local entrypoint remains responsible for its own bounded editable paths, tests, 100% production statement and branch coverage, public docstrings, package and security verification, exact-head publication, and pull-request creation. A missing compliant entrypoint is a deliberate no-op, not permission to inject a generic writer into that repository. -## Failure and operations +## Failure, evidence, and operations The schedule runs at minute 7 rather than minute 0 to reduce exposure to the documented start-of-hour GitHub Actions load spike. The central workflow has no `workflow_dispatch` entrypoint, so branch-selected coordinator source cannot be executed; scheduled execution occurs only from protected default `main`. Local operators may use the script's `--dry-run` mode from a reviewed checkout without adding a central manual workflow entrypoint. -Organization and repository inventories are paginated. One inaccessible repository is recorded as an inspection error while other independently safe repositories continue. +Organization, workflow, active-run, and pull-request inventories are paginated. One inaccessible repository is recorded as an inspection error while other independently safe repositories continue. A run fails nonzero when every selected repository inspection fails or when every planned dispatch fails; partial, independently contained failures remain visible without discarding successful work. + +Each run writes one deterministic JSON receipt and the same bounded evidence to the GitHub Actions job summary. The JSON is uploaded through the immutable, SHA-pinned artifact action with a three-day retention period. Artifact upload receives no maintainer or model credential. The receipt proves only coordinator observations and downstream dispatch acceptance; it is not merge, release, or product-quality evidence. No queued, pending, skipped-required, cancelled, absent, stale-head, predecessor-head, synthetic-merge-only, or failed check is converted to passing evidence. The coordinator's successful dispatch means only that exact state was revalidated and a bounded downstream workflow was accepted by GitHub. @@ -56,6 +60,8 @@ GitHub. (n.d.). *Automatic token authentication*. GitHub Docs. Retrieved August GitHub. (n.d.). *Events that trigger workflows*. GitHub Docs. Retrieved August 8, 2026, from https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows +GitHub. (n.d.). *REST API endpoints for artifacts*. GitHub Docs. Retrieved August 8, 2026, from https://docs.github.com/en/rest/actions/artifacts + GitHub. (n.d.). *REST API endpoints for workflows*. GitHub Docs. Retrieved August 8, 2026, from https://docs.github.com/en/rest/actions/workflows GitHub. (n.d.). *REST API endpoints for workflow runs*. GitHub Docs. Retrieved August 8, 2026, from https://docs.github.com/en/rest/actions/workflow-runs From 9f46ea9dd067d2b30a042710ab0ce022513b13f6 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 8 Aug 2026 22:39:45 +0900 Subject: [PATCH 36/36] docs(changelog): record durable fleet operations --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6a5bf2a9..32af94836 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ Semantic Versioning where the repository publishes a release. ### Added -- Added an hourly organization commercial-readiness coordinator that discovers writable repositories, honors enabled dedicated writer leases and live writer runs, refetches exact repository/workflow/run/PR state before dispatch, rotates bounded review-repair and opt-in NVIDIA OpenCode product-development targets, and keeps the existing 15-minute merge scheduler authoritative. +- Added an hourly organization commercial-readiness coordinator that discovers writable repositories, honors enabled dedicated writer leases and fully paginated live writer runs, refetches exact repository/workflow/run/PR state before dispatch, rotates bounded review-repair and opt-in NVIDIA OpenCode product-development targets, fails nonzero on fleet-wide inspection or dispatch outages, retains three-day JSON receipts, and keeps the existing 15-minute merge scheduler authoritative. - Added a trusted pull-request comment router for `@cwl-noema-review` and review-only `@opencode-agent` dispatches, with an organization sweep, exact-head receipts, repository allowlisting, fixed runners, immutable checkout pins, and a permanent 100% statement/branch/docstring quality gate. - Added exact-base `uv.lock` materialization that reconstructs standalone nested projects with a checksum-pinned official `uv` exporter, isolated frozen/offline execution, strict exact-pin and SHA-256 output validation, and complete Python 3.10/3.14 quality evidence.