jeo-code 0.8.24 → 0.8.25
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 +14 -3
- package/README.ja.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/package.json +1 -1
- package/src/agent/plan.ts +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
The README mirrors the latest 5 entries — regenerate with `bun run changelog:sync`.
|
|
8
8
|
|
|
9
|
+
## [0.8.25] - 2026-07-13
|
|
10
|
+
_Post-audit follow-up: 0.8.24's fixture-repair subagent flagged (but, correctly, did not itself fix — out of its assigned scope) a case-sensitivity bug in the new PlanSchema maker→verifier ordering rule. Fixed._
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **PlanSchema ordering rule: role matching is now case-insensitive, matching dispatch** (`src/agent/plan.ts`) — the ordering rule's local `READONLY_ROLES`/`VERIFIER_ROLES` lookup compared `step.role?.trim()` directly, while `subagents.ts`'s `normalizeRoleId` (which every actual role DISPATCH goes through) lowercases first. A plan ending in e.g. `role: ARCHITECT` (or any mixed-case role) resolved correctly at runtime but was WRONGLY rejected by the schema as an unverified mutation (`READONLY_ROLES["ARCHITECT"]` is `undefined`, not `true`) — a real, live discrepancy between what `jeo team` would actually execute and what `PlanSchema`/`jeo approve` would accept. Fixed with `.toLowerCase()` at the one lookup site; an uppercase MUTATING role with no trailing verifier is still correctly rejected (verified — case-insensitivity does not widen `READONLY_ROLES` itself).
|
|
14
|
+
|
|
15
|
+
### Verified
|
|
16
|
+
- Full `bun test` — 3050 pass / 0 fail across 301 files (3049 baseline + 1 new dedicated test: mixed/upper-case verifier roles now accept, an upper-case mutating role with no verifier still correctly rejects).
|
|
17
|
+
- `bun run typecheck` — no errors.
|
|
18
|
+
- Live end-to-end (real CLI entrypoint, no mocks) — genuinely reproduced BEFORE fixing, not merely reasoned about: `git stash` the fix, ran `jeo approve` on a plan ending in `role: ARCHITECT` — refused with exit 1, the exact "unverified mutation" message quoted above; `git stash pop` restored the fix, re-ran the SAME plan — approved successfully, exit 0.
|
|
19
|
+
|
|
9
20
|
## [0.8.24] - 2026-07-13
|
|
10
21
|
_Follow-up gap analysis against the same external "self-improving agent system" framework (Fable-5-style loops), continuing 0.8.23's audit into 4 more primitives: independent-verifier ENFORCEMENT (0.8.23 had the gate logic but nothing forced a plan to actually contain one), model-tier safety-boundary fallback (a false-positive safety refusal previously backed off forever on the SAME model instead of trying a genuinely different one — the pattern already shipped for rate limits), memory confidence that was self-assigned once instead of earned via a real verification event, and Dynamic Workflows (jeo had parallel fan-out but no sequential composition or real control flow across subagent calls). Closed all 4, the last one non-trivially: an in-process `AsyncFunction` (the same pattern `browser {run}` already ships) cannot be given a real wall-clock timeout — a synchronous bug in agent-authored code blocks jeo's own event loop forever, and `Promise.race` can never preempt it (verified empirically). Fixed by running Dynamic Workflows scripts in an isolated `Worker` (a genuinely separate OS thread `worker.terminate()` can preempt unconditionally, mirroring `bashTool`'s own SIGTERM/SIGKILL escalation on a spawned process) with `task()` bridged back to the main thread over a `postMessage` RPC — config/credentials never leave the main thread, and every dispatch (however the script shapes it) stays bounded by a real concurrency semaphore, not just a per-call count cap._
|
|
11
22
|
|
|
@@ -14,13 +25,13 @@ _Follow-up gap analysis against the same external "self-improving agent system"
|
|
|
14
25
|
- **Evidence gate: independent verifiers must show their work** (`src/agent/task-tool.ts`'s `SubagentRunResult.readOnlyEvidenceCalls`, `src/commands/team.ts`'s `evaluateSubagentResult`, `src/commands/ralplan.ts`'s `runConsensusCriticGate`) — an architect/critic verdict (`[OKAY]`/`Architectural Status: CLEAR`) was text the model could emit with ZERO real inspection; both independent-verifier code paths in jeo (the per-step role gate AND ralplan's separate consensus-critic gate) now count OBSERVED `read`/`search`/`find`/`ast_grep`/`lsp` calls during the run and hard-fail any read-only-role verdict with zero evidence calls — unconditional, never softened by `--strict-mutations`, mirroring `goal-verifier.ts`'s existing `applyEvidenceGate` philosophy applied to the OTHER verifier path in the codebase.
|
|
15
26
|
- **Safety-boundary automatic model fallback** (`src/agent/engine.ts`'s `AgentLoopOptions.safetyFallbackAvailable`/`SAFETY_FALLBACK_TAG`, wired into `src/agent/task-tool.ts` and `src/commands/launch.ts`) — an UNCATEGORIZED refusal (bare `stop_reason=refusal`/`finish_reason=content_filter`/Gemini `SAFETY`, distinct from a `Refusal (<category>)`-shaped deterministic content-policy hit, which is UNTOUCHED and still hard-fails with zero fallback) previously backed off forever on the SAME model. When a genuinely different-PROVIDER candidate is available (same-provider siblings share the same classifier, so they're excluded too — stricter than the rate-limit fallback's same-credential-scope-only exclusion), the engine now bails with a distinctly-tagged doneReason and the caller switches models instead of riding the unbounded backoff — mirrors the already-shipped rate-limit fast-fallback's exact reroute-and-retry shape (never a bail-only predicate with nothing to switch to), reusing its provider-exclusion accumulation across repeated bails. `launch.ts`'s `routeFailureReason`/`equivalentRouteFallback` gained the same provider-level exclusion for the main interactive turn, and the internal tag is stripped from every user-visible surface (never leaks into a reply or a `[route]` notice).
|
|
16
27
|
- **Memory: earned confidence, active staleness tracking** (`src/agent/memory.ts`'s `isConceptStale`, `upsertConceptFile`'s new `opts.verified`, `distillSessionMemory`'s new `opts.sessionVerified`) — a concept's `last_verified` date was written unconditionally on every distillation pass, meaning "verified" was really just "written," never actually earned by a real verification event. `last_verified` is now written ONLY when the caller explicitly marks the session's distillation as verified; `isConceptStale` (pure, no I/O) treats a concept as stale when it has never been verified OR its last verification is older than 30 days (configurable) — 2026 industry pattern: confidence must be earned and staleness must be actively tracked, not read off a passive write-timestamp. Also fixed: `.jeo/` now self-ignores in git on first creation (`ensureJeoGitignore` in `src/agent/state.ts`) — memory/skill-lesson writes under `.jeo/` are agent-local working state, and without this a CI routine (`jeo routine init` + `create-pull-request`) shipped `.jeo/memory/*`/`.jeo/skills/*` churn into every generated PR.
|
|
17
|
-
- **Dynamic Workflows: `eval` tool, an agent-authored orchestration primitive** (`src/agent/eval-tool.ts`, wired into `src/commands/launch.ts`) — `task`'s `tasks[]` batch is ONE declarative, single-stage, parallel-only fan-out with no way to pipe one subagent's output into the next, branch on a result, or run N stages with a barrier between them. `eval {code, timeoutMs?}` lets the agent write an actual async JS function body composing THREE orchestration primitives — `task(role, taskText, context?)`, `parallel(thunks)`, `pipeline(items, ...stages)` (plus `log`) — with real loops/conditionals/sequencing. Runs in an isolated `Worker` (own OS thread) with a genuinely preemptive wall-clock timeout via `worker.terminate()` — NOT the same-process `AsyncFunction` pattern `browser {run}` uses, which cannot be given a real timeout at all (a synchronous bug blocks jeo's own event loop; `Promise.race` can never preempt it — verified empirically against a `while(true){}` reproduction). `task()` bridges back to the main thread over a `postMessage` RPC (config/credentials never enter the worker); every dispatch — however the script shapes it, including N raw concurrent `task()` calls that bypass `parallel()`/`pipeline()` entirely — is bounded by a real concurrency semaphore at `MAX_FANOUT` (4) in the RPC handler itself, plus a 40-dispatch total-count cap and a 20-item queue cap per `parallel()`/`pipeline()` call. Trust model: full `bash`-tier process access (NOT a security sandbox — `node:vm`/`vm2` offer no real isolation in 2026; documented as such), gated by the identical deep-interview mutation lock; never exposed to a subagent's own toolset (mirrors `task`'s own recursion-prevention exclusion).
|
|
28
|
+
- **Dynamic Workflows: `eval` tool, an agent-authored orchestration primitive** (`src/agent/eval-tool.ts`, wired into `src/commands/launch.ts`) — `task`'s `tasks[]` batch is ONE declarative, single-stage, parallel-only fan-out with no way to pipe one subagent's output into the next, branch on a result, or run N stages with a barrier between them. `eval {code, timeoutMs?}` lets the agent write an actual async JS function body composing THREE orchestration primitives — `task(role, taskText, context?)`, `parallel(thunks)`, `pipeline(items, ...stages)` (plus `log`) — with real loops/conditionals/sequencing. Runs in an isolated `Worker` (own OS thread) with a genuinely preemptive wall-clock timeout via `worker.terminate()` — NOT the same-process `AsyncFunction` pattern `browser {run}` uses, which cannot be given a real timeout at all (a synchronous bug blocks jeo's own event loop; `Promise.race` can never preempt it — verified empirically against a `while(true){}` reproduction). `task()` bridges back to the main thread over a `postMessage` RPC (config/credentials never enter the worker); every dispatch — however the script shapes it, including N raw concurrent `task()` calls that bypass `parallel()`/`pipeline()` entirely — is bounded by a real concurrency semaphore at `MAX_FANOUT` (4) in the RPC handler itself, plus a 40-dispatch total-count cap and a 20-item queue cap per `parallel()`/`pipeline()` call. A settle-aware abort signal (separate from the timeout/cancel signal) additionally cancels any fire-and-forget `task()` call the script fired without awaiting — whether still QUEUED behind `MAX_FANOUT` other dispatches or already IN-FLIGHT inside `runSubagentOnce` — the instant the tool itself settles, so a zombie subagent dispatch never keeps running invisibly (burning LLM calls whose result is discarded) after the tool has already returned to the model. Trust model: full `bash`-tier process access (NOT a security sandbox — `node:vm`/`vm2` offer no real isolation in 2026; documented as such), gated by the identical deep-interview mutation lock; never exposed to a subagent's own toolset (mirrors `task`'s own recursion-prevention exclusion).
|
|
18
29
|
|
|
19
30
|
### Verified
|
|
20
|
-
- Full `bun test` —
|
|
31
|
+
- Full `bun test` — 3049 pass / 0 fail across 301 files (2997 baseline (post-audit fixture repair for the 20 pre-existing tests broken by the new PlanSchema ordering rule and evidence gate, none weakened — Pattern A: trailing verifier step; Pattern B: a real read-tool-call evidence turn) + 52 new: 8 dedicated PlanSchema ordering-rule tests covering the reject/accept boundary the fixture repairs alone never exercised, 4 safety-fallback engine tests, 3 task-tool safety-reroute tests, 4 launch.ts safety-fallback end-to-end tests, 23 eval-tool tests (including 3 covering the settle-aware fire-and-forget cancellation fix), plus the memory/gitignore additions).
|
|
21
32
|
- `bun run typecheck` — no errors.
|
|
22
33
|
- Live end-to-end (real CLI entrypoint, no mocks): `jeo approve` on a schema-invalid (unverified-mutation) plan refuses with exit code 1 and the exact ordering-rule message; the real (unmocked) `eval` tool composing `pipeline()` → `parallel()` in one script and returning a structured result; a genuine `while(true){}` script terminated by the Worker timeout at ~803ms for an 800ms budget (proving REAL preemption, not a same-thread race that would have hung indefinitely — confirmed the bug is real by first reproducing the hang against a bare `Promise.race`, which required an external OS-level `timeout` to recover from).
|
|
23
|
-
- Each new feature's highest-value contract mutation-tested against the ACTUAL source, not merely reasoned about: the ordering rule (neutered `ctx.addIssue` in `plan.ts`, full suite re-run — exactly the 4 reject-direction tests among the 8 new dedicated ordering-rule tests failed (13 pass / 4 fail), every accept-direction and unrelated test stayed green, confirming the 12 earlier fixture repairs only ever proved the ACCEPT direction and closing that real coverage gap before shipping; restored,
|
|
34
|
+
- Each new feature's highest-value contract mutation-tested against the ACTUAL source, not merely reasoned about: the ordering rule (neutered `ctx.addIssue` in `plan.ts`, full suite re-run — exactly the 4 reject-direction tests among the 8 new dedicated ordering-rule tests failed (13 pass / 4 fail), every accept-direction and unrelated test stayed green, confirming the 12 earlier fixture repairs only ever proved the ACCEPT direction and closing that real coverage gap before shipping; restored, the full suite green again); the evidence gate (zero-evidence verdict correctly blocked, one real read call correctly clears it); the safety fallback (categorized `Refusal (<category>)` NEVER checks `safetyFallbackAvailable`, confirmed via a spy — true-positive path fully untouched); the eval concurrency semaphore (10 raw concurrent `task()` calls bypassing `parallel()`/`pipeline()` entirely still peak at ≤4 in-flight, proven via a real overlapping-delay probe, not a label); the settle-aware fire-and-forget cancellation (a `task()` call fired without `await` is proven to NEVER reach `callLlm`, verified with a 300ms grace-period probe after the tool returns, not a bare synchronous assertion that would trivially pass even if cancellation were completely broken).
|
|
24
35
|
|
|
25
36
|
## [0.8.23] - 2026-07-12
|
|
26
37
|
_Gap analysis against an external "self-improving agent system" framework (Fable-5-style loops: independent verifiers, memory compounding, model-tier cost discipline, and scheduled routines) found jeo-code already had strong equivalents for most primitives — but 3 real gaps and 1 deliberately-scoped-safe gap. Closed all 4: skills that were "hand-authored, read-mostly, zero learning" now compound from real session failures; screenshots that were captured but never judged now close a real vision-verify loop; the `/goal` verifier and bulk fan-out dispatch that silently rode the same full-price model as the work they graded/executed now default to a cheap tier; and "runs without your laptop" is now achievable via a generated GitHub Actions template wrapping jeo's existing headless mode — with zero new attack surface inside jeo-code itself (no code-exec sandbox, no in-process scheduler/webhook receiver, both deliberately rejected as out of scope). Also absorbs 3 fixes shipped after 0.8.22 but never changelogged: a rate-limit fast-fallback audit that closed 4 real gaps, plus the cross-file `mock.module()` test-isolation class this release's own test additions collided with and fixed at its root cause._
|
package/README.ja.md
CHANGED
|
@@ -281,11 +281,11 @@ CI は `.github/workflows/npm-publish.yml` で公開します — GitHub リリ
|
|
|
281
281
|
## 変更履歴 (Changelog)
|
|
282
282
|
|
|
283
283
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
284
|
+
- **[0.8.25]** (2026-07-13) — Post-audit follow-up: 0.8.24's fixture-repair subagent flagged (but, correctly, did not itself fix — out of its assigned scope) a case-sensitivity bug in the new PlanSchema maker→verifier ordering rule. Fixed.
|
|
284
285
|
- **[0.8.24]** (2026-07-13) — Follow-up gap analysis against the same external "self-improving agent system" framework (Fable-5-style loops), continuing 0.8.23's audit into 4 more primitives: independent-verifier ENFORCEMENT (0.8.23 had the gate logic but nothing forced a plan to actually contain one), model-tier safety-boundary fallback (a false-positive safety refusal previously backed off forever on the SAME model instead of trying a genuinely different one — the pattern already shipped for rate limits), memory confidence that was self-assigned once instead of earned via a real verification event, and Dynamic Workflows (jeo had parallel fan-out but no sequential composition or real control flow across subagent calls). Closed all 4, the last one non-trivially: an in-process `AsyncFunction` (the same pattern `browser {run}` already ships) cannot be given a real wall-clock timeout — a synchronous bug in agent-authored code blocks jeo's own event loop forever, and `Promise.race` can never preempt it (verified empirically). Fixed by running Dynamic Workflows scripts in an isolated `Worker` (a genuinely separate OS thread `worker.terminate()` can preempt unconditionally, mirroring `bashTool`'s own SIGTERM/SIGKILL escalation on a spawned process) with `task()` bridged back to the main thread over a `postMessage` RPC — config/credentials never leave the main thread, and every dispatch (however the script shapes it) stays bounded by a real concurrency semaphore, not just a per-call count cap.
|
|
285
286
|
- **[0.8.23]** (2026-07-12) — Gap analysis against an external "self-improving agent system" framework (Fable-5-style loops: independent verifiers, memory compounding, model-tier cost discipline, and scheduled routines) found jeo-code already had strong equivalents for most primitives — but 3 real gaps and 1 deliberately-scoped-safe gap. Closed all 4: skills that were "hand-authored, read-mostly, zero learning" now compound from real session failures; screenshots that were captured but never judged now close a real vision-verify loop; the `/goal` verifier and bulk fan-out dispatch that silently rode the same full-price model as the work they graded/executed now default to a cheap tier; and "runs without your laptop" is now achievable via a generated GitHub Actions template wrapping jeo's existing headless mode — with zero new attack surface inside jeo-code itself (no code-exec sandbox, no in-process scheduler/webhook receiver, both deliberately rejected as out of scope). Also absorbs 3 fixes shipped after 0.8.22 but never changelogged: a rate-limit fast-fallback audit that closed 4 real gaps, plus the cross-file `mock.module()` test-isolation class this release's own test additions collided with and fixed at its root cause.
|
|
286
287
|
- **[0.8.22]** (2026-07-11) — A rescan of the working tree turned up a resume-fidelity gap plus two unwired TUI safety-net helpers left by a concurrent session; each was traced, wired where needed, and verified before shipping.
|
|
287
288
|
- **[0.8.21]** (2026-07-10) — "반영할꺼 같은방식으로 체크하고 배포까지" — a rescan of the working tree (after the prior audit pass) turned up 15 uncommitted files: 3 genuinely distinct features left unwired by a concurrent session, partially casualty of an earlier accidental `git checkout` incident this session (disclosed in the 0.8.20 entry above). Each was independently traced from its existing plumbing, wired to a real call site, tested, and one live-verified end-to-end over a real PTY before shipping.
|
|
288
|
-
- **[0.8.20]** (2026-07-10) — "모든 검증 다시 리뷰하고 변경사항 모두 체크해" — 4 fresh, skeptical subagents independently re-audited every change from v0.8.17-0.8.19 (bc8768f..92c6b7d) with zero trust in prior claims: a code-correctness auditor manually traced the Antigravity routing logic against the live catalog, a test-integrity auditor mutation-tested the new tests (confirmed each one genuinely fails when its fix is reverted) and ran the suite fresh, a live-behavior verifier re-reproduced all 4 behavioral claims from scratch with self-generated data (own session ids, own mock server, own HTTP status code), and a docs-accuracy auditor cross-checked every README/CHANGELOG claim against current code in isolated git worktrees. Verdict: all core logic and tests GENUINE/CONFIRMED CORRECT — but the audit surfaced 1 real doc staleness gap, 1 changelog count error, and 2 minor precision gaps, all fixed here.
|
|
289
289
|
|
|
290
290
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
291
291
|
<!-- CHANGELOG:END -->
|
package/README.ko.md
CHANGED
|
@@ -282,11 +282,11 @@ CI는 `.github/workflows/npm-publish.yml`로 배포합니다 — GitHub 릴리
|
|
|
282
282
|
## 변경 이력 (Changelog)
|
|
283
283
|
|
|
284
284
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
285
|
+
- **[0.8.25]** (2026-07-13) — Post-audit follow-up: 0.8.24's fixture-repair subagent flagged (but, correctly, did not itself fix — out of its assigned scope) a case-sensitivity bug in the new PlanSchema maker→verifier ordering rule. Fixed.
|
|
285
286
|
- **[0.8.24]** (2026-07-13) — Follow-up gap analysis against the same external "self-improving agent system" framework (Fable-5-style loops), continuing 0.8.23's audit into 4 more primitives: independent-verifier ENFORCEMENT (0.8.23 had the gate logic but nothing forced a plan to actually contain one), model-tier safety-boundary fallback (a false-positive safety refusal previously backed off forever on the SAME model instead of trying a genuinely different one — the pattern already shipped for rate limits), memory confidence that was self-assigned once instead of earned via a real verification event, and Dynamic Workflows (jeo had parallel fan-out but no sequential composition or real control flow across subagent calls). Closed all 4, the last one non-trivially: an in-process `AsyncFunction` (the same pattern `browser {run}` already ships) cannot be given a real wall-clock timeout — a synchronous bug in agent-authored code blocks jeo's own event loop forever, and `Promise.race` can never preempt it (verified empirically). Fixed by running Dynamic Workflows scripts in an isolated `Worker` (a genuinely separate OS thread `worker.terminate()` can preempt unconditionally, mirroring `bashTool`'s own SIGTERM/SIGKILL escalation on a spawned process) with `task()` bridged back to the main thread over a `postMessage` RPC — config/credentials never leave the main thread, and every dispatch (however the script shapes it) stays bounded by a real concurrency semaphore, not just a per-call count cap.
|
|
286
287
|
- **[0.8.23]** (2026-07-12) — Gap analysis against an external "self-improving agent system" framework (Fable-5-style loops: independent verifiers, memory compounding, model-tier cost discipline, and scheduled routines) found jeo-code already had strong equivalents for most primitives — but 3 real gaps and 1 deliberately-scoped-safe gap. Closed all 4: skills that were "hand-authored, read-mostly, zero learning" now compound from real session failures; screenshots that were captured but never judged now close a real vision-verify loop; the `/goal` verifier and bulk fan-out dispatch that silently rode the same full-price model as the work they graded/executed now default to a cheap tier; and "runs without your laptop" is now achievable via a generated GitHub Actions template wrapping jeo's existing headless mode — with zero new attack surface inside jeo-code itself (no code-exec sandbox, no in-process scheduler/webhook receiver, both deliberately rejected as out of scope). Also absorbs 3 fixes shipped after 0.8.22 but never changelogged: a rate-limit fast-fallback audit that closed 4 real gaps, plus the cross-file `mock.module()` test-isolation class this release's own test additions collided with and fixed at its root cause.
|
|
287
288
|
- **[0.8.22]** (2026-07-11) — A rescan of the working tree turned up a resume-fidelity gap plus two unwired TUI safety-net helpers left by a concurrent session; each was traced, wired where needed, and verified before shipping.
|
|
288
289
|
- **[0.8.21]** (2026-07-10) — "반영할꺼 같은방식으로 체크하고 배포까지" — a rescan of the working tree (after the prior audit pass) turned up 15 uncommitted files: 3 genuinely distinct features left unwired by a concurrent session, partially casualty of an earlier accidental `git checkout` incident this session (disclosed in the 0.8.20 entry above). Each was independently traced from its existing plumbing, wired to a real call site, tested, and one live-verified end-to-end over a real PTY before shipping.
|
|
289
|
-
- **[0.8.20]** (2026-07-10) — "모든 검증 다시 리뷰하고 변경사항 모두 체크해" — 4 fresh, skeptical subagents independently re-audited every change from v0.8.17-0.8.19 (bc8768f..92c6b7d) with zero trust in prior claims: a code-correctness auditor manually traced the Antigravity routing logic against the live catalog, a test-integrity auditor mutation-tested the new tests (confirmed each one genuinely fails when its fix is reverted) and ran the suite fresh, a live-behavior verifier re-reproduced all 4 behavioral claims from scratch with self-generated data (own session ids, own mock server, own HTTP status code), and a docs-accuracy auditor cross-checked every README/CHANGELOG claim against current code in isolated git worktrees. Verdict: all core logic and tests GENUINE/CONFIRMED CORRECT — but the audit surfaced 1 real doc staleness gap, 1 changelog count error, and 2 minor precision gaps, all fixed here.
|
|
290
290
|
|
|
291
291
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
292
292
|
<!-- CHANGELOG:END -->
|
package/README.md
CHANGED
|
@@ -289,11 +289,11 @@ Huge thanks to [gajae-code](https://github.com/Yeachan-Heo/gajae-code) for the i
|
|
|
289
289
|
## Changelog
|
|
290
290
|
|
|
291
291
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
292
|
+
- **[0.8.25]** (2026-07-13) — Post-audit follow-up: 0.8.24's fixture-repair subagent flagged (but, correctly, did not itself fix — out of its assigned scope) a case-sensitivity bug in the new PlanSchema maker→verifier ordering rule. Fixed.
|
|
292
293
|
- **[0.8.24]** (2026-07-13) — Follow-up gap analysis against the same external "self-improving agent system" framework (Fable-5-style loops), continuing 0.8.23's audit into 4 more primitives: independent-verifier ENFORCEMENT (0.8.23 had the gate logic but nothing forced a plan to actually contain one), model-tier safety-boundary fallback (a false-positive safety refusal previously backed off forever on the SAME model instead of trying a genuinely different one — the pattern already shipped for rate limits), memory confidence that was self-assigned once instead of earned via a real verification event, and Dynamic Workflows (jeo had parallel fan-out but no sequential composition or real control flow across subagent calls). Closed all 4, the last one non-trivially: an in-process `AsyncFunction` (the same pattern `browser {run}` already ships) cannot be given a real wall-clock timeout — a synchronous bug in agent-authored code blocks jeo's own event loop forever, and `Promise.race` can never preempt it (verified empirically). Fixed by running Dynamic Workflows scripts in an isolated `Worker` (a genuinely separate OS thread `worker.terminate()` can preempt unconditionally, mirroring `bashTool`'s own SIGTERM/SIGKILL escalation on a spawned process) with `task()` bridged back to the main thread over a `postMessage` RPC — config/credentials never leave the main thread, and every dispatch (however the script shapes it) stays bounded by a real concurrency semaphore, not just a per-call count cap.
|
|
293
294
|
- **[0.8.23]** (2026-07-12) — Gap analysis against an external "self-improving agent system" framework (Fable-5-style loops: independent verifiers, memory compounding, model-tier cost discipline, and scheduled routines) found jeo-code already had strong equivalents for most primitives — but 3 real gaps and 1 deliberately-scoped-safe gap. Closed all 4: skills that were "hand-authored, read-mostly, zero learning" now compound from real session failures; screenshots that were captured but never judged now close a real vision-verify loop; the `/goal` verifier and bulk fan-out dispatch that silently rode the same full-price model as the work they graded/executed now default to a cheap tier; and "runs without your laptop" is now achievable via a generated GitHub Actions template wrapping jeo's existing headless mode — with zero new attack surface inside jeo-code itself (no code-exec sandbox, no in-process scheduler/webhook receiver, both deliberately rejected as out of scope). Also absorbs 3 fixes shipped after 0.8.22 but never changelogged: a rate-limit fast-fallback audit that closed 4 real gaps, plus the cross-file `mock.module()` test-isolation class this release's own test additions collided with and fixed at its root cause.
|
|
294
295
|
- **[0.8.22]** (2026-07-11) — A rescan of the working tree turned up a resume-fidelity gap plus two unwired TUI safety-net helpers left by a concurrent session; each was traced, wired where needed, and verified before shipping.
|
|
295
296
|
- **[0.8.21]** (2026-07-10) — "반영할꺼 같은방식으로 체크하고 배포까지" — a rescan of the working tree (after the prior audit pass) turned up 15 uncommitted files: 3 genuinely distinct features left unwired by a concurrent session, partially casualty of an earlier accidental `git checkout` incident this session (disclosed in the 0.8.20 entry above). Each was independently traced from its existing plumbing, wired to a real call site, tested, and one live-verified end-to-end over a real PTY before shipping.
|
|
296
|
-
- **[0.8.20]** (2026-07-10) — "모든 검증 다시 리뷰하고 변경사항 모두 체크해" — 4 fresh, skeptical subagents independently re-audited every change from v0.8.17-0.8.19 (bc8768f..92c6b7d) with zero trust in prior claims: a code-correctness auditor manually traced the Antigravity routing logic against the live catalog, a test-integrity auditor mutation-tested the new tests (confirmed each one genuinely fails when its fix is reverted) and ran the suite fresh, a live-behavior verifier re-reproduced all 4 behavioral claims from scratch with self-generated data (own session ids, own mock server, own HTTP status code), and a docs-accuracy auditor cross-checked every README/CHANGELOG claim against current code in isolated git worktrees. Verdict: all core logic and tests GENUINE/CONFIRMED CORRECT — but the audit surfaced 1 real doc staleness gap, 1 changelog count error, and 2 minor precision gaps, all fixed here.
|
|
297
297
|
|
|
298
298
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
299
299
|
<!-- CHANGELOG:END -->
|
package/README.zh.md
CHANGED
|
@@ -281,11 +281,11 @@ CI 通过 `.github/workflows/npm-publish.yml` 发布 — GitHub 发布 release
|
|
|
281
281
|
## 更新日志 (Changelog)
|
|
282
282
|
|
|
283
283
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
284
|
+
- **[0.8.25]** (2026-07-13) — Post-audit follow-up: 0.8.24's fixture-repair subagent flagged (but, correctly, did not itself fix — out of its assigned scope) a case-sensitivity bug in the new PlanSchema maker→verifier ordering rule. Fixed.
|
|
284
285
|
- **[0.8.24]** (2026-07-13) — Follow-up gap analysis against the same external "self-improving agent system" framework (Fable-5-style loops), continuing 0.8.23's audit into 4 more primitives: independent-verifier ENFORCEMENT (0.8.23 had the gate logic but nothing forced a plan to actually contain one), model-tier safety-boundary fallback (a false-positive safety refusal previously backed off forever on the SAME model instead of trying a genuinely different one — the pattern already shipped for rate limits), memory confidence that was self-assigned once instead of earned via a real verification event, and Dynamic Workflows (jeo had parallel fan-out but no sequential composition or real control flow across subagent calls). Closed all 4, the last one non-trivially: an in-process `AsyncFunction` (the same pattern `browser {run}` already ships) cannot be given a real wall-clock timeout — a synchronous bug in agent-authored code blocks jeo's own event loop forever, and `Promise.race` can never preempt it (verified empirically). Fixed by running Dynamic Workflows scripts in an isolated `Worker` (a genuinely separate OS thread `worker.terminate()` can preempt unconditionally, mirroring `bashTool`'s own SIGTERM/SIGKILL escalation on a spawned process) with `task()` bridged back to the main thread over a `postMessage` RPC — config/credentials never leave the main thread, and every dispatch (however the script shapes it) stays bounded by a real concurrency semaphore, not just a per-call count cap.
|
|
285
286
|
- **[0.8.23]** (2026-07-12) — Gap analysis against an external "self-improving agent system" framework (Fable-5-style loops: independent verifiers, memory compounding, model-tier cost discipline, and scheduled routines) found jeo-code already had strong equivalents for most primitives — but 3 real gaps and 1 deliberately-scoped-safe gap. Closed all 4: skills that were "hand-authored, read-mostly, zero learning" now compound from real session failures; screenshots that were captured but never judged now close a real vision-verify loop; the `/goal` verifier and bulk fan-out dispatch that silently rode the same full-price model as the work they graded/executed now default to a cheap tier; and "runs without your laptop" is now achievable via a generated GitHub Actions template wrapping jeo's existing headless mode — with zero new attack surface inside jeo-code itself (no code-exec sandbox, no in-process scheduler/webhook receiver, both deliberately rejected as out of scope). Also absorbs 3 fixes shipped after 0.8.22 but never changelogged: a rate-limit fast-fallback audit that closed 4 real gaps, plus the cross-file `mock.module()` test-isolation class this release's own test additions collided with and fixed at its root cause.
|
|
286
287
|
- **[0.8.22]** (2026-07-11) — A rescan of the working tree turned up a resume-fidelity gap plus two unwired TUI safety-net helpers left by a concurrent session; each was traced, wired where needed, and verified before shipping.
|
|
287
288
|
- **[0.8.21]** (2026-07-10) — "반영할꺼 같은방식으로 체크하고 배포까지" — a rescan of the working tree (after the prior audit pass) turned up 15 uncommitted files: 3 genuinely distinct features left unwired by a concurrent session, partially casualty of an earlier accidental `git checkout` incident this session (disclosed in the 0.8.20 entry above). Each was independently traced from its existing plumbing, wired to a real call site, tested, and one live-verified end-to-end over a real PTY before shipping.
|
|
288
|
-
- **[0.8.20]** (2026-07-10) — "모든 검증 다시 리뷰하고 변경사항 모두 체크해" — 4 fresh, skeptical subagents independently re-audited every change from v0.8.17-0.8.19 (bc8768f..92c6b7d) with zero trust in prior claims: a code-correctness auditor manually traced the Antigravity routing logic against the live catalog, a test-integrity auditor mutation-tested the new tests (confirmed each one genuinely fails when its fix is reverted) and ran the suite fresh, a live-behavior verifier re-reproduced all 4 behavioral claims from scratch with self-generated data (own session ids, own mock server, own HTTP status code), and a docs-accuracy auditor cross-checked every README/CHANGELOG claim against current code in isolated git worktrees. Verdict: all core logic and tests GENUINE/CONFIRMED CORRECT — but the audit surfaced 1 real doc staleness gap, 1 changelog count error, and 2 minor precision gaps, all fixed here.
|
|
289
289
|
|
|
290
290
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
291
291
|
<!-- CHANGELOG:END -->
|
package/package.json
CHANGED
package/src/agent/plan.ts
CHANGED
|
@@ -89,7 +89,11 @@ export const PlanSchema = z.object({
|
|
|
89
89
|
}
|
|
90
90
|
let pendingUnverifiedMutation: string | undefined;
|
|
91
91
|
for (const unit of units) {
|
|
92
|
-
|
|
92
|
+
// .toLowerCase() mirrors subagents.ts's normalizeRoleId (dispatch is
|
|
93
|
+
// case-insensitive) — without it, a plan ending in e.g. `role: ARCHITECT`
|
|
94
|
+
// would resolve correctly at runtime but be WRONGLY rejected here as an
|
|
95
|
+
// unverified mutation (READONLY_ROLES["ARCHITECT"] is undefined, not true).
|
|
96
|
+
const roleIds = unit.steps.map(s => (s.role?.trim().toLowerCase() || DEFAULT_STEP_ROLE));
|
|
93
97
|
const unitMutates = roleIds.some(r => READONLY_ROLES[r] !== true);
|
|
94
98
|
const unitVerifies = roleIds.some(r => VERIFIER_ROLES[r] === true);
|
|
95
99
|
if (unitMutates) {
|