fix(cli): route bare gjc models to --list-models - #12
Open
innocarpe wants to merge 594 commits into
Open
Conversation
…eo#3480) Co-authored-by: Yeachan-Heo <yeachan-heo@gajae.dev>
Yeachan-Heo#3559 made a docs-only dev PR select exactly one shard, `test:packages/coding-agent/test/docs-index-lazy.test.ts`. That key starts with `test:`, so `taskNeedsNative` reports it as a native consumer and the matrix entry carries `native: true`. But the plan had no native producer, so `has_native` was `false`, `affected-native` was skipped, and the artifact `dev-affected-native-${run_id}` was never uploaded — while the shard's `if: ${{ matrix.native }}` download step still fired against it. The escalation that would have caught this, `ensureNativeBuild`, sits after the docs-only early return in `planTargetedTasks`, so that path never reached it; `planTasks` has no such tail at all. Both are fixed at their own seam. Yeachan-Heo#3559's own CI stayed green because it edits the test file and `scripts/`, so it never produced a docs-only plan and never exercised the path. Measured on this branch, `CI_DEV_CHANGED_PATHS=docs/guide.md` now reports `native=true` where dev reports `native=false`. The merged assertion `toEqual([EMBEDDED_DOCS_GATE_KEY])` was pinning the defect; it now requires the producer. A separate contract test states the invariant as the matrix sees it: a docs-only plan must never carry a native consumer without a producer. The `--native-build is a no-op` fixture moves off `docs/readme.md`, which now legitimately has a producer, onto `CHANGELOG.md`, which has none.
…producer fix(ci): give the docs-only plan the native producer its gate needs
…t and widen provenance to Rust (Yeachan-Heo#3583) * test: bind viewport evidence to renderer state * style: format viewport observation types * docs(tui): record renderer viewport observation and alternate-scroll ownership * fix: make ascii-no-color viewport evidence host-independent The ascii-no-color render mode relied on chalk.level = 0, but theme.ts emits SGR directly through fgAnsi/bgAnsi without consulting chalk. Its colour form follows detectColorMode(): truecolor when COLORTERM=truecolor, indexed 38;5;N when TERM is dumb/empty/linux. CI has neither COLORTERM nor a rich TERM, so it captured indexed colour where a developer host captured truecolor. Strip ANSI for ascii-no-color artifacts so they are genuinely escape-free on every host, and derive both the persisted payload and the recorded cursor frame digest from that one canonical string. Restore the strict escape-free assertion for that mode; the colour branch keeps the widened check because the previous regex missed background and bright colour. * fix: derive viewport capacity oracle from committed paint The verifier compared transcript_capacity against pin_boundary.row, but tui.ts assigns both from one renderer local, so that assertion could never fail. It also dropped the frame-derived capacity derivation and the ordered suffix marker oracle, leaving 19 of 20 keys bound to renderer self-report. Derive capacity, status-row index and notice cardinality from the committed paint, then require the renderer report to AGREE with it, which is strictly stronger than either source alone. Restore the ordered suffix marker oracle over the production root order. Add a pin_boundary.row mutation case that is only detectable against the paint, so the assertion cannot silently become tautological again. * fix: address viewport evidence review findings - capture: replace Awaited<ReturnType<typeof ...>> with a declared CaptureProvenance type (AGENTS.md prohibits ReturnType<>) - tui: reject non-finite setViewportSelection coordinates, matching the Number.isFinite guard already in scrollViewportBy. NaN previously survived the clamp, latched #mouseSelectionDragged, and forced a repaint every frame while reporting a NaN selection - virtual-terminal: delete unused getCursorPosition(). Measured against all 20 fixture keys it agrees with the reported cursor in only 5; the other 15 sit at (rows-1, columns) where the final frame write left the emulator cursor, so it cannot serve as a cursor oracle - CHANGELOG: record the reported-cursor-column clamp, and scope the wheel-scrollback claim to the capture-off case * style: collapse capture signature to one line * fix: canonicalize every persisted ascii-no-color viewport frame Required metadata.json artifacts carried raw ANSI through captureFrame(), so the visible-empty IRC frame and all nine resize probes embedded whichever colour form the capture host negotiated (indexed 38;5;n under TERM=dumb, truecolor 38;2;r;g;b otherwise). The earlier canonicalAnsi strip covered only the top-level terminal-ansi.txt and the cursor digest, leaving the required metadata host-dependent while both verifiers reported success. - captureFrame() now canonicalizes at the single point every persisted frame flows through, deriving text and sha256 from that canonical value. - The verifier rejects any CSI/ESC byte in every required ascii-no-color frame field, not just the top-level payload. - semantic_anchor.id embedded a per-run entry id, which made the bundle irreproducible even within one host; it is now a deterministic digest of the anchor's own geometry. - Adds two-environment reproducibility coverage and a rehashed metadata corruption case that reaches the new guard. - Removes the orphan hardware-cursor doc line left by the deleted accessor. * docs(tui): move unreleased changelog entries out of the released 0.12.1 section The PR's Added/Changed/Fixed bullets were nested under the already-released [0.12.1] heading, leaving [Unreleased] empty. AGENTS.md requires new entries under [Unreleased] only. Every heading from [0.12.2] down is restored byte-identical to upstream; the change is 12 insertions, 0 deletions. * fix(test): bind semantic anchor identity to a domain-separated digest and drop repo-derived status text The persisted `semantic_anchor.id` was the only field anchoring the painted row, but it hashed geometry alone and truncated to 8 hex. That made it both heavily aliased (distinct entries painting different content at equal offsets collapsed onto one id) and brute-forceable, and the verifier only checked that it was a nonempty string. The id is now the full domain-separated SHA-256 of the entry key, namespace, painted row text, complete geometry including frameRow, and the committed frame digest. Every preimage input is persisted, and the verifier recomputes the expected id from those inputs plus the committed paint before any downstream metadata check, rejecting arbitrary, transplanted, aliased, malformed, and truncated ids as well as content mutation under unchanged geometry. Required evidence frames also embedded the capture host's repository state: `#getGitStatus()` returns its cache and fires the fetch asynchronously, so one paint rendered `detached` and a later one `detached +8` in the same worktree. The fixture now pins the status line to model/session_name segments, so no repo-derived text reaches required metadata at all. * fix(test): scope viewport provenance digest to its declared surface The provenance digest hashed `git diff --binary HEAD --` over the entire worktree, and the verifier recomputes it live. That coupled bundle validity to every tracked file in the repo, so an unrelated edit anywhere retroactively marked already-captured bundles stale — and any write landing inside the capture-to-verify window flipped the digest mid-run, masking whichever guard was actually under test. Narrow the digest to a declared scope and persist `git_diff_scope` so the covered surface is read off the bundle rather than inferred, with the verifier comparing it against its own constant. Proven behaviorally: an out-of-scope edit is accepted, an in-scope edit is still rejected. * docs(tui): keep unreleased changelog entries out of released sections * fix(test): derive semantic anchor row and geometry from an immutable source expectation The persisted semantic_anchor.id was a full domain-separated digest, but the verifier recomputed it from producer-supplied fields. A producer that mints the bundle therefore mints a cryptographically valid id for any chosen row and geometry: transplanting geometry from another entry and relocating the anchor one painted row down, then recomputing every digest, manifest, review-input binding, and scoped provenance, was accepted. Digest consistency proves internal consistency, not semantic authenticity. The verifier now carries a frozen per-entry expectation for frame row and complete grapheme/cell geometry. That table is authoritative because the verifier's own bytes are inside source_sha256, so a bundle producer cannot rewrite it without invalidating provenance. Measured across both color environments, the geometry is identical for all 17 anchors, so the table is a host-independent invariant rather than a captured artifact. The id preimage bound the host-negotiated ANSI frame digest, which made 16 of 17 ids differ between indexed-color and truecolor hosts even though the stripped semantic paint was byte-identical. Semantic identity now binds the stripped-text digest; the ANSI digest stays persisted as an artifact binding and is still checked against the committed frame. * fix(test): anchor oracle expectation integrity to the committed blob The semantic-anchor expectation table is only immutable if its digest comes from outside the bundle's reach. captureProvenance() hashes the WORKTREE file, so mutating the table and restamping provenance was accepted: the stamp described the mutation instead of rejecting it. Compare every oracle source against its committed blob at the manifest's own git_head. A bundle author cannot restamp that without pushing a commit, which changes git_head. Fails closed when the blob is unreadable, and runs before semantic-anchor validation so a mutated table cannot ride through. * test(tui): reject a restamped oracle-expectation mutation * fix(test): bind oracle integrity to any reachable committed blob and widen provenance scope to Rust crates * fix(test): bind oracle integrity to any reachable commit and widen provenance scope to Rust * test(tui): derive the synthetic-merge base from dev instead of local topology * fix(test): make oracle integrity authority a single exact commit The previous gate fell back to reachableBlobSha256s() over --all, so oracle bytes committed on ANY local or remote-tracking ref satisfied it. Reachability is not review authority: an unrelated attacker ref could authorize bytes that were never the reviewed head, and in CI the fetch topology silently became a security input. Authority is now exactly one commit: GJC_STICKY_VIEWPORT_ORACLE_COMMIT when set, otherwise provenance.git_head. It is validated as a full commit object, both oracle sources must resolve at that same commit, the chosen commit is persisted as provenance.oracle_commit and cross-checked at verify, and there is no ref fallback. * fix(test): supply git identity to the oracle ref-topology regression --------- Co-authored-by: twoimo <twoimo@twoimoui-MacBookPro.local> Co-authored-by: twoimo <twoimo@users.noreply.github.com>
…eo#3582) The exact cancellation-ownership merge made deferred agent_end publication await background persistence and the user extension queue. That tied public session readiness to extension latency and regressed the same message-pipeline shard on two consecutive dev heads. Start persistence and extension delivery in the established background order, but retain the exact producer lease until the queued extension event settles. Constraint: Public agent_end must settle before user extension handlers while session shutdown still drains queued delivery and exact cancellation ownership remains live through that delivery. Rejected: Restore the old immediate lease close | loses the cancellation-domain lifetime introduced by the ownership fix. Confidence: high Scope-risk: narrow Reversibility: clean Directive: Do not await user extension delivery from public terminal publication; retain its producer lease through queue settlement instead. Tested: 181 focused coding-agent/agent tests passed with 852 assertions; coding-agent Biome and TypeScript checks; git diff --check. Not-tested: Full hosted Dev CI and install-method matrix.
Resolve sticky-viewport provenance and oracle source reads from one canonical repository root, and replace the post-merge-invalid authority topology assumption with an explicit deterministic older commit.
Bind ANSI-stripped text for all 20 reviewed sticky-viewport frames to the exact oracle commit, including null-anchor capacity-zero cases and coordinated non-anchor forgery regressions.
…eak (Yeachan-Heo#3605) Five ultragoal test suites (critic-gate, dogfood, review, durable-completion-release, runtime) created their temp checkpoints inside the enclosing git work tree. computeCheckpointChangeSet merges the CI planner's CI_DEV_CHANGED_PATHS into the computed change set, so on any branch that touches a computer control surface path (tools/index.ts, settings-schema.ts, computer.ts, pi-natives/computer/) the generic gate fixtures falsely triggered the mandatory computer red-team suite and failed with COMPUTER_REDTEAM_CASE_MISSING: ... must include kill-switch-bypass. The production kill-switch-bypass gate is correct and unchanged. The fixtures simply did not isolate their own contract from the host branch's diff. ultragoal-runtime.test.ts already solved this for its validation- batch tests via batchTempDir() (outside git + pinned env); the other suites never applied the same hermetic pattern. Each affected suite now captures CI_DEV_CHANGED_PATHS once at module load, clears it in beforeEach, and restores the original in afterAll. The explicit CI-leak tests that set their own value (computer-red-team- fixtures, review branch-merge) continue to work because beforeEach clears the baseline before each test and their own try/finally restores within scope. Added a positive regression: a complete mandatory computer red-team gate (all seven adversarialCases incl. kill-switch-bypass) PASSES on a genuine computer change -- proving the gate is not weakened. Lore-id: 3533redteam Constraint: must not weaken, bypass, or suppress the kill-switch-bypass gate Tested: all 1211 gjc-runtime tests pass with CI_DEV_CHANGED_PATHS pinned to a computer surface path Not-tested: full dev-ci shard matrix (run on push) Confidence: high Scope-risk: narrow Reversibility: trivial Co-authored-by: Yeachan-Heo <yeachan-heo@gajae.dev>
…tinuation dispatch (Yeachan-Heo#3607) * fix(gjc-runtime): make psmux authority and continuation dispatch host-independent Restacks the Windows psmux authority work onto current dev, dropping the storage lineage dev already absorbed via squash, and repairs every darwin-only failure in the slice. Five separate platform sources decided psmux behavior independently; four ignored the authority test seam entirely, so Windows-authority paths were unreachable on POSIX and eleven tmux-sessions tests failed there: - psmuxAuthorityEnvironments gated persisted-authority discovery on raw process.platform, aborting before any later guard could run. - resolveGjcTmuxProviderContext and createGjcTmuxSession each recomputed the platform instead of consulting the seam. - teamProviderAuthority read process.platform directly; GjcTeamConfig now carries the platform so startGjcTeam's value reaches it. Continuation dispatch had two real defects: the ack-loop deadline used raw Date.now() while every other timestamp in the file routes through the seamed clock, and the reservation site threw where the revalidation site records a skipped outcome, so one worker's short lease aborted an entire monitor pass. tmux-sessions: 35/35 on darwin (was 24/35). team-runtime: 115/117, with zero psmux-only failures - both remaining names also fail at dev, and this slice fixes three that dev fails. * test: align session-command untagged diagnostic with the psmux authority message * fix(lifecycle): keep POSIX on dev's tmux lifecycle path psmux rewrote the darwin lifecycle spawn/cleanup path (completeNonLinuxLifecycleSpawn, cleanupDirectLifecycleAttempt), which regressed POSIX: dev is 60 pass / 0 fail on notifications-lifecycle-control-runtime, psmux was 51 / 9. psmux is a Windows-only provider and POSIX uses tmux, so the darwin path must stay dev's. Reverting the file to dev keeps every psmux suite green (tmux-sessions 35/0, psmux-detect 39/0, launch-tmux 137/0, tmux-gc 9/0) and preserves the win32 lifecycle content, which dev already carries from the earlier merged psmux-authority slices. * fix(test): restore POSIX lifecycle and session metadata round-trip fidelity * fix(gjc-runtime): unblock psmux authority publish after dev reverted the managed sync lock * fix(gjc-runtime): tolerate non-claim task version bumps during continuation revalidation * Revert "fix(gjc-runtime): tolerate non-claim task version bumps during continuation revalidation" This reverts commit ebc3ca196801cd6b50b726c51d22ed3ba704e9ce. * Reapply "fix(gjc-runtime): tolerate non-claim task version bumps during continuation revalidation" This reverts commit 56f68822097d04d335126c7542f19e9dd720748e. * fix(gjc-runtime): enforce psmux authority migration exclusion without the managed sync lock The Windows psmux authority publish previously acquired `acquireManagedLockSync` from managed-session storage. Dev removed that symbol when it reverted Yeachan-Heo#3489, so the import broke on merge and the whole slice failed at module load. Reviewers asked for the sync lock to return only alongside a real consumer and a shared async/sync release contract, which belongs to the resident storage branch rather than here. So this slice now enforces the property it actually needs on its own: a retained lock descriptor for the exact authority name blocks publication unless its owner process is definitely gone. Expiry alone is not permission, because a paused writer with an expired lease is still live and stealing the name would let two writers publish one generation-scoped authority. `publishManagedFileNoReplaceSync` already supplies create-without-clobber exclusion for the payload itself, so no lease helper is required. * fix(gjc-runtime): fence continuation dispatch and restore the split marker Repairs the two blockers the reviewer identified on the previous head. 1. A public authority-changing operation dispatched no continuation argv. The continuation reservation is written under the task lock, that lock is released, and only then does dispatch revalidate eligibility. A concurrent claim-releasing operation could land in that window, so revalidation observed no current claim and the incident was journalled skipped with nothing dispatched. Revalidation plus send-keys now runs inside the same team mutation fence every other public authority-changing operation takes, and the fence is released before the ACK wait because the ACK is published by a separate receiver process that must acquire the same cross-process fence. Worker GC prune now takes that fence too, since it deletes claim records. 2. Replacement settled before pane-launch ACK. The fake tmux rewrite dropped the three-field tmux-last-split marker its shell predecessor published on every split. The memory-guard replacement test waits on that marker before publishing the generation-bound startup ACK, so the ACK never arrived, relaunch hit its startup deadline, and the guard reported retrying. The marker is restored. The same test also aborted its marker waiter before its own advisory-host early return, which masked the advisory outcome on non-Linux hosts; the ordering is fixed. * fix(gjc-runtime): keep pane id narrowing in the fenced dispatch closure The fence-hold restructure moved the send-keys argv construction into a closure, which dropped the outer non-null narrowing of `worker.pane_id`. Assert it the same way the adjacent `executeTeamTmuxMutation` calls already do, so the frozen argv stays `readonly string[]`. * fix(gjc-runtime): bind a proven pane id for fenced continuation dispatch --------- Co-authored-by: twoimo <twoimo@twoimoui-MacBookPro.local> Co-authored-by: gjc <gjc@local>
Retry-hint inspection tees response bodies, so a response abandoned for another attempt can retain buffered data. Begin cancellation only after every caller-return path is excluded, and do not await transport-controlled cleanup that could stall retry or abort progress. Constraint: Returned responses must remain unconsumed, including final attempts and over-cap retry hints. Rejected: Await body cancellation before retry | a custom or stalled transport can leave the cancellation promise pending indefinitely. Confidence: high Scope-risk: narrow Reversibility: clean Directive: Keep discarded-body cleanup non-blocking and after all response-return decisions. Tested: 8 focused fetch-retry tests including pending/rejecting cancellation and abort; packages/utils Biome and typecheck; git diff --check Not-tested: Live network socket reuse and transport-specific cancellation behavior
Proxy event conversion already rejects type-mismatched delta and end events except for toolcall_end. Failing closed at the same conversion boundary prevents a malformed proxy sequence from being silently accepted as a successful terminal message while preserving valid tool-call finalization. Constraint: Preserve the existing proxy event and valid tool-call output contract. Rejected: Ignore the malformed event and rely on a later terminal | accepts incomplete provider state without diagnostics. Confidence: high Scope-risk: narrow Reversibility: clean Directive: Keep proxy content-finalization events fail-closed when their content index has the wrong type. Tested: bun test packages/agent/test; bun --cwd=packages/agent run check; git diff --check Not-tested: Live remote proxy transport
…ent shard-red captureIncomplete (Yeachan-Heo#3611) The prior fix (Yeachan-Heo#3605) cleared CI_DEV_CHANGED_PATHS in beforeEach but left temp dirs inside the enclosing git work tree. Under parallel shard load (bun test --shard=N/8), git commands inside computeCheckpointChangeSet timeout at their 5s budget, causing captureIncomplete=true which unconditionally triggers the mandatory computer red-team suite -- even when no computer surface path is present in the change set. Root cause: captureIncomplete=true is a conservative production safety default, but it fires falsely in test environments under parallel load because the git diff/ls-files commands race the timeout. Fix: relocate all five affected suites' tempDir() to os.tmpdir() (outside the git work tree). When the cwd is not inside a git work tree AND ciChangedPaths is non-empty, computeCheckpointChangeSet returns { paths: ciChangedPaths } without captureIncomplete. Pin CI_DEV_CHANGED_PATHS to a non-computer test path so the returned paths don't trigger the suite. This mirrors the existing batchTempDir() pattern from ultragoal-runtime.test.ts which has been stable since its introduction. Also adds .tmp-* to packages/coding-agent/.gitignore to prevent any remaining in-repo test artifacts from polluting untracked-file inventory. The production kill-switch-bypass gate (MANDATORY_COMPUTER_CASE_IDS, requiresComputerRedTeamSuite, validateMandatoryComputerAdversarialCases) is byte-identical to dev. No enforcement is weakened. Lore-id: 3533shard5 Constraint: must not weaken genuine computer red-team enforcement Tested: shard 5/8 with exact CI plan paths -> 0 COMPUTER_REDTEAM failures Not-tested: full 8-shard matrix (run on push) Confidence: high Scope-risk: narrow Reversibility: trivial Co-authored-by: Yeachan-Heo <yeachan-heo@gajae.dev>
…dedup (Yeachan-Heo#3613) (Yeachan-Heo#3615) recordUltragoalReviewBlockers created unbounded review_blocker goal chains and duplicated goals for identical objectives, unlike its sibling recordReviewFindingGoals which already deduped via findOpenReviewBlockerGoal. Independently reproduced on dev 29ddfe0: identical objectives produced duplicate goals (2 calls -> 2 goals); distinct findings grew without bound (8 calls -> 8 goals, no cap); no user-reachable safe stop existed. Fix (3 parts, all in ultragoal-runtime.ts): 1. Exact-objective dedup reusing findOpenReviewBlockerGoal, scoped to the same blockedGoalId. On dedup-hit: idempotent return of the matched existing goal id, no writePlan, no appendLedger. 2. MAX_REVIEW_BLOCKER_DESCENTS=3 cap counting unresolved descents (status not in {complete,superseded}) off the blocked goal. 4th attempt throws typed UltragoalReviewBlockerRecursionCapError BEFORE any mutation (read-check-then-write on the persisted plan snapshot). CLI surfaces it as exit 1 with the typed marker. Dedup applied before budget; same-root budget durable across replay/restart/concurrency. 3. CLI record-review-blockers returns the matched existing id on dedup-hit, new id on creation (was blindly goals.at(-1)). 9 direct regressions added: identical-objective dedup, CLI receipt truthfulness, cap+typed-error+no-partial-mutation, CLI cap surfacing, resolved-ancestor exclusion, restart/replay durability, missing-goal handling, ordinary single-round preservation, cross-goal non-dedup. All 198 tests pass (181 existing + 17 nudge-guard + 9 new). TS check clean. Signed maintainer admission: the unbounded review_blocker growth defect in recordUltragoalReviewBlockers is independently confirmed on dev 29ddfe0 via repository-owned reproduction. Evidence is structural unboundedness + identical- commit repro only; no private token totals or third-party session counts are validated as repository fact. The disputed attribution figure is retracted. Lore-id: 3613-ultragoal-recursion-cap Constraint: MAX_REVIEW_BLOCKER_DESCENTS must default to 3 (descents 1..3 ok, 4th triggers terminal handoff) Constraint: dedup before budget check; same-root budget durable across replay/restart/concurrency Constraint: fail closed without corrupting goals.json/ledger Constraint: preserve ordinary single-round and sibling recordReviewFindingGoals behavior Rejected: dedup only no cap | distinct findings still unbounded, no safe stop Rejected: cap only no dedup | duplicates still corrupt identity/ledger Confidence: high Scope-risk: narrow Reversibility: trivial Tested: 198 tests (181 existing + 17 nudge-guard + 9 new regressions) Not-tested: cross-process file-locking (out of scope, single-process TOCTOU closed) Closes Yeachan-Heo#3613 Co-authored-by: Yeachan-Heo <yeachan-heo@gajae.dev>
Co-authored-by: Yeachan-Heo <yeachan-heo@gajae.dev>
Co-authored-by: Yeachan-Heo <yeachan-heo@gajae.dev>
Adds the official bundled OpenAI Codex LunaMaxxing profile with exact role mappings and catalog coverage.
Co-authored-by: Yeachan-Heo <yeachan-heo@gajae.dev>
Align historical issue dispositions and monitor documentation with the current product surface. Coalesce persistent monitor notifications and preserve local URL authority decoding safeguards.
Review lanes could self-declare matching hashes even after the worktree advanced. Runtime-owned cohorts now derive canonical source identity before dispatch, persist lane provenance, classify late delivery as stale, and require current delivery receipts at the completion gate. Lore-id: issue-3469 Constraint: preserve one issue per branch and PR Rejected: equal reviewer-declared hashes | stale lanes can agree on the wrong source Confidence: high Scope-risk: medium Reversibility: revertable Tested: package check; 236 focused tests; definition and rebrand gates Not-tested: full workspace check blocked by pre-existing stale generated docs index on current dev
The source snapshot coordinator was implemented and documented but omitted from the canonical workflow manifest, so static skill-doc verification rejected the public command. Register the verb and typed arguments, expose help, and add black-box manifest coverage. Lore-id: issue-3469-ci-repair Constraint: do not absorb the dev docs-index regeneration owned by PR Yeachan-Heo#3630 Confidence: high Scope-risk: low Reversibility: revertable Tested: coding-agent check; 238 focused tests; workflow manifest and skill-doc gates
Hostile review found bypasses around legacy hash-only gates, partial dispatch binding, nested persisted records, post-delivery source changes, and concurrent cohort writes. Require runtime cohort authority, bind every dispatch field, validate nested provenance, revalidate source at join, reject unsupported isolated review execution, sanitize rerun output, and retry CAS conflicts. Lore-id: issue-3469-review-fixes Confidence: high Scope-risk: medium Reversibility: revertable Tested: coding-agent check; source/receipt/command/default focused suites; manifest and skill-doc gates
Fresh hostile review found stale classification could be fooled by reverting owner bytes and that delivery identity remained ambiguous. Bind deliveries to opaque dispatch/cohort IDs, classify against the active cohort, dedupe replay, reject ambiguous persisted authority, reuse unchanged freezes, and bind every declared task field. Lore-id: issue-3469-final-review-fixes Confidence: high Scope-risk: medium Reversibility: revertable Tested: coding-agent check; focused source/receipt/command/default suites
The first fail-closed gate applied runtime cohort authority to every completion, breaking ordinary checkpoints and replay flows. Preserve existing non-source-aware cohort semantics while requiring runtime authority whenever persisted cohorts, cohort IDs, or delivery IDs assert source-aware review evidence. Lore-id: issue-3469-runtime-repair Confidence: high Scope-risk: medium Reversibility: revertable Tested: complete ultragoal runtime suite; source/command/task receipt suites; coding-agent check; manifest and skill-doc gates
…n-Heo#3632) `bc11b36ca` edited `docs/sdk-rpc-parity-audit.md` and `docs/tools/monitor.md` without regenerating the embedded docs index, so `check:public-sync` and `docs-index-lazy.test.ts` fail on dev and on every PR based on it. Regenerated with the repo's own generator; no hand edits. Co-authored-by: GJC <gjc@example.test>
The current PR head changes the public workflow surface and public-sync deterministically requires the canonical embedded docs index generated from the exact base plus PR tree. Lore-id: issue-3469-public-sync Generated: bun run generate-docs-index Tested: bun run check:public-sync
… preset The docs-index.generated.ts embeds a hash of models.md; adding the new qwen-deepseek profile preset changed the models.md length, so the embedded hash went stale and failed the check:public-sync gate. Lore-id: 8f2e1c9a Confidence: high Scope-risk: low Reversibility: revert-profile Tested: check:public-sync Not-tested: full test suite (worktree has no node_modules)
The affected-path check:@gajae-code/ai gate failed on a formatting violation: Biome prefers the models.find(...) call on a single line. Collapse it to satisfy the formatter. Lore-id: 8f2e1c9a Confidence: high Scope-risk: low Reversibility: revert-profile Tested: biome check packages/ai/scripts/generate-models.ts
fix(ai): honor MiniMax M3 official 1M routes
…presets (Yeachan-Heo#3827) feat(alibaba-token-plan): add qwen-deepseek profile preset
…puter suite (Yeachan-Heo#3767) The SKILL says the computer-use red-team suite is "conditional, not universal" and tells the agent to pick the surface that matches what the change actually ships. The runtime is stricter than that: since Yeachan-Heo#3543 it decides applicability from the computed change set and fails closed, so any edit to a shared behavior registry demands the suite even when the diff contains nothing computer-related. Following the doc as written leads an agent to conclude the suite is skippable, then hit COMPUTER_REDTEAM_CASE_MISSING at `checkpoint --status complete` with no explanation of why -- and the tempting way out is to invent the seven mandatory cases, which is exactly what the gate exists to prevent. Record the real rule instead: the suite is required for computer source, the computer tool, the three shared behavior registries (`config/settings-schema.ts`, `tools/index.ts`, `tools/renderers.ts`), and any incomplete change-set capture; generated bindings, prompt/skill docs and everything else do not trigger it on their own. Also state the sanctioned way out -- supply a genuine suite or escalate for an authorized override -- so the failure mode has a documented exit that is not fabrication. Path claims verified against `categorizeComputerChangePath` and `isComputerControlSurfaceCategory` rather than transcribed by hand. Docs only; no runtime behavior change. Co-authored-by: Yeachan-Heo <yeachan-heo@gajae.dev>
…xact unlink (Yeachan-Heo#3834) * fix(notifications): resolve intermediate notifications dir only for exact unlink Successor to closed Yeachan-Heo#3832. Multi-account layouts that share notifications/ via a directory symlink still need intermediate reparse points resolved before native exact unlink can retire transition locks. Full-path realpath followed final components and could race a final-component symlink swap past native AT_SYMLINK_NOFOLLOW. Canonicalize only the parent directory and rejoin the original basename so native mutation still no-follows the final path component. Bump DAEMON_GENERATION 49→50 and refresh the generation guard manifest for the protected exactUnlinkNotificationFile change. Lore-id: 3761act02 Constraint: final-component file symlink must remain reparse_point under TOCTOU Constraint: do not claim full Yeachan-Heo#3761 closure -- bounded activation slice only Rejected: full-file realpathSync | weakens final-component no-follow under race Confidence: high Scope-risk: narrow Reversibility: easy Tested: issue-3761-symlinked-notifications-activation; generation-50 pin; generation-guard suite; coding-agent check Not-tested: live Linux multi-account Telegram bot inbound round-trip Refs Yeachan-Heo#3761 * fix(sdk): lock registerToolSessionTransitionCleanup out of public inventory Yeachan-Heo#3813 added AgentSession.registerToolSessionTransitionCleanup for shared artifact-manager ownership on session transitions. The method is an internal lifecycle registration seam, parallel to registerToolSessionCleanup, but was never added to LOCKED_EXCLUSIONS. Exact-head Dev CI then fails the generated SDK operation inventory check on any PR based on current dev. Classify the seam as a locked exclusion and regenerate the committed matrix. Lore-id: 3813seam01 Constraint: do not expose as a public SDK control Rejected: map to a new SDK operation | no user-facing control exists Confidence: high Scope-risk: narrow Reversibility: easy Tested: sdk-operation-inventory.test.ts (17 pass); inventory --check Not-tested: full coding-agent shard matrix on CI Refs Yeachan-Heo#3813
…eo#3840) A Darwin crash during exact replacement cleanup can leave an empty exchange placeholder at the canonical receipt name, causing every later append to fail closed. Reconcile that state only when the receipt quarantine identity proves the placeholder is stale, while continuing to reject substituted non-empty receipts. Also migrate version-one receipts left by interrupted upgrades. Lore-id: 6f4a2c91 Constraint: never delete a canonical replacement receipt unless its detached identity is proven Constraint: preserve live transcripts and quarantined receipt payloads during recovery Rejected: trust the canonical placeholder by filename | an attacker or concurrent writer could substitute a live entry Confidence: high Scope-risk: focused Reversibility: simple Tested: Darwin native receipt recovery, legacy v1 receipt migration, managed replacement regressions, typecheck, Biome Not-tested: concurrent multi-process replacement stress
…eachan-Heo#3831) Configured legacy retry.* could re-issue a turn after partial assistant text, thinking, or tool-call content had already crossed the public stream boundary (e.g. proxy response.failed / upstream_stream_error). That path only applied replay-safety checks to first-event timeouts and bare defaults, so unclassified failures still entered bounded unknown retry. Apply one universal automatic gate: once the failed attempt carries observable assistant content, non-managed auto-retry returns false. Content-free clean failures keep existing bounded/unbounded policy; managed provisional discard, credential rotation, first-event scope checks, and manual /retry remain unchanged. Lore-id: 3791a1b2 Constraint: must not invent a parallel retry classifier -- extend existing content/replay helpers Constraint: managed provisional discard and content-free credential rotation must remain retryable Rejected: terminal special-case for upstream_stream_error only | same bug class under any code/message Rejected: blanket hasCleanRetryReplaySafety for all legacy retries | over-blocks mid-turn after prior tool results Confidence: high Scope-risk: narrow Reversibility: easy Directive: do not auto-continue committed partial responses as retry Tested: agent-session-resilient-retry (Yeachan-Heo#3791 cases) + retry-fallback + manual-retry + coding-agent check Not-tested: live Responses proxy partial-then-failed e2e; extension-only current-attempt effects without content Supersedes: none Fixes Yeachan-Heo#3791
…nses/Azure setup (Yeachan-Heo#3829) * fix(ai): delegate lazy stream watchdogs to transports The lazy provider wrapper watched normalized assistant events while several providers already watched richer raw transport events. That second clock could expire after transport-only progress, replace a live response with a blank generic stall error, and race provider-specific failure handling. Providers with raw watchdogs now own timeout decisions; the shared wrapper remains for providers that need it. OpenAI Completions now honors caller idle overrides internally, Azure shares the semantic Responses progress filter, and provider-owned paths preserve caller cancellation. Lore-id: e4a32f9c Constraint: providers without raw transport watchdogs retain the shared lazy watchdog Rejected: raise the global timeout | masks watchdog ownership and delays genuine stalls Confidence: high Scope-risk: medium Reversibility: code-only Tested: packages/ai check; 2153 package tests and 10224 assertions; 115 timeout and concurrency tests Not-tested: live provider outage recovery * fix(ai): bound Responses/Azure setup to first-event timeout Delegating lazy-stream watchdogs to transports removed the outer first-event clock, but Responses and Azure only armed their idle iterator after create() returned. A never-resolving pre-headers fetch could then wait the SDK default (10 minutes) before any provider watchdog existed. Map streamFirstEventTimeoutMs into the OpenAI/Azure SDK request timeout via a shared helper (Completions parity), and normalize pre-connect Azure SDK timeouts to typed stream_first_event_timeout. Keep transport-owned idle progress after the stream arms. Lore-id: b7c4e19a Constraint: keep provider-owned raw-event idle after create() returns Constraint: Completions-style explicit-vs-fallback SDK timeout rules Rejected: re-enable outer first-event for all provider-owned paths | dual clocks race transport progress Confidence: high Scope-risk: medium Reversibility: code-only Tested: packages/ai check; openai-first-event-timeout, register-builtins, stream-timeout-defaults Not-tested: live Azure/Responses hung-header outage recovery
Slack's conversations.replies endpoint rejects JSON request bodies with invalid_arguments even though equivalent form-encoded requests succeed. Serialize all Slack Web API POST parameters with URLSearchParams, omit undefined fields, and pin the request contract with a regression test. Confidence: high Scope-risk: narrow Reversibility: easy Tested: Slack provider and daemon 60/60; coding-agent check; CLI smoke Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
PR Yeachan-Heo#3806 flattened time-dependent loaders to 80 ms everywhere, making the working shimmer visibly step on direct terminals. Restore the 16 ms color cadence only for direct local sessions while keeping SSH and multiplexers on the bounded cadence and retaining congestion-based frame drops. Lore-id: tui-local-shimmer-cadence Constraint: SSH and multiplexed terminals must retain 80 ms decorative churn bounds Rejected: revert Yeachan-Heo#3806 and Yeachan-Heo#3814 | restores slow-terminal stale-frame backlogs Confidence: high Scope-risk: narrow Reversibility: clean-revert Tested: loader cadence and scheduler congestion tests; TUI and coding-agent package checks Not-tested: visual comparison across physical terminal emulators
Restores the 16 ms time-dependent loader cadence on direct local terminals while retaining 80 ms transport bounds and congestion dropping for SSH and multiplexers.
Successor to closed PR Yeachan-Heo#3700, rebased on current dev. - Shared durable Telegram topic authority with generation-CAS convergence, durable pre-create claims, lease-fenced effects, and host-qualified file locks (owner_host_id) that fail closed for foreign hosts. - Requires ok === false, error_code === 400, and an exact allowlisted Telegram description before treating an archive error as idempotently settled; identical TOPIC_NOT_FOUND text under 401/403/429/500 remains archive_pending with a durable bounded retry job. - Remote archive closes daemon-created topics (closeForumTopic) without deleting retained records; user-created topics are never closed/removed. - Crash-atomic topic registry persistence (fsync file+directory, native Windows exact write-through replacement); versionless legacy state is quarantined, never interpreted as empty. - Isolated owner-backed validation-supergroup mode for bot-API testing that persists nothing. - Generation 51 / serving epoch 5; exact-generation ownership compatibility (fail-closed).
`gjc update` fetched `https://registry.npmjs.org/@gajae-code/coding-agent/latest` directly, and so did the interactive startup version check. The install that follows shells out to bun/npm and therefore already honors whatever registry the user configured, so on any network that mirrors or blocks the public registry the two halves disagreed: the check died with `Failed to fetch release info:` — empty, because an intercepting proxy returns a status with no statusText — while the install it was gating would have succeeded. Resolve the registry before the request, the way npm does, and attach the credentials registered for it by walking the registry path up one segment at a time like npm's nerf darts. A configured-but-unusable registry now throws instead of quietly falling back to the public one, which would reintroduce the bug. Lore-id: 7c3f9a1e Constraint: the version check must reach the same registry the install shells out to Constraint: a repository the user merely cloned must not choose the host this process talks to Rejected: read <cwd>/.npmrc like npm does | a hostile repo could name the destination and supply an ${ENV}-expanded token to send there; npm skips project config in global mode anyway, and this check gates a global install Rejected: read process.env directly | Bun merges cwd/.env into it, so the same repo-controlled path returns through the environment; $credentialEnv is the boundary this repo already established for exactly that Rejected: shell out to `npm config get registry` | adds a process spawn to interactive startup Rejected: fall back to registry.npmjs.org when the configured mirror fails | converts a deterministic misconfiguration into an intermittent one and leaks the request to a host the user excluded Directive: do not promote a userinfo-only registry URL to a credential — `https://trusted.example.com@attacker.example.com` is that shape Confidence: high Scope-risk: narrow Reversibility: easy Tested: bun test packages/coding-agent/test/npm-registry.test.ts Tested: bun test packages/coding-agent/test/update-cli.test.ts packages/coding-agent/test/startup-update-contract.test.ts Tested: bun run check:tools and tsc -p packages/coding-agent/tsconfig.json --noEmit Tested: live resolution against a corporate network that returns HTTP 503 for registry.npmjs.org, reaching the Nexus mirror named in the user .npmrc Not-tested: an authenticated mirror end to end; credential attachment is covered only by unit tests Co-authored-by: Claude <noreply@anthropic.com>
* feat(slack): adopt existing threads before readiness Add an opt-in prepare, bind, and activate lifecycle for daemon-owned Slack thread adoption. Fence binding and activation on exact live authority, corroborate durable mappings, and drop control frames before chat mutation. Co-authored-by: gaebal-gajae <gaebal-gajae@users.noreply.github.com> Co-Authored-By: Claude <noreply@anthropic.com> * fix(slack): fence cancellation, activation, and binding authority Owner review of Yeachan-Heo#3816 found six blocking gaps where a failure or an unvalidated input was allowed to fall through instead of stopping. Cancellation: the cleanup unlinked the request and the response claim while suppressing both errors. If only the request unlink failed the orphaned request stayed servable, so a submission already answered `cancelled` could be re-claimed and committed. The claim is now released only once the request is proven gone; a leaked response object is inert, releasing it is not. Activation: deferred readiness withheld `session_ready` but left the control dispatcher reachable, making activation optional for input admission. `control_request` is now refused while prepared. `session_activate` is a separate frame type, so activation itself is unaffected. Binding authority: the proof was built from one endpoint read and the connection made from a second, and neither derived the state-root scope nor compared `endpointMtimeMs`. A replacement process repeating the endpoint generation could be connected to, and a `.gjc/state/chat/sdk` session was read at the wrong scope. Authority now derives scope exactly as the runtime's attach() fence does, verifies the endpoint mtime the index observed, and carries the proven endpoint so activation never re-resolves. Preparation input: `prepare_existing_thread` was compared with `=== true` against unvalidated dispatch arguments, so the string "true" silently became false and started an ordinary session that accepted the prompt. A non-boolean is now rejected before any mutation. Compensation: a failed defensive `session.close` was swallowed and the resulting error sealed under the idempotency key, leaving a live untracked session while retries replayed the cached failure. The failure now names the session and is marked nonterminal so the key stays open. Shutdown: `#started` stayed true across the unregister await, so an activation resolving during teardown could publish readiness afterwards. Teardown now fences before its first await. Lore-id: 4b91c7d2 Constraint: activation must remain reachable while controls are withheld Constraint: a cancelled submission must never commit later Rejected: gate query_request and register_provider too | read-only and setup paths, blocking them risks breaking legitimate pre-activation clients without closing an admission gap Rejected: keep the second endpoint read and compare pid again | the generation and pid can both repeat across a restart; only the mtime-proven endpoint is unambiguous Confidence: high Scope-risk: moderate Reversibility: easy Tested: bun test sdk-session-readiness-lifecycle sdk-slack-thread-binding sdk-chat-daemon-control-frames notify-thread-commands coordinator-mcp-server (128 pass, 0 fail) Tested: bun --cwd=packages/coding-agent run check Not-tested: prepare_existing_thread rejection and the compensation nonterminal path have no dedicated case; the coordinator harness needs setup this change did not add Co-authored-by: Claude <noreply@anthropic.com> --------- Co-authored-by: gaebal-gajae <gaebal-gajae@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
…acklog (Yeachan-Heo#3848) The issues/ directory read as 21 open items while README already recorded 01-08, 14-18, 20-21 as resolved and 11-13, 19 as obsolete (stdio RPC retired). Spot-checks against current dev re-confirmed the fixes (credential-import root guards, web-search local-baseUrl guard, session.resumeModelBehavior). Resolved/obsolete files move to issues/archive/ for provenance; only the deferred architectural pair 09/10 stays top-level. Confidence: high Scope-risk: narrow Reversibility: easy Tested: manual spot-checks of fixes 14, 17, 21 against source Not-tested: full re-verification of every archived item Co-authored-by: Yeachan-Heo <yeachan-heo@gajae.dev>
Boundary-review advisory from the ultragoal backlog sweep: the doc pointed at issues/01-issues/13, which now live under issues/archive/ (and 09/10 were never archived). Correct the path range and regenerate the embedded docs index. Confidence: high Scope-risk: narrow Reversibility: clean-revert Tested: docs-index regeneration; grep confirms no remaining stale issues/0N live-path references
Cohort report (cleaner/architect/qa joined lanes), terminal-critic verdict, PTY verification capture, and replayExempt record for the ultragoal backlog-resolution run's completion gate. Evidence for commits 35b0b4c and 959632f. Confidence: high Scope-risk: narrow Reversibility: clean-revert Tested: gjc ultragoal quality-gate validate passes against these artifacts
Yeachan-Heo#3851) (Yeachan-Heo#3854) * fix(session): graceful fallback for oversized (~64 MiB) session resume (Yeachan-Heo#3851) Resuming a session whose transcript file is at or above the ~64 MiB managed-storage per-file bound no longer OOMs, stalls the process, or fails with a bare unhandled rejection. The resume/open path now performs a stat-based size pre-check before the full read/decode/parse path and fails closed with a structured `oversized` reason (SessionTranscriptOversizedError) plus recovery guidance. The bound matches the existing MANAGED_ARTIFACT_MAX_FILE_BYTES (64 * 1024 * 1024) and is not raised; sub-limit sessions resume unchanged. The pre-check fires in inspectResumeSessionFile (covering --resume picker, --continue, and auto-resume) and in the explicit-path branch of SessionManager.open (covering --resume <path>). Lore-id: a1b2c3d4 Constraint: must not raise the on-disk managed-storage per-file limit Constraint: must not break sub-limit session resume or missing-file create-fresh behavior Rejected: silently raise MANAGED_ARTIFACT_MAX_FILE_BYTES | masks OOM risk; does not solve in-session growth Rejected: lazy/streaming transcript parse | large scope change to identity hash + schema validation contract Confidence: high Scope-risk: moderate Reversibility: trivial Tested: oversized resume fail-closed (inspect, openExistingStrict, SessionManager.open) Tested: sub-limit session resume unchanged Tested: operator-facing error message redaction (bare-resume + normal startup) Not-tested: native Linux managed-storage read_managed content_too_large path (existing coverage unchanged) Closes Yeachan-Heo#3851 * style(session): biome formatter/import hygiene for Yeachan-Heo#3851 oversized resume Fixes five Biome-only errors blocking CI on PR Yeachan-Heo#3854: - Sort imports in session-manager.ts (MANAGED_ARTIFACT_MAX_FILE_BYTES) - Sort imports in main.ts (SessionTranscriptOversizedError) - Sort imports in resume-confirm-continue.test.ts - Fix indentation in session-manager.ts explicit/inspect resume guards - Remove unused TempDir import from session-manager-resume-oversized.test.ts No behavioral changes. All 61 focused resume tests pass. Lore-id: a1b2c3d4 Confidence: high Scope-risk: trivial Reversibility: trivial Tested: bun --cwd=packages/coding-agent run check (biome + tsc clean) Tested: 61 resume-focused tests pass (oversized + readonly + confirm-continue) --------- Co-authored-by: gaebal-gajae <gaebal-gajae@users.noreply.github.com>
The reference client wrote capability negotiation failures through console.warn, which bypassed centralized logging and made embedding unsafe for the TUI. Route bounded diagnostics through the shared logger and expose an immutable optional callback without allowing callback failures to stop message handling. Lore-id: c58e17e1 Constraint: diagnostics must exclude transport secrets, identifiers, raw frames, and user content Rejected: injectable logger sink | duplicates the centralized logging policy and lets embedders suppress the default record Confidence: high Scope-risk: narrow Reversibility: clean Tested: Telegram reference and notification e2e suites; coding-agent package check
…and loader tests (Yeachan-Heo#3865) The G010 animation-scheduler red-team tests assumed timeDependentColor loaders always share the 80ms cadence bucket, but Yeachan-Heo#3845 routes them to a 16ms bucket on direct local terminals; no dev CI lane runs the tui suite, so the stale expectations surfaced as the 0.12.12 main-push shard failure. Review then found the same host-dependence in loader.test.ts: its env helper omitted TERM, which the multiplexer predicate treats as tmux/screen when so prefixed. Pin the terminal transport context (including TERM) in both files, add a DIRECT-LOCAL test asserting the 16ms/80ms split, and keep the SSH/TMUX constrained-terminal tests on explicit signals. Lore-id: a9f3c102 Constraint: must follow existing terminal-env stubbing conventions from loader.test.ts and animation-scheduler.test.ts Rejected: revert resolveAnimationCadence to 80ms-only | the 60fps direct-local gradient is intended shipped behavior (Yeachan-Heo#3845) Rejected: environment-conditional assertions | nondeterministic across CI runners and developer shells Confidence: high Scope-risk: narrow Reversibility: clean-revert Tested: full packages/tui suite 1068/0 across 76 files; adversarial host envs (SSH, TMUX, cleared, TERM=tmux-256color, TERM=screen-256color) 8/8 each on both files; combined sibling invocation 18/18; biome + tsc clean; Dev CI green Not-tested: windows CI runner timing (suite runs under fake timers)
…tion (Yeachan-Heo#3867) The 600-table fixture wrote one CREATE TABLE per autocommit, so fixture creation cost was a per-statement fsync storm (~4.6-6.8s under CI disk load vs ~830ms idle). That blows bun's 5s per-test timeout; the timeout then lets afterEach rm the temp dir while the read lifecycle is still in flight, so the pending read surfaces a spurious `Path ... not found` ToolError. Batching the schema writes into a single BEGIN/COMMIT keeps all 600 tables byte-identical while collapsing the fsync cost to one commit, making the test deterministic within the budget without touching the timeout or weakening the direction assertions. Confidence: high Scope-risk: narrow Reversibility: clean-revert Tested: focused test 25x under concurrent fsync load (was 0/x passing) Tested: full read-direction file 10x under load (19/19) Tested: read suite (read-goldens, read-receipt, read-stream-collector, read-artifact-spill, read-artifact-tree-authorization, read-acp-fs, read-multi-range, read-summary, read-tool-group) 232 tests Tested: tools/sqlite.test.ts 33 tests Tested: bun --cwd=packages/coding-agent run check (biome + tsc) Not-tested: CI shard re-run (no merge/CI rerun per task) Co-authored-by: gaebal-gajae <gaebal-gajae@users.noreply.github.com>
Agents often invoke `gjc models` from the bash tool expecting a catalog. Without a route, `models` was a free-form launch prompt, so nested agents re-ran the same command and spawned an unbounded process chain. Rewrite the mistaken subcommand to the existing non-agent --list-models path so the invocation exits after a bounded listing. Lore-id: 3857models Constraint: must not start an interactive agent for bare `models` Constraint: managed child/session launch paths unchanged Rejected: nested-session hard refuse | broader than this regression; breaks intentional one-shot launches from tool env Rejected: dedicated models subcommand registration | --list-models already owns listing semantics Confidence: high Scope-risk: narrow Reversibility: easy Tested: routeModelsAlias unit cases; nested GJC_SESSION_ID spawn; no leftover grandchild process Not-tested: full interactive agent recursion tree under load Fixes: Yeachan-Heo#3857
CI check:@gajae-code/coding-agent failed solely because biome wanted the multi-arg routeModelsAlias expectation on one line. Lore-id: 3857fmt01 Constraint: no behavior change -- formatter only Confidence: high Scope-risk: narrow Reversibility: easy Tested: cli-command-surface + issue-3857-nested-models-chain
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Showcase mirror of upstream Yeachan-Heo#3885. Fixes Yeachan-Heo#3857 (upstream).
Bare
gjc modelsroutes to--list-modelsso nested bash-tool invocations cannot spawn unbounded agent chains.