fix: engine FM-merge protection + browse perf & detail-view overhaul - #374
Conversation
…no intent.md markers) The version auto-bump to 10.0.0 activated the v9→v10 migration, which materializes `stages` onto intent.md. When that ran on intent main mid-flight, it diverged intent main's intent.md from a stage branch's — and `ensureOnStageBranch` Stage 2 (the per-tick main→stage enforcement merge) was a PLAIN `git merge` with no engine-state guard. It conflicted on intent.md and left conflict markers in a workflow-managed file, so the seal choked parsing it (`YAMLException`) and the cursor reported "stage-branch enforcement failed". CI on the bump commit went red on seal-intent-commits. Route Stage 2 through `engineProtectedMergeInCwd` like every other engine merge — target/HEAD-authoritative. Per the stage-branch invariant the stage is ahead of main and authoritative for its own state (downstream-sync-clobber), so this keeps the stage's rich FM AND deterministically resolves intent.md to one valid copy — no markers ever reach the agent. Also hardens `mergeStageBranchIntoMain` the same way (settleEngineConflicts on each conflict-return path). Tests (at v10): seal-intent-commits green again; new ensure-stage-branch-engine-fm pins that ensureOnStageBranch resolves divergent intent.md without markers; downstream-sync-clobber + unit-worktree-sibling-clobber still green (target- authoritative invariant preserved). Full suite 2070/0 at v10. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…og, write-audit) The engine appends to intent-root journals (action-log.jsonl, write-audit.jsonl, drift baselines) during a unit's work, so they show up in the unit's git diff — and `autoPopulateOutputs` was missing them from its bookkeeping exclusion, so they leaked into `outputs:` and rendered on the SPA output surface. - Source: `autoPopulateOutputs` now excludes `INTENT_ROOT_INTERNAL_ENTRIES` (the same set the intent-root file parser already hides) — no new leaks. - SPA display: `parseUnitOutputs` drops any declared output whose basename is an intent-root journal — covers intents that leaked before the source fix. - Website already filters `.jsonl` from the outputs list (isBookkeepingArtifact). Test: parse-output-artifacts pins that action-log.jsonl / write-audit.jsonl declared in a unit's outputs never surface, while the real deliverable does. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…p the O(3N) fan-out The list view was O(3N): per haiku/<slug>/main branch it did a readFile + an MR fetch + a per-stage unit probe, plus a separate MR fetch for every stage branch. That's the slowness. Lean path: - Drop the per-stage-branch MR fan-out entirely (MR/PR status loads lazily in the detail view, where it's already fetched). - Replace the per-main readFile + MR + per-stage-probe loop with ONE raw aliased GraphQL request (`batchMainBranchData`): for every main branch, read `intent.md` + the immediate `stages/` subdir names as per-branch aliases, chunked. Relay queries are static and can't fan out across a variable set of refs, so this uses a raw POST to /api/graphql. - Active stage + progress derive from the stage-dir set (the lean equivalent of the old per-stage unit probe) — the card's `Stage:` + `N/total` bar. - Removed the now-dead `probeStagesWithUnits`. Default-branch catalog still loads via listIntentsFromRef (tree + batched blobs). Per-main is now one batched request instead of 3N. (Folding the default-branch blobs into the same raw batch — to hit a strict ≤3 queries — is a follow-up.) Network path verified by typecheck + the pure-helper browse tests; full load needs in-browser verification against a real GitLab project. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ity with GitLab) Mirror the GitLab lean loader on the GitHub provider. The per-main fan-out was readFile + per-stage unit probe per haiku/<slug>/main branch; replace it with ONE raw aliased GraphQL request (`batchMainBranchData`) that reads each main branch's `intent.md` text + its `.haiku/intents/<slug>/stages/` subdir names (stage-dir count) via per-branch `object(expression:"ref:path")` aliases, chunked. Active stage + progress derive from the stage-dir set. PR metadata is already inline in the branch-list query, so it's kept at no extra cost (no separate PR fetch). Removed the now-dead `probeStagesWithUnits`. Relay queries are static (can't fan out across refs), hence the raw POST to api.github.com/graphql. Network path verified by typecheck + the pure-helper browse tests; full load needs in-browser verification against a real GitHub repo. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ult branch An intent is no longer sealed the moment its approvals sign. Sealing is the terminal write-lock (`sealed_at`), and the work isn't actually delivered until `haiku/<slug>/main` lands on the repo's default branch. So the cursor now gates the seal on that merge. Engine: - New `orchestrator/workflow/intent-delivery.ts` — `intentDeliveryState` / `isAwaitingMerge`, squash-merge-aware via the existing `isBranchMerged` (local `--is-ancestor` first, gh/glab merged-PR fallback), plus a cheap local-only mode for per-request display paths. - Cursor terminal gate emits a new `pending_seal` action and HOLDS (no `sealed_at`) when the hub branch isn't an ancestor of the default branch. Falls through to `seal_intent` when merged, in filesystem mode, or when no default branch resolves. The engine never merges itself (honors "never merge unless asked"); the next tick re-checks and seals once the merge lands. - `pending_seal` prompt builder + template, registered. - On `/haiku:haiku-pickup` of a held intent, `haiku_run_next` re-opens the `PR_INTERACTION_ROLES` approvals (`delivery-verifier`) so it re-audits the open change request and files feedback for new review comments before sealing. Keyed on the role-class set, so cascade overrides are honored. Phase indicators: - Statusline: new `pending_seal` phase (render kind + violet hue, "pending seal" label, gated). - Derived status `pending_seal` on `haiku_intent_list`. Left `haiku_capacity` sealed_at-only (throughput report, not a phase indicator — held intents count as in-flight there). - SPA wire: `current_state.seal_status` + `awaiting_merge_into` (Zod + engine type + `current-state.ts`); `IntentCompleteView` renders a "Pending seal" badge and "awaiting merge into <default>" copy. - Website architecture map post-intent card + actors/payload sync; CLAUDE.md concept row; PROMPTS.md folder listing. Tests: - `seal-intent-commits` now proves both halves: it holds at `pending_seal` with no `sealed_at`, then seals after a simulated delivery. - New shared `deliverIntent` test helper (merges the hub branch onto the default branch — what the human/host does); the 8 git-backed lifecycle/e2e drivers call it on `pending_seal` so they still reach `sealed`. - Refreshed the stale `parity.spec.tsx` DOM snapshot (a pre-existing GateDecisionBar copy drift unrelated to this change). Full suites green: haiku 2069, haiku-api 171, haiku-ui 574; haiku-ui + website typecheck clean; MCP build green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…intents never vanish A main-only intent (haiku/<slug>/main not yet on the default branch) disappeared from the list view: the new raw aliased batch returned no intent.md for it and the loader skipped it silently. Two fixes: - rawGraphql now console.warns GraphQL `errors[]` (they come back HTTP 200 with null data) + HTTP/transport failures — a dropped intent was otherwise indistinguishable from "no such intent". - batchMainBranchData falls back PER BRANCH to the proven single-ref reads (readFileFromRef for intent.md + a stages-dir tree query) whenever the batch yields no intent.md — correctness first; the batch stays the fast path. The console warning will show why the batch missed so the fast path can be fixed definitively. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…wse-perf Consolidate the pending-seal feature onto this branch so it ships as one PR alongside the engine-FM-merge / browse-perf work. Conflicts resolved: - state-tools.ts: import collision only (kept both `isAwaitingMerge` and `INTENT_ROOT_INTERNAL_ENTRIES`); the derived-status edits auto-merged. - plugin/bin/haiku.mjs: regenerated by rebuild (now bakes v10). Consolidated suites green: haiku 2071, haiku-ui 574; haiku-ui + website typecheck clean; MCP build clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…anch #100 were dropped) `branchNames(searchPattern:"haiku/*", limit:100)` returned a single 100-branch page. A busy monorepo has far more than 100 `haiku/*` branches (every unit branch counts — 168 here), so any intent whose `*/main` branch sorted past the cutoff silently vanished from the list (worker-new-badge: branch #100+ → missing). Two changes: - Narrow the glob to `haiku/*/main` — the lean list only needs the per-intent main branches, not unit/stage branches. 168 → 53 results here. - Paginate: loop `offset` by 100 until a short page signals the end, so it scales past any single-page cap. Verified live (Playwright, real GitLab monorepo): list went 88 → 98 intents and the worker-new-badge card renders correctly — "Add \"New\" badge to recent workers", completed, Security, 6/6 stages. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ab fix) `refs(refPrefix: "refs/heads/haiku/", first: 100)` capped at a single page, so on a repo with >100 `haiku/*` branches any intent whose `*/main` ref sorted past #100 dropped off the list — same bug just fixed for GitLab. GitHub's `refs` is cursor-paginated (not offset), so loop on `pageInfo.hasNextPage`/`endCursor` until exhausted. Done via raw GraphQL rather than the static Relay artifact so `after:` can be threaded without regenerating compiled queries; the artifact + its import stay for the single-slug detail path (scoped to one intent's branches, no cap risk). Trimmed the per-node selection to the fields actually consumed (name + PR number/url/state). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…the display layer
A sealed_at stamp written before the merge gate landed (or any premature
seal) shouldn't read as "done" while the work is still ahead of the
default branch. The write-gate stops NEW premature seals, but the display
surfaces still trusted sealed_at blindly, so a legacy sealed-but-unmerged
intent kept showing "sealed".
Now the status surfaces re-check the merge locally and show pending-seal
when the hub branch hasn't landed — honoring the original ask: "while the
cursor signal may say sealed, if the branch isn't merged its status
should be pending seal."
- statusline: the sealed render block flips to the `pending_seal` phase
("pending seal", gated) when `isAwaitingMerge` (local-only); pickActiveIntent
keeps a sealed-but-unmerged intent in the live set so it still shows.
- current-state (SPA wire): `seal_status`/`awaiting_merge_into` derive
pending_seal for a sealed-but-unmerged intent, not just an unsealed one.
- haiku_intent_list: a sealed stamp resolves to "pending_seal" when the
hub branch isn't merged, else "completed".
All local probes (no gh/glab) so the per-prompt status line stays fast.
Full suites green: haiku 2071, statusline 43, intent-list 127.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…puts viewable The detail view loaded an intent's metadata from its haiku/<slug>/main branch but then read each artifact's bytes from the DEFAULT branch (provider.readFile used this.branch, which is empty on a slug-only URL). An unmerged intent's deliverables don't exist on the default branch, so every output/input rendered "no file is on disk" (website) / "(empty)" (SPA) even though the files were right there on the intent branch. - Add an optional `ref` to BrowseProvider.readFile / resolveAssetUrl (GitLab + GitHub honor it; local ignores it). The detail views pass the intent's branch so artifacts resolve from where they actually live. - Thread intent.branch through IntentDetailView -> StageDetail/UnitOutputsSection (stage UNIT OUTPUTS) and -> UnitDetailView -> Artifacts/Refs sections (unit view). - Unit view: a declared output is either repo-root code (web/.../X.tsx) or intent-relative (stages/.../plan.md). It only ever tried the intent-relative shape; add the same as-is-then-intent-relative candidate resolution the stage view already used, so code outputs resolve too. - Code-type inputs/outputs are now clickable + syntax-highlighted: the unit view had its own narrow text allowlist that classified .tsx/.ts/.js as binary -> a dead download link. Switch to the shared FilePreview/isTextFile (CODE_LANG map -> hljs), so code opens in the doc modal highlighted like the stage view. Verified live (Playwright, GitLab monorepo, worker-new-badge intent): both the stage UNIT OUTPUTS rows and the unit-detail inputs/outputs resolve real content from the branch (no "no file on disk"), and WorkerDates.test.tsx opens with full TSX syntax highlighting (252 hljs tokens) on the unit view, 50 on the stage view. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…FM as YAML Unit detail view, Reviews & Approvals: - Each non-engine role now links to its studio definition on the stage page (`/studios/<studio>/stages/<stage>/#agent-<role>` for the review walk, `#approve-agent-<role>` for the approval walk — anchors the stage page already emits). Engine-owned roles (spec, continuity, cross-stage-consistency) and the gate slots (quality_gates, user) have no def page, so they stay plain text. Threads `intent.studio` through to the sign-offs section. Raw-frontmatter accordion: - Renders syntax-highlighted YAML (the on-disk format) via the shared FilePreview instead of dumping raw JSON. Serialized with gray-matter's stringify (the website's existing YAML lib), fences stripped. Verified live (Playwright, worker-new-badge unit): six studio agents link out on each of the review + approval walks; the five engine/gate roles are not linked; the FM accordion shows highlighted YAML (977 hljs tokens). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…y as markdown Feedback cards (unit + intent scope): - The mono pill showed the FB's `origin` (a classification — adversarial-review, engine-review, studio-review). The engine already stamps the filing agent's role in `author` (every review/approval/intent-review/continuity dispatch passes author=<role>), so surface that instead: a finding from the security agent reads "security", not "adversarial-review". Falls back to origin when no author is stamped. Hat history (unit) + Fix history (feedback): - Each iteration's handoff baton now renders as markdown inside a collapsed-by-default <details>, with the hat/result/commit (or bolt) line as the summary. Was a plain-text paragraph, always expanded. Extracted a shared IterationHeading for the summary row. Verified live (Playwright, worker-new-badge): FB pills show agent names (cross-stage-consistency, etc.) with no adversarial-review/engine-review; hat history renders 3 collapsed details that expand to rendered markdown. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…s merged Closes the legacy/coherence gap: the cursor's sealed short-circuit fired on `sealed_at` alone, so an intent sealed before the merge gate (or any premature seal) whose `haiku/<slug>/main` is still ahead of the default branch was treated as terminal — a pickup couldn't re-audit it. Now the short-circuit fast-paths to `sealed` ONLY when the work has landed (squash-merge-aware `intentDeliveryState`). A sealed-but-unmerged intent falls through to the full walk, so a pickup re-opens the delivery-verifier (the PR_INTERACTION re-audit already in haiku_run_next) and the terminal re-emits `pending_seal` until the merge lands. The terminal merge gate now fires whether or not `sealed_at` is set. Inapplicable in filesystem mode / no default branch → seals exactly as before. Tests: - seal-intent-commits gains a legacy guard: a stamped-but-unmerged intent stays held at pending_seal (doesn't short-circuit to sealed), then seals once delivered. - Removed the two degenerate cursor-walk "sealed_at → sealed" sanity tests — that invariant is gone by design; realistic sealed paths are covered on the completed fixture in seal-intent-commits. Full suite green: 2069 passed, 0 failed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…inking out The unit-detail Reviews & Approvals roles linked to the studio stage page. Open the agent's mandate in a modal in-place instead — less context loss. A small client loader (studio-defs.ts) lazy-fetches the bundled studio content (/prototype-stage-content.json, the same asset the architecture map reads) and resolves the review-agent body for (studio, stage, role), falling back to any stage in the studio for a borrowed agent. Engine roles (spec/continuity/ cross-stage-consistency) and the user/quality-gate slots ship no def, so they stay plain text. Verified live (Playwright, worker-new-badge unit): clicking "Architecture" opens a modal titled Architecture showing the rendered mandate from plugin/studios/software/stages/development/review-agents/architecture.md. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The engine already merges the default branch into the hub branch every tick/pickup and surfaces genuine conflicts as pre_cursor_sync_conflict, so no new conflict-resolve mechanics are needed (confirmed). The pending_seal prompt now says the branch was kept current and to resolve any surfaced conflict. Also rebuilds plugin/bin/haiku.mjs (v10) so the committed bundle matches the Part 1 engine changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…lockquotes Consistency: the stage view's UNIT OUTPUTS expanded inline while the unit view opened a modal. Standardize on the modal — a unit-output row now opens its file in a centered modal (new OutputFileModal shell, mirrors the unit DocModal), rendered via the same FilePreview, so outputs open the same way on both surfaces. Hat/Fix history: a `>` aside in a handoff baton rendered with the default `prose` blockquote style — oversized italic text wrapped in curly quotation marks, which looked off for a one-line note. Tone it down to a quiet left-ruled, non-italic note and drop the auto-inserted quote glyphs (shared BATON_MARKDOWN_CLASS across hat + fix history). Verified live (Playwright): clicking a stage UNIT OUTPUTS row opens the file in a modal (plan-unit-001-render-new-tag.md rendered inside). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The collapsed-row list (per-row left-border stubs, a chevron per hat) read as cluttered and sparse. Replace it with a horizontal stepper: the hat sequence as connected dots (result-colored, filled when selected) with the hat name + result under each, and a single handoff panel below that shows the selected step's baton as rendered markdown. Nothing selected initially — the timeline reads as a flow first, detail on demand. Shared IterationStepper backs both the unit Hat history and the feedback Fix history. Verified live (Playwright, worker-new-badge unit): planner → builder → reviewer render as a connected stepper; clicking builder opens its handoff markdown. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…tion Intent-level approvals now use the SAME sign-off component as the unit view (extracted SignOffGroup), and every role — unit or intent — opens a modal explaining what it does, not just studio review agents: - studio review / intent-review agents -> their `*.md` mandate - engine roles (spec / continuity / cross-stage-consistency) -> the engine prompt body for the phase walk (review = pre-execute, approve = post-execute, intent = completion) - user -> a description of the human gate - quality_gates / intent_quality_gates -> the executable command list (unit's own gates; intent scope shows the deduped union across all units) Bundling (build): `_build-prototype-content.mjs` now captures studio `intent-review-agents/`, the global `plugin/intent-review-agents/` tier (delivery-verifier), and the engine-review bodies (review/approve/intent × spec/continuity/cross-stage-consistency) into prototype-stage-content.json. `loadRoleDef` in studio-defs.ts resolves all of the above; the unit's IntentApprovalsCard collapses to a thin wrapper over the shared component. Verified live (Playwright, worker-new-badge intent): Delivery Verifier opens its global mandate, Spec opens the intent-scope engine prompt, User opens the gate description, Intent Quality Gates opens the command union. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The unit "Duration" stat measured earliest-iteration-start to latest-end — a
wall clock that counts every idle gap (waiting on the user, queueing, time
between bolts). Each iteration carries `started_at`/`completed_at`, so sum each
hat-dispatch's own duration instead: that's the actual working time.
The stat tile now leads with "Active" (the summed dispatch time) and keeps the
wall-clock span as secondary context ("21h elapsed · <dates>"). Falls back to
the old Duration/Elapsed when no iteration carries both stamps (v3 units).
Adds a `formatDurationMs(ms)` helper to @haiku/shared (minutes-aware, seconds
for sub-minute totals) alongside the existing span-based formatDuration.
Verified live (Playwright, worker-new-badge unit-001): ACTIVE 10m vs 21h
wall-clock — the unit had ~10m of hat work but sat for ~21h.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The unit stat tiles read dead v4 fields: `bolt` and `hat` were removed from the unit FM (the schema says so outright — both derive from the iterations log now), so the browse read `data.bolt`/`data.hat` and always showed "Bolt 0" / "Hat —". Criteria parsed body checkboxes most v4 units don't use, so it showed "0/0". - Derive `bolt` = iteration count (hat dispatches) and `hat` = the most recent iteration's hat in the unit parse, so both carry real values (also fixes the KanbanView card, which already guarded on them). - Unit detail tiles now render only when they carry signal: Criteria only when the unit declared checkbox criteria; Iterations only when the unit has run; Current Hat only while in-flight (a completed unit's hats are in the Hat history stepper). Relabel "Bolt" -> "Iterations" (it's a dispatch count, not the removed bolt field); Kanban "Bolt N" -> "N iters". Verified live (Playwright, completed worker-new-badge unit-001): tiles are now Iterations 3 · Status Completed · Active 10m — no more Bolt 0 / Hat — / 0/0. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The card only rendered a date when `started_at` was present (a start→end span + duration), so list intents that carry `created_at` but no `started_at` showed no date at all — and the list sorts newest-first by created date, so it was the one temporal field worth surfacing. Add a "Created: <date>" to the meta row (`createdAt ?? startedAt`). Verified live (Playwright, GitLab monorepo): every card shows its created date (May 26 / May 21 / May 19 …), matching the newest-first order. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
GitLab's `TreeEntry.id` is content-addressed (the blob SHA), so two identical files at different paths — e.g. a DESIGN-BRIEF.md copied into both `knowledge/` and `stages/design/` — come back with the SAME id and different `path`. The compiled Relay artifact auto-injects `id` on the Node-typed tree entries, so RelayResponseNormalizer floods the console with "Invalid record … conflicting field … same id" and lets one path clobber the other. The recursive intent-tree fetch only reads `name`/`path` into plain objects and never touches the Relay store, so route it through `rawGraphql` (the same raw POST the lean list loaders use) requesting exactly `name`/`path` — no `id`, no normalization, no warning. Drop the now-unused artifact import; the generated `$data` type still types the response. Verified live (Playwright, location-timesheet-summary — the intent from the report): detail view loads with 0 console errors and no RelayResponseNormalizer warning. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Every browse page flashed the portfolio (list) skeleton while loading, even a
deep link straight to a unit. Now the skeleton matches the page being loaded.
- New BrowseSkeletons.tsx: list / intent / stage / unit skeletons mirroring each
view's real layout, with a `BrowseSkeleton({ location })` picker
(unit > stage > intent > list).
- RemoteBrowseView's init (provider-auth) loading and PortfolioView's
deep-link-detail loading both render the path-aware skeleton instead of the
hardcoded list skeleton. (Wired up the previously-unused loadingDetail flag for
the deep-link guard.)
Pathing: the unit segment is now keyword-delimited like its siblings —
`…/intent/<slug>/stage/<stage>/unit/<unit>/` instead of the positional
`…/stage/<stage>/<unit>/`. buildBrowseUrl emits the `unit/` form; parseBrowsePath
accepts it and still parses the legacy positional + pre-stage-keyword forms for
back-compat.
Verified live (Playwright, GitLab monorepo): the new `/unit/` URL resolves to the
unit detail (breadcrumb Development › Unit 001); during load the page is the
unit-width container, not the portfolio list.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Claude finished @jwaldrip's task in 6m 46s —— View job PR #374 Review
Overall AssessmentSolid branch. Three well-scoped themes that each have clear motivation, adequate test coverage, and no correctness holes I could find. The pending-seal merge gate is the most architecturally significant change; the browse perf work is the most impactful for users. I found one true perf issue (double delivery probe per tick), one caching regression worth noting (GitLab detail tree), and three minor nits. Nothing blocking. Engine —
|
Review comments: - cursor.ts: a sealed-but-unmerged intent probed intentDeliveryState twice per tick (each falls back to `gh pr list` in a squash-merge repo). Hoist the result from the seal short-circuit and reuse it at the terminal merge gate. - gitlab-provider: cache the recursive intent-tree listing in glCache (TTL + already cleared by clearBranchCache's `intentTree` purge) — the rawGraphql fetch that fixed the Relay dup-id warning bypasses Relay's store, so a detail re-mount otherwise re-fetched the tree every time. - gitlab-provider: warn when the batch AND the readFileFromRef fallback both return null for a branch's intent.md (it silently falls back to the default-branch baseline — now debuggable). - github-provider: extract the inline `CHUNK = 10` to a module-level `CHUNK_SIZE` matching GitLab. - parser.ts: note the journal filter is a basename check (intentionally drops a reserved internal name anywhere, not just the intent root). - haiku_run_next.ts: tighten the pickup re-open comment — it only re-opens already-stamped delivery approvals; if the verifier hasn't run, the next tick dispatches it. Biome: fix import ordering in the three pending-seal files CI flagged. Engine tests pass (cursor-walk 31/31, seal-intent, squash-merge-fallback, engine-never-merges-mainline). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Claude finished @jwaldrip's task in 5m 19s —— View job PR #374 Re-review (after new commits)
Re-review SummaryThe Previous review comments — all addressed
New observations (informational, non-blocking)
GitHub batch has no per-item retry. Unlike GitLab's Chunk fetches are serial, not parallel. Both providers process chunks with a sequential Legacy seal guard test is solid. The test in
Test coverageThe new test suite is good:
|
|
Addressed all six review comments in
Engine tests pass locally (cursor-walk 31/31, seal-intent, squash-merge-fallback, engine-never-merges-mainline); Biome Lint green. |
Summary
Three themes, all on this branch, building cleanly on current
main(24 commits, 56 files).Browse — list view performance & correctness
*/main-branch reads in one aliased GraphQL request, dropping the old O(3N) per-branch fan-out.worker-new-badge).Browse — detail view
haiku/<slug>/mainbranch (was reading the default branch → "no file on disk").userthe gate description,quality_gatesthe command list. Bundles intent-review-agents + engine-review bodies.TreeEntry.idcollides for identical files at two paths) by reading the recursive tree via raw GraphQL.…/stage/<stage>/unit/<unit>/.Engine
pending_seal: an intent is not sealed until its work lands on the default branch — a sealed stamp is reinterpreted against merge state at the display layer, and only short-circuits once merged.intent.mdconflict markers.action-log.jsonl, write-audit) never surface as unit outputs.Test plan
packages/haiku/src, engine test suite, website build/typecheck)websitetypecheck + biome clean across all touched files🤖 Generated with Claude Code