Skip to content

Tags: kamp-us/phoenix

Tags

pipeline-cli-v0.2.1

Toggle pipeline-cli-v0.2.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix(ship-it): never park a `--auto` merge intent — clear it on every …

…path that does not enqueue (#3723) (#3774)

* fix(ship-it): never park a `--auto` merge intent — clear it on every path that does not enqueue (#3723)

A `gh pr merge --auto` left armed by an earlier or interrupted ship-it run survives a
rebase + re-review and fires the instant a fresh control-plane approval lands, so GitHub
enqueues a §CP PR *before* the ship-it run that asserts the machine gates has started
(PR #3700: `added_to_merge_queue` one second after the approving review). The approval
requirement still holds — the defect is ordering: the current-head verdicts, the SHA-bound
run-evidence bundle, the leak scan and the unresolved-thread check can all be skipped at
the decisive instant.

The enqueue primitive is unchanged. What is added is a lifecycle invariant (ADR 0198): an
armed merge intent may exist only between a fully-gated Step-4 enqueue and the queue
accepting the PR. Four mandated sites clear it — run start (catches the interrupted run),
every STOP/refusal, a merge-queue ejection, and a post-reconcile enqueue that never took
effect. A live queue entry is never disturbed, and a repo with no merge queue keeps its
legitimate armed auto-merge.

- new `pipeline-cli merge-intent disarm`: the branch in a pure, unit-tested core; the `gh`
  IO in a service that verifies the clear by re-reading `auto_merge` (the `--disable-auto`
  exit code is non-zero both when it fails and when nothing was armed, so it cannot carry
  the guarantee). Fail-closed: an unreadable arm state disarms, an unprovable clear exits 1.
- ship-it: guard 6 + the invariant section, the four sites wired in, and a refusal ledger
  that names an uncleared intent instead of reporting a clean stop.

Fixes #3723

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(merge-intent): key the pre-queue exemption on the base branch's regime, fail closed on the probe

Repairs the three current-head FAIL verdicts on PR #3774.

The `post-enqueue` exemption keyed on `everQueued`, a per-PR fact — but the property
it is for ("this repo has no merge queue, so `--auto` IS the enqueue mechanism") is a
property of the base branch. Under a merge queue every PR on its FIRST enqueue attempt
has no queue history, so the exemption fired exactly where the parked intent lives: arm
at Step 4, no queue acceptance inside the reconcile budget, reconcile -> pending -> keep,
run ends with the arm outliving it. Now the predicate is a `merge_queue` rule on
`GET /repos/{repo}/rules/branches/{branch}`.

Same root closed the fail-open path: the regime read recovers every fault to
`queueGoverned: true`, so an unreadable probe can never reach the keep. `readQueue` split
into `readQueued` (live membership, unchanged reasoning) and `readQueueGoverned`.

ship-it/SKILL.md: `disarm_intent preflight` is now wired at Step 0 on the line after `PR=`
(previously it appeared only in the preamble block, which runs before $PR/$REPO exist — so
the site that catches the interrupted run was never called). The Site-2 enumeration now
leads with the rule and names the paths it omitted (Step 2 guard 1's FAIL stop, Step 1's
draft/closed/no-linked-issue), and those sites plus the three prose-wired ones use the
coded `|| INTENT_UNCLEARED=1` form so a failed disarm always reaches the refusal ledger.

ADR 0198 rewritten (immutable-once-landed, so before merge): the Consequences no longer
claim the approval is inert for a never-yet-queued PR, the Decision separates "a repo with
no queue" from "a PR the queue has not governed", and the fail-closed section covers both
reads. Number 0198 kept.

Comment discipline: `merge-intent.ts` and `command.ts` docblocks collapsed to pointers;
the README's why and `decideMergeIntent`'s precedence docblock kept.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

pipeline-cli-v0.2.0

Toggle pipeline-cli-v0.2.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
docs(adr): 0197 — crew rendezvous is per-repo canonical, keyed on the…

… shared git dir (#3747)

Records the founder ruling on #3626: Option B (per-repo canonical
rendezvous); machine-global is out, since the crew will run across many
repos on one machine.

The load-bearing constraint: `canonical` resolves to the main checkout's
shared git dir (`--git-common-dir`), never a worktree's `--show-toplevel`
— write-code runs in isolation:worktree and each worktree has a distinct
toplevel, so keying on it would re-create the cwd-split bug.

Closes #3626

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

epic-ledger-v0.1.2

Toggle epic-ledger-v0.1.2's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat(epic-ledger,repo): repo-agnostic gate (#408) + @kampus scope rep…

…o-wide (#404) (#413)

#408 — epic-ledger gate no longer hardcodes kamp-us/phoenix. The target repo is
resolved once at the Github layer build (ADR 0062 §1): CLAUDE_PIPELINE_REPO →
GITHUB_REPOSITORY → `gh repo view`, captured in the closure for all 5 URL builders.
Fails RepoResolutionError when nothing resolves — never a silent phoenix default.
Bumps the package to 0.1.2; adds resolution-order test coverage.

#404 — renames the remaining 6 @phoenix/* packages (web, dashboard, fate-effect,
leak-guard, crabbox-manifest, infra) and every live reference to the @kampus/*
scope, so the repo speaks one scope (epic-ledger was already @kampus from #366).
Pure rename, no behavior change: worker/stack names are string literals decoupled
from package names. Only historical ADR prose in .decisions/** keeps @phoenix/.

Fixes #404
Fixes #408

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

epic-ledger-v0.1.1

Toggle epic-ledger-v0.1.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix(epic-ledger): ship compiled ESM dist, not raw .ts (fixes #405) (#407

)

Published @kampus/epic-ledger@0.1.0 shipped bin/exports pointing at ./src/*.ts
with files:["src"] and no build, so any consumer under node_modules crashed with
ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING (Node won't strip TS types under
node_modules). The package now compiles src/ → ESM dist/ and ships dist only.

- add tsconfig.build.json (extends tsconfig.json): noEmit:false, rootDir/outDir,
  declaration + maps, rewriteRelativeImportExtensions (.ts imports → .js in emit),
  excludes tests + fixtures. tsc emit keeps runtime deps external (no bundling).
- package.json: bin → ./dist/bin.js, exports → {types,import} dist, main/module/types
  → dist, files → ["dist"]; add build + prepublishOnly scripts; bump 0.1.0 → 0.1.1
  (0.1.0 is published-immutable). The in-repo `gate` script stays node src/bin.ts.
- publish workflow: explicit build step before npm publish. Version-guard unchanged;
  it now expects tag epic-ledger-v0.1.1 ↔ package.json 0.1.1.

dist/bin.js keeps the shebang and runs clean; npm-pack→install→run from node_modules
no longer hits the type-stripping error. In-repo node src/bin.ts --help still works.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>