Skip to content

Latest commit

 

History

History
159 lines (100 loc) · 20.5 KB

File metadata and controls

159 lines (100 loc) · 20.5 KB

Changelog

Unreleased

Added: base branch identity in land markers

  • Add required Base branch: to LAND_READY and LAND_BLOCKED markers. The formatter now emits it, and the validator rejects land markers that omit it.
  • Clarify that /land proves readiness for the exact current HEAD and the PR's current base branch, so PRs targeting branches such as dev are handled by the same PACT flow without assuming main.
  • Require /merge to reject a current-HEAD LAND_READY marker when its recorded Base branch: no longer matches the PR's current base branch.

Docs: agent-addressed prime block and session-local-by-default clarification

  • Add a prime block at the top of README.md addressed to an agent that was handed the repo link: read the contract + vendor adapter, then run /code /loop /review /land /merge as PACT commands and post the marker to the PR every time, without asking. Closes a failure mode where an agent did a clean review but withheld the marker because the trigger looked like a generic chat review.
  • State explicitly that priming is session-local: by itself it installs nothing, pins no version, vendors no files, and edits no repo files (CLAUDE.md / AGENTS.md). Separates "use PACT for this session" (priming) from "adopt PACT into this repo" (the explicit, committed pin step), so an "adopt"-style instruction is not misread as authorization to modify project docs.
  • Reinforce in the priming step that the deliverable of every marker-producing command is the posted marker, and frame "Optional: pin a version" as the persistent-adoption counterpart. No marker schema, lane, severity, escalation, or merge-gate change.

Added: merge-commit status disclosure for /land and /merge

  • Add required Merge commit status: to LAND_READY and LAND_BLOCKED markers. The formatter now emits it, and the validator rejects land markers that omit it.
  • Document the PR-head-vs-future-merge-commit distinction: LAND_READY proves the current PR HEAD and base branch, but it proves the future merge commit only when the status says tested green. If the platform exposes a merge queue, merge group, synthetic merge ref, or equivalent pre-merge commit check and it is red/pending/unknown, /land must post LAND_BLOCKED.
  • Clarify that not tested / unavailable merge-commit status is an explicit residual risk disclosure, not proof of post-merge CI. Repositories that need hard prevention of post-merge red builds should require a merge queue or synthetic-merge check.

Added: human-commanded /merge executor

  • Add /merge <PR> [--admin-bypass] [--squash|--merge|--rebase] [--wait-deploy] as an optional merge executor only after /land has completed successfully for the current HEAD by posting LAND_READY. It posts no marker; it revalidates the current PR HEAD, PACT comments, GitHub checks, open/conflict-free state, and newest exact-HEAD land marker before invoking the platform merge command.
  • Clarify that agents still never merge autonomously. A merge through /merge is allowed only when the human explicitly commands it in the current turn; the agent is acting as the human-operator execution interface. Admin bypass requires an explicit --admin-bypass request and a successful current-HEAD /land result for the exact HEAD being merged. When supplied, --admin-bypass also authorizes required operator mechanics for that named PR, including draft conversion, followed by a fresh HEAD/check/LAND_READY revalidation before merge.
  • Document head-pinned merge execution (gh pr merge --match-head-commit <sha>), no branch deletion unless explicitly requested, and optional deploy-wait/reporting behavior. No marker schema, lane, severity, or review-gate change.

Added: final /land landing gate

  • Add /land <PR> [--fix-red-base] as the mandatory final read-only readiness gate before human merge. It inspects current-HEAD PACT markers, unresolved findings, GitHub checks, and base-branch status, then posts LAND_READY or LAND_BLOCKED.
  • Add LAND_READY and LAND_BLOCKED marker schemas plus validator/formatter support. LAND_BLOCKED may report PACT: PASS with GitHub checks: FAIL, preserving the exact failure mode where two vendors were clean but Browser E2E was red.
  • Update README, CONTRACT, and vendor adapters so admin bypass is allowed only after a current LAND_READY marker for the exact HEAD being merged. Clarify that draft status, review-required state, approval requirements, and admin-bypass mechanics do not block LAND_READY once PACT markers, current-HEAD checks, and base status are green.

Added: deterministic marker rendering helper

  • Add scripts/pact_format_marker.py, a stdlib JSON-to-marker formatter for CODE_DONE, LOOP_DONE, REVIEW_CLEAN, and REVIEW_FINDINGS comments. It emits the current CONTRACT §5 schema, validates its own output with scripts/validate-marker.py by default, and refuses clean markers with nonzero P0/P1/P2 counts.
  • Add formatter tests covering clean loop markers, clean review markers with existing-marker enumeration, findings markers with computed lane counts, and rejection of malformed clean-marker payloads.
  • Document the marker formatter in README.md and direct /loop and /review command implementations to prefer it over hand-written marker text, preventing drift such as CQ PASS | SP PASS | TC PASS shorthand.

No marker schema, lane, severity, escalation, or merge-gate change.

Added: deterministic progress reporting helpers

  • Add scripts/pact_format_event.py, a stdlib formatter that converts structured PACT progress JSON events into compact Slack/Markdown blocks with clickable PR, marker-comment, commit, and file/line links.
  • Add scripts/pact_progress_watch.py, a progress.jsonl watcher for detached /loop and /review runs. It remembers reported lines, merges a clean final round with LOOP_DONE, and emits only new progress blocks suitable for cron/no-agent delivery.
  • Document structured progress events and the watcher/formatter workflow in README.md.

No marker schema, lane, severity, escalation, or merge-gate change.

v1.1.1 — 2026-05-28

Clarification: marker authorship vs. vendor attribution

  • New paragraph in CONTRACT §5: "Marker authorship: GitHub author ≠ vendor". Every PACT marker is posted via gh pr comment from the human operator's GitHub account, so all marker comments on a given PR share the same authorLogin. The authoritative vendor attribution is the marker title's <vendor> token and the Vendor: field in the body — never the GitHub author. Concluding "the other vendor hasn't reviewed yet" because every comment is authored by the same human is the canonical PACT misread; this paragraph closes that confusion.
  • commands/review.md step 2 reinforced. When enumerating existing markers on HEAD, identify them by title prefix and Vendor: field, not by authorLogin. The instruction now points at the new CONTRACT §5 paragraph.

Docs-only — no marker schema, lane, severity, escalation, or merge-gate change. Existing markers on existing PRs remain valid; agents that re-fetched main will read the clarified rule automatically.

v1.1.0 — 2026-05-28

Adds: workspace isolation for parallel PRs, explicit fluid-role model, explicit push-vs-merge boundary

  • New CONTRACT §4a "Workspace isolation" (mandatory). Every /code, /loop, and /review session must run in its own isolated git worktree bound to exactly one PR's branch — never shared across PRs, never shared across two sessions running at the same time — and must fetch/fast-forward to the PR's latest pushed HEAD before coding. This is the rule that lets many PRs run in parallel (and two vendors advance one PR) without clobbering each other's uncommitted work. commands/code.md, commands/loop.md, commands/review.md, and roles/coder.md each gain a Workspace note pointing at §4a.
  • CONTRACT §4 clarified: roles are activities, not vendor assignments. Either vendor may write/modify the code and either may review it, in any order, across or within rounds (both vendors can land fixes in the same round); each review is attributed to its vendor via the marker Vendor: field. The sole invariant remains the merge gate (§1): two different vendors' clean reviews on the same final HEAD.
  • CONTRACT §7 clarified: agents push, only humans merge. Pushing commits and posting markers are normal autonomous parts of the commands (that is how the other vendor gets a HEAD to review); an agent never waits for permission to push. Merging — landing the PR into the base branch — was reserved to the human operator in this release line; later versions add an explicit human-commanded /merge executor without permitting autonomous agent merges.
  • Adapter + canonical fetch URLs repointed from a pinned tag to main. adapters/{claude-code,codex-cli}/{code,loop,review}.md and the contract's own Canonical URL now fetch …/fastxyz/pact/main/… instead of a hardcoded version tag, so future contract clarifications reach agents immediately without per-release URL churn. Pin a tag only when strict reproducibility is needed (see README). Version tags remain as historical records.

No changes to marker schemas, lanes, severities, escalation triggers, or the merge-gate definition itself.

v1.0.7 — 2026-05-27

Schema + UX clarification

  • LOOP_DONE, REVIEW_CLEAN, and REVIEW_FINDINGS first lines now must include aggregate P0/P1/P2/P3 totals followed by CQ/SP/TC per-category P0/P1/P2/P3 counts immediately after the marker title. The validator rejects markers that omit these first-line counts or whose aggregate or per-category totals disagree with the per-lane counts. This is intended to make severity visible at a glance in PR comments, especially for Codex-style review summaries.
  • Every /review result, /loop round status, cap-exhausted halt, duplicate-guard exit, and final user response after a review/loop marker now must start its first paragraph with TOTAL P0=<n> P1=<n> P2=<n> P3=<n>. When P0/P1/P2 are zero, it must explicitly say P0/P1/P2 are zero before merge-gate or next-action text.
  • /loop now must print user-facing P0/P1/P2/P3 statistics at the start and finish of every internal round, with aggregate counts first and CQ/SP/TC per-category counts second. This keeps loop progress centered on the user's goal: understanding whether P0/P1/P2 blockers remain, not narrating commits or low-level execution details.

v1.0.6 — 2026-05-26

Fix (v1.0.5 round-zero check was wrong; this version replaces it)

v1.0.5 added a "round-zero check" to commands/review.md that fired when a different-vendor REVIEW_CLEAN/LOOP_DONE existed on the current HEAD and exited without posting — on the premise that "the merge gate is already satisfied." That premise is wrong: CONTRACT §1 requires TWO different vendors' clean markers, not one. A different-vendor clean marker alone leaves the gate at 1/2; this vendor's review is exactly what produces the second vote.

If v1.0.5's round-zero had actually fired on a real PR with only one prior vendor's clean marker, the running vendor would have exited without contributing the second vote and the merge gate would have been stuck at 1/2 indefinitely. The check was caught by the very PR audit it was meant to validate (fastxyz/fast-shop, 2026-05-26) before any agent applied it in anger.

v1.0.6 replaces v1.0.5's broken round-zero check with a narrow same-HEAD duplicate guard (commands/review.md step 3):

  • Fires ONLY when REVIEW_CLEAN_<this-vendor>_<sha> or LOOP_DONE_<this-vendor>_<sha> already exists on the current HEAD AND there are no unresolved REVIEW_FINDINGS. The condition is about THIS vendor's own prior coverage, not about another vendor's.
  • When it fires, this vendor has already cast its vote on this HEAD; re-posting is a same-vendor duplicate, not a fresh vote. The guard prints "This vendor already cleared HEAD <sha> at " plus a state-derived merge-gate status line and exits without posting.
  • A different vendor's clean marker on its own NEVER triggers the guard — this vendor's review is still needed to contribute the second vote.

The actual fix for the original "wrong closing line" failure mode is kept: the required Existing markers on HEAD: field in CONTRACT §5 (REVIEW_CLEAN + REVIEW_FINDINGS schemas, unchanged from v1.0.5) plus the state-derived closing-line spec in commands/review.md step 9 (three cases enumerated). When the agent enumerates prior markers as a precondition for posting, the closing line cannot template "needs another vendor" while a prior vendor's marker is sitting in the body.

Asymmetric with /loop's round-zero on purpose. /loop's round-zero exit POSTS LOOP_DONE (with Internal rounds taken: 0) because that IS how a /loop invocation contributes to the merge gate when there's no Coder work to do — a real review with zero rounds, still a vote. /review's same-HEAD duplicate guard is different: this vendor has ALREADY posted its vote on this HEAD; re-posting would be a same-vendor duplicate. v1.0.5 modeled /review's round-zero on /loop's shape but dropped the "still post the marker" half, which is the half that contributes to the gate.

No changes to marker schemas, lane structure, severities, escalation triggers, or the merge gate definition. The Existing markers on HEAD field and validator enforcement remain (v1.0.5).

v1.0.5 — 2026-05-26

Docs + schema (closes a recurring failure mode)

Failure mode. An agent runs /review <PR> without first reading the PR's existing markers, posts its own REVIEW_CLEAN, and closes with the templated "needs another vendor's clean marker on this HEAD" line — even when a different vendor's clean marker already covers that exact HEAD and the merge gate was satisfied minutes earlier. Wasted compute, duplicate marker on the PR, and a closing line that contradicts the actual gate state. Observed at least twice in real use of fastxyz/pact v1.0.4 (claude-code adapter).

Two changes close it:

  • commands/review.md — add a "round-zero check" step (new step 3, between "read PR state" and "compute R counter") that mirrors /loop's round-zero check from v1.0.3. If a different-vendor REVIEW_CLEAN_* or LOOP_DONE_* exists on the current HEAD AND no unresolved REVIEW_FINDINGS_* exist anywhere on the PR, the merge gate is already satisfied — print "Merge gate satisfied on HEAD <sha>" and EXIT. Do not run the lanes, do not run local gates, do not post a marker. Force-override available via /review <PR> --cross-verify when the user has a substantive reason to triple-check.
  • commands/review.md — closing line MUST be derived from the marker body's Existing markers on HEAD field, never from a template. Three cases enumerated (this clean + prior clean = gate satisfied; this clean alone = needs other vendor; findings = run /code or /loop).
  • CONTRACT.md — add the required Existing markers on HEAD: field to both REVIEW_CLEAN and REVIEW_FINDINGS marker schemas. The field enumerates every prior marker on the current HEAD (with ISO timestamps). The reviewer cannot post a marker without producing this list, which forces the round-zero check to be observed in practice even if the agent skipped step 3.

The two changes are intentionally redundant — they catch the same failure at different layers. The round-zero check prevents the redundant marker in the common case. The required schema field catches the residual case where the agent forgets the round-zero check too: it cannot fill out the marker body without enumerating prior markers, which surfaces the duplicate before posting.

Round-zero exit added to edge cases. commands/review.md Edge cases now explicitly documents the round-zero exit as the canonical "second vendor confirms gate already met" path — the symmetric counterpart to /loop's round-zero exit from v1.0.3. /review is the appropriate command when the user wants a literal review with no Coder phase even allocated; the round-zero check makes the two effectively equivalent when there's nothing to review.

No changes to marker types, severities, lanes, escalation triggers, or the merge gate definition. v1.0.4 agents continue to work; v1.0.5 adds a required field (gracefully detectable — missing field is a contract violation, validator updated).

v1.0.3 — 2026-05-25

Docs (clarification, no behavior change for correct agents)

  • commands/loop.md — add a "round-zero check" step that explicitly skips the Coder phase when the latest PR marker is a clean marker (REVIEW_CLEAN / LOOP_DONE) from any vendor AND no unresolved REVIEW_FINDINGS exist. Without this, a strict-vs-lenient reading of step 5a ("Coder phase: implement code, run gates, push") could let a lenient agent push speculative changes when there's nothing to address — which would (a) stale the prior vendor's clean marker, (b) waste compute, (c) risk introducing new bugs the prior vendor would then have to re-flag.
  • commands/loop.md — explicit "Round-zero exit" edge case documenting that Internal rounds taken: 0 is the correct LOOP_DONE state when a different vendor's clean marker already covers the existing HEAD AND this vendor's self-review also finds it clean. This is the canonical "second vendor confirms first vendor's clean review" path.
  • commands/loop.md — print-to-user note distinguishing the round-zero case from the normal case: when /loop's round-zero check fires AND a different vendor has already posted a clean marker, the merge gate is satisfied immediately; the user should be told that rather than "switch to another vendor's CLI and run /review".
  • roles/coder.md — add a "Trigger (when the Coder is allowed to act)" section enumerating the three conditions under which the Coder may act (unresolved findings, initial R1, same-loop self-review findings). Forbids speculative pushes outside these conditions.

No changes to CONTRACT.md, marker formats, escalation triggers, or merge gate. Existing correct agents continue to work; the clarification removes a reading ambiguity that could cause lenient agents to push speculative commits and stale prior vendor clean markers.

v1.0.2 — 2026-05-25

Docs (clarification, no behavior change)

  • commands/code.md — clarify that /code accepts findings from ANY vendor (different OR same), not only from a cross-vendor REVIEW_FINDINGS marker. Prior wording ("from a different vendor", "from another vendor") could be misread by a strict agent as a hard restriction, breaking composability with /review in the same vendor's window. The merge gate (§6) is enforced at the gate, not at the source of findings.
  • commands/loop.md — same clarification on the "ingest cross-vendor findings" step; add an "Equivalence to manual composition" note explaining that /loop is the automated form of alternating /review + /code in one vendor's window, and the two produce semantically equivalent results.

No changes to CONTRACT.md, marker formats, escalation triggers, or merge gate. Existing agents continue to work; the clarification only removes a reading ambiguity that could cause stricter agents to refuse valid same-vendor /code invocations.

v1.0.1 — 2026-05-25

Docs

  • README.md — reframe the primary usage as the URL-only path: prime each session once with "Learn https://github.com/fastxyz/pact", then issue short commands like /code 282, /loop [10] 282, /review 282. No local install needed. The "install as native slash commands" path is demoted to an Optional section for frequent local use. This better matches ephemeral / VPS-hopping / fresh-session workflows where per-machine setup is friction.
  • No content changes to CONTRACT.md, roles/, commands/, or adapters/. Behavior identical to v1.0.0.

v1.0.0 — 2026-05-25

Initial release.

Contract

  • CONTRACT.md — canonical rules: 3 lanes (CQ/SP/TC), 5 severities (P0/P1/P2/P3/Nit), 4 marker types (CODE_DONE, LOOP_DONE, REVIEW_CLEAN, REVIEW_FINDINGS), escalation triggers, disagreement protocol, merge gate.
  • roles/coder.md, roles/reviewer.md — vendor-agnostic role definitions.
  • commands/code.md, commands/loop.md, commands/review.md — vendor-agnostic command specs.

Adapters

  • adapters/claude-code/ — Claude Code skill files for /code, /loop, /review.
  • adapters/codex-cli/ — Codex CLI prompt templates for /code, /loop, /review.

Tooling

  • scripts/validate-marker.py — stdlib Python marker validator with unittest suite.

Docs

  • README.md — leads with the merge gate; installation + opt-in instructions.
  • examples/annotated-pr-loop-transcript.md — worked example of tight (/loop + /review) and granular (/code + /review) flows.