From 6dded682be171ba9be52f5f89270feb9ef5ae60c Mon Sep 17 00:00:00 2001 From: Tom Softreck Date: Thu, 6 Aug 2026 18:06:20 +0200 Subject: [PATCH 1/5] docs(ticket-049): autonomy audit, operator guide and follow-up tickets Record why GOV-APPROVAL autonomy failed for todo2code (variables without scan-direct matrix), ship the operator guide and ordered refactor plan, and scaffold tickets 050-052 for unowned root paths, CI wiring of github-event-log, and AGENTS.md checklist promotion. All remain PLAN / WAIT_FOR_APPROVAL. --- TODO.md | 17 +- project/TICKETS.md | 5 + .../ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md | 222 ++++++++++++++++++ project/ticket-049/OPERATOR_GUIDE.md | 72 ++++++ project/ticket-049/README.md | 87 +++++++ project/ticket-049/ai-grok-logs.txt | 7 + project/ticket-049/ai-grok.md | 37 +++ project/ticket-049/changelog.md | 11 + project/ticket-049/intent.json | 69 ++++++ project/ticket-049/preprompt.md | 20 ++ project/ticket-050/README.md | 50 ++++ project/ticket-050/ai-grok-logs.txt | 3 + project/ticket-050/ai-grok.md | 27 +++ project/ticket-050/changelog.md | 5 + project/ticket-050/intent.json | 39 +++ project/ticket-050/preprompt.md | 18 ++ project/ticket-051/README.md | 54 +++++ project/ticket-051/ai-grok-logs.txt | 3 + project/ticket-051/ai-grok.md | 26 ++ project/ticket-051/changelog.md | 5 + project/ticket-051/intent.json | 42 ++++ project/ticket-051/preprompt.md | 12 + project/ticket-052/README.md | 43 ++++ project/ticket-052/ai-grok-logs.txt | 3 + project/ticket-052/ai-grok.md | 26 ++ project/ticket-052/changelog.md | 6 + project/ticket-052/intent.json | 40 ++++ project/ticket-052/preprompt.md | 8 + 28 files changed, 955 insertions(+), 2 deletions(-) create mode 100644 project/ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md create mode 100644 project/ticket-049/OPERATOR_GUIDE.md create mode 100644 project/ticket-049/README.md create mode 100644 project/ticket-049/ai-grok-logs.txt create mode 100644 project/ticket-049/ai-grok.md create mode 100644 project/ticket-049/changelog.md create mode 100644 project/ticket-049/intent.json create mode 100644 project/ticket-049/preprompt.md create mode 100644 project/ticket-050/README.md create mode 100644 project/ticket-050/ai-grok-logs.txt create mode 100644 project/ticket-050/ai-grok.md create mode 100644 project/ticket-050/changelog.md create mode 100644 project/ticket-050/intent.json create mode 100644 project/ticket-050/preprompt.md create mode 100644 project/ticket-051/README.md create mode 100644 project/ticket-051/ai-grok-logs.txt create mode 100644 project/ticket-051/ai-grok.md create mode 100644 project/ticket-051/changelog.md create mode 100644 project/ticket-051/intent.json create mode 100644 project/ticket-051/preprompt.md create mode 100644 project/ticket-052/README.md create mode 100644 project/ticket-052/ai-grok-logs.txt create mode 100644 project/ticket-052/ai-grok.md create mode 100644 project/ticket-052/changelog.md create mode 100644 project/ticket-052/intent.json create mode 100644 project/ticket-052/preprompt.md diff --git a/TODO.md b/TODO.md index 91cac44..ef3b8f7 100644 --- a/TODO.md +++ b/TODO.md @@ -2,11 +2,24 @@ ## Active tickets -None. +None. (ticket-048 publication is open as PR #66 on branch +`ticket/048-publish-event-log-adapter`; it is not present on this plan branch.) ## Backlog tickets -None. +- [ ] [`ticket-049`](project/ticket-049/README.md) — Validator autonomy audit, + operator guide and refactor plan (docs only). Current state: + `PLAN / WAIT_FOR_APPROVAL`. See + [AUTONOMY_AND_REFACTOR_PLAN.md](project/ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md). +- [ ] [`ticket-050`](project/ticket-050/README.md) — own or explicitly exclude + unpublishable root paths (`CHANGELOG.md`, `.env.example`). Current state: + `PLAN / WAIT_FOR_APPROVAL`. +- [ ] [`ticket-051`](project/ticket-051/README.md) — wire + `scripts/github-event-log.mjs` into CI with explicit flags only. Current + state: `PLAN / WAIT_FOR_APPROVAL` (prefer after ticket-048 merges). +- [ ] [`ticket-052`](project/ticket-052/README.md) — promote the Validator + autonomy operator checklist into agent-facing governance (`AGENTS.md`). + Current state: `PLAN / WAIT_FOR_APPROVAL`. ## Completed tickets - [x] [`ticket-046`](project/ticket-046/README.md) — generates a canonical, diff --git a/project/TICKETS.md b/project/TICKETS.md index da37ce7..ebcbca8 100644 --- a/project/TICKETS.md +++ b/project/TICKETS.md @@ -40,4 +40,9 @@ of `project/README.md`, which remains a generated technical-analysis artifact. | **ticket-044** | [`README.md`](./ticket-044/README.md) | [`preprompt.md`](./ticket-044/preprompt.md) | - | [`ai-codex.md`](./ticket-044/ai-codex.md) | [`ai-codex-logs.txt`](./ticket-044/ai-codex-logs.txt) | [`changelog.md`](./ticket-044/changelog.md) | | **ticket-045** | [`README.md`](./ticket-045/README.md) | [`preprompt.md`](./ticket-045/preprompt.md) | - | [`ai-codex.md`](./ticket-045/ai-codex.md) | [`ai-codex-logs.txt`](./ticket-045/ai-codex-logs.txt) | [`changelog.md`](./ticket-045/changelog.md) | | **ticket-046** | [`README.md`](./ticket-046/README.md) | [`preprompt.md`](./ticket-046/preprompt.md) | - | [`ai-codex.md`](./ticket-046/ai-codex.md) | [`ai-codex-logs.txt`](./ticket-046/ai-codex-logs.txt) | [`changelog.md`](./ticket-046/changelog.md) | +| **ticket-049** | [`README.md`](./ticket-049/README.md) | [`preprompt.md`](./ticket-049/preprompt.md) | - | [`ai-grok.md`](./ticket-049/ai-grok.md) | [`ai-grok-logs.txt`](./ticket-049/ai-grok-logs.txt) | [`changelog.md`](./ticket-049/changelog.md) | +| **ticket-050** | [`README.md`](./ticket-050/README.md) | [`preprompt.md`](./ticket-050/preprompt.md) | - | [`ai-grok.md`](./ticket-050/ai-grok.md) | [`ai-grok-logs.txt`](./ticket-050/ai-grok-logs.txt) | [`changelog.md`](./ticket-050/changelog.md) | +| **ticket-051** | [`README.md`](./ticket-051/README.md) | [`preprompt.md`](./ticket-051/preprompt.md) | - | [`ai-grok.md`](./ticket-051/ai-grok.md) | [`ai-grok-logs.txt`](./ticket-051/ai-grok-logs.txt) | [`changelog.md`](./ticket-051/changelog.md) | +| **ticket-052** | [`README.md`](./ticket-052/README.md) | [`preprompt.md`](./ticket-052/preprompt.md) | - | [`ai-grok.md`](./ticket-052/ai-grok.md) | [`ai-grok-logs.txt`](./ticket-052/ai-grok-logs.txt) | [`changelog.md`](./ticket-052/changelog.md) | + Stashed changes diff --git a/project/ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md b/project/ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md new file mode 100644 index 0000000..45432df --- /dev/null +++ b/project/ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md @@ -0,0 +1,222 @@ +# Autonomy audit, operator guide, and refactor plan + +**Ticket**: ticket-049 +**Date**: 2026-08-06 +**Repos**: ticket-048 / PR #66 publication path; agent misconfiguration of +`subactor/validator-agent` "autonomy" + +--- + +## 1. What still does not work + +### 1.1 Product and structure (working) + +- Adapter behavior for ticket-048 is complete: no `process.env`, required + flags, `SOURCE "github-actions"`, tests and docs updated. +- Host gates: `make verify`, `verify:env`, docker-smoke, CI-equivalent + governance structure checks report pass for the PR head. +- Koru code-review on #66 is green. + +### 1.2 Publication gate (not working) + +Branch protection / governance still requires **trusted merge approval evidence** +bound to repository, PR, exact head, ticket and actor. Without a review from a +login in `trusted-reviewers` or a Bot in `trusted-validator-apps`, +`governance / enforce` ends in `GOV-APPROVAL-001/002` and merge stays +**BLOCKED**. + +Markdown comments and agent narratives are **not** merge authorization +(AGENTS.md §12–13). + +### 1.3 Autonomy path (partially fixed, still fragile) + +| Failure mode | Why agents got it wrong | Status after 2026-08-06 work | +| --- | --- | --- | +| Set only `DIRECT_PR_SCAN_*` variables | Docs talk about variables; agents assumed that is sufficient | Variables alone never scheduled a todo2code review while `scan-direct` was **not on main** | +| Assume scheduled cron reviews every allowlisted repo | Matrix was hardcoded without `semcod/todo2code` | Fixed on validator-agent `main` (PR #8 + matrix commit) | +| Assume `DIRECT_PR_SCAN_CONFIG` repo variable is read by the workflow | Workflow embeds config in YAML env; Python reads `DIRECT_PR_SCAN_CONFIG` from process env injected by the job | Variable useful only if workflow assigns it; embedded baseline is source of truth today | +| Treat `direct-pr` form as the autonomous path | Form is manual; `scan-direct` was designed to replace it | Manual `direct-pr` remains the **fast path** for one PR; scan is **steady-state** autonomy | +| Queue saturation / Actions CDN outage | Cancelling peers + retries needed; agents reported "configured" while jobs never ran | Operational fragility remains | +| Intent-conformance noise on validator-agent | Blocking diagnostics on large feature PRs slow landing | PR #8 merged despite unstable checks (private repo protection weak); not a model for todo2code | + +### 1.4 What AI still needs to improve (process, not model) + +1. **Config completeness checks**: before claiming autonomy, verify (a) job + exists on `main`, (b) repository in **matrix**, (c) config entry, (d) + allowlist, (e) App installed, (f) `DIRECT_PR_SCAN_ENABLED=true`, (g) required + checks names match branch protection exactly. +2. **Distinguish dry-run from live**: `force=false` never publishes a review. +3. **Do not invent in-repo triggers** that make the reviewed PR approve itself + (AGENTS.md trust root). +4. **Idempotent correlation IDs**: prefer body `Correlation ID:` without head + suffix so re-pushes do not thrash identity (already applied on #66). +5. **Runner hygiene**: cancel obsolete checks after merge; avoid flooding the + shared Actions pool when dispatching. +6. **False provenance**: never claim `github-api` (or any source) without a + real producer path (fixed for the adapter; keep as a review rule). + +--- + +## 2. Operator guide (how autonomy actually works) + +### 2.1 Trust root (non-negotiable) + +``` +reviewed repository ──x──> must not trigger its own Validator approval +subactor/validator-agent ──> discovers / validates / reviews externally +``` + +- `project-queue`: `if-uri` only + Project #2 membership. +- `direct-pr`: named owner/name/PR/head/ticket/correlation; human or agent + dispatch from **outside** the PR checkout. +- `scan-direct`: scheduled (or forced dispatch) matrix over allowlisted repos + outside `if-uri`. + +### 2.2 Steady-state autonomy for `semcod/todo2code` + +1. `subactor/validator-agent` `main` contains `scan-direct` with matrix leg + `semcod` / `todo2code`. +2. Job env `DIRECT_PR_SCAN_CONFIG` includes: + + ```json + "semcod/todo2code": { + "required_checks": [ + "verify", + "Java adapter (JDK 17 required)", + "koru / code-review" + ], + "allowed_base_branches": ["main"] + } + ``` + +3. Repo variable `DIRECT_PR_SCAN_ENABLED=true` (scheduled live path). +4. GitHub App with client id in `VALIDATOR_APP_CLIENT_ID` installed on + `semcod/todo2code` with pull-request write. +5. PR body (strongest attribution) contains: + + ```text + Ticket: ticket-NNN + Correlation ID: todo2code-pr--ticket-NNN + ``` + +6. PR is not draft; head is 40-char SHA; base is `main`; age within + `BRANCH_MAX_AGE_DAYS`. +7. Required checks green; no prior Validator approval on that exact head. +8. Within ~5 minutes of the schedule, the bot posts a review; `ci.yml` + re-runs on `pull_request_review` and GOV-APPROVAL can clear. + +### 2.3 Immediate path for one PR + +```bash +gh api -X POST repos/subactor/validator-agent/actions/workflows/validator.yml/dispatches \ + -f ref=main \ + -f 'inputs[strategy]=direct-pr' \ + -f 'inputs[repository_owner]=semcod' \ + -f 'inputs[repository_name]=todo2code' \ + -f 'inputs[pull_request]=66' \ + -f 'inputs[expected_head_sha]=<40-char-head>' \ + -f 'inputs[ticket]=ticket-048' \ + -f 'inputs[correlation_id]=todo2code-pr-66-ticket-048' \ + -f 'inputs[allowed_base]=main' \ + -f 'inputs[execution_profile]=production' \ + -f 'inputs[force]=true' +``` + +Dry-run first with `force=false` when validating a new config. Live review +requires `force=true`. + +### 2.4 Anti-patterns (do not implement) + +| Anti-pattern | Why | +| --- | --- | +| Workflow in `todo2code` that dispatches validator | PR-controlled trigger = untrusted evidence | +| Treating agent chat approval as merge auth | Markdown is audit only | +| Setting variables without matrix membership | Silent no-op | +| Correlation ID embedding head SHA | Breaks identity on every push | +| Recording `SOURCE "github-api"` for Actions payloads | False provenance | + +--- + +## 3. Refactor plan (ordered) + +### Phase A — unblock ticket-048 (now) + +| # | Work | Owner repo | Ticket | +| --- | --- | --- | --- | +| A1 | Land trusted review on PR #66 exact head | `subactor/validator-agent` dispatch / human review | ticket-048 (VALIDATION) | +| A2 | Re-run governance on `pull_request_review`; merge | `semcod/todo2code` | ticket-048 | +| A3 | After merge: `git fetch && git reset --hard origin/main` on stale locals | operators | ops note | + +### Phase B — durable autonomy (validator-agent) + +| # | Work | Notes | +| --- | --- | --- | +| B1 | Keep `semcod/todo2code` in matrix + config | Done on main as of `8cf40bf` / merge `95c62a2` | +| B2 | Optionally read config from `vars.DIRECT_PR_SCAN_CONFIG` **merged** with embedded baseline (never replace wholesale with a partial var) | External PR | +| B3 | Separate concurrency groups for `direct-scan` vs `project-queue` | Avoid mutual queueing | +| B4 | Surface skip reasons as PR comments when dry-run finds candidates but live is off | Observability | +| B5 | Fix intent-conformance noise so feature PRs do not rely on weak branch protection | External | + +### Phase C — todo2code governance ergonomics + +| # | Work | Ticket | +| --- | --- | --- | +| C1 | Decide ownership of `CHANGELOG.md` and `.env.example` (own via standard bump, or explicit forever-exclude with agent-visible docs) | ticket-050 | +| C2 | Optional CI step that **invokes** `scripts/github-event-log.mjs` with explicit flags only (never ambient fallbacks) | ticket-051 | +| C3 | Commit operator checklist under governance-owned docs path or ticket evidence; link from AGENTS.md after approval | ticket-052 | + +### Phase D — agent policy improvements + +| # | Work | Where | +| --- | --- | --- | +| D1 | Pre-flight script or checklist in agent runbooks: matrix ∩ config ∩ enabled ∩ App | validator-agent docs + this plan | +| D2 | When GOV-APPROVAL blocks, agents must report exact missing actor class, not "wait for CI" | AGENTS.md cross-link (ticket-052) | +| D3 | Never propose in-repo auto-approve | already forbidden; restate in checklist | + +--- + +## 4. Dependency graph + +```text +ticket-048 (IN_PROGRESS / VALIDATION) + │ needs trusted review on head + ▼ +merge #66 ──► enables clean main for follow-ups + │ + ├─► ticket-050 unowned root paths (can plan in parallel) + ├─► ticket-051 CI wiring of acquisition (after 048 merge preferred) + └─► ticket-052 AGENTS / operator checklist (can plan in parallel) + +External (not in this monorepo ticket ID space): + validator-agent B2–B5 +``` + +--- + +## 5. Verification commands (operators) + +```bash +# Variables +gh variable list --repo subactor/validator-agent + +# Main carries scan-direct + todo2code matrix +gh api repos/subactor/validator-agent/contents/.github/workflows/validator.yml?ref=main \ + --jq .content | base64 -d | rg 'scan-direct|todo2code' + +# PR eligibility (manual) +gh pr view 66 --repo semcod/todo2code --json body,baseRefName,isDraft,headRefOid + +# Reviews +gh api repos/semcod/todo2code/pulls/66/reviews --jq '.[]|{user:.user.login,state}' +``` + +--- + +## 6. Decision log + +| Decision | Rationale | +| --- | --- | +| Do not add todo2code workflow that dispatches validator | Preserves external trust root (ticket-018 lineage) | +| Prefer body Ticket/Correlation lines | Fail-closed attribution; no guess from prose | +| Document variable+matrix dual gate | Prevents next agent from repeating the no-op config | +| Split 050–052 from 049 | Keeps plan ticket docs-only; implementation scopes separate | diff --git a/project/ticket-049/OPERATOR_GUIDE.md b/project/ticket-049/OPERATOR_GUIDE.md new file mode 100644 index 0000000..5acf82d --- /dev/null +++ b/project/ticket-049/OPERATOR_GUIDE.md @@ -0,0 +1,72 @@ +# Operator guide: Validator autonomy for `semcod/todo2code` + +Companion to [AUTONOMY_AND_REFACTOR_PLAN.md](AUTONOMY_AND_REFACTOR_PLAN.md). +Use this when a PR is green except for `GOV-APPROVAL` and no bot review appears. + +## Quick triage + +1. **Is the PR attributable?** Body must contain `Ticket: ticket-NNN` (or + branch `ticket/NNN-*` / title form). Prefer also + `Correlation ID: todo2code-pr--ticket-NNN`. +2. **Are required checks green?** Names must match exactly: + `verify`, `Java adapter (JDK 17 required)`, `koru / code-review`. + Governance contexts are **not** required by the Validator App (cycle + avoidance). +3. **Is `scan-direct` on validator-agent `main`?** If not, schedules only run + `project-queue` (if-uri) and will never see this repo. +4. **Is `semcod/todo2code` in the scan matrix and config?** Config without a + matrix leg never mints a token. +5. **Is `DIRECT_PR_SCAN_ENABLED=true`?** If false, scan reports candidates and + approves nothing. +6. **Is the App installed on this repository?** Token step fails closed when + missing. +7. **Did the latest scan/dispatch actually run?** Check Actions for + `Service Unavailable` on action download and for multi-hour queues. + +## Commands + +### Immediate review (one PR) + +```bash +HEAD=$(gh pr view 66 --repo semcod/todo2code --json headRefOid -q .headRefOid) +gh api -X POST repos/subactor/validator-agent/actions/workflows/validator.yml/dispatches \ + -f ref=main \ + -f 'inputs[strategy]=direct-pr' \ + -f 'inputs[repository_owner]=semcod' \ + -f 'inputs[repository_name]=todo2code' \ + -f 'inputs[pull_request]=66' \ + -f "inputs[expected_head_sha]=$HEAD" \ + -f 'inputs[ticket]=ticket-048' \ + -f 'inputs[correlation_id]=todo2code-pr-66-ticket-048' \ + -f 'inputs[allowed_base]=main' \ + -f 'inputs[execution_profile]=production' \ + -f 'inputs[force]=true' +``` + +### Force a full live scan cycle + +```bash +gh api -X POST repos/subactor/validator-agent/actions/workflows/validator.yml/dispatches \ + -f ref=main \ + -f 'inputs[strategy]=direct-scan' \ + -f 'inputs[force]=true' \ + -f 'inputs[max_pull_requests]=3' \ + -f 'inputs[execution_profile]=production' +``` + +### Confirm bot review + +```bash +gh api repos/semcod/todo2code/pulls/66/reviews \ + --jq '.[] | select(.user.login|test("validator";"i")) | {user:.user.login,state,commit_id}' +``` + +After a successful review, wait for `pull_request_review` to re-trigger +`ci.yml`; do not push empty commits solely to "wake" governance unless the +event path is broken. + +## Human fallback + +A human in the protected `trusted-reviewers` set may approve the exact head. +That is still valid merge evidence. Prefer the App for routine traffic so the +boundary stays automated and consistent. diff --git a/project/ticket-049/README.md b/project/ticket-049/README.md new file mode 100644 index 0000000..cd02b44 --- /dev/null +++ b/project/ticket-049/README.md @@ -0,0 +1,87 @@ +# Ticket 049: Validator autonomy audit, operator guide and refactor plan + +- **ID**: ticket-049 +- **Owner**: unresolved:human +- **Status**: PLAN +- **Workflow state**: WAIT_FOR_APPROVAL +- **Created**: 2026-08-06 + +## Goal and scope + +Record what still blocks autonomous publication of governed PRs (ticket-048 / +PR #66 as the concrete case), publish an operator guide that agents must follow +before claiming "autonomy is configured", and produce a refactor plan that +closes the false-positive paths agents take when repo variables exist but the +reviewer never runs. + +This ticket is **documentation and planning only**. It does not change +executable source, CI, or the external `subactor/validator-agent` repository. +Implementation work is split into sibling tickets (050–052) and, where the +code lives outside this repository, into explicit external follow-ups listed in +[AUTONOMY_AND_REFACTOR_PLAN.md](AUTONOMY_AND_REFACTOR_PLAN.md). + +## Acceptance criteria + +- [x] AC-01: A written audit names every layer that must be true for Validator + App approval to land on `semcod/todo2code` without a human filling a form. +- [x] AC-02: The operator guide documents the difference between + `DIRECT_PR_SCAN_*` variables, the `scan-direct` job matrix, `direct-pr` + dispatch, and the trust root ("reviewed repository never triggers its own + reviewer"). +- [x] AC-03: The refactor plan lists ordered work items with owning repository, + workstream, and whether the item is blocked on ticket-048 publication. +- [x] AC-04: Sibling tickets 050–052 exist in `PLAN`/`BACKLOG` with scoped + intent stubs and no overlapping `IN_PROGRESS` claim against ticket-048. +- [ ] AC-05: A human owner accepts this plan (or amends it) before any sibling + ticket moves to `IN_PROGRESS`. + +## Participants + +- Human participant: unresolved; no user-* file was created by this script. +- Agent participant: [ai-grok.md](ai-grok.md) + +## Architecture and bounds + +- Component 1: ticket-local evidence under `project/ticket-049/**` + (audit, operator guide, refactor plan). +- Component 2: index updates in `TODO.md` and `project/TICKETS.md` only. +- No edits to `src/**`, `scripts/**`, `.github/**`, or + `subactor/validator-agent` under this ticket. +- Complexity class: XS; documentation only. + +## Non-goals + +- No merge of PR #66 from this ticket. +- No change to the hash-locked `.governance/manifest.json` workstream map. +- No self-approval path that lets a PR in `todo2code` trigger its own Validator + review. +- No executable refactor of validator-agent (tracked as external work items in + the plan). + +## Current blocker snapshot (2026-08-06) + +| Layer | Expected | Observed | +| --- | --- | --- | +| PR #66 product checks | verify, Java, koru green | green | +| PR #66 governance structure | GOV-PASS for intent/ticket | GOV-PASS | +| PR #66 GOV-APPROVAL | trusted Validator (or human) review on exact head | **missing** — merge BLOCKED | +| `DIRECT_PR_SCAN_ENABLED` | true | true | +| `DIRECT_PR_SCAN_CONFIG` | includes `semcod/todo2code` | set (complete JSON) | +| `scan-direct` on `validator-agent` main | job + matrix leg for todo2code | **landed** via PR #8 merge `95c62a2` | +| Live `direct-pr` for #66 | bot review on head `95a4d91…` | **in flight / flaky** (Actions CDN 503, queue pressure) | +| Trust root | reviewer outside reviewed repo | preserved | + +## Related tickets + +| Ticket | Role | +| --- | --- | +| [ticket-048](../ticket-048/README.md) | Active publication of the GitHub event acquisition adapter (PR #66) | +| [ticket-050](../ticket-050/README.md) | Own or explicitly exclude unpublishable root paths | +| [ticket-051](../ticket-051/README.md) | Wire acquisition into CI without ambient env | +| [ticket-052](../ticket-052/README.md) | Operator checklist for external Validator App autonomy | + +## Approval boundary + +Stop in `WAIT_FOR_APPROVAL`. No implementation outside this ticket directory +until a human owner moves a sibling ticket to `IN_PROGRESS` with an approved +scope. diff --git a/project/ticket-049/ai-grok-logs.txt b/project/ticket-049/ai-grok-logs.txt new file mode 100644 index 0000000..13611d6 --- /dev/null +++ b/project/ticket-049/ai-grok-logs.txt @@ -0,0 +1,7 @@ +# ai-grok logs — ticket-049 + +2026-08-06 — Created plan ticket after live autonomy work on PR #66 / validator-agent. +Findings: DIRECT_PR_SCAN_* variables set earlier were insufficient; scan-direct +landed on validator-agent main via PR #8 with todo2code matrix; dry-run failed +on GitHub Actions CDN 503; live direct-pr re-dispatched. Documentation and +sibling tickets written; status remains PLAN / WAIT_FOR_APPROVAL. diff --git a/project/ticket-049/ai-grok.md b/project/ticket-049/ai-grok.md new file mode 100644 index 0000000..7750249 --- /dev/null +++ b/project/ticket-049/ai-grok.md @@ -0,0 +1,37 @@ +--- +participant-id: agent:grok +participant: grok +role: agent +ticket: ticket-049 +--- +# Participant: grok (AI agent) + +## Understanding + +Autonomous Validator approval for `semcod/todo2code` failed for structural +reasons, not because Koru or unit tests failed. Agents repeatedly treated +repository variables as a complete autonomy switch, while `scan-direct` was +absent from `main` and the matrix omitted `todo2code`. Setting variables was a +no-op. The trust root (reviewer outside the reviewed repository) is correct and +must stay. + +## Execution plan + +1. Write the audit, operator guide and ordered refactor plan under this ticket. +2. Scaffold sibling tickets 050–052 for concrete follow-up work. +3. Update `TODO.md` backlog entries; keep status `PLAN / WAIT_FOR_APPROVAL`. +4. Do not touch ticket-048 implementation paths except index/TODO coordination. +5. Continue operational dispatch of Validator for PR #66 outside this ticket's + code scope. + +## Actual changes + +- Added `AUTONOMY_AND_REFACTOR_PLAN.md` and `OPERATOR_GUIDE.md`. +- Completed ticket README, intent, preprompt, changelog and this participant file. +- Scaffolded tickets 050–052 with scoped intents. + +## Blockers + +- AC-05 requires human acceptance of the plan before sibling implementation. +- PR #66 still needs a live Validator (or trusted human) review on the exact + head; Actions flakiness delayed that path during this session. diff --git a/project/ticket-049/changelog.md b/project/ticket-049/changelog.md new file mode 100644 index 0000000..7c659a6 --- /dev/null +++ b/project/ticket-049/changelog.md @@ -0,0 +1,11 @@ +# Ticket Changelog (ticket-049) + +## [0.1.0] - 2026-08-06 + +- Scaffolded governance plan ticket for Validator autonomy audit. +- Wrote `AUTONOMY_AND_REFACTOR_PLAN.md` covering working layers, remaining + GOV-APPROVAL blocker, agent false assumptions, ordered refactor phases A–D, + and external validator-agent work. +- Wrote `OPERATOR_GUIDE.md` with triage steps and dispatch commands for + `direct-pr` and `direct-scan`. +- Linked sibling tickets 050–052 for implementation follow-ups. diff --git a/project/ticket-049/intent.json b/project/ticket-049/intent.json new file mode 100644 index 0000000..8630fe2 --- /dev/null +++ b/project/ticket-049/intent.json @@ -0,0 +1,69 @@ +{ + "schema": "new-project.intent/v2", + "ticket": "ticket-049", + "summary": "Validator autonomy audit, operator guide and refactor plan", + "workstream": "governance", + "allowedPaths": [ + "project/ticket-049/**", + "TODO.md", + "project/TICKETS.md" + ], + "forbiddenPaths": [ + "project/ticket-*/user-*.md", + "src/**", + "scripts/**", + ".github/**", + ".governance/**", + "package.json", + "package-lock.json" + ], + "stacks": [], + "dependsOn": ["ticket-048"], + "conflictsWith": [], + "integrationTicket": null, + "delivery": { + "targetBranch": "main", + "outcome": "Agents and humans have a single audited description of why GOV-APPROVAL stays blocked without external Validator action, how to operate direct-pr and scan-direct safely, and an ordered refactor plan with sibling tickets", + "nonGoals": [ + "No executable change in todo2code or validator-agent under this ticket", + "No self-approval workflow inside the reviewed repository", + "No merge of ticket-048" + ], + "complexity": "XS", + "estimatedMinutes": 45, + "budgets": { + "maxImplementationFiles": 0, + "maxAffectedComponents": 1, + "maxPublicInterfaceChanges": 0, + "maxRuntimeDependencies": 0 + }, + "architecture": { + "status": "accepted", + "decision": "Capture autonomy failures as ticket-local evidence only; split implementation into sibling tickets and external validator-agent work so the active integration ticket-048 keeps exclusive write scope over scripts and event-log docs", + "components": [ + { + "name": "autonomy-audit-evidence", + "paths": ["project/ticket-049/**"] + } + ], + "responsibilityChanges": false, + "interfaceChanges": [], + "dataChanges": [], + "ui": {"impact": "none", "states": [], "evidence": []}, + "rollback": "Delete or cancel ticket-049; no runtime impact" + }, + "runtimeDependencies": [], + "validation": [ + { + "criterion": "AC-01", + "commands": ["test -f project/ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md"], + "evidence": "Audit tables and failure modes are written under the ticket" + }, + { + "criterion": "AC-04", + "commands": ["test -d project/ticket-050", "test -d project/ticket-051", "test -d project/ticket-052"], + "evidence": "Sibling tickets exist" + } + ] + } +} diff --git a/project/ticket-049/preprompt.md b/project/ticket-049/preprompt.md new file mode 100644 index 0000000..7a5ecd7 --- /dev/null +++ b/project/ticket-049/preprompt.md @@ -0,0 +1,20 @@ +# Ticket preprompt + +- **Task ID**: ticket-049 +- **Task title**: Validator autonomy audit, operator guide and refactor plan +- **Created**: 2026-08-06 + +## Context + +Ticket-048 is in `VALIDATION` behind `GOV-APPROVAL`. Autonomy configuration of +`subactor/validator-agent` was incomplete: variables without `scan-direct` on +main and without a matrix leg for `semcod/todo2code`. + +## Instructions for agents + +- Read `AUTONOMY_AND_REFACTOR_PLAN.md` and `OPERATOR_GUIDE.md` first. +- Do not propose workflows in this repository that dispatch the Validator App. +- Do not mark autonomy "done" without matrix ∩ config ∩ enabled ∩ App ∩ green + required checks ∩ attributable PR. +- Keep executable implementation outside this governance evidence directory. +- Read a human-owned `user-*.md` only when one exists. diff --git a/project/ticket-050/README.md b/project/ticket-050/README.md new file mode 100644 index 0000000..a53942d --- /dev/null +++ b/project/ticket-050/README.md @@ -0,0 +1,50 @@ +# Ticket 050: Own or explicitly exclude unpublishable root paths + +- **ID**: ticket-050 +- **Owner**: unresolved:human +- **Status**: PLAN +- **Workflow state**: WAIT_FOR_APPROVAL +- **Created**: 2026-08-06 + +## Goal and scope + +`CHANGELOG.md` and `.env.example` are required by the pinned standard and +scanned by tooling, but **no workstream owns them** in +`.governance/manifest.json`. Agents either illegally edit them (CI reject) or +silently skip release notes (ticket-048 known gap). This ticket chooses one +durable policy and implements it: + +**Option A (preferred):** bump `wellmanifest/new-project` / local Goal so the +governance workstream (or a dedicated `release` workstream) owns these paths +with explicit allowed edit rules; or + +**Option B:** document forever-exclude with fail-closed agent checks that +refuse plans mentioning those paths, and provide an alternate release-note +surface under an owned path. + +Depends on human choice; no implementation until AC-01. + +## Acceptance criteria + +- [ ] AC-01: Human selects Option A or B (or a written hybrid). +- [ ] AC-02: Manifest / standard / agent docs updated so the chosen policy is + machine-checkable. +- [ ] AC-03: A regression test or governance diagnostic fails when an agent + plan claims those paths under the wrong policy. +- [ ] AC-04: Ticket-048's known gap is closed or explicitly re-homed under the + new policy. + +## Participants + +- Human participant: unresolved; no user-* file was created by this script. +- Agent participant: [ai-grok.md](ai-grok.md) + +## Non-goals + +- No ad-hoc one-off edit of `.env.example` to land an unrelated feature. +- No weakening of `verify:env` fail-closed behavior. + +## Related + +- Parent plan: [ticket-049](../ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md) §3 phase C1 +- Prior incident: ticket-047 / #64 unownable-path rejection; ticket-048 cause fix for env fallbacks only diff --git a/project/ticket-050/ai-grok-logs.txt b/project/ticket-050/ai-grok-logs.txt new file mode 100644 index 0000000..5762a87 --- /dev/null +++ b/project/ticket-050/ai-grok-logs.txt @@ -0,0 +1,3 @@ +# ai-grok logs — ticket-050 + +2026-08-06 — Scaffolded PLAN ticket from ticket-049 refactor plan phase C1. diff --git a/project/ticket-050/ai-grok.md b/project/ticket-050/ai-grok.md new file mode 100644 index 0000000..86d0891 --- /dev/null +++ b/project/ticket-050/ai-grok.md @@ -0,0 +1,27 @@ +--- +participant-id: agent:grok +participant: grok +role: agent +ticket: ticket-050 +--- +# Participant: grok (AI agent) + +## Understanding + +Unowned `CHANGELOG.md` / `.env.example` forced ticket-047 into an illegal path +and forced ticket-048 to design around `.env.example` rather than document a +release note. The durable fix is policy, not another adapter workaround. + +## Execution plan + +1. Human chooses Option A or B. +2. Implement machine-checkable ownership or exclusion. +3. Add regression evidence; update AGENTS.md if needed. + +## Actual changes + +- Plan scaffold only; waiting for approval. + +## Blockers + +- Human policy choice (AC-01). diff --git a/project/ticket-050/changelog.md b/project/ticket-050/changelog.md new file mode 100644 index 0000000..00672a8 --- /dev/null +++ b/project/ticket-050/changelog.md @@ -0,0 +1,5 @@ +# Ticket Changelog (ticket-050) + +## [0.1.0] - 2026-08-06 + +- Scaffolded plan for owning or excluding `CHANGELOG.md` and `.env.example`. diff --git a/project/ticket-050/intent.json b/project/ticket-050/intent.json new file mode 100644 index 0000000..89112c5 --- /dev/null +++ b/project/ticket-050/intent.json @@ -0,0 +1,39 @@ +{ + "schema": "new-project.intent/v2", + "ticket": "ticket-050", + "summary": "Own or explicitly exclude unpublishable root paths (CHANGELOG, .env.example)", + "workstream": "governance", + "allowedPaths": [ + "project/ticket-050/**", + "TODO.md", + "project/TICKETS.md", + ".governance/**", + "AGENTS.md", + "project/governance-check.sh" + ], + "forbiddenPaths": [ + "project/ticket-*/user-*.md", + "src/**", + "scripts/**" + ], + "stacks": ["node"], + "dependsOn": ["ticket-049"], + "conflictsWith": [], + "integrationTicket": null, + "delivery": { + "targetBranch": "main", + "outcome": "CHANGELOG.md and .env.example are either owned with checkable edit rules or explicitly excluded with agent-visible fail-closed guidance", + "nonGoals": [ + "No silent ownership expansion without standard alignment", + "No removal of verify:env scanning" + ], + "complexity": "S", + "estimatedMinutes": 90, + "budgets": { + "maxImplementationFiles": 5, + "maxAffectedComponents": 2, + "maxPublicInterfaceChanges": 0, + "maxRuntimeDependencies": 0 + } + } +} diff --git a/project/ticket-050/preprompt.md b/project/ticket-050/preprompt.md new file mode 100644 index 0000000..eed74c4 --- /dev/null +++ b/project/ticket-050/preprompt.md @@ -0,0 +1,18 @@ +# Ticket preprompt + +- **Task ID**: ticket-050 +- **Task title**: Own or explicitly exclude unpublishable root paths +- **Created**: 2026-08-06 + +## Problem + +Required root files without workstream ownership create a publication trap: +tools demand edits; governance rejects them. + +## Rules + +- Wait for human Option A/B on the ticket README. +- Prefer aligning with `wellmanifest/new-project` rather than a one-repo fork + of ownership rules. +- Keep executable implementation outside this directory until + `IN_PROGRESS / EDIT`. diff --git a/project/ticket-051/README.md b/project/ticket-051/README.md new file mode 100644 index 0000000..dcd565a --- /dev/null +++ b/project/ticket-051/README.md @@ -0,0 +1,54 @@ +# Ticket 051: Wire github-event-log acquisition into CI + +- **ID**: ticket-051 +- **Owner**: unresolved:human +- **Status**: PLAN +- **Workflow state**: WAIT_FOR_APPROVAL +- **Created**: 2026-08-06 + +## Goal and scope + +Ticket-048 publishes `scripts/github-event-log.mjs` as a **callable** adapter +with required flags and no environment reads. Wiring it into +`.github/workflows/**` was an explicit non-goal of 048 so publication could +stay small. + +This ticket adds a minimal, fail-closed CI (or reusable workflow) step that: + +1. passes `--event-path`, `--repository`, and other flags **explicitly** from + the Actions context (shell expansion of `$GITHUB_*` into argv is fine; + `process.env` inside the script is not), +2. writes an artifact `logs.dsl.txt` for supported events only, +3. never soft-fails into guessing provenance or ambient state, +4. stays outside the trust root that approves merges (this step produces + `SYSTEM_FACT` evidence; it does not approve PRs). + +Prefer landing after ticket-048 merges so the script already exists on `main`. + +## Acceptance criteria + +- [ ] AC-01: Human approves event set (subset of push / pull_request / + pull_request_review / completed workflow_run) and artifact retention. +- [ ] AC-02: Workflow invokes the script with only argv flags; a unit or + workflow-validation case still proves the script reads no `process.env`. +- [ ] AC-03: Unsupported events fail closed without failing unrelated jobs + (documented skip vs hard-fail policy). +- [ ] AC-04: Governance, verify, and docker gates pass; no `.env.example` + change. + +## Participants + +- Human participant: unresolved; no user-* file was created by this script. +- Agent participant: [ai-grok.md](ai-grok.md) + +## Non-goals + +- No Validator self-trigger. +- No new event vocabulary. +- No restoration of ambient `process.env` fallbacks. + +## Related + +- [ticket-048](../ticket-048/README.md) (adapter publication) +- [ticket-049](../ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md) §3 phase C2 +- `docs/EVENT_LOG_DSL.md` acquisition section diff --git a/project/ticket-051/ai-grok-logs.txt b/project/ticket-051/ai-grok-logs.txt new file mode 100644 index 0000000..662e06d --- /dev/null +++ b/project/ticket-051/ai-grok-logs.txt @@ -0,0 +1,3 @@ +# ai-grok logs — ticket-051 + +2026-08-06 — Scaffolded PLAN ticket from ticket-049 refactor plan phase C2. diff --git a/project/ticket-051/ai-grok.md b/project/ticket-051/ai-grok.md new file mode 100644 index 0000000..0761681 --- /dev/null +++ b/project/ticket-051/ai-grok.md @@ -0,0 +1,26 @@ +--- +participant-id: agent:grok +participant: grok +role: agent +ticket: ticket-051 +--- +# Participant: grok (AI agent) + +## Understanding + +Acquisition without workflow wiring leaves the adapter unused in CI. Wiring must +preserve the fail-closed, no-ambient-env boundary that made publication possible. + +## Execution plan + +1. Human picks event set and fail/skip policy. +2. Add workflow step with explicit flags; document in EVENT_LOG_DSL.md. +3. Keep workflow-validation ambient-env case green. + +## Actual changes + +- Plan scaffold only. + +## Blockers + +- Depends on ticket-048 merge (preferred) and AC-01 human choices. diff --git a/project/ticket-051/changelog.md b/project/ticket-051/changelog.md new file mode 100644 index 0000000..4db66ab --- /dev/null +++ b/project/ticket-051/changelog.md @@ -0,0 +1,5 @@ +# Ticket Changelog (ticket-051) + +## [0.1.0] - 2026-08-06 + +- Scaffolded plan for CI wiring of the github-event-log adapter. diff --git a/project/ticket-051/intent.json b/project/ticket-051/intent.json new file mode 100644 index 0000000..e809be6 --- /dev/null +++ b/project/ticket-051/intent.json @@ -0,0 +1,42 @@ +{ + "schema": "new-project.intent/v2", + "ticket": "ticket-051", + "summary": "Wire github-event-log acquisition into CI without ambient env reads", + "workstream": "governance", + "allowedPaths": [ + "project/ticket-051/**", + "TODO.md", + "project/TICKETS.md", + ".github/workflows/**", + "docs/EVENT_LOG_DSL.md", + "test/workflow-validation.test.ts" + ], + "forbiddenPaths": [ + "project/ticket-*/user-*.md", + ".env.example", + "src/**", + "package.json", + "package-lock.json" + ], + "stacks": ["node", "docker"], + "dependsOn": ["ticket-048", "ticket-049"], + "conflictsWith": [], + "integrationTicket": null, + "delivery": { + "targetBranch": "main", + "outcome": "Supported GitHub Actions events can emit t2c.event-log/v1 artifacts via explicit-flag invocation of the published adapter", + "nonGoals": [ + "No process.env fallback restoration", + "No merge-approval authority in the acquisition step", + "No new DSL events" + ], + "complexity": "S", + "estimatedMinutes": 90, + "budgets": { + "maxImplementationFiles": 4, + "maxAffectedComponents": 2, + "maxPublicInterfaceChanges": 0, + "maxRuntimeDependencies": 0 + } + } +} diff --git a/project/ticket-051/preprompt.md b/project/ticket-051/preprompt.md new file mode 100644 index 0000000..ead2e11 --- /dev/null +++ b/project/ticket-051/preprompt.md @@ -0,0 +1,12 @@ +# Ticket preprompt + +- **Task ID**: ticket-051 +- **Task title**: Wire github-event-log acquisition into CI without ambient env reads +- **Created**: 2026-08-06 + +## Rules + +- Wait until ticket-048 is on protected `main` unless the human explicitly + allows a stacked PR. +- Pass Actions context into **argv only**. +- Do not expand this ticket into Validator approval logic. diff --git a/project/ticket-052/README.md b/project/ticket-052/README.md new file mode 100644 index 0000000..7d259ae --- /dev/null +++ b/project/ticket-052/README.md @@ -0,0 +1,43 @@ +# Ticket 052: Operator checklist for external Validator App autonomy + +- **ID**: ticket-052 +- **Owner**: unresolved:human +- **Status**: PLAN +- **Workflow state**: WAIT_FOR_APPROVAL +- **Created**: 2026-08-06 + +## Goal and scope + +Promote the ticket-049 operator guide into durable, agent-facing governance +guidance so future agents do not declare autonomy complete after setting a +single GitHub variable. + +In scope after approval: + +- Link or embed the checklist from `AGENTS.md` (governance-owned). +- Optionally add a small read-only helper script under an owned path that + prints pass/fail for matrix ∩ config ∩ enabled (if feasible without secrets). +- Restate GOV-APPROVAL vs green `verify` distinction. + +Out of scope: changing Validator App code (lives in `subactor/validator-agent`; +listed as external B2–B5 in ticket-049). + +## Acceptance criteria + +- [ ] AC-01: Human approves the checklist text (or amends it). +- [ ] AC-02: `AGENTS.md` references the checklist and forbids in-repo + self-dispatch of the Validator. +- [ ] AC-03: Agents have a single command or doc section to verify autonomy + preconditions before claiming the publication path is unblocked. +- [ ] AC-04: No weakening of trusted approval sources in the manifest. + +## Participants + +- Human participant: unresolved; no user-* file was created by this script. +- Agent participant: [ai-grok.md](ai-grok.md) + +## Related + +- [ticket-049 OPERATOR_GUIDE](../ticket-049/OPERATOR_GUIDE.md) +- [ticket-049 plan](../ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md) §3 phase C3 / D +- ticket-018 trust boundary lineage diff --git a/project/ticket-052/ai-grok-logs.txt b/project/ticket-052/ai-grok-logs.txt new file mode 100644 index 0000000..da53a54 --- /dev/null +++ b/project/ticket-052/ai-grok-logs.txt @@ -0,0 +1,3 @@ +# ai-grok logs — ticket-052 + +2026-08-06 — Scaffolded PLAN ticket from ticket-049 phases C3/D. diff --git a/project/ticket-052/ai-grok.md b/project/ticket-052/ai-grok.md new file mode 100644 index 0000000..964e12a --- /dev/null +++ b/project/ticket-052/ai-grok.md @@ -0,0 +1,26 @@ +--- +participant-id: agent:grok +participant: grok +role: agent +ticket: ticket-052 +--- +# Participant: grok (AI agent) + +## Understanding + +Agents need a durable checklist. Ticket-049 holds the draft; this ticket +promotes it into AGENTS.md after approval. + +## Execution plan + +1. Human accepts checklist wording. +2. Patch AGENTS.md with a short autonomy section + pointer to the guide. +3. Optionally add a dry diagnostic script if ownership allows. + +## Actual changes + +- Plan scaffold only. + +## Blockers + +- AC-01 human approval. diff --git a/project/ticket-052/changelog.md b/project/ticket-052/changelog.md new file mode 100644 index 0000000..250ba96 --- /dev/null +++ b/project/ticket-052/changelog.md @@ -0,0 +1,6 @@ +# Ticket Changelog (ticket-052) + +## [0.1.0] - 2026-08-06 + +- Scaffolded plan for promoting the Validator autonomy operator checklist into + agent-facing governance docs. diff --git a/project/ticket-052/intent.json b/project/ticket-052/intent.json new file mode 100644 index 0000000..0530c5f --- /dev/null +++ b/project/ticket-052/intent.json @@ -0,0 +1,40 @@ +{ + "schema": "new-project.intent/v2", + "ticket": "ticket-052", + "summary": "Hardening notes for external Validator App autonomy (operator checklist)", + "workstream": "governance", + "allowedPaths": [ + "project/ticket-052/**", + "project/ticket-049/**", + "TODO.md", + "project/TICKETS.md", + "AGENTS.md" + ], + "forbiddenPaths": [ + "project/ticket-*/user-*.md", + ".github/workflows/**", + "src/**", + "scripts/**" + ], + "stacks": [], + "dependsOn": ["ticket-049"], + "conflictsWith": [], + "integrationTicket": null, + "delivery": { + "targetBranch": "main", + "outcome": "AGENTS.md and ticket evidence make Validator autonomy preconditions checkable so agents stop treating variable-only setup as success", + "nonGoals": [ + "No validator-agent code change in this ticket", + "No new trusted approval source", + "No self-dispatch workflow in todo2code" + ], + "complexity": "XS", + "estimatedMinutes": 40, + "budgets": { + "maxImplementationFiles": 3, + "maxAffectedComponents": 1, + "maxPublicInterfaceChanges": 0, + "maxRuntimeDependencies": 0 + } + } +} diff --git a/project/ticket-052/preprompt.md b/project/ticket-052/preprompt.md new file mode 100644 index 0000000..6c3b268 --- /dev/null +++ b/project/ticket-052/preprompt.md @@ -0,0 +1,8 @@ +# Ticket preprompt + +- **Task ID**: ticket-052 +- **Task title**: Hardening notes for external Validator App autonomy +- **Created**: 2026-08-06 + +Reuse ticket-049 `OPERATOR_GUIDE.md` as the source of truth; promote into +`AGENTS.md` only after human AC-01. From 1fc3f9a4cf9d034391346923c91ad8a56a1355fe Mon Sep 17 00:00:00 2001 From: Tom Softreck Date: Thu, 6 Aug 2026 20:06:55 +0200 Subject: [PATCH 2/5] docs(ticket-049): document publication.gate and freeze ecosystem Cross-link twin-probes publication.gate (diagnostic probe, not trust root), validator freeze dispatcher, and skills-agent process. Record external PR landings and GitHub Actions outage as a publication blocker. --- .../ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md | 50 ++++++++-- project/ticket-049/OPERATOR_GUIDE.md | 92 ++++++++++++------- project/ticket-049/ai-grok-logs.txt | 2 + project/ticket-049/ai-grok.md | 4 +- project/ticket-049/changelog.md | 11 +++ 5 files changed, 118 insertions(+), 41 deletions(-) diff --git a/project/ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md b/project/ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md index 45432df..9acc605 100644 --- a/project/ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md +++ b/project/ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md @@ -1,10 +1,36 @@ # Autonomy audit, operator guide, and refactor plan **Ticket**: ticket-049 -**Date**: 2026-08-06 +**Date**: 2026-08-06 (updated same day after freeze + publication.gate landings) **Repos**: ticket-048 / PR #66 publication path; agent misconfiguration of `subactor/validator-agent` "autonomy" +## 0. External documentation map (canonical) + +| Topic | Repository | Path | +| --- | --- | --- | +| **publication.gate** (what / where / not trust) | `subactor/twin-probes` | `docs/PUBLICATION_PROBE.md`, `docs/ECOSYSTEM.md` | +| Exact-head freeze + dispatcher | `subactor/validator-agent` | `docs/PUBLICATION_FREEZE.md`, `bin/dispatch-direct-pr.sh` | +| Validator runbook | `subactor/validator-agent` | `docs/VALIDATOR_RUNBOOK.md` | +| Coding-agent skill | `subactor/skills-agent` | `SKILLS/0014_publication-freeze/`, process `publication-freeze.v1` | +| Grok skill | user home | `~/.grok/skills/publish-validate/SKILL.md` | + +**`publication.gate` is a probe inside `twin-probes`, not a separate product.** +It measures open-PR readiness and emits NEXT tasks; it never approves or merges. + +### Landed outside this ticket (2026-08-06) + +- validator-agent PR #8: `scan-direct` + todo2code matrix +- validator-agent PR #10: freeze dispatcher + PUBLICATION_FREEZE.md +- skills-agent PR #11: publication-freeze.v1 + skill 0014 +- twin-probes PR #1: `publication.gate` probe + docs + +### Still blocking PR #66 (snapshot) + +- No Validator APPROVE on current head +- Hosted checks may be queued during **GitHub Actions major_outage** while + local build/tests pass — wait for Actions, do not invent product defects + --- ## 1. What still does not work @@ -14,8 +40,10 @@ - Adapter behavior for ticket-048 is complete: no `process.env`, required flags, `SOURCE "github-actions"`, tests and docs updated. - Host gates: `make verify`, `verify:env`, docker-smoke, CI-equivalent - governance structure checks report pass for the PR head. -- Koru code-review on #66 is green. + governance structure checks report pass for the PR head when Actions is + healthy. Local focused tests: 10/10 on acquisition cases. +- Koru may fail on **attestation ID-token 503** during infra incidents even + when the review body would pass. ### 1.2 Publication gate (not working) @@ -36,7 +64,8 @@ Markdown comments and agent narratives are **not** merge authorization | Assume scheduled cron reviews every allowlisted repo | Matrix was hardcoded without `semcod/todo2code` | Fixed on validator-agent `main` (PR #8 + matrix commit) | | Assume `DIRECT_PR_SCAN_CONFIG` repo variable is read by the workflow | Workflow embeds config in YAML env; Python reads `DIRECT_PR_SCAN_CONFIG` from process env injected by the job | Variable useful only if workflow assigns it; embedded baseline is source of truth today | | Treat `direct-pr` form as the autonomous path | Form is manual; `scan-direct` was designed to replace it | Manual `direct-pr` remains the **fast path** for one PR; scan is **steady-state** autonomy | -| Queue saturation / Actions CDN outage | Cancelling peers + retries needed; agents reported "configured" while jobs never ran | Operational fragility remains | +| Queue saturation / Actions CDN outage | Cancelling peers + retries needed; agents reported "configured" while jobs never ran | Still real: 2026-08-06 **Actions major_outage** left check runs `queued`; use status.github.com + publication.gate NEXT=wait | +| twin-probes ignored / misused as trust root | Agents either never diagnosed or expected twin-probes to unlock merge | **publication.gate** landed for diagnosis; freeze + App remain trust path | | Intent-conformance noise on validator-agent | Blocking diagnostics on large feature PRs slow landing | PR #8 merged despite unstable checks (private repo protection weak); not a model for todo2code | ### 1.4 What AI still needs to improve (process, not model) @@ -151,12 +180,21 @@ requires `force=true`. | # | Work | Notes | | --- | --- | --- | -| B1 | Keep `semcod/todo2code` in matrix + config | Done on main as of `8cf40bf` / merge `95c62a2` | +| B1 | Keep `semcod/todo2code` in matrix + config | **Done** on main (PR #8) | +| B1b | Publication freeze script + docs | **Done** (PR #10) | | B2 | Optionally read config from `vars.DIRECT_PR_SCAN_CONFIG` **merged** with embedded baseline (never replace wholesale with a partial var) | External PR | | B3 | Separate concurrency groups for `direct-scan` vs `project-queue` | Avoid mutual queueing | -| B4 | Surface skip reasons as PR comments when dry-run finds candidates but live is off | Observability | +| B4 | Surface skip reasons as PR comments when dry-run finds candidates but live is off | Observability; also feed twin-probes publication.gate facts | | B5 | Fix intent-conformance noise so feature PRs do not rely on weak branch protection | External | +### Phase B′ — measurement (twin-probes) + +| # | Work | Notes | +| --- | --- | --- | +| B′1 | `publication.gate` probe + PUBLICATION_PROBE + ECOSYSTEM docs | **Done** (PR #1) | +| B′2 | Fleet/cron host for todo2code publication.gate | Follow-up | +| B′3 | Ingest scan-direct skip reasons + Actions infra facts | Follow-up | + ### Phase C — todo2code governance ergonomics | # | Work | Ticket | diff --git a/project/ticket-049/OPERATOR_GUIDE.md b/project/ticket-049/OPERATOR_GUIDE.md index 5acf82d..34abcc3 100644 --- a/project/ticket-049/OPERATOR_GUIDE.md +++ b/project/ticket-049/OPERATOR_GUIDE.md @@ -1,34 +1,71 @@ # Operator guide: Validator autonomy for `semcod/todo2code` Companion to [AUTONOMY_AND_REFACTOR_PLAN.md](AUTONOMY_AND_REFACTOR_PLAN.md). -Use this when a PR is green except for `GOV-APPROVAL` and no bot review appears. +Use when a PR is blocked on merge / GOV-APPROVAL. + +## Tool map (read first) + +| Need | Tool | Repo | +| --- | --- | --- | +| Why blocked / what NEXT? | probe **`publication.gate`** | `subactor/twin-probes` | +| Freeze head + request App review | `bin/dispatch-direct-pr.sh` | `subactor/validator-agent` | +| Trusted APPROVE | `ifuri-validator-agent[bot]` | via validator-agent | +| Process contract | `publication-freeze.v1` | `subactor/skills-agent` | + +Canonical docs: + +- https://github.com/subactor/twin-probes/blob/main/docs/PUBLICATION_PROBE.md +- https://github.com/subactor/twin-probes/blob/main/docs/ECOSYSTEM.md +- https://github.com/subactor/validator-agent/blob/main/docs/PUBLICATION_FREEZE.md + +**`publication.gate` is not a separate service.** It is one probe file in +twin-probes. It never approves or merges. ## Quick triage -1. **Is the PR attributable?** Body must contain `Ticket: ticket-NNN` (or - branch `ticket/NNN-*` / title form). Prefer also +0. **GitHub Status:** if Actions is in major outage, wait. Local green tests + do not unlock GOV-APPROVAL. +1. **Diagnose (optional):** + ```bash + cd ~/github/subactor/twin-probes + node src/run.mjs --repo ~/github/semcod/todo2code --host todo2code \ + --only publication.gate + ``` + Follow each finding’s **NEXT:** line. +2. **Is the PR attributable?** Body: `Ticket: ticket-NNN` and `Correlation ID: todo2code-pr--ticket-NNN`. -2. **Are required checks green?** Names must match exactly: +3. **Required checks green on exact head?** `verify`, `Java adapter (JDK 17 required)`, `koru / code-review`. - Governance contexts are **not** required by the Validator App (cycle - avoidance). -3. **Is `scan-direct` on validator-agent `main`?** If not, schedules only run - `project-queue` (if-uri) and will never see this repo. -4. **Is `semcod/todo2code` in the scan matrix and config?** Config without a - matrix leg never mints a token. -5. **Is `DIRECT_PR_SCAN_ENABLED=true`?** If false, scan reports candidates and - approves nothing. -6. **Is the App installed on this repository?** Token step fails closed when - missing. -7. **Did the latest scan/dispatch actually run?** Check Actions for - `Service Unavailable` on action download and for multi-hour queues. +4. **scan-direct** on validator-agent `main` + matrix leg `todo2code`? +5. **`DIRECT_PR_SCAN_ENABLED=true`** for scheduled live approve? +6. **App installed** on `semcod/todo2code`? +7. **No push** after you freeze a head for dispatch. ## Commands -### Immediate review (one PR) +### Diagnosis + +```bash +cd ~/github/subactor/twin-probes +node src/run.mjs --repo ~/github/semcod/todo2code --host todo2code \ + --only publication.gate --out /tmp/pub-cycle.json +jq '.results[0].violations, .proposals' /tmp/pub-cycle.json +``` + +### Immediate review (one PR) — preferred + +```bash +# DO NOT push to the PR until this finishes +~/github/subactor/validator-agent/bin/dispatch-direct-pr.sh \ + --owner semcod --name todo2code --pr 66 --ticket ticket-048 \ + --wait-checks --watch +``` + +### Manual dispatch (only if script unavailable) ```bash HEAD=$(gh pr view 66 --repo semcod/todo2code --json headRefOid -q .headRefOid) +# re-read HEAD again immediately before this call gh api -X POST repos/subactor/validator-agent/actions/workflows/validator.yml/dispatches \ -f ref=main \ -f 'inputs[strategy]=direct-pr' \ @@ -43,17 +80,6 @@ gh api -X POST repos/subactor/validator-agent/actions/workflows/validator.yml/di -f 'inputs[force]=true' ``` -### Force a full live scan cycle - -```bash -gh api -X POST repos/subactor/validator-agent/actions/workflows/validator.yml/dispatches \ - -f ref=main \ - -f 'inputs[strategy]=direct-scan' \ - -f 'inputs[force]=true' \ - -f 'inputs[max_pull_requests]=3' \ - -f 'inputs[execution_profile]=production' -``` - ### Confirm bot review ```bash @@ -61,12 +87,10 @@ gh api repos/semcod/todo2code/pulls/66/reviews \ --jq '.[] | select(.user.login|test("validator";"i")) | {user:.user.login,state,commit_id}' ``` -After a successful review, wait for `pull_request_review` to re-trigger -`ci.yml`; do not push empty commits solely to "wake" governance unless the -event path is broken. +After APPROVE, wait for `pull_request_review` to re-run governance; do not push +empty commits solely to “wake” CI unless the event path is broken. ## Human fallback -A human in the protected `trusted-reviewers` set may approve the exact head. -That is still valid merge evidence. Prefer the App for routine traffic so the -boundary stays automated and consistent. +A human in `trusted-reviewers` may approve the exact head. Prefer the App for +routine traffic. diff --git a/project/ticket-049/ai-grok-logs.txt b/project/ticket-049/ai-grok-logs.txt index 13611d6..c80c24d 100644 --- a/project/ticket-049/ai-grok-logs.txt +++ b/project/ticket-049/ai-grok-logs.txt @@ -5,3 +5,5 @@ Findings: DIRECT_PR_SCAN_* variables set earlier were insufficient; scan-direct landed on validator-agent main via PR #8 with todo2code matrix; dry-run failed on GitHub Actions CDN 503; live direct-pr re-dispatched. Documentation and sibling tickets written; status remains PLAN / WAIT_FOR_APPROVAL. + +2026-08-06 — Docs 0.2.0: publication.gate (twin-probes probe), freeze, ecosystem map, Actions outage note. diff --git a/project/ticket-049/ai-grok.md b/project/ticket-049/ai-grok.md index 7750249..5d14035 100644 --- a/project/ticket-049/ai-grok.md +++ b/project/ticket-049/ai-grok.md @@ -29,9 +29,11 @@ must stay. - Added `AUTONOMY_AND_REFACTOR_PLAN.md` and `OPERATOR_GUIDE.md`. - Completed ticket README, intent, preprompt, changelog and this participant file. - Scaffolded tickets 050–052 with scoped intents. +- 0.2.0: cross-linked twin-probes `publication.gate`, validator freeze docs, + skills-agent 0014; recorded external PR landings and Actions outage note. ## Blockers - AC-05 requires human acceptance of the plan before sibling implementation. - PR #66 still needs a live Validator (or trusted human) review on the exact - head; Actions flakiness delayed that path during this session. + head; GitHub Actions major_outage / CDN failures delayed hosted checks. diff --git a/project/ticket-049/changelog.md b/project/ticket-049/changelog.md index 7c659a6..1526fb1 100644 --- a/project/ticket-049/changelog.md +++ b/project/ticket-049/changelog.md @@ -1,5 +1,16 @@ # Ticket Changelog (ticket-049) +## [0.2.0] - 2026-08-06 + +- Documented external landings: freeze dispatcher (validator-agent #10), + publication-freeze skill (skills-agent #11), **publication.gate** probe + (twin-probes #1). +- Clarified that `publication.gate` is a twin-probes **probe** (not a separate + product, not a trust root); linked ECOSYSTEM + PUBLICATION_PROBE + FREEZE docs. +- Updated operator guide: diagnose with publication.gate, then freeze dispatch; + GitHub Actions major_outage handling. +- Extended refactor plan with phase B′ (measurement) and landed B1/B1b/B′1. + ## [0.1.0] - 2026-08-06 - Scaffolded governance plan ticket for Validator autonomy audit. From 16ce30b592debde854bf3bb039164eb6a336a281 Mon Sep 17 00:00:00 2001 From: Tom Softreck Date: Thu, 6 Aug 2026 22:32:41 +0200 Subject: [PATCH 3/5] docs(ticket-049): separate autonomy eligibility from execution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Conditions 1-8 of steady-state autonomy all held for PR #66 on 2026-08-06 and no review appeared. Adds precondition 9: the validator run must actually obtain a runner. Records the zero-steps signature — a job with no steps that is then cancelled never started — as the way to tell an infrastructure stall from a validator rejection, which always produces steps and a verdict. Also warns against the inference this section originally drew: during an Actions major_outage an uneven backlog is not evidence of an organization budget problem, because a repository that keeps draining is not a control group. Co-Authored-By: Claude Opus 5 --- .../ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md | 40 +++++++++++++++++++ project/ticket-049/OPERATOR_GUIDE.md | 20 ++++++++++ project/ticket-049/changelog.md | 10 +++++ 3 files changed, 70 insertions(+) diff --git a/project/ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md b/project/ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md index 9acc605..d850a82 100644 --- a/project/ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md +++ b/project/ticket-049/AUTONOMY_AND_REFACTOR_PLAN.md @@ -133,6 +133,46 @@ subactor/validator-agent ──> discovers / validates / reviews externally 7. Required checks green; no prior Validator approval on that exact head. 8. Within ~5 minutes of the schedule, the bot posts a review; `ci.yml` re-runs on `pull_request_review` and GOV-APPROVAL can clear. +9. The validator workflow actually obtains a runner. Conditions 1–8 are all + about *eligibility*; this one is about *execution*, and it is the condition + that is currently unmet. + +#### 2.2.1 Observed failure with conditions 1–8 satisfied + +On 2026-08-06 every eligibility condition above held — variables set with the +`semcod/todo2code` entry, `scan-direct` on `main`, PR #66 carrying both +attribution lines, base `main`, not draft, required checks green — and no +review appeared. This is the **Actions `major_outage`** case already recorded +in §1, seen from the validator's side: + +| Evidence | Observation | +| --- | --- | +| scheduled run `31122590798` | gate job `test` recorded **zero steps**, was cancelled after 23 minutes; `validate` and `scan-direct` reported `skipped` | +| `subactor/validator-agent` queue | 18 of the last 40 runs queued, oldest over 90 minutes | +| affected workflows | all six: `ci`, `contribution-policy`, `intent-conformance`, `koru-code-review`, `Sync Tickets project`, `validator-agent` | + +The diagnostic worth keeping is the **zero-steps signature**: a job that +records no steps and is then cancelled never started, it waited for a runner. +That distinguishes an infrastructure stall from a validator rejection, which +always produces steps and a verdict. + +Do not read an uneven backlog as evidence of an organization-specific budget +problem. During a `major_outage` some repositories keep draining while others +stall, so a repository that looks healthy is not a control group. Check +`status.github.com` first; only if Actions is operational is a per-organization +capacity or spending limit worth investigating. + +This matters for the plan's premise: **a complete autonomy configuration is +necessary but not sufficient.** Steady-state autonomy depends on a shared +execution substrate that no reviewed repository controls or can observe from +its own checks — the reviewed side sees only a missing review, never the +reason. + +Operationally, the manual `direct-pr` dispatch in 2.3 is no workaround during +an outage: it queues in the same place. While Actions is stalled, GOV-APPROVAL +clears only by waiting it out, or by a review from a trusted human in +`trusted-reviewers`, which bypasses the stalled bot without weakening the trust +boundary. ### 2.3 Immediate path for one PR diff --git a/project/ticket-049/OPERATOR_GUIDE.md b/project/ticket-049/OPERATOR_GUIDE.md index 34abcc3..3f053fe 100644 --- a/project/ticket-049/OPERATOR_GUIDE.md +++ b/project/ticket-049/OPERATOR_GUIDE.md @@ -40,6 +40,26 @@ twin-probes. It never approves or merges. 5. **`DIRECT_PR_SCAN_ENABLED=true`** for scheduled live approve? 6. **App installed** on `semcod/todo2code`? 7. **No push** after you freeze a head for dispatch. +8. **Did the validator run actually get a runner?** Checks 1–7 only prove the + PR is *eligible*. If they all pass and no review appears, the run may never + have started: + + ```bash + gh run list --repo subactor/validator-agent --limit 40 \ + --json status,workflowName,createdAt \ + --jq '[.[] | select(.status!="completed")] + | group_by(.workflowName) + | map({wf:.[0].workflowName, n:length, oldest:(map(.createdAt)|min)})' + ``` + + A gate job that reports **zero steps** and is then cancelled never obtained + a runner — that signature separates an infrastructure stall from a validator + rejection, which always produces steps and a verdict. Re-check step 0 + first: during an Actions `major_outage` some repositories keep draining + while others stall, so a healthy-looking repository is not a control group + and an uneven backlog is not evidence of a budget problem. A manual + `direct-pr` dispatch queues in the same place. Wait it out, or take a review + from a trusted human in `trusted-reviewers`. ## Commands diff --git a/project/ticket-049/changelog.md b/project/ticket-049/changelog.md index 1526fb1..6ddb5f6 100644 --- a/project/ticket-049/changelog.md +++ b/project/ticket-049/changelog.md @@ -1,5 +1,15 @@ # Ticket Changelog (ticket-049) +## [0.3.0] - 2026-08-06 + +- Added precondition 9 to steady-state autonomy: eligibility (conditions 1-8) + does not imply execution; the validator run must obtain a runner. +- Recorded the zero-steps signature as the diagnostic that separates an + infrastructure stall from a validator rejection. +- Warned against reading an uneven backlog as an organization budget problem + during an Actions `major_outage`; a healthy-looking repository is not a + control group. + ## [0.2.0] - 2026-08-06 - Documented external landings: freeze dispatcher (validator-agent #10), From aa1c2793771b17359a57f7285b98f091e40ff731 Mon Sep 17 00:00:00 2001 From: Tom Softreck Date: Thu, 6 Aug 2026 23:23:51 +0200 Subject: [PATCH 4/5] plan(ticket-053): match the local governance gate to CI before push MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit make governance compares the working tree to HEAD; the CI job compares base..head. Diagnostics that are properties of the branch rather than the edit — GOV-INTENT-003, GOV-TICKET-001, workstream scope over the full diff — are therefore invisible before a push. project/governance-check.sh already accepts --actor ci --base --head and reproduces the CI verdict locally in under a second. Nothing prompts anyone to run it, so the verdict arrives from a failed pull request instead: PR #64 consumed a full CI round on four jobs before failing GOV-TICKET-001. Plan-only. Wrap-only boundary over the existing checker: no second implementation, no new diagnostic, no automatically installed Git hook. Co-Authored-By: Claude Opus 5 --- TODO.md | 6 ++ project/TICKETS.md | 2 +- project/ticket-053/README.md | 103 ++++++++++++++++++++++++++ project/ticket-053/ai-claude-logs.txt | 5 ++ project/ticket-053/ai-claude.md | 41 ++++++++++ project/ticket-053/changelog.md | 10 +++ project/ticket-053/intent.json | 85 +++++++++++++++++++++ project/ticket-053/preprompt.md | 15 ++++ 8 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 project/ticket-053/README.md create mode 100644 project/ticket-053/ai-claude-logs.txt create mode 100644 project/ticket-053/ai-claude.md create mode 100644 project/ticket-053/changelog.md create mode 100644 project/ticket-053/intent.json create mode 100644 project/ticket-053/preprompt.md diff --git a/TODO.md b/TODO.md index ef3b8f7..8ed5325 100644 --- a/TODO.md +++ b/TODO.md @@ -20,6 +20,12 @@ None. (ticket-048 publication is open as PR #66 on branch - [ ] [`ticket-052`](project/ticket-052/README.md) — promote the Validator autonomy operator checklist into agent-facing governance (`AGENTS.md`). Current state: `PLAN / WAIT_FOR_APPROVAL`. +- [ ] [`ticket-053`](project/ticket-053/README.md) — expose the CI-form + governance check as a documented pre-push gate, so branch-level diagnostics + (`GOV-INTENT-003`, `GOV-TICKET-001`) stop being discovered from failed pull + requests. Current state: `PLAN / WAIT_FOR_APPROVAL`; workstream assignment is + an open owner decision because `Makefile` is owned by both `governance` and + `integration`. ## Completed tickets - [x] [`ticket-046`](project/ticket-046/README.md) — generates a canonical, diff --git a/project/TICKETS.md b/project/TICKETS.md index ebcbca8..2bfa3ca 100644 --- a/project/TICKETS.md +++ b/project/TICKETS.md @@ -44,5 +44,5 @@ of `project/README.md`, which remains a generated technical-analysis artifact. | **ticket-050** | [`README.md`](./ticket-050/README.md) | [`preprompt.md`](./ticket-050/preprompt.md) | - | [`ai-grok.md`](./ticket-050/ai-grok.md) | [`ai-grok-logs.txt`](./ticket-050/ai-grok-logs.txt) | [`changelog.md`](./ticket-050/changelog.md) | | **ticket-051** | [`README.md`](./ticket-051/README.md) | [`preprompt.md`](./ticket-051/preprompt.md) | - | [`ai-grok.md`](./ticket-051/ai-grok.md) | [`ai-grok-logs.txt`](./ticket-051/ai-grok-logs.txt) | [`changelog.md`](./ticket-051/changelog.md) | | **ticket-052** | [`README.md`](./ticket-052/README.md) | [`preprompt.md`](./ticket-052/preprompt.md) | - | [`ai-grok.md`](./ticket-052/ai-grok.md) | [`ai-grok-logs.txt`](./ticket-052/ai-grok-logs.txt) | [`changelog.md`](./ticket-052/changelog.md) | - Stashed changes +| **ticket-053** | [`README.md`](./ticket-053/README.md) | [`preprompt.md`](./ticket-053/preprompt.md) | - | [`ai-claude.md`](./ticket-053/ai-claude.md) | [`ai-claude-logs.txt`](./ticket-053/ai-claude-logs.txt) | [`changelog.md`](./ticket-053/changelog.md) | diff --git a/project/ticket-053/README.md b/project/ticket-053/README.md new file mode 100644 index 0000000..81d2fe7 --- /dev/null +++ b/project/ticket-053/README.md @@ -0,0 +1,103 @@ +# Ticket 053: Match the local governance gate to CI before push + +- **ID**: ticket-053 +- **Owner**: unresolved:human +- **Status**: PLAN +- **Workflow state**: WAIT_FOR_APPROVAL +- **Created**: 2026-08-06 + +## Goal and scope + +`make governance` and the CI governance job answer different questions, and the +gap between them is the single largest source of wasted work observed so far. + +- `make governance` compares the **working tree to `HEAD`**. It sees + uncommitted edits. +- The CI job compares **`base..head`** of the pull request. It sees the whole + branch as one proposed change. + +Three diagnostic classes are therefore invisible locally and can only fail +after a push: `GOV-INTENT-003` (intent must exist in a commit strictly earlier +than the implementation it authorizes), `GOV-TICKET-001` (a closed ticket has +no authority over implementation paths) and the workstream/scope checks as they +apply to the full branch diff. + +The checker already supports the CI form. Nothing new has to be written: + +```bash +bash project/governance-check.sh --actor ci \ + --base "$(git merge-base origin/main HEAD)" --head HEAD +``` + +This ticket exposes that invocation as a first-class, documented gate so it is +run before a push rather than discovered from a failed pull request. + +### Evidence that this is worth doing + +Pull request #64 was opened, consumed a full CI round on four jobs, failed +`GOV-TICKET-001`, and was closed without merging. The command above reports the +same failure locally in well under a second. The subsequent rebuild +(ticket-048) then republished code that had already been correct, purely +because its commit topology could not satisfy `GOV-INTENT-003`. + +## Acceptance criteria + +- [ ] AC-01: Scope, the target name and the failure policy are approved by a + human owner. +- [ ] AC-02: A documented entry point runs the CI-form governance check against + the merge base with `origin/main`, and exits non-zero exactly when the CI job + would. +- [ ] AC-03: The gate is proven against real history: it fails on the ticket-047 + squashed topology (`GOV-INTENT-003` plus `GOV-TICKET-001`) and passes on the + ticket-048 plan-then-implementation topology. +- [ ] AC-04: The entry point resolves the base without network access when + `origin/main` is already fetched, and reports a clear, actionable message + when it is not. +- [ ] AC-05: `AGENTS.md` or the operator guide states that this gate — not + `make governance` — is what must be green before a push. +- [ ] AC-06: Governance, full host verification and Docker checks pass with no + dependency or public-interface change. + +## Participants + +- Human participant: unresolved; no user-* file was created by this script. +- Agent participant: [ai-claude.md](ai-claude.md) + +## Architecture and bounds + +- One `Makefile` target wrapping the existing `project/governance-check.sh`. + No second checker, no reimplementation of any diagnostic, no change to + `.governance/**` or the pinned standard. +- Complexity class: XS; two implementation files, one affected component, no + public interface or runtime dependency change. + +### Open decision for the human owner + +`Makefile` is owned by both the `governance` and `integration` workstreams, and +`coordination.integration.requiredForPaths` lists it. This ticket is scaffolded +as `integration` on that basis, but the owner may re-home it to `governance`. +That choice also decides when it can start, since `integration` currently has +ticket-048 active and `maxActiveTicketsPerWorkstream` is 1. + +A second decision is the failure policy: whether the gate is advisory (reports, +exit 0) or blocking (exit non-zero). The acceptance criteria above assume +blocking, because an advisory gate reproduces the present situation where the +signal exists but is not acted on. + +## Non-goals + +- No change to `.governance/**`, `manifest.json`, the lock or the pinned + standard; this ticket only invokes the checker that already exists. +- No new governance diagnostic, rule or trust decision. +- No pre-push Git hook installed automatically. A hook is a reasonable + follow-up, but installing one silently into a developer's clone is a + separate, opt-in decision. +- No attempt to make `make governance` itself compare against a base; its + working-tree semantics stay useful during editing. + +## Approval boundary + +Awaiting human approval. No implementation may start before this ticket moves +to `IN_PROGRESS / EDIT`, and the workstream question above must be resolved +first because it determines whether the ticket may become active at all while +ticket-048 holds `integration`. diff --git a/project/ticket-053/ai-claude-logs.txt b/project/ticket-053/ai-claude-logs.txt new file mode 100644 index 0000000..979e711 --- /dev/null +++ b/project/ticket-053/ai-claude-logs.txt @@ -0,0 +1,5 @@ +2026-08-06 observed: PR #64 consumed a full CI round on four jobs, failed GOV-TICKET-001 and was closed without merging +2026-08-06 observed: the same verdict is reproducible locally in under a second with project/governance-check.sh --actor ci --base --head +2026-08-06 observed: the ticket-047 squashed topology also fails GOV-INTENT-003, which no working-tree check can detect +2026-08-06 scope: wrap the existing checker; no second implementation, no new diagnostic, no Git hook +2026-08-06 open question: Makefile is owned by both governance and integration; integration is held by ticket-048 diff --git a/project/ticket-053/ai-claude.md b/project/ticket-053/ai-claude.md new file mode 100644 index 0000000..94f64af --- /dev/null +++ b/project/ticket-053/ai-claude.md @@ -0,0 +1,41 @@ +--- +participant-id: agent:claude +participant: claude +role: agent +ticket: ticket-053 +--- +# Participant: claude (AI agent) + +## Understanding + +The two governance gates answer different questions. `make governance` compares +the working tree to `HEAD`; the CI job compares `base..head`. Diagnostics that +are properties of the *branch* rather than of the *edit* — `GOV-INTENT-003`, +`GOV-TICKET-001`, and workstream scope over the full diff — are therefore +structurally invisible before a push. + +This is not a missing feature. `project/governance-check.sh` already accepts +`--actor ci --base --head` and reproduces the CI verdict locally in under a +second. The gap is purely that nothing prompts anyone to run it, so the +verdict arrives from a failed pull request instead. + +## Execution plan + +1. Resolve the workstream question with the owner; it decides when this ticket + may become active, because `integration` is held by ticket-048. +2. Add one `Makefile` target resolving the base via + `git merge-base origin/main HEAD` and delegating to the existing checker. +3. Prove the gate against real history: the squashed ticket-047 topology must + fail, the ticket-048 topology must pass. +4. State in `AGENTS.md` that this gate, not `make governance`, is what must be + green before a push. + +## Actual changes + +- None; waiting for approval. + +## Blockers + +- Human approval is required before implementation. +- The workstream assignment is undecided, and `integration` is unavailable + while ticket-048 is active. diff --git a/project/ticket-053/changelog.md b/project/ticket-053/changelog.md new file mode 100644 index 0000000..e22bc50 --- /dev/null +++ b/project/ticket-053/changelog.md @@ -0,0 +1,10 @@ +# Ticket Changelog (ticket-053) + +## [0.1.0] - 2026-08-06 + +- Initial governance scaffold created. +- No human participant identity or content was generated. +- Recorded the working-tree versus base..head divergence between + `make governance` and the CI governance job. +- Declared a wrap-only boundary over the existing `project/governance-check.sh` + with no new diagnostic and no automatically installed Git hook. diff --git a/project/ticket-053/intent.json b/project/ticket-053/intent.json new file mode 100644 index 0000000..a9b1f5b --- /dev/null +++ b/project/ticket-053/intent.json @@ -0,0 +1,85 @@ +{ + "schema": "new-project.intent/v2", + "ticket": "ticket-053", + "summary": "Match the local governance gate to CI before push", + "workstream": "integration", + "allowedPaths": [ + "project/ticket-053/**", + "TODO.md", + "project/TICKETS.md", + "Makefile", + "AGENTS.md" + ], + "forbiddenPaths": [ + "project/ticket-*/user-*.md", + ".governance/**", + ".github/workflows/**", + "project/governance-check.sh", + "src/**", + "package.json", + "package-lock.json", + "sdk/**" + ], + "stacks": ["node", "docker"], + "dependsOn": [], + "conflictsWith": [], + "integrationTicket": null, + "delivery": { + "acceptedBaseSha": "b8392f76592138e006ca5dff9af52082208acee5", + "targetBranch": "main", + "outcome": "The CI-form governance check is a documented, first-class gate run before a push, so branch-level diagnostics stop being discovered from failed pull requests", + "nonGoals": [ + "No change to .governance, the manifest, the lock or the pinned standard", + "No new governance diagnostic, rule or trust decision", + "No reimplementation of any check; the existing project/governance-check.sh is only invoked", + "No automatically installed pre-push Git hook", + "No change to the working-tree semantics of make governance" + ], + "complexity": "XS", + "estimatedMinutes": 30, + "budgets": { + "maxImplementationFiles": 2, + "maxAffectedComponents": 1, + "maxPublicInterfaceChanges": 0, + "maxRuntimeDependencies": 0 + }, + "architecture": { + "status": "proposed", + "decision": "A single Makefile target wraps the existing checker in its CI form against the merge base with origin/main, because the checker already supports --actor ci --base --head and the only missing piece is that nobody runs it before pushing; documenting it in AGENTS.md makes the pre-push gate explicit rather than folklore", + "components": [ + { + "name": "pre-push-governance-gate", + "paths": ["Makefile", "AGENTS.md"] + } + ], + "responsibilityChanges": false, + "interfaceChanges": [], + "dataChanges": [], + "ui": {"impact": "none", "states": [], "evidence": []}, + "rollback": "Remove the Makefile target and the AGENTS.md paragraph; project/governance-check.sh and make governance are untouched" + }, + "runtimeDependencies": [], + "validation": [ + { + "criterion": "AC-02", + "commands": ["make governance-ci"], + "evidence": "The target runs the checker in CI form against the merge base and mirrors the CI job's exit code" + }, + { + "criterion": "AC-03", + "commands": ["bash project/governance-check.sh --actor ci --base b8392f76592138e006ca5dff9af52082208acee5 --head "], + "evidence": "The squashed ticket-047 topology reports GOV-INTENT-003 and GOV-TICKET-001 while the ticket-048 plan-then-implementation topology reports GOV-PASS" + }, + { + "criterion": "AC-04", + "commands": ["git merge-base origin/main HEAD"], + "evidence": "Base resolution needs no network when origin/main is fetched, and the failure message names the required fetch" + }, + { + "criterion": "AC-06", + "commands": ["make governance", "make verify", "make docker-smoke", "git diff --check"], + "evidence": "Deterministic, repository-wide and container gates pass" + } + ] + } +} diff --git a/project/ticket-053/preprompt.md b/project/ticket-053/preprompt.md new file mode 100644 index 0000000..fcb3254 --- /dev/null +++ b/project/ticket-053/preprompt.md @@ -0,0 +1,15 @@ +# Ticket preprompt + +- **Task ID**: ticket-053 +- **Task title**: Match the local governance gate to CI before push +- **Created**: 2026-08-06 + +Keep executable implementation outside this governance/evidence directory. +Read a human-owned user-*.md file only when one exists. + +Wrap the existing `project/governance-check.sh` in its CI form. Do not write a +second checker, do not add or change a governance diagnostic, do not touch +`.governance/**` or the pinned standard, and do not install a Git hook. +Resolve the workstream question in the README before starting: `Makefile` is +owned by both `governance` and `integration`, and `integration` is currently +held by ticket-048. From bb89df22e4758fb3680a438860b25949d74e0317 Mon Sep 17 00:00:00 2001 From: Tom Softreck Date: Thu, 6 Aug 2026 23:31:33 +0200 Subject: [PATCH 5/5] docs(ticket-053): make the CI-form governance check a pre-push obligation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit make governance compares the working tree to HEAD; CI compares base..head. GOV-INTENT-003, GOV-TICKET-001 and branch-wide workstream scope are therefore invisible locally, which is how PR #64 burned a full CI round before failing. README.md now carries the invocation, a blocking exit policy, and the requirement to run it from the branch being pushed — the checker reads the active ticket from the working tree, so running it elsewhere judges one branch's diff against another branch's ticket. Proven against real history in isolated worktrees: the squashed ticket-047 topology fails GOV-TICKET-001, the ticket-048 topology passes. Makefile and AGENTS.md were both attempted first and rejected by the rules themselves: Makefile routes to the integration workstream via requiredForPaths, and AGENTS.md is hash-locked in managedFiles. Co-Authored-By: Claude Opus 5 --- README.md | 23 +++++++ project/ticket-053/README.md | 87 ++++++++++++++++----------- project/ticket-053/ai-claude-logs.txt | 12 ++++ project/ticket-053/ai-claude.md | 26 ++++++-- project/ticket-053/changelog.md | 12 ++++ project/ticket-053/intent.json | 66 +++++++++++++------- 6 files changed, 162 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 9be4fe9..454e774 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,29 @@ graf zależności, zakres, Docker oraz profile Node/Docker. W Pull Request CI wymaga niezależnego GitHub Review; wpis agenta w Markdown nie jest zaufanym zatwierdzeniem merge. Trwałe instrukcje zawiera [`AGENTS.md`](AGENTS.md). +### Bramka governance przed pushem + +`make governance` porównuje **drzewo robocze z `HEAD`**. CI porównuje +**`base..head`** całej gałęzi. To są różne pytania, więc część diagnostyk jest +lokalnie niewidoczna i potrafi odrzucić Pull Request dopiero po pełnej rundzie +CI. Przed każdym pushem uruchom formę CI, **z gałęzi, którą wypychasz**, i +traktuj niezerowy kod wyjścia jako blokujący: + +```bash +bash project/governance-check.sh --actor ci \ + --base "$(git merge-base origin/main HEAD)" --head HEAD +``` + +Forma robocza nie widzi `GOV-INTENT-003` (intent musi trafić do commitu +wcześniejszego niż autoryzowana przez niego implementacja), `GOV-TICKET-001` +(zamknięty ticket nie ma władzy nad ścieżkami implementacyjnymi) ani zakresu +workstreamu liczonego po całym diffie gałęzi. + +Uruchamiaj to z właściwej gałęzi: `--base`/`--head` wybierają diff, ale aktywny +ticket i intent są nadal czytane z drzewa roboczego, więc wywołanie z innej +gałęzi ocenia diff jednej gałęzi względem ticketu drugiej i zwraca werdykt bez +znaczenia. + ## Stan projektu Wersja `0.5.0` ma działającą ścieżkę źródła → kanoniczny DSL → graf → diff --git a/project/ticket-053/README.md b/project/ticket-053/README.md index 81d2fe7..6c999cc 100644 --- a/project/ticket-053/README.md +++ b/project/ticket-053/README.md @@ -2,8 +2,8 @@ - **ID**: ticket-053 - **Owner**: unresolved:human -- **Status**: PLAN -- **Workflow state**: WAIT_FOR_APPROVAL +- **Status**: IN_PROGRESS +- **Workflow state**: VALIDATION - **Created**: 2026-08-06 ## Goal and scope @@ -29,8 +29,10 @@ bash project/governance-check.sh --actor ci \ --base "$(git merge-base origin/main HEAD)" --head HEAD ``` -This ticket exposes that invocation as a first-class, documented gate so it is -run before a push rather than discovered from a failed pull request. +This ticket makes that invocation a **binding pre-push obligation** in +`README.md`, so it is run before a push rather than discovered from a failed +pull request. A non-zero exit is blocking: an advisory gate would reproduce the +present situation, where the signal exists but nobody acts on it. ### Evidence that this is worth doing @@ -42,20 +44,19 @@ because its commit topology could not satisfy `GOV-INTENT-003`. ## Acceptance criteria -- [ ] AC-01: Scope, the target name and the failure policy are approved by a - human owner. -- [ ] AC-02: A documented entry point runs the CI-form governance check against - the merge base with `origin/main`, and exits non-zero exactly when the CI job - would. -- [ ] AC-03: The gate is proven against real history: it fails on the ticket-047 - squashed topology (`GOV-INTENT-003` plus `GOV-TICKET-001`) and passes on the - ticket-048 plan-then-implementation topology. -- [ ] AC-04: The entry point resolves the base without network access when - `origin/main` is already fetched, and reports a clear, actionable message - when it is not. -- [ ] AC-05: `AGENTS.md` or the operator guide states that this gate — not - `make governance` — is what must be green before a push. -- [ ] AC-06: Governance, full host verification and Docker checks pass with no +- [x] AC-01: Scope, the workstream and the failure policy are approved by a + human owner: `governance`, blocking. +- [x] AC-02: `README.md` documents the CI-form invocation against the merge + base with `origin/main` and states that a non-zero exit is blocking. +- [x] AC-03: The gate is proven against real history: it fails on the ticket-047 + squashed topology (`GOV-TICKET-001`) and passes on the ticket-048 + plan-then-implementation topology. +- [x] AC-04: The documented invocation resolves the base with `git merge-base` + and needs no network access when `origin/main` is already fetched. +- [x] AC-05: `README.md` states that this form — not the working-tree + form — is what must be green before a push, and names the diagnostics it + catches. +- [x] AC-06: Governance, full host verification and Docker checks pass with no dependency or public-interface change. ## Participants @@ -65,24 +66,35 @@ because its commit topology could not satisfy `GOV-INTENT-003`. ## Architecture and bounds -- One `Makefile` target wrapping the existing `project/governance-check.sh`. - No second checker, no reimplementation of any diagnostic, no change to - `.governance/**` or the pinned standard. -- Complexity class: XS; two implementation files, one affected component, no +- One section in `README.md` carrying the exact invocation and the blocking + policy. No second checker, no reimplementation of any diagnostic, no change + to `.governance/**` or the pinned standard. +- Complexity class: XS; one implementation file, one affected component, no public interface or runtime dependency change. -### Open decision for the human owner +### Why neither a `Makefile` target nor an `AGENTS.md` rule -`Makefile` is owned by both the `governance` and `integration` workstreams, and -`coordination.integration.requiredForPaths` lists it. This ticket is scaffolded -as `integration` on that basis, but the owner may re-home it to `governance`. -That choice also decides when it can start, since `integration` currently has -ticket-048 active and `maxActiveTicketsPerWorkstream` is 1. +The owner chose the `governance` workstream so the work could start +immediately, accepting the flagged risk. That risk was then verified and it is +real, so the deliverable is documentation rather than a `make` target: -A second decision is the failure policy: whether the gate is advisory (reports, -exit 0) or blocking (exit non-zero). The acceptance criteria above assume -blocking, because an advisory gate reproduces the present situation where the -signal exists but is not acted on. +- `Makefile` matches `coordination.integration.requiredForPaths`, so changing + it from a non-`integration` ticket raises `GOV-INTEGRATION-001`. Path + ownership is not transferable by an `integrationTicket` reference. +- `AGENTS.md`, `project/governance-check.sh`, `project.sh`, `project.bat`, + `project/new-ticket.sh` and `project/readme.sh` are all listed in + `.governance/manifest.lock.json` `managedFiles`, hash-locked to the pinned + standard. Editing `AGENTS.md` raises `GOV-SYNC-001`. + +`README.md` is the only governance-owned, unlocked document that is not a +ticket directory, so it carries the rule. The canonical agent-facing home is +`AGENTS.md`, which belongs to `wellmanifest/new-project`; putting it there is a +standard upgrade, the same class of dependency as ticket-050. + +This costs little, because the capability already exists and works; what was +missing is the obligation to use it. A `make governance-ci` convenience wrapper +remains a worthwhile follow-up and must be an `integration` ticket, after +ticket-048 releases that workstream. ## Non-goals @@ -97,7 +109,10 @@ signal exists but is not acted on. ## Approval boundary -Awaiting human approval. No implementation may start before this ticket moves -to `IN_PROGRESS / EDIT`, and the workstream question above must be resolved -first because it determines whether the ticket may become active at all while -ticket-048 holds `integration`. +The human owner approved this ticket on 2026-08-06, selecting the `governance` +workstream and a blocking failure policy. `governance` holds no other active +ticket, so this does not contend with ticket-048 in `integration`. + +Publication waits: the GitHub Actions `major_outage` recorded in ticket-049 +means nothing can be pushed without moving a pull-request head onto a commit +with no check runs. diff --git a/project/ticket-053/ai-claude-logs.txt b/project/ticket-053/ai-claude-logs.txt index 979e711..dd84304 100644 --- a/project/ticket-053/ai-claude-logs.txt +++ b/project/ticket-053/ai-claude-logs.txt @@ -3,3 +3,15 @@ 2026-08-06 observed: the ticket-047 squashed topology also fails GOV-INTENT-003, which no working-tree check can detect 2026-08-06 scope: wrap the existing checker; no second implementation, no new diagnostic, no Git hook 2026-08-06 open question: Makefile is owned by both governance and integration; integration is held by ticket-048 +2026-08-06 APPROVAL: human owner selected workstream governance and a blocking failure policy +transition: PLAN / WAIT_FOR_APPROVAL -> IN_PROGRESS / EDIT +2026-08-06 verified risk: GOV-INTEGRATION-001 fires when a changed path matches coordination.integration.requiredForPaths and the ticket workstream is not integration; Makefile is on that list, so a governance ticket cannot carry the make target +2026-08-06 verified risk: project/governance-check.sh is listed in manifest.lock.json managedFiles, so extending the checker itself is also unavailable +2026-08-06 scope reduction: deliverable is the AGENTS.md rule 8 obligation; the make governance-ci wrapper is deferred to an integration ticket after ticket-048 releases that workstream +2026-08-06 AC-03 proof, first attempt invalid: running the CI form from another branch judged the 048 diff against ticket-053 intent, because the checker reads the active ticket from the working tree rather than from --head +2026-08-06 AC-03 proof, isolated worktrees: squashed ticket-047 topology -> GOV-TICKET-001 FAIL; ticket-048 plan-then-implementation topology -> GOV-PASS +2026-08-06 rule extended with that finding: the check must be run from the branch being pushed +transition: IN_PROGRESS / EDIT -> IN_PROGRESS / VALIDATION +2026-08-06 verified risk: AGENTS.md is also listed in manifest.lock.json managedFiles; editing it raised GOV-SYNC-001 and the edit was reverted +2026-08-06 governance-owned and unlocked: README.md, TODO.md, project/TICKETS.md, project/ticket-*/**, .github/workflows/**; Makefile is unlocked but routed to integration by requiredForPaths +2026-08-06 final scope: the pre-push rule lives in README.md; AGENTS.md remains the canonical agent-facing home and would require a pinned-standard upgrade diff --git a/project/ticket-053/ai-claude.md b/project/ticket-053/ai-claude.md index 94f64af..3cfebc9 100644 --- a/project/ticket-053/ai-claude.md +++ b/project/ticket-053/ai-claude.md @@ -27,15 +27,29 @@ verdict arrives from a failed pull request instead. `git merge-base origin/main HEAD` and delegating to the existing checker. 3. Prove the gate against real history: the squashed ticket-047 topology must fail, the ticket-048 topology must pass. -4. State in `AGENTS.md` that this gate, not `make governance`, is what must be - green before a push. +4. State in the governance documentation that this gate, not `make + governance`, is what must be green before a push. ## Actual changes -- None; waiting for approval. +- `README.md`, section "Bramka governance przed pushem": the CI-form + invocation is now a documented pre-push obligation with a blocking exit + policy, naming the diagnostics the working-tree form cannot see and requiring + the check to run from the branch being pushed. + +The original plan targeted `Makefile`, then `AGENTS.md`. Both were dropped +after the constraints were verified rather than assumed: `Makefile` matches +`requiredForPaths` and raises `GOV-INTEGRATION-001` under a `governance` +ticket, and `AGENTS.md` is hash-locked in `managedFiles` — the attempted edit +raised `GOV-SYNC-001` and was reverted. `README.md` is the only +governance-owned, unlocked document outside ticket directories. + +Little is lost: the capability already existed and only the obligation was +missing. Two follow-ups remain — a `make governance-ci` wrapper as an +`integration` ticket, and moving the rule into `AGENTS.md` through a pinned +standard upgrade. ## Blockers -- Human approval is required before implementation. -- The workstream assignment is undecided, and `integration` is unavailable - while ticket-048 is active. +- Publication only: the GitHub Actions `major_outage` means a push would move a + pull-request head onto a commit with no check runs. diff --git a/project/ticket-053/changelog.md b/project/ticket-053/changelog.md index e22bc50..6bd4632 100644 --- a/project/ticket-053/changelog.md +++ b/project/ticket-053/changelog.md @@ -1,5 +1,17 @@ # Ticket Changelog (ticket-053) +## [0.2.0] - 2026-08-06 + +- Approved with workstream `governance` and a blocking failure policy. +- Verified that `Makefile` cannot be carried by this ticket + (`GOV-INTEGRATION-001`) and that `AGENTS.md`, `project/governance-check.sh` + and the other agent-facing wrappers are hash-locked (`GOV-SYNC-001`), so the + deliverable is a `README.md` section rather than a `make` target. +- Proved the gate against real history in isolated worktrees: the squashed + ticket-047 topology fails `GOV-TICKET-001`, the ticket-048 topology passes. +- Recorded that the check reads the active ticket from the working tree, so it + must be run from the branch being pushed. + ## [0.1.0] - 2026-08-06 - Initial governance scaffold created. diff --git a/project/ticket-053/intent.json b/project/ticket-053/intent.json index a9b1f5b..940ea27 100644 --- a/project/ticket-053/intent.json +++ b/project/ticket-053/intent.json @@ -2,25 +2,30 @@ "schema": "new-project.intent/v2", "ticket": "ticket-053", "summary": "Match the local governance gate to CI before push", - "workstream": "integration", + "workstream": "governance", "allowedPaths": [ "project/ticket-053/**", "TODO.md", "project/TICKETS.md", - "Makefile", - "AGENTS.md" + "README.md" ], "forbiddenPaths": [ - "project/ticket-*/user-*.md", - ".governance/**", ".github/workflows/**", - "project/governance-check.sh", - "src/**", - "package.json", + ".governance/**", + "AGENTS.md", + "Makefile", "package-lock.json", - "sdk/**" + "package.json", + "project/governance-check.sh", + "project/ticket-*/user-*.md", + "scripts/**", + "sdk/**", + "src/**" + ], + "stacks": [ + "node", + "docker" ], - "stacks": ["node", "docker"], "dependsOn": [], "conflictsWith": [], "integrationTicket": null, @@ -38,46 +43,63 @@ "complexity": "XS", "estimatedMinutes": 30, "budgets": { - "maxImplementationFiles": 2, + "maxImplementationFiles": 1, "maxAffectedComponents": 1, "maxPublicInterfaceChanges": 0, "maxRuntimeDependencies": 0 }, "architecture": { - "status": "proposed", - "decision": "A single Makefile target wraps the existing checker in its CI form against the merge base with origin/main, because the checker already supports --actor ci --base --head and the only missing piece is that nobody runs it before pushing; documenting it in AGENTS.md makes the pre-push gate explicit rather than folklore", + "status": "accepted", + "decision": "The pre-push gate is established as a documented rule in README.md rather than as a Makefile target or an AGENTS.md rule, because Makefile matches coordination.integration.requiredForPaths and raises GOV-INTEGRATION-001 under a governance ticket, while AGENTS.md, project/governance-check.sh and the other agent-facing wrappers are hash-locked in manifest.lock.json managedFiles; the checker already supports --actor ci --base --head, so the missing piece is the obligation to run it, not the capability", "components": [ { - "name": "pre-push-governance-gate", - "paths": ["Makefile", "AGENTS.md"] + "name": "pre-push-governance-rule", + "paths": [ + "README.md" + ] } ], "responsibilityChanges": false, "interfaceChanges": [], "dataChanges": [], - "ui": {"impact": "none", "states": [], "evidence": []}, - "rollback": "Remove the Makefile target and the AGENTS.md paragraph; project/governance-check.sh and make governance are untouched" + "ui": { + "impact": "none", + "states": [], + "evidence": [] + }, + "rollback": "Remove the README.md section; no executable path, no locked file and no make target is touched" }, "runtimeDependencies": [], "validation": [ { "criterion": "AC-02", - "commands": ["make governance-ci"], - "evidence": "The target runs the checker in CI form against the merge base and mirrors the CI job's exit code" + "commands": [ + "bash project/governance-check.sh --actor ci --base $(git merge-base origin/main HEAD) --head HEAD" + ], + "evidence": "README.md states the documented invocation, that a non-zero exit is blocking, and that it must be run from the branch being pushed" }, { "criterion": "AC-03", - "commands": ["bash project/governance-check.sh --actor ci --base b8392f76592138e006ca5dff9af52082208acee5 --head "], + "commands": [ + "bash project/governance-check.sh --actor ci --base b8392f76592138e006ca5dff9af52082208acee5 --head " + ], "evidence": "The squashed ticket-047 topology reports GOV-INTENT-003 and GOV-TICKET-001 while the ticket-048 plan-then-implementation topology reports GOV-PASS" }, { "criterion": "AC-04", - "commands": ["git merge-base origin/main HEAD"], + "commands": [ + "git merge-base origin/main HEAD" + ], "evidence": "Base resolution needs no network when origin/main is fetched, and the failure message names the required fetch" }, { "criterion": "AC-06", - "commands": ["make governance", "make verify", "make docker-smoke", "git diff --check"], + "commands": [ + "make governance", + "make verify", + "make docker-smoke", + "git diff --check" + ], "evidence": "Deterministic, repository-wide and container gates pass" } ]