@beremaran/ralphie 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +832 -0
- package/LICENSE +21 -0
- package/README.md +53 -2
- package/dist/ralphie.js +33691 -0
- package/docs/README.md +71 -0
- package/docs/architecture.md +159 -0
- package/docs/cli-reference.md +126 -0
- package/docs/configuration.md +269 -0
- package/docs/development.md +248 -0
- package/docs/getting-started.md +134 -0
- package/docs/operations-and-recovery.md +328 -0
- package/docs/safety.md +189 -0
- package/docs/workflows.md +411 -0
- package/package.json +83 -3
- package/vendor/mattpocock-skills/LICENSE +21 -0
- package/vendor/mattpocock-skills/code-review/SKILL.md +87 -0
- package/vendor/mattpocock-skills/code-review/agents/openai.yaml +3 -0
- package/vendor/mattpocock-skills/codebase-design/DEEPENING.md +37 -0
- package/vendor/mattpocock-skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
- package/vendor/mattpocock-skills/codebase-design/SKILL.md +114 -0
- package/vendor/mattpocock-skills/codebase-design/agents/openai.yaml +3 -0
- package/vendor/mattpocock-skills/diagnosing-bugs/SKILL.md +138 -0
- package/vendor/mattpocock-skills/diagnosing-bugs/agents/openai.yaml +3 -0
- package/vendor/mattpocock-skills/diagnosing-bugs/scripts/hitl-loop.template.sh +44 -0
- package/vendor/mattpocock-skills/implement/SKILL.md +15 -0
- package/vendor/mattpocock-skills/implement/agents/openai.yaml +5 -0
- package/vendor/mattpocock-skills/lock.json +37 -0
- package/vendor/mattpocock-skills/tdd/SKILL.md +38 -0
- package/vendor/mattpocock-skills/tdd/agents/openai.yaml +3 -0
- package/vendor/mattpocock-skills/tdd/mocking.md +59 -0
- package/vendor/mattpocock-skills/tdd/tests.md +77 -0
- package/vendor/mattpocock-skills/to-tickets/SKILL.md +105 -0
- package/vendor/mattpocock-skills/to-tickets/agents/openai.yaml +5 -0
- package/vendor/mattpocock-skills/triage/AGENT-BRIEF.md +207 -0
- package/vendor/mattpocock-skills/triage/OUT-OF-SCOPE.md +105 -0
- package/vendor/mattpocock-skills/triage/SKILL.md +112 -0
- package/vendor/mattpocock-skills/triage/agents/openai.yaml +5 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,832 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Ralphie are documented here. The project follows
|
|
4
|
+
[Semantic Versioning](https://semver.org/) and the Keep a Changelog structure.
|
|
5
|
+
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
## [0.2.0] - 2026-10-07
|
|
9
|
+
|
|
10
|
+
This release replaces the in-process pi agent with headless harness CLIs and
|
|
11
|
+
moves every setting into a configuration file. It contains breaking changes to
|
|
12
|
+
the command line, the configuration, the run state, the JSON Lines output, and
|
|
13
|
+
the way issues are selected and handed back to humans. Read the Removed and
|
|
14
|
+
Changed sections before upgrading.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- Transient harness failures no longer hand issues off. A rate, usage, session
|
|
19
|
+
or quota limit, an overloaded or unreachable provider, exhausted credits or an
|
|
20
|
+
expired login now defers the issue untouched (no labels or comments change),
|
|
21
|
+
stops the rest of the queue, and exits `75` with a message naming the failure
|
|
22
|
+
and its reset time. Definite failures still hand off. `scripts/live-smoke.ts`
|
|
23
|
+
reports such a halt as INCONCLUSIVE and requires a decomposition to have a
|
|
24
|
+
child worked to a genuine outcome before it passes. It also waits for the
|
|
25
|
+
created issues to appear in the label listing before it starts Ralphie, passes
|
|
26
|
+
the implementation scenario only when Ralphie reported the closure and a new
|
|
27
|
+
commit added `greeting.txt`, and saves each run's `--output json` log to a
|
|
28
|
+
temp file whose path and `Run completed` line it prints.
|
|
29
|
+
- Parallel reviewer sessions in one working directory no longer collide while
|
|
30
|
+
skills are injected (`ENOTEMPTY` when setting a same-named repository skill
|
|
31
|
+
aside). They share one injection, and the last release restores the checkout,
|
|
32
|
+
including directories Ralphie created.
|
|
33
|
+
- Harnesses and roles. Every agent session runs on a headless harness CLI:
|
|
34
|
+
Claude Code (`claude`, the default), Codex (`codex`), pi (`pi`) or OpenCode
|
|
35
|
+
(`opencode`). The `harnesses` (per-harness `model`, `effort`, `approval`) and
|
|
36
|
+
`roles` keys assign a harness, model and effort to each of the eight roles
|
|
37
|
+
(`triager`, `preflight`, `implementer`, `fixer`, `standards-reviewer`,
|
|
38
|
+
`spec-reviewer`, `resolution-verifier`, `decomposer`). Every role falls back
|
|
39
|
+
to `roles.default`, both reviewers to `roles.reviewer`, and the fixer to the
|
|
40
|
+
implementer. See `docs/configuration.md`.
|
|
41
|
+
- OpenCode is experimental. Its adapter has not been verified against a live
|
|
42
|
+
model, so startup refuses any role assigned to `opencode` until the
|
|
43
|
+
configuration sets `harnesses.opencode.experimental: true`.
|
|
44
|
+
- YAML configuration. Ralphie reads `$XDG_CONFIG_HOME/ralphie/config.yaml` (else
|
|
45
|
+
`~/.config/ralphie/config.yaml`, or `--config <path>`), validated with a
|
|
46
|
+
strict schema at startup. Settings layer from defaults, the top level, the
|
|
47
|
+
matching `repos."owner/repo"` entry, and repeatable `--set path=value`
|
|
48
|
+
overrides. Review rounds and verification fixes are configurable under
|
|
49
|
+
`limits`, and `labels` maps the five canonical triage labels.
|
|
50
|
+
- `ralphie init` detects the harnesses on PATH and writes a commented config
|
|
51
|
+
file at the default location (or `--config`), never overwriting an existing
|
|
52
|
+
one. A run without a config file points at it.
|
|
53
|
+
- `approval: safe | yolo` (top level, per repository, and per harness) sets how
|
|
54
|
+
the editing roles run. Startup verifies that every assigned harness is
|
|
55
|
+
installed, that safe approval is available, and that pi and OpenCode editing
|
|
56
|
+
roles are set to `yolo`, failing within seconds with the config change that
|
|
57
|
+
fixes it.
|
|
58
|
+
- `limits.sessionTimeoutMinutes` (`edit` 60, `readOnly` 15) bounds each session;
|
|
59
|
+
a timeout kills the session's process group. `limits.maxBudgetUsd` caps spend
|
|
60
|
+
per session, enforced only by Claude Code, with a startup warning for the
|
|
61
|
+
other harnesses.
|
|
62
|
+
- Vendored skills. Sessions run Matt Pocock's `triage`, `to-tickets`,
|
|
63
|
+
`implement`, `tdd`, `code-review`, `codebase-design` and `diagnosing-bugs`
|
|
64
|
+
skills from a pinned copy in `vendor/mattpocock-skills/`, packaged with the
|
|
65
|
+
release. Ralphie injects them (or `skills.dir`) into the harness's project
|
|
66
|
+
skills directory for the session, excludes them from Git, removes them
|
|
67
|
+
afterwards, and generates `docs/agents` tracker and label docs only when the
|
|
68
|
+
repository lacks them. `bun run skills:sync` refreshes the copy and a
|
|
69
|
+
scheduled workflow opens a PR when upstream moves.
|
|
70
|
+
- Hand-offs, always on. Anything that needs a human moves the issue to
|
|
71
|
+
`needs-info` (missing information, conflicting requirements, cannot
|
|
72
|
+
reproduce, outdated premise; Triage Notes comment) or `ready-for-human`
|
|
73
|
+
(exhausted implementation attempts or verification repairs, the
|
|
74
|
+
decomposition depth limit, an external dependency, a decision that needs
|
|
75
|
+
human judgment; write-up with the diagnostics location). Ralphie replaces
|
|
76
|
+
the issue's single triage state label, so the next run's intake skips it.
|
|
77
|
+
Every comment Ralphie posts starts with the AI disclaimer.
|
|
78
|
+
- Opt-in AFK triage (`triage.enabled`, default off). A read-only `triager`
|
|
79
|
+
session runs the vendored `/triage` over unlabelled issues, `needs-triage`
|
|
80
|
+
issues and `needs-info` issues the reporter has answered. It promotes an issue
|
|
81
|
+
to `ready-for-agent` with an Agent Brief (implemented in the same run), hands
|
|
82
|
+
off to `needs-info` or `ready-for-human`, or closes an already implemented
|
|
83
|
+
issue as completed once a fresh resolution verifier proves it. It never
|
|
84
|
+
applies `wontfix` and never writes `.out-of-scope/`.
|
|
85
|
+
- Candidate-commit review gate. After verification Ralphie creates a local
|
|
86
|
+
candidate commit and runs a standards reviewer and a spec reviewer in
|
|
87
|
+
parallel over the range diff; smells never block. Approved candidates are
|
|
88
|
+
squashed into the single delivered commit.
|
|
89
|
+
- Session isolation: sessions start without `GH_TOKEN`, `GITHUB_TOKEN` and the
|
|
90
|
+
enterprise variants, with an empty `GH_CONFIG_DIR`, origin's push URL
|
|
91
|
+
disabled inside the workspace, and a fingerprint check that fails any
|
|
92
|
+
read-only session that changed the checkout.
|
|
93
|
+
- `bun run smoke:live`, an opt-in script that runs the CLI against a scratch
|
|
94
|
+
repository per installed harness. It is not part of `bun run check` or CI.
|
|
95
|
+
- Harness-neutral session events in JSON Lines output (see Changed) and a
|
|
96
|
+
shared contract suite for harness adapters.
|
|
97
|
+
|
|
98
|
+
### Changed
|
|
99
|
+
|
|
100
|
+
- Breaking: JSON Lines events that reported the `grounding` and
|
|
101
|
+
`issue-grounding` stages now report `preflight` (pre-flight work) or
|
|
102
|
+
`hand-off` (hand-off decisions and their verification).
|
|
103
|
+
- Every terminal implementation failure (repeated blocking review findings, a
|
|
104
|
+
review fix that changes nothing, a failed or timed-out session, a repair that
|
|
105
|
+
changes the tree after the last review) now ends in an
|
|
106
|
+
`implementation_exhausted` hand-off, not only an exhausted retry budget.
|
|
107
|
+
- Agent session failures in pre-flight, resolution verification and
|
|
108
|
+
decomposition now become `ready-for-human` hand-offs too; checkout and GitHub
|
|
109
|
+
errors still fail so the next run retries.
|
|
110
|
+
- Session isolation also removes `SSH_AUTH_SOCK` and askpass helpers, empties
|
|
111
|
+
the global and system git config and credential helpers, disables git
|
|
112
|
+
terminal prompts and makes `GIT_SSH_COMMAND` fail, so a session cannot push
|
|
113
|
+
over ssh even in yolo mode. Keys readable on disk or in a keyring still need
|
|
114
|
+
a dedicated OS user.
|
|
115
|
+
- The latest `## Agent Brief` comment is exempt from the 4000-character comment
|
|
116
|
+
trim and the 20-comment limit when issues are read.
|
|
117
|
+
- `--notify-needs-attention` and `--needs-attention-label` fail with tailored
|
|
118
|
+
errors; startup now checks each harness against a minimum version and skips
|
|
119
|
+
the `triager` role when `triage.enabled` is false.
|
|
120
|
+
- Breaking: Ralphie is invoked as `ralphie [owner/]repo` and requires the
|
|
121
|
+
configuration file; a missing file fails with the path it looked for. A bare
|
|
122
|
+
repository name takes its owner from `defaultOwner` or the `gh` login.
|
|
123
|
+
- Breaking: intake reads only open issues carrying the `labels.ready-for-agent`
|
|
124
|
+
label (and every `intake.requireLabels` label). Issues without them are never
|
|
125
|
+
read, so existing queues must be labelled or run with `triage.enabled`.
|
|
126
|
+
- Breaking: one read-only pre-flight session per issue replaces the grounding
|
|
127
|
+
session and the 0-5 complexity assessment. It returns `actionable` with
|
|
128
|
+
`fitsOneSession`, `already_resolved`, `blocked` (skipped without a label
|
|
129
|
+
change) or `hand_off`. Open-blocker skips from queue order are `skipped`
|
|
130
|
+
outcomes that change nothing on GitHub. Decomposition no longer carries a
|
|
131
|
+
complexity estimate.
|
|
132
|
+
- Breaking: hand-offs replace "needs attention" and the notification flags
|
|
133
|
+
throughout. The outcome kind, result field, progress stage and status, and
|
|
134
|
+
artifacts are renamed (`hand-off`, `hand_off`, `hand-off-decision`,
|
|
135
|
+
`pending-hand-off`). The implementer's own result keeps
|
|
136
|
+
`status: needs_attention`, which is routed as a hand-off request.
|
|
137
|
+
- Breaking: run state is version 15 (version 13 replaced `selection` with the
|
|
138
|
+
per-role assignments, 14 renamed the hand-off fields, 15 added the `deferred`
|
|
139
|
+
outcome). Older state is not
|
|
140
|
+
migrated, and artifacts written by earlier versions (`complexity-decision`,
|
|
141
|
+
decomposition breakdowns with `body` and `estimatedComplexity`) are not read.
|
|
142
|
+
- Breaking: `--output json` carries `session_event` records instead of
|
|
143
|
+
`agent_event` records: `{type, sessionID, directory, harness, title?, event}`
|
|
144
|
+
where `event` is one harness-neutral shape (`session_started`,
|
|
145
|
+
`assistant_text`, `tool_call`, `tool_result`, `error`, `usage`,
|
|
146
|
+
`session_finished`). Tool names and inputs are the harness's own. See
|
|
147
|
+
`docs/operations-and-recovery.md`.
|
|
148
|
+
- Breaking: decomposition runs the vendored `/to-tickets` skill. Children use
|
|
149
|
+
`{key, title, whatToBuild, acceptanceCriteria, dependsOn}` and are created
|
|
150
|
+
blockers first in the to-tickets template (`## Parent`, `## What to build`,
|
|
151
|
+
`## Acceptance criteria`, `## Blocked by`) with the agent-ready label and the
|
|
152
|
+
parent's `intake.requireLabels` labels. The parent issue's body is never rewritten
|
|
153
|
+
any more; it is recognised by its native sub-issues, and closed with one
|
|
154
|
+
disclaimed comment when its children are done.
|
|
155
|
+
- Implementation runs the vendored `/implement` skill, and the implementer
|
|
156
|
+
writes the commit message (no separate commit-message session). Fixes resume
|
|
157
|
+
the implementer's session where the harness allows it, starting a fresh
|
|
158
|
+
session when resuming fails or the estimated context nears 400,000 characters.
|
|
159
|
+
- Read-only sessions have no shell on Claude Code, so Ralphie puts the range
|
|
160
|
+
diff in the reviewers' prompts.
|
|
161
|
+
- Structured results are validated values, with the optional hand-off request
|
|
162
|
+
as a field of the result instead of a tool call; repair sessions can no
|
|
163
|
+
longer raise one.
|
|
164
|
+
- Interactive output: the TUI header no longer shows a model. Pause (`p`), stop
|
|
165
|
+
(`s`) and quit (`q`) are unchanged.
|
|
166
|
+
|
|
167
|
+
### Removed
|
|
168
|
+
|
|
169
|
+
- Breaking: the in-process pi SDK runtime, its credential store and model
|
|
170
|
+
catalog, and the `@earendil-works/pi-agent-core` and `@earendil-works/pi-ai`
|
|
171
|
+
dependencies. Ralphie no longer reads `~/.pi/agent/auth.json`,
|
|
172
|
+
`PI_CODING_AGENT_DIR` or provider API-key variables; each harness CLI keeps
|
|
173
|
+
its own login. The pi CLI remains available as a harness.
|
|
174
|
+
- Breaking: the TUI model picker (`m`).
|
|
175
|
+
- Breaking: `--branch` (`-b`), `--verify-command`, `--issue-label`,
|
|
176
|
+
`--issue-sort`, `--implementation-attempts`, `--max-decomposition-depth`,
|
|
177
|
+
`--workspace`, `--model` and `--thinking`. Each fails with an error naming
|
|
178
|
+
the configuration key that replaces it (`docs/configuration.md`).
|
|
179
|
+
- Breaking: `--notify-needs-attention`, `--needs-attention-label` and the
|
|
180
|
+
`notifications` configuration section. Hand-offs are always on, so there is
|
|
181
|
+
nothing left to opt into; each flag fails with a tailored error (see
|
|
182
|
+
Changed).
|
|
183
|
+
|
|
184
|
+
## Before the harness release
|
|
185
|
+
|
|
186
|
+
Everything below predates the harness release. It was kept under a single
|
|
187
|
+
Unreleased heading, so it mixes what shipped in v0.1.0 to v0.1.2 with changes
|
|
188
|
+
merged afterwards and is not attributed to a version. Mentions of removed
|
|
189
|
+
surfaces (OpenCode, the pi SDK, `--on-needs-attention`, `lgtm`, and so on)
|
|
190
|
+
describe history, not the current tool.
|
|
191
|
+
|
|
192
|
+
### Removed
|
|
193
|
+
|
|
194
|
+
- Remove the `quiet` and `verbose` output modes. `--output` now accepts only
|
|
195
|
+
`default` (live transcript and progress) and `json` (JSON Lines). The
|
|
196
|
+
structured `details` payload is no longer rendered on human-readable lines;
|
|
197
|
+
JSON output and the `events.jsonl` audit retain it.
|
|
198
|
+
|
|
199
|
+
- Remove `--max-issues`, `--implementation-fallback-model`, `--resume`,
|
|
200
|
+
`--dry-run`, and `--clean`. Every run now processes the whole matching open
|
|
201
|
+
issue queue with no budget, retries always use the selected model, and there
|
|
202
|
+
is no preview or resume path. The workspace is removed before preparation
|
|
203
|
+
and after a successful run; cleanup is skipped when the run fails, drains
|
|
204
|
+
with issue failures, or is cancelled. Notification recovery, state loading,
|
|
205
|
+
legacy-state migration, and the read-only dry-run executor and planner are
|
|
206
|
+
gone. `RunState` is version 12.
|
|
207
|
+
|
|
208
|
+
- Remove the halt policies. `--on-needs-attention` and `--on-issue-failure` are
|
|
209
|
+
gone; a needs-attention outcome or an ordinary issue failure now always
|
|
210
|
+
records the outcome, leaves the issue open, and continues the queue. A
|
|
211
|
+
drained run exits `1` when any issue failed, and the former handled-stop exit
|
|
212
|
+
status `2` no longer exists.
|
|
213
|
+
|
|
214
|
+
- Remove dead integration weight inherited from the removed modes: managed
|
|
215
|
+
feature-branch revision safety, the feature-branch and base-restore Git
|
|
216
|
+
operations, the always-false `allowMissingRemoteBranch` seam, unused safety
|
|
217
|
+
exports, and progress rendering for events pi never emits (compaction,
|
|
218
|
+
automatic/summarization retries, queue/session/entry updates, thinking-level
|
|
219
|
+
changes, and bash execution updates). No behavior change.
|
|
220
|
+
|
|
221
|
+
- Remove the `pr` workflow. Ralphie now always delivers through the direct
|
|
222
|
+
`lgtm` path: the `--workflow` flag, feature branches, pull requests, the
|
|
223
|
+
post-PR review/revision coordinator, the check gate, and the read-only check
|
|
224
|
+
observer are gone, along with their Git, run-state, artifact, prompt, test,
|
|
225
|
+
and documentation surfaces. `RunState` is version 10.
|
|
226
|
+
|
|
227
|
+
- Remove every top-level execution mode other than the issue workflow. The
|
|
228
|
+
`--mode` flag, `maintain-issues`, `get-pipelines-green`, and
|
|
229
|
+
`--duplicate-action`/`--max-attempts`/`--pipeline-timeout` are gone, along
|
|
230
|
+
with the maintenance snapshot/planning/state subsystem, the pipeline
|
|
231
|
+
delivery/diagnostics/repair subsystem, and their tests and docs.
|
|
232
|
+
|
|
233
|
+
- Replace the external OpenCode server integration and the multi-harness/ACP
|
|
234
|
+
discovery layer with an in-process agent runtime (itself replaced by the
|
|
235
|
+
harness CLIs, see above). Deleted
|
|
236
|
+
`src/harness/` (six-kind harness contracts and Antigravity
|
|
237
|
+
executable/ACP discovery) and `src/opencode/` (server client, transport,
|
|
238
|
+
permission watcher, and model-variant catalog). `--opencode-url`,
|
|
239
|
+
`--opencode-token`, `OPENCODE_URL`, `OPENCODE_TOKEN`, and the mandatory
|
|
240
|
+
Antigravity preflight are gone; no external agent server is required.
|
|
241
|
+
|
|
242
|
+
- Remove every non-npm distribution channel: the native standalone bundles
|
|
243
|
+
(four-platform `bun compile` builds, `scripts/install.sh`, `bun run targets`
|
|
244
|
+
catalog machinery), the Homebrew tap/formula (generators, validators,
|
|
245
|
+
reconciliation, checksums), the Docker image and container registry
|
|
246
|
+
publication (GHCR, OCI indexes, tag plans, SBOM/SLSA attestations), and the
|
|
247
|
+
release checksum/Sigstore verification surface (`SHA256SUMS`). The release
|
|
248
|
+
and public-distribution workflows are replaced by one tag-triggered publish
|
|
249
|
+
workflow (`.github/workflows/npm-publish.yml`): validate the tag/package
|
|
250
|
+
version (`scripts/validate-npm-context.ts`), build the package bundle,
|
|
251
|
+
smoke-check the packed tarball, and `bun publish`. `bunx
|
|
252
|
+
@beremaran/ralphie` is the only supported way to run Ralphie.
|
|
253
|
+
|
|
254
|
+
- Remove the shared redaction implementation (`src/shared/redaction.ts`,
|
|
255
|
+
`tests/shared/redaction.test.ts`) and every `[REDACTED]` reporting assertion.
|
|
256
|
+
`redactSensitiveText`/`redactSensitiveValue` no longer exist; the terminal
|
|
257
|
+
control sanitizer they contained moved to `src/shared/terminal.ts`
|
|
258
|
+
(`stripTerminalControls`).
|
|
259
|
+
|
|
260
|
+
### Changed
|
|
261
|
+
|
|
262
|
+
- Replace the hand-rolled interactive renderer with OpenTUI, the same
|
|
263
|
+
terminal rendering core OpenCode 1.0 uses. Interactive runs now render a
|
|
264
|
+
borderless layout: a background header line with the repository, active
|
|
265
|
+
model, and pause state; an issue sidebar with outcome glyphs and a
|
|
266
|
+
processed count; a per-issue streaming transcript with role bullets,
|
|
267
|
+
indented assistant text, dim thinking, and one-row tool calls with elapsed
|
|
268
|
+
time; and a footer status line. The sidebar lists the discovered queue
|
|
269
|
+
with each issue's outcome and follows the active issue until the user
|
|
270
|
+
navigates; `[`/`]` (or Ctrl+Left/Right) switch between processed, active, and
|
|
271
|
+
queued issues. Interactive runs start paused so the discovered plan can be
|
|
272
|
+
inspected before work begins; `p` resumes or pauses the queue between issues,
|
|
273
|
+
`s` stops the queue after the active issue and drains the run with a "Run
|
|
274
|
+
stopped by request" summary, and `q` cancels immediately. The
|
|
275
|
+
footer/breadcrumb/terminal-controller stack and its PTY test suites are gone. Plain (piped/CI) and JSON output are unchanged in
|
|
276
|
+
shape, and the interactive renderer loads lazily so help, plain, and JSON
|
|
277
|
+
paths never touch the native module.
|
|
278
|
+
|
|
279
|
+
- Report the discovered issue queue and skipped issues through progress:
|
|
280
|
+
`issue-queue` events carry the pending issue numbers and titles, and an issue
|
|
281
|
+
that no longer matches the filters is reported as skipped instead of
|
|
282
|
+
disappearing silently. Plain output gains one line per skipped issue and the
|
|
283
|
+
JSON audit gains the queue details.
|
|
284
|
+
|
|
285
|
+
- Give GitHub adapters an owned session. `connect()` authenticates once and
|
|
286
|
+
the capability adapters read the client internally, so no port method,
|
|
287
|
+
executor context, or workflow call carries an Octokit handle; the SDK is
|
|
288
|
+
confined to `src/github/adapters/`.
|
|
289
|
+
|
|
290
|
+
- Inject `Clock`, `IdGenerator`, and `RunLayout` through the runtime bundle.
|
|
291
|
+
Workflow, artifacts, and recovery no longer call `new Date()`,
|
|
292
|
+
`randomUUID()`, or compose workspace paths; the composition root resolves
|
|
293
|
+
the workspace expansion and run layout.
|
|
294
|
+
|
|
295
|
+
- Move parent completion and issue preparation into `issues/app/` with their
|
|
296
|
+
contracts in `issues/ports.ts`, and add the `IssueWorkflow` driving port so
|
|
297
|
+
the CLI depends on the use-case contract rather than the workflow function.
|
|
298
|
+
|
|
299
|
+
- Add shared port contract suites under `tests/contracts/` that run the same
|
|
300
|
+
behavioral spec against in-memory fakes and the live adapters for
|
|
301
|
+
`RunEventLog` and `IssueArtifactStore`.
|
|
302
|
+
|
|
303
|
+
- Restructure the source into hexagonal, context-first packages: each bounded
|
|
304
|
+
context (`agent`, `pi`, `github`, `git`, `issues`, `progress`, `run`,
|
|
305
|
+
`process`, `workspace`, `workflow`) owns its `ports.ts` contract, its domain
|
|
306
|
+
model, and its `adapters/` implementation together. `src/runtime.ts` and
|
|
307
|
+
`src/command.ts` are the only modules that instantiate adapters. Non-adapter
|
|
308
|
+
code imports no `node:fs`, `node:child_process`, vendor SDK, or process
|
|
309
|
+
stream; Octokit appears only inside the `github` context; the artifact and
|
|
310
|
+
recovery file systems are injected ports implemented under
|
|
311
|
+
`src/issues/adapters/`. `tests/architecture.test.ts` enforces these rules.
|
|
312
|
+
|
|
313
|
+
- Decouple execution from presentation. The progress contract now lives in
|
|
314
|
+
`src/ports/progress.ts` (no rendering or I/O dependencies), the renderers in
|
|
315
|
+
`src/progress/` implement it, and execution code no longer imports the
|
|
316
|
+
presentation layer. The `events.jsonl` audit moved out of the renderer into
|
|
317
|
+
`src/run/event-log.ts` and is closed by the run before workspace removal; the
|
|
318
|
+
dead `writeRaw`/`stopPersisting` surface is gone. `tests/architecture.test.ts`
|
|
319
|
+
enforces the import directions and process-stream ownership.
|
|
320
|
+
|
|
321
|
+
- Verification is now opt-in. The `package.json` `bun run check` discovery
|
|
322
|
+
default is removed; when no `--verify-command` is supplied the deterministic
|
|
323
|
+
gate is skipped and review proceeds on the staged diff. Supplied commands
|
|
324
|
+
still run through `/bin/sh`, their evidence is still bound to the staged
|
|
325
|
+
tree, and non-zero exits still trigger the bounded repair loop.
|
|
326
|
+
|
|
327
|
+
- Collapse every per-stage thinking setting into one `--thinking` level applied
|
|
328
|
+
to all sessions. The `--grounding-thinking`, `--implementation-thinking`,
|
|
329
|
+
`--complexity-thinking`, `--review-thinking`, and `--commit-thinking` flags
|
|
330
|
+
are gone; the default level remains `medium`.
|
|
331
|
+
|
|
332
|
+
- Pi is now the only execution backend. `--model provider/model` resolves
|
|
333
|
+
against pi's built-in catalog (defaulting to the model saved in pi's
|
|
334
|
+
`settings.json`), thinking flags accept pi levels (`off` through `max`), and
|
|
335
|
+
credentials resolve through `~/.pi/agent/auth.json`
|
|
336
|
+
(`PI_CODING_AGENT_DIR`) with provider environment variables as fallback.
|
|
337
|
+
- Agent tools are pi's built-in `read`, `write`, `edit`, and `bash`, rooted at
|
|
338
|
+
the repository checkout and guarded before execution (delivery-state shell
|
|
339
|
+
denylist plus workspace path containment); review-profile sessions expose
|
|
340
|
+
read-only tools. JSON transcript records are now `agent_event`, and the
|
|
341
|
+
progress stage `opencode-runtime` is `agent-runtime`.
|
|
342
|
+
- Add `@earendil-works/pi-agent-core`, `@earendil-works/pi-ai`, and
|
|
343
|
+
`proper-lockfile` as runtime dependencies; pi packages stay external to the
|
|
344
|
+
bundle so their lazy provider SDKs install through npm.
|
|
345
|
+
|
|
346
|
+
- Complete the post-PR review and revision lifecycle. `pr` delivery now
|
|
347
|
+
persists the immutable pull-request base/head, runs a resumable coordinator
|
|
348
|
+
with one shared five-attempt review budget, performs fresh exact-tree
|
|
349
|
+
non-force revisions when findings require changes, publishes head-scoped
|
|
350
|
+
review attempts idempotently, and records review/revision/publication/check/
|
|
351
|
+
merge boundaries in RunState v9 and the per-issue delivery artifact.
|
|
352
|
+
Merging requires a fail-closed proof containing approved structured review
|
|
353
|
+
evidence and a stable green check snapshot for the same PR/base/head; stale
|
|
354
|
+
or incomplete proof cannot merge. Exhaustion and recoverable delivery
|
|
355
|
+
failures retain the open issue, branch, and PR. Added service, coordinator,
|
|
356
|
+
workflow, resume, failure-boundary, and end-to-end coverage plus the
|
|
357
|
+
lifecycle/recovery documentation.
|
|
358
|
+
|
|
359
|
+
- Complete the first user-visible `--mode maintain-issues` release slice. The
|
|
360
|
+
mode is a bounded one-shot issue-reconciliation pass separate from the
|
|
361
|
+
default `--mode issues` delivery queue: read-only OpenCode planning feeds
|
|
362
|
+
schema/policy validation, while deterministic GitHub services perform only
|
|
363
|
+
live-revalidated additive labels, managed questions/answers, and reciprocal
|
|
364
|
+
relationship or duplicate links. Duplicate closure remains an explicit
|
|
365
|
+
`--duplicate-action close` opt-in with link → existing `duplicate` label →
|
|
366
|
+
duplicate-close ordering; uncertainty, stale data, and insufficient evidence
|
|
367
|
+
skip or replan instead of guessing. Versioned maintenance state checkpoints
|
|
368
|
+
every action for exact resume, and maintenance dry runs perform no workspace,
|
|
369
|
+
GitHub, state-file, artifact, or event-log mutation. Added offline
|
|
370
|
+
fake-GitHub/OpenCode integration coverage for reconciliation, ambiguity,
|
|
371
|
+
interruption/resume, output modes, permissions, dry-run isolation, and exit
|
|
372
|
+
codes (`tests/integration/maintain-issues.test.ts`). The documentation records
|
|
373
|
+
the required permissions, output/recovery contract, and first-release
|
|
374
|
+
non-goals; no mutation-enabled network smoke test is included.
|
|
375
|
+
|
|
376
|
+
- Dependency-blocked issues (open queue prerequisites) are recorded as
|
|
377
|
+
needs-attention outcomes but no longer publish a needs-attention GitHub
|
|
378
|
+
comment or label: the opt-in notifier is reserved for agent-reported
|
|
379
|
+
blockers that need a human decision, while queue-order blocks resolve by
|
|
380
|
+
completing the open dependencies. The `--on-needs-attention` halt/continue
|
|
381
|
+
policy and run-level progress events are unchanged.
|
|
382
|
+
|
|
383
|
+
- Progress detail, activity rows, and short JSON snapshots are no longer
|
|
384
|
+
redacted. The reporting boundary now preserves supplied values verbatim
|
|
385
|
+
(`src/progress/activity.ts` sanitizes only terminal control sequences),
|
|
386
|
+
matching the already-lossless `opencode_event` transcript records and
|
|
387
|
+
durable event log. Credentials and other sensitive values pass through into
|
|
388
|
+
transcripts, breadcrumbs, JSON Lines, and `events.jsonl` exactly as
|
|
389
|
+
supplied; only terminal control sequences are stripped from human-readable
|
|
390
|
+
rows. Documentation (`README.md`, `docs/architecture.md`, and
|
|
391
|
+
`docs/operations-and-recovery.md`) now describes this intentional unredacted
|
|
392
|
+
output contract.
|
|
393
|
+
|
|
394
|
+
- Validate OpenCode model/variant compatibility before execution and fail fast
|
|
395
|
+
on silent turns. After the OpenCode runtime starts, the workflow lists the
|
|
396
|
+
server's model catalog (`src/opencode/server.ts`, `src/opencode/variants.ts`)
|
|
397
|
+
and checks every planned stage variant (grounding, complexity,
|
|
398
|
+
implementation, review, commit message, plus the implementation fallback
|
|
399
|
+
model) against the variants each model advertises (`default` is always
|
|
400
|
+
accepted). Unsupported combinations abort the run before any issue work with
|
|
401
|
+
the offending stage, model, available variants, and the exact
|
|
402
|
+
`--*-thinking` flag to adjust, instead of failing mid-run with a misleading
|
|
403
|
+
contract error. Separately, structured and unstructured prompts now treat a
|
|
404
|
+
turn that produces no assistant message (for example a server-side model
|
|
405
|
+
resolution failure) as a distinct silent-turn failure naming the model,
|
|
406
|
+
variant, and session, with no pointless contract-violation retries; genuine
|
|
407
|
+
contract misses now emit the transcript and include a response preview in
|
|
408
|
+
the error. Covered by `tests/opencode-variants.test.ts`, new silent-turn
|
|
409
|
+
cases in `tests/opencode-client.test.ts`, and fail-fast workflow tests.
|
|
410
|
+
|
|
411
|
+
- Lock down the cross-mode display contract with end-to-end regression
|
|
412
|
+
coverage: the interactive in-progress activity surface is measured in
|
|
413
|
+
physical terminal rows (never newline counts) and stays within the shared
|
|
414
|
+
three-row replaceable region across repeated tool calls, long
|
|
415
|
+
commands/paths, narrow terminals and resize, interleaved streamed assistant
|
|
416
|
+
text, ANSI/control-sequence boundaries, completion, failure, and cleanup;
|
|
417
|
+
streamed assistant text is preserved exactly, plain/CI output stays
|
|
418
|
+
deterministic and append-only with no carriage-return or ANSI cursor bytes,
|
|
419
|
+
JSON Lines output remains parseable and lossless, and quiet mode surfaces
|
|
420
|
+
no routine activity. The command-runtime display suite drives the real
|
|
421
|
+
coordinator wiring through `runCommand`, and the docs describe the bounded
|
|
422
|
+
interactive region, concise completion/error summaries, and the
|
|
423
|
+
noninteractive fallback.
|
|
424
|
+
|
|
425
|
+
- Route the OpenCode event stream and progress updates through the compact activity
|
|
426
|
+
surface in the real coordinator/CLI path: tool-call start/delta/end, tool
|
|
427
|
+
execution start/update/end, bash execution updates, streamed thinking,
|
|
428
|
+
compaction/retry lifecycle, and active progress changes map to bounded
|
|
429
|
+
activity rows in the replaceable interactive region. The human transcript no
|
|
430
|
+
longer streams multi-line partial/final tool output or streamed thinking;
|
|
431
|
+
each tool completion emits at most one concise `✓ <tool> done` line, and a
|
|
432
|
+
failure emits one sanitized, 140-character-bounded line with enough error
|
|
433
|
+
detail to act. Assistant text deltas, session headers, durable breadcrumbs,
|
|
434
|
+
and lossless JSON `opencode_event` records are unchanged, the region never clears
|
|
435
|
+
or corrupts assistant response bytes, and `--output verbose` keeps the live
|
|
436
|
+
row count at its fixed three-row cap. Plain, JSON, and quiet modes retain
|
|
437
|
+
their append-only/structured/failure-only contracts. Coordinator-level tests
|
|
438
|
+
cover repeated calls, missing ids, interleaved assistant text, success and
|
|
439
|
+
failure, and mode-specific behavior.
|
|
440
|
+
|
|
441
|
+
- Render the interactive activity view in one replaceable three-row terminal
|
|
442
|
+
region: the sticky stage/status line plus the bounded activity rows share a
|
|
443
|
+
single region whose total height never exceeds three terminal rows (no panel
|
|
444
|
+
added beneath the footer), every row is clipped before it can wrap, and each
|
|
445
|
+
replacement repaints the region in place using the terminal stream boundary
|
|
446
|
+
primitives: repaints are deferred while a transcript fragment is open
|
|
447
|
+
mid-line or a control sequence is incomplete, and the region clears/restores
|
|
448
|
+
without overwriting streamed assistant text, splitting an ANSI/control
|
|
449
|
+
sequence, or inserting bytes into a partial line. Resize, disposal, stale
|
|
450
|
+
rows, and completion removal are handled; cursor controls remain limited to
|
|
451
|
+
interactive mode, and plain, CI, piped, JSON, and quiet surfaces stay
|
|
452
|
+
append-only or structured with no cursor-control artifacts.
|
|
453
|
+
|
|
454
|
+
- Finalize the interactive footer layout as `durable-transcript-breadcrumbs`
|
|
455
|
+
(`INTERACTIVE_FOOTER_LAYOUT_STRATEGY`, `INTERACTIVE_FOOTER_USES_SCROLL_REGION=false`,
|
|
456
|
+
`INTERACTIVE_FOOTER_USES_RESERVED_ROW=false`): the status is an in-place
|
|
457
|
+
replaceable region below streamed content, never a reserved bottom row or
|
|
458
|
+
DECSTBM scroll region, so reserved-row/scroll-region cursor manipulation is
|
|
459
|
+
disabled (no DECSTBM, CUP, alternate-screen, or save/restore sequences; only
|
|
460
|
+
in-place erase and single-row step-up repaint the region with strict
|
|
461
|
+
clear-before-draw). Interactive mode requires stdin and stderr TTYs with `CI`
|
|
462
|
+
neither `"true"` nor `"1"`; footer-only repaints coalesce at roughly 100–125 ms
|
|
463
|
+
while transcript token deltas stream immediately; partial-line/control-open
|
|
464
|
+
fragments defer repaints, rows clip at their paint-time width, resize repaints
|
|
465
|
+
only at a safe boundary, and completion/interruption (SIGINT/Ctrl-C)/failure
|
|
466
|
+
erases the region, settles on a fresh line, and emits no further bytes.
|
|
467
|
+
Plain/CI output is deterministic append-only with no `ESC`/carriage-return or
|
|
468
|
+
footer residue, verbose never expands the three-row cap, quiet keeps failures
|
|
469
|
+
and handled needs-attention stops only, and JSON stays JSON Lines on stdout
|
|
470
|
+
with stderr empty. `README.md` and `docs/operations-and-recovery.md` now
|
|
471
|
+
publish exactly this tested contract,
|
|
472
|
+
locked by `tests/progress/interactive-footer-layout-strategy.test.ts`, the PTY
|
|
473
|
+
streaming-stress fixture, the real-PTY lifecycle fixture, and the
|
|
474
|
+
noninteractive cleanup matrix.
|
|
475
|
+
|
|
476
|
+
- Deliver managed feature-branch revisions as one deterministic operation
|
|
477
|
+
with authoritative remote reconciliation: the revision safety checks run
|
|
478
|
+
before staging/commit and again immediately before the push, the exact-tree
|
|
479
|
+
revision commit is created from the allowed staged tree, the push uses only
|
|
480
|
+
Git's non-force mode to the explicit `HEAD:refs/heads/<branch>` destination
|
|
481
|
+
ref, and the outcome is classified from the authoritative post-push
|
|
482
|
+
`git ls-remote` read (never from a tracking ref or command response alone).
|
|
483
|
+
The discriminated, typed outcome distinguishes `confirmed` delivery (remote
|
|
484
|
+
equals the new commit with a clean checkout, including a lost push response
|
|
485
|
+
reconciled to success), `external-movement` (remote no longer equals the
|
|
486
|
+
expected prior head: halt without retry or force), and `ambiguous` delivery
|
|
487
|
+
(remote read cannot prove whether the new commit arrived; the created clean
|
|
488
|
+
commit is retained for safe reconciliation). Movement detected before
|
|
489
|
+
staging/commit prevents the commit from being created, cancellation is
|
|
490
|
+
checked at every mutation boundary, the push is attempted at most once, and
|
|
491
|
+
the `lgtm` direct-push path and its shared, regression-tested helpers are
|
|
492
|
+
unchanged.
|
|
493
|
+
|
|
494
|
+
- Tighten human transcript bounds to 3 lines/140 characters: tool incremental
|
|
495
|
+
output uses `LIVE_OUTPUT_LIMIT=140`, thinking/assistant streams use the same
|
|
496
|
+
140-character bound, and final previews truncate to 3 lines/140 characters
|
|
497
|
+
with the existing truncation marker. Truncated tool, thinking, and assistant
|
|
498
|
+
streams still report background totals (total characters and lines with a
|
|
499
|
+
`truncated` marker). JSON and durable logs remain lossless.
|
|
500
|
+
|
|
501
|
+
- Add the needs-attention recovery contract across the OpenCode boundary, issue
|
|
502
|
+
executor, recovery service, and local end-to-end path: bounded fenced
|
|
503
|
+
`needs-attention` blocks (`reason` one of `outdated_premise`,
|
|
504
|
+
`conflicting_requirements`, `missing_information`, `external_dependency`, or
|
|
505
|
+
`cannot_reproduce`, plus an optional message capped at 2,000 characters)
|
|
506
|
+
accompany the required schema-valid fenced `json` result from grounding,
|
|
507
|
+
complexity, implementation, review-fix, commit-message, review, and
|
|
508
|
+
decomposition sessions; each signal is confirmed by exactly one fresh
|
|
509
|
+
read-only verifier session before any further artifact, Git, or GitHub
|
|
510
|
+
mutation. A confirmed `needs_attention` disposition persists the structured
|
|
511
|
+
decision with its summary, evidence, questions, and issue-freshness
|
|
512
|
+
fingerprint, leaves the source issue open, performs no GitHub mutation and
|
|
513
|
+
no commit or push, and restores the clean checkpoint by removing staged,
|
|
514
|
+
unstaged, and untracked agent changes; verifier rejection continues the
|
|
515
|
+
original attempt, and diagnostic, restoration, or repository-invariant
|
|
516
|
+
failures are reported as recoverable rather than successful. Recovery
|
|
517
|
+
diagnostics live under
|
|
518
|
+
`runs/<run-id>/issues/<issue-number>/needs-attention-<id>/` with
|
|
519
|
+
`changes.patch` and `metadata.json`, keyed by fingerprint and reused only on
|
|
520
|
+
exact matches.
|
|
521
|
+
|
|
522
|
+
- Bound every command execution with a hard deadline so a hung process cannot
|
|
523
|
+
stall an unattended issue run: OpenCode task shell commands default to a
|
|
524
|
+
120-second timeout with a 600-second maximum (an omitted `timeout` gets the
|
|
525
|
+
default and a larger declared timeout is clamped), Ralphie-owned git/gh and
|
|
526
|
+
workspace commands default to a 10-minute timeout via `CommandRunnerLive`,
|
|
527
|
+
and deterministic verification commands run under a 30-minute timeout. A
|
|
528
|
+
timed-out command is killed and reported as `CommandTimeoutError` with the
|
|
529
|
+
deadline and command in the message; agent tool calls surface
|
|
530
|
+
`Command timed out after N seconds` with partial output and can retry with
|
|
531
|
+
an explicit timeout.
|
|
532
|
+
|
|
533
|
+
- Resolve open dependencies on decomposed tracking parents transitively to
|
|
534
|
+
their open leaf children in the issue queue, so a child depending on a
|
|
535
|
+
decomposed-but-open container issue can never deadlock against a parent
|
|
536
|
+
that is never queued for execution.
|
|
537
|
+
- Surface dependency-blocked end-of-run issues as explicit needs-attention
|
|
538
|
+
outcomes (reason `external_dependency`) with evidence naming each open
|
|
539
|
+
dependency, instead of failing the run with a bare "blocked by open
|
|
540
|
+
dependencies" error: `--on-needs-attention halt` stops with the handled
|
|
541
|
+
stop; `continue` completes the run with the preserved issues still pending,
|
|
542
|
+
and no GitHub notification or label is published for queue-order blocks
|
|
543
|
+
(the opt-in notifier is reserved for agent-reported blockers).
|
|
544
|
+
- Pin grounding and resolution-verification evidence to the exact
|
|
545
|
+
checked-out commit: the read-only prompts now name the checked-out SHA
|
|
546
|
+
alongside the repository path and target branch.
|
|
547
|
+
|
|
548
|
+
### Fixed
|
|
549
|
+
- Live OpenCode transcript streaming renders every `thinking_delta` / `text_delta`
|
|
550
|
+
(and tool output update) inline on the already-open `⋯ thinking` / `✦ assistant`
|
|
551
|
+
row instead of forcing one token per `│`-prefixed line; incremental deltas no
|
|
552
|
+
longer break the open stream, so interactive output wraps naturally at the
|
|
553
|
+
terminal width and durable progress/breadcrumb lines still interleave cleanly.
|
|
554
|
+
- Repeated structured-output attempts that never produce a schema-valid result
|
|
555
|
+
now trip a circuit breaker that aborts the OpenCode session after five
|
|
556
|
+
consecutive failures and reports the likely cause instead of letting the
|
|
557
|
+
model retry until the prompt-attempt budget expires.
|
|
558
|
+
### Changed
|
|
559
|
+
|
|
560
|
+
- Added `--max-decomposition-depth` (default `3`) and persisted it in run state.
|
|
561
|
+
A direct or review-escalated decomposition beyond the configured ceiling now
|
|
562
|
+
leaves the issue open as `decomposition_limit_reached` needs attention and
|
|
563
|
+
continues independent queued work instead of failing and halting the run;
|
|
564
|
+
dependent issues remain blocked.
|
|
565
|
+
|
|
566
|
+
- OpenCode implementation sessions now allow ordinary composed shell commands,
|
|
567
|
+
pipes, redirection, and interpreters while continuing to reject explicit
|
|
568
|
+
orchestration-owned Git/GitHub mutations.
|
|
569
|
+
- Implementation completion is schema validated. Unresolved empty diffs enter
|
|
570
|
+
a bounded fresh-session retry loop with verifier evidence, configurable
|
|
571
|
+
implementation thinking, retry count, and optional fallback model.
|
|
572
|
+
- A tentative `already_resolved` grounding route now continues through
|
|
573
|
+
complexity assessment when fresh verification finds unresolved work. The
|
|
574
|
+
verifier evidence seeds the first implementation session, unresolved
|
|
575
|
+
resolution artifacts cannot short-circuit resumed work, and operational or
|
|
576
|
+
malformed verification failures still fail closed.
|
|
577
|
+
- `--on-issue-failure continue` restores failed issue checkouts and drains
|
|
578
|
+
independent queued work before returning an aggregate non-zero result;
|
|
579
|
+
failed prerequisites continue to block dependent issues.
|
|
580
|
+
|
|
581
|
+
- Deterministic verification command failures now enter a bounded repair loop
|
|
582
|
+
instead of immediately failing the issue and halting the queue. Each repair
|
|
583
|
+
receives the exact staged diff and bounded failed-command evidence in a fresh
|
|
584
|
+
mutating session, is restaged and reverified, and must pass before review or
|
|
585
|
+
commit. Repairs that change an approved staged tree force another review;
|
|
586
|
+
exhausted repairs and verification integrity faults still fail closed.
|
|
587
|
+
|
|
588
|
+
- Decomposition now uses native GitHub sub-issues and dependencies: every
|
|
589
|
+
created or recovered child is attached to the original issue as a native
|
|
590
|
+
sub-issue, declared `dependsOn` edges become native `blocked_by`
|
|
591
|
+
relationships, and the decomposed parent stays open as a tracking issue
|
|
592
|
+
instead of being closed as a duplicate. Child bodies keep only the stable
|
|
593
|
+
recovery marker and dependency list, and decomposed parents are never
|
|
594
|
+
re-queued for execution. Native relationships are reconciled idempotently on
|
|
595
|
+
resume; conflicting hierarchy or markers halt with a recovery diagnostic.
|
|
596
|
+
- Dequeued issues are refreshed from GitHub before branch or OpenCode work; closed or
|
|
597
|
+
label-ineligible issues are durably skipped without mutations, and cached
|
|
598
|
+
grounding, complexity, and resolution decisions now require matching live
|
|
599
|
+
issue freshness metadata.
|
|
600
|
+
- The `pr` workflow now gates merged delivery: after creating or finding the
|
|
601
|
+
matching feature-branch pull request it persists the PR number and head SHA,
|
|
602
|
+
publishes review attempts, waits for the exact-SHA check observer to reach
|
|
603
|
+
its documented green state, re-reads the PR immediately before merging, and
|
|
604
|
+
invokes the expected-head merge only while the head is unchanged. A failed,
|
|
605
|
+
cancelled, timed-out, absent, unknown, changed-head, closed, or unmergeable
|
|
606
|
+
gate retains the feature branch and PR, persists an active recoverable
|
|
607
|
+
closure gate, and never merges or closes the source issue; resume locates
|
|
608
|
+
the existing PR instead of duplicating it, continues polling pending gates,
|
|
609
|
+
invalidates saved green evidence on a changed head, re-observes failed
|
|
610
|
+
gates on a later rerun, and reconciles an already-merged PR without another
|
|
611
|
+
merge call. Run state version 6 records the PR number, observed head SHA,
|
|
612
|
+
latest normalized check snapshot, observation start/last-update timestamps,
|
|
613
|
+
gate status, and terminal reason for an active PR closure, with migration
|
|
614
|
+
coverage for versions 2–5. The `lgtm` workflow and dry-run paths are
|
|
615
|
+
unchanged, and GitHub mutations remain in the deterministic `src/github/`
|
|
616
|
+
services.
|
|
617
|
+
|
|
618
|
+
### Added
|
|
619
|
+
|
|
620
|
+
- `bun run probe:structured-output` accepts `--union` to pre-flight a model
|
|
621
|
+
against the exact grounding decision contract plus `--model provider/model`,
|
|
622
|
+
`--agent`, and `--variant` for targeting a specific model before a run.
|
|
623
|
+
- The `pr` gate now streams dedicated `pr-gate` progress events for
|
|
624
|
+
registration (pull-request number and exact head SHA), poll progress only
|
|
625
|
+
for meaningful check transitions (registration, checks registering,
|
|
626
|
+
appearing or disappearing, and status changes: unchanged polls never
|
|
627
|
+
emit), head invalidation, and terminal success/failure, timeout, and
|
|
628
|
+
cancellation with the check summary and reason. Human and verbose output
|
|
629
|
+
explain the PR number, exact SHA, check summary, and reason; JSON output
|
|
630
|
+
exposes the structured normalized snapshot and timestamps; quiet output
|
|
631
|
+
suppresses the routine gate milestones while still reporting gate failures.
|
|
632
|
+
The observer exposes an optional `onTransition` callback invoked only on
|
|
633
|
+
meaningful transitions, and a merged gate record now retains the green
|
|
634
|
+
observation snapshot as persistent merge evidence.
|
|
635
|
+
- Deterministic PR-gate regression coverage: a local end-to-end PR workflow
|
|
636
|
+
with a fake GitHub check service that records merge calls and proves none
|
|
637
|
+
occur before a stable green snapshot, resume from pending/green/failed and
|
|
638
|
+
already-merged gate states, unknown and cancelled gate outcomes, expected-head
|
|
639
|
+
merge rejection recording a stale gate, pending-to-failure and mixed Check
|
|
640
|
+
Run/commit-status transitions, and quiet/JSON rendering of gate events.
|
|
641
|
+
|
|
642
|
+
- A deterministic, read-only pipeline observation service
|
|
643
|
+
(`src/github/pipeline-observation.ts`) that polls normalized pipeline
|
|
644
|
+
snapshots for one exact SHA: it tolerates an initial registration grace
|
|
645
|
+
period while no checks are visible, keeps polling while any item is pending,
|
|
646
|
+
requires configurable stable terminal confirmations, fails closed on
|
|
647
|
+
unknown, cancelled, failing, and empty terminal results, collects every
|
|
648
|
+
page from Check Runs and legacy commit statuses, uses bounded exponential
|
|
649
|
+
backoff and bounded rate-limit retries with delta-seconds, HTTP-date, and
|
|
650
|
+
reset metadata without retrying before server hints or sleeping past an
|
|
651
|
+
absolute deadline, honors caller cancellation reasons, emits only
|
|
652
|
+
meaningful state transitions, and finishes with a race-safe remote-HEAD
|
|
653
|
+
check that reports a stale result when the branch advances so callers can
|
|
654
|
+
follow a newly advanced HEAD.
|
|
655
|
+
- Complete the `--mode get-pipelines-green` release slice. The dedicated
|
|
656
|
+
direct base-branch runner authenticates and prepares one selected branch,
|
|
657
|
+
observes every supported Check Run, Check Suite, legacy status, and Actions
|
|
658
|
+
workflow source for one exact SHA, collects bounded terminal-sanitized
|
|
659
|
+
diagnostics, and runs a persisted repair/verify/commit/non-force-push loop.
|
|
660
|
+
A green exit requires a non-empty all-passing snapshot with no source or
|
|
661
|
+
completeness errors and a final current-HEAD proof; pending, acceptable,
|
|
662
|
+
failing, cancelled, unknown, and no-pipeline outcomes fail closed. The
|
|
663
|
+
versioned pipeline state adapter records absolute deadlines, confirmed-push
|
|
664
|
+
attempts, checkpoints, fingerprints, diagnostic references, and commit
|
|
665
|
+
evidence atomically; resume invalidates stale snapshots, reconciles an
|
|
666
|
+
ambiguous push without duplicate charging, and preserves the original
|
|
667
|
+
deadline. Dry-run performs authentication, preparation, observation, and
|
|
668
|
+
diagnostics only. The CLI reference, end-to-end trace, safety model,
|
|
669
|
+
operations/recovery guide, architecture map, and README document the mode,
|
|
670
|
+
output/exit contract, incompatible flags, provider limitations, untrusted CI
|
|
671
|
+
handling, artifact paths, cancellation, and recovery behavior.
|
|
672
|
+
- An opt-in `RALPHIE_RUN_GITHUB_SUB_ISSUES_SMOKE` integration test that
|
|
673
|
+
exercises the real native sub-issue and dependency API in a configured
|
|
674
|
+
sandbox repository: attachment and dependency idempotency, reads, live
|
|
675
|
+
parent-completion reconciliation, and cleanup.
|
|
676
|
+
- Deterministic decomposed-parent completion: finishing the final child
|
|
677
|
+
reconciles its tracking parent immediately, and every non-dry-run run
|
|
678
|
+
reconciles discovered decomposed parents, closing a parent as `completed`
|
|
679
|
+
only when every native sub-issue is closed. Parents awaiting sub-issue
|
|
680
|
+
attachment recovery, non-Ralphie parents, and already-closed parents are
|
|
681
|
+
left untouched.
|
|
682
|
+
- Dry-run decomposition reporting: a complexity 4–5 dry run performs the
|
|
683
|
+
read-only breakdown session and reports the intended native sub-issue
|
|
684
|
+
hierarchy: children to create or reuse, sub-issue attachments, dependency
|
|
685
|
+
edges, and the open tracking parent: without mutating GitHub or writing
|
|
686
|
+
artifacts. An unverified needs-attention signal from the planning session is
|
|
687
|
+
reported as a needs-attention route without invoking recovery.
|
|
688
|
+
- A deterministic GitHub issue-relationship domain service
|
|
689
|
+
(`src/github/issue-relationships.ts`) that lists, attaches, and validates
|
|
690
|
+
native sub-issues and dependencies with idempotent, response-loss-safe
|
|
691
|
+
mutations and actionable unsupported-endpoint errors.
|
|
692
|
+
- A terminal output controller (`src/progress/terminal-controller.ts`) that
|
|
693
|
+
wraps the footer view scheduler and the shared `ProgressOutput` primitives
|
|
694
|
+
and arbitrates every transcript/raw write with the terminal stream boundary
|
|
695
|
+
tracker: an active footer is cleared before transcript or durable progress
|
|
696
|
+
output, token deltas are forwarded immediately, and the footer is restored
|
|
697
|
+
only at safe line boundaries. Durable progress lines are deferred while a
|
|
698
|
+
transcript fragment is open mid-line so progress never merges with,
|
|
699
|
+
overwrites, or falsely closes the fragment; footer bytes are emitted only
|
|
700
|
+
through the strategy's footer surface and never enter transcript/control
|
|
701
|
+
payload or durable scrollback; every replacement repaint clears a visible
|
|
702
|
+
footer before drawing the new one; durable transcript breadcrumbs remain
|
|
703
|
+
the safe default fallback with cursor-reserved-row behavior disabled by
|
|
704
|
+
default. Coverage exercises partial transcript lines, progress
|
|
705
|
+
interleaving, immediate token forwarding, split ANSI/control strings,
|
|
706
|
+
footer suppression while unsafe, restoration after a safe boundary, and
|
|
707
|
+
strict clear-before-draw ordering through fake sinks and fake strategies.
|
|
708
|
+
- A persisted `created-issue-dependencies` artifact that records each child's
|
|
709
|
+
dependency issue numbers so queue eligibility never depends on live GitHub
|
|
710
|
+
state alone.
|
|
711
|
+
|
|
712
|
+
- A single package-version authority with build-time commit metadata and plain
|
|
713
|
+
or JSON `--version` output that works without repository or OpenCode configuration.
|
|
714
|
+
- An isolated package smoke check that inspects the tarball allowlist, installs
|
|
715
|
+
production dependencies in a fresh project, and verifies scoped identity and
|
|
716
|
+
manifest-backed `--version` output.
|
|
717
|
+
- Staged-tree-bound deterministic verification before review, after review
|
|
718
|
+
fixes, and before commit, with persisted command evidence and repeatable
|
|
719
|
+
`--verify-command` overrides.
|
|
720
|
+
- Stage-specific thinking controls for grounding, complexity routing, review,
|
|
721
|
+
and commit-message generation.
|
|
722
|
+
- Discriminated top-level CLI configuration for issue,
|
|
723
|
+
`maintain-issues`, and `get-pipelines-green` modes, including duplicate
|
|
724
|
+
handling policy, bounded attempts, and strict pipeline timeout values.
|
|
725
|
+
- Read-only issue grounding with a persisted needs-attention deferral: blocked
|
|
726
|
+
issues keep their evidence, questions, and freshness fingerprint, remain
|
|
727
|
+
open, and are never closed or marked complete; complexity is never a
|
|
728
|
+
needs-attention reason.
|
|
729
|
+
- An explicit `halt` (default) / `continue` needs-attention policy with
|
|
730
|
+
versioned run-state migration, resume conflict protection, exit status `2`
|
|
731
|
+
for handled stops and exit `0` only when `continue` drains the queue.
|
|
732
|
+
- Confirmed needs-attention recovery that atomically preserves bounded,
|
|
733
|
+
binary-safe worktree diagnostics before restoring and verifying the exact
|
|
734
|
+
clean issue checkpoint.
|
|
735
|
+
- Resumable needs-attention handoffs with one fresh read-only verifier for every
|
|
736
|
+
executor signal, immutable confirmation before recovery, and idempotent,
|
|
737
|
+
freshness-bound diagnostics across interruptions.
|
|
738
|
+
- Durable needs-attention notification recovery: structured outcomes and label
|
|
739
|
+
intent are saved before GitHub mutation, and resume retries the stable marker
|
|
740
|
+
without rerunning agent work.
|
|
741
|
+
- An explicit, disabled-by-default `--notify-needs-attention` CLI opt-in with a
|
|
742
|
+
trimmed `--needs-attention-label`; label-only usage is rejected, dry runs
|
|
743
|
+
never notify, and failed notifications retain their intent for safe resume
|
|
744
|
+
and retry.
|
|
745
|
+
- Native Bun CLI foundation with GitHub, Git, workspace, and OpenCode domain
|
|
746
|
+
services.
|
|
747
|
+
- Resumable issue execution with complexity routing, bounded review loops,
|
|
748
|
+
deterministic commits and pushes, and dependency-aware decomposition.
|
|
749
|
+
- Typed progress events, JSON Lines output, and diagnostics.
|
|
750
|
+
- Structured no-change resolution verification with persisted evidence.
|
|
751
|
+
|
|
752
|
+
### Changed
|
|
753
|
+
|
|
754
|
+
- Refresh each issue before mandatory grounding, route actionable work through
|
|
755
|
+
the existing complexity thresholds, require fresh concrete verification for
|
|
756
|
+
already-resolved closure, and keep needs-attention outcomes out of closure
|
|
757
|
+
and PR delivery. Complexity is never a needs-attention reason.
|
|
758
|
+
- Document the cross-mode display contract: interactive sticky footer and
|
|
759
|
+
contextual OpenCode session output, periodic and lifecycle breadcrumbs, the
|
|
760
|
+
`LIVE_OUTPUT_LIMIT` character threshold and human-preview defaults, active
|
|
761
|
+
leaf-stage status, append-only plain/CI output, quiet output limited to
|
|
762
|
+
failures and handled needs-attention stops,
|
|
763
|
+
lossless JSON Lines without human breadcrumb records, and the independent
|
|
764
|
+
durable progress-event log preserving supplied values (never redacted).
|
|
765
|
+
- Expose grounding and needs-attention decisions consistently across default,
|
|
766
|
+
interactive, verbose, quiet, and JSON Lines output, including complete
|
|
767
|
+
evidence, questions, artifact paths, policy, and final outcome counts.
|
|
768
|
+
- Make dry-run grounding and routing strictly read-only: report all routes,
|
|
769
|
+
reuse persisted decisions without rewriting issue artifacts, and keep resumed
|
|
770
|
+
dry runs away from implementation, delivery, and Git/GitHub mutations.
|
|
771
|
+
- Refresh live issue and comment metadata when resuming pending work, and reuse
|
|
772
|
+
needs-attention grounding only while its freshness fingerprint matches;
|
|
773
|
+
changed or invalid artifacts are atomically invalidated before regrounding.
|
|
774
|
+
- Keep OpenCode configuration separate from persistent workspace state:
|
|
775
|
+
`--opencode-url`/`OPENCODE_URL` and `--opencode-token`/`OPENCODE_TOKEN` are
|
|
776
|
+
operator-owned inputs, while local background-service discovery remains
|
|
777
|
+
outside the workspace state tree.
|
|
778
|
+
- Define noninteractive `github.com` authentication through the preferred
|
|
779
|
+
`GH_TOKEN` and fallback `GITHUB_TOKEN` environment variables, without
|
|
780
|
+
requiring `gh auth login` or a mounted GitHub CLI profile.
|
|
781
|
+
- Document the published scoped Bun package and use
|
|
782
|
+
`bunx @beremaran/ralphie` for installation, version verification, dry-run,
|
|
783
|
+
and workflow examples; the scope distinguishes this CLI from the unrelated
|
|
784
|
+
unscoped npm package named `ralphie`.
|
|
785
|
+
- Resolve dependencies on decomposed closed issues to their open descendants,
|
|
786
|
+
stop repeated identical review findings early, permit safe compound shell
|
|
787
|
+
inspection commands, and use GitHub REST API version `2026-03-10`.
|
|
788
|
+
- Polish human-readable OpenCode streaming with grouped session blocks, readable tool
|
|
789
|
+
calls, indented de-duplicated tool output, bounded previews, and safe handling
|
|
790
|
+
of terminal control sequences while preserving the lossless JSON event stream.
|
|
791
|
+
- Stream the complete OpenCode event transcript, including token-level thinking
|
|
792
|
+
and assistant output plus tool calls and results, and remove parallel issue
|
|
793
|
+
and OpenCode session execution.
|
|
794
|
+
- Consolidate the CLI surface: fold `--issue-order` into
|
|
795
|
+
`--issue-sort <field>[:asc|desc]`; use `--thinking` for the selected OpenCode
|
|
796
|
+
variant and `--opencode-url`/`--opencode-token` for the external server;
|
|
797
|
+
replace `--start-clean` and `--cleanup` with `--clean <start|end|both>`;
|
|
798
|
+
and replace `--verbose`, `--json`, and `--quiet` with
|
|
799
|
+
`--output <default|verbose|quiet|json>`.
|
|
800
|
+
- Keep model selection under `--model <provider/model>` and server credentials
|
|
801
|
+
under `OPENCODE_URL` and `OPENCODE_TOKEN`; the retired embedded-agent flags
|
|
802
|
+
and `RALPHIE_MODEL_*` environment variables are no longer part of the CLI.
|
|
803
|
+
|
|
804
|
+
### Added
|
|
805
|
+
|
|
806
|
+
- Native Bun CLI foundation with GitHub, Git, workspace, and OpenCode domain
|
|
807
|
+
explicit service factories, and an ordinary runtime dependency object.
|
|
808
|
+
- Focus execution on one required repository and accept all configuration through
|
|
809
|
+
CLI arguments and flags; remove JSON configuration, named projects, repository
|
|
810
|
+
patterns, and multi-repository orchestration.
|
|
811
|
+
- Use the external `@opencode-ai/client` server integration, operator-run
|
|
812
|
+
OpenCode sessions, a permission watcher and denylist for defense in depth,
|
|
813
|
+
and fenced structured-output/needs-attention responses validated by Zod.
|
|
814
|
+
- Rely on the authoritative non-force Git push for GitHub branch policy and
|
|
815
|
+
permission enforcement while retaining destination, commit, and divergence
|
|
816
|
+
safety checks.
|
|
817
|
+
- Render interactive progress through a bounded replaceable terminal region with
|
|
818
|
+
nested-stage tracking instead of creating an OpenTUI renderer.
|
|
819
|
+
- Close completed implementation issues after verified delivery, with
|
|
820
|
+
idempotent recovery for interrupted or ambiguous GitHub responses.
|
|
821
|
+
|
|
822
|
+
### Fixed
|
|
823
|
+
|
|
824
|
+
- Prevent final progress events from recreating a workspace removed by
|
|
825
|
+
`--clean end`.
|
|
826
|
+
- Prevent viewport repainting, split-stream output, and accumulating
|
|
827
|
+
`CliRenderer` destroy listeners during long runs.
|
|
828
|
+
- Prevent no-change agent runs from being silently skipped without proving
|
|
829
|
+
whether the issue is already resolved.
|
|
830
|
+
|
|
831
|
+
[Unreleased]: https://github.com/beremaran/ralphie/compare/v0.2.0...HEAD
|
|
832
|
+
[0.2.0]: https://github.com/beremaran/ralphie/compare/v0.1.2...v0.2.0
|