mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-16 01:45:29 +02:00
* feat: add a restricted and supervised Claude Code runner Preserve configured authentication and models while enforcing tool access, strict completion JSON, bounded output and process cleanup. Cover argv, failure handling, session metadata and Windows process containment. * feat: route outside reviews by harness and migrate wrapper installs Use Claude Code from Codex and Codex from other supported hosts, with shared invocation rendering, positive gate validation and per-phase provenance. Rename /claude to /claude-code, repair managed shared and copied installations safely, and generate native Kiro skills. Add installed-workflow, failure-injection and live cross-harness regression coverage. * test: recognize CEO mode labels without terminal spacing The paid workflow rendered SCOPEEXPANSION at option 4, but its driver required a literal space. Match the leading mode title without cursor-spacing artifacts and ignore adjacent preview text. Preserve missing-target failures and downstream posture assertions. * test: isolate plan-count fixtures before starting review workflows Seed the complete test plan in a private git repository before launching Claude, so a bare slash command cannot review the live workspace while a delayed fixture message remains queued. Preserve count thresholds, parsers and budgets. Add initial-context and installed-discovery tests, and retain startup/terminal diagnostics on failed evaluations. * test: stabilize review fixtures and Claude eval startup Preserve source boundaries in workflow judge inputs, isolate CEO mode plans, and wait for interactive trust input readiness. Keep startup failure evidence and retain existing models, budgets, and assertions. Co-Authored-By: OpenAI Codex <noreply@openai.com> * test: classify collapsed review modes and isolate seeded findings Keep review questions out of the setup count when terminal cursor positioning removes spaces. State existing webhook safeguards so the five-finding control measures its seeded defects without accidental extra security and concurrency gaps. Preserve question bands and the paired control. Co-Authored-By: OpenAI Codex <noreply@openai.com> * test: isolate browser daemon state across free shards Co-Authored-By: OpenAI Codex <noreply@openai.com> * test: stabilize native review counting and interactive navigation Co-Authored-By: OpenAI Codex <noreply@openai.com> * chore: prepare v1.82.0.0 release Co-Authored-By: OpenAI Codex <noreply@openai.com> * fix: eliminate browser and process-cleanup test flakes Pin every CI surface to Bun 1.4.0 to avoid extra-stdio finalizers closing reused live sockets. Add an isolated GC/listener regression that fails on Bun 1.3.13, and prevent coordinated rollback to an affected CI runtime. Check renderer cleanup against the render's own staging directory so concurrent renders cannot invalidate the assertion. Make the no-pgrep process-tree walk tolerate disappearing /proc entries, and synchronize its test fixture through child readiness and pipe EOF instead of sleeps. Validation: 9,157 passed, 31 skipped, zero failures across 556 files with retries disabled. Build, all-host generation freshness, and skill checks passed. All three races have failing-before/passing-after regressions. * fix: count completed native review questions in evals * fix: drive review navigation from confirmed native choices * fix: require complete section-loading eval reports * test: isolate telemetry HTTP transport from local assertions * fix: keep review input on the active native question * test: let tunnel revocation daemon choose an available port * test: allocate available ports for pairing and watchdog fixtures * fix: stabilize planning eval navigation and phase reporting * test: isolate installed runtime paths in planning evals * test: stabilize review evidence and concurrent refresh fixtures * fix: resolve design findings before editing the plan * fix: honor and persist disabled outside plan reviews * fix: preserve planning decisions and terminal evidence Load installed host reviews at autoplan phase entry and wait for completed reviewers and saved artifacts. Reuse approved remedies while preserving individual finding decisions. Drive interactive evals from the current terminal viewport, bind native questions across scrolling, and require complete native report evidence. Cover captured stale menus, permission lifecycles, setup classification, and disabled-review tool availability with deterministic regressions. Advance release metadata and the upgrade migration to the unclaimed 1.83.0.0 slot. * fix: drive native review questions and preserve current plans Use the native single-choice keyboard protocol and current terminal viewport, with per-question navigation inside packets and completed-call coverage. Keep permissions, multi-select menus, and Submit controls distinct. Send Autoplan reviewers the amended implementation plan, keep its review record separate, and supply retained application contracts in the chain fixture. Clarify individual DevEx decisions and complete CEO fix options; use one active plan destination for the section-loading report. * fix: preserve complete plan-review decisions * fix: recognize native plan dialogs and reviewer controls * fix: preserve review decisions and phase completion * fix: recognize completed reviews without losing findings * fix: preserve review continuity and native eval completion * test: fix native review completion and eval retry isolation * test: handle native review menus and complete eval fixtures * test: fix native review setup, completion, and isolation failures * test: limit native skill discovery to runtime assets * fix: bind Autoplan reviews to full ordered phase inputs * test: fix planning eval routing, counting, and timeout handling * chore: advance queued release to v1.84.0.0 * fix: preserve complete review inputs and planning decisions * fix: reconcile review approvals and preserve phase obligations * fix: preserve review obligations and unblock eval permissions Carry recorded Autoplan requirements into blind phase inputs, require Eng review approvals before exit, and exercise combined asynchronous flows in CEO reviews. Correct native finding and handoff classification and unblock repeated report edits using scoped request identities. * fix: retain plan requirements and complete native review dialogs * fix: complete native review prompts and retain plan references * fix: preserve review inputs and classify native eval evidence * fix: check competing completion orders in CEO reviews * fix: recognize review decisions and require phase methodology Require the current phase methodology before Autoplan snapshots. Correct substantive decision, closed handoff, and cache-finding classification, and honor the recommended implementation approach in native review dialogs. Add captured-transcript regressions without changing review thresholds, provider models, retries, or deadlines. * test: bind native review decisions and close completed handoffs * fix: complete review dialogs and verify methodology delivery * fix: preserve review evidence and unblock native eval prompts * fix: handle native review question completions * fix: recognize native review narration and controls * fix: count native review decisions and isolate eval fixtures * test: verify seeded review coverage and current artifact permissions * test: isolate model and brain-aware skill renders * fix: repair native workflow evaluation and clarify review steps * fix: stabilize workflow eval evidence and review guidance * test: repair native workflow observation and fixture isolation * fix: recognize completed workflow evidence and owned skill reads * test: repair seeded workflow delivery and completion evidence * test: recognize current review evidence across native forms * test: handle native review variants and permission redraws * fix: honor review preferences and recognize native eval evidence * test: recognize completed review decisions and queued permissions * test: match current review contracts and partial-line edits * test: recognize completed workflow evidence and bounded human waits * fix: preserve review entry gates and native eval interactions * fix: recognize native workflow evidence and preserve review gates * test: recognize current review evidence and preconfigure workflow fixtures * test: recognize completed review findings and scoped artifact permissions * fix: stabilize native workflow review and permission evidence * fix: recognize current review evidence and scoped edit confirmations Clarify Design and engineering review entry instructions and Design scoring. Recognize required legacy coverage and public Autoplan completion recaps. Bind the pending Edit confirmation to its exact file, ordered digest, and one-request approval when a preceding command display remains visible. Keep reviews within their existing size limits and preserve scope gates when extracting workflow fixtures from either supported preamble header. Keep failure outcomes, review thresholds, provider choices, and eval budgets. * fix: recover review workflow progress and eval evidence * fix: recognize valid review evidence and scope selection * test: fix review evidence parsing and repeated artifact prompts * test: recognize valid review decisions and pending native cards * fix(plan-eng-review): keep final navigation consistent with approved tasks * test: recognize valid review evidence and bind legacy diff requests * fix: stabilize review eval evidence and harness repair guidance * docs: update project documentation for v1.85.0.0 Co-Authored-By: OpenAI Codex <noreply@openai.com> * test: fix Windows CI fixtures and credential scan Rebase captured JSON values and filesystem evidence using the appropriate path convention. Compile native fake CLIs on Windows and synchronize pipe holder readiness, with cleanup retained when assertions fail. Assemble synthetic credential fixtures at runtime so the added-line scan keeps enforcing the same gate without flagging its own rejection controls. Discover generated skills directly for the empty-find regression check, avoiding a recursive scan through saved evaluation artifacts and dependencies. * fix: preserve source renders on Windows Compare canonical generator paths using native separators so an output sidecar pointing at the source cannot overwrite its skill or metadata. Keep the regression fixture isolated from the real checkout and expose freshness diagnostics before asserting subprocess status. Detach Windows drain-test pipe holders from the fake provider's automatic child cleanup while preserving the enclosing runner job and its assertions. * fix: clarify outside review fallback and CEO decisions Render one applicable own-harness fallback path and retain native review, disabled policy, and missing-coverage semantics. Align report field names and mode labels, and make the existing per-cut scope approval explicit. Regenerate skill outputs and keep the workflow judge's model, thresholds, and retry policy unchanged. * chore: move release to free version slot (v1.86.0.0) PR #2852 now claims v1.85.0.0. Align the release metadata and rename migration so upgrades from that version still receive it. Co-Authored-By: OpenAI Codex <noreply@openai.com> * fix: include engineering review prerequisites and restore branch context * fix: recognize coverage diagrams and clarify design review instructions * fix: preserve file identities and join Windows test processes --------- Co-authored-by: OpenAI Codex <noreply@openai.com>
10 lines
36 KiB
JSON
10 lines
36 KiB
JSON
{
|
|
"sourceHead": "c9e7a422be47b69d855f48cfce9024457e0dd4fc",
|
|
"sessionId": "6ce43790-8ac2-45d1-a7ef-a764737578e3",
|
|
"publicReportSha256": "4be3eeaaef4f9a8f28c09d0d86305a900902aa774bb840150f130875d70450ac",
|
|
"writeLine": 2717,
|
|
"ackLine": 2721,
|
|
"report": "# Plan: cache profile summaries in one process\n\n> Reviewed by `/plan-ceo-review` on 2026-09-10, mode HOLD SCOPE. Original plan\n> text is preserved below. Accepted amendments are marked `[A1]`..`[A5]` inline\n> and defined in the review's Decision Registry. Nothing else in scope changed.\n\n## Measured problem and accepted scope\nThe existing profile-summary service has one active process. A one-week trace\nshows repeated reads of about 900 hot keys: DB CPU is 70%, with read p95 120 ms.\nAdd a process-local LRU wrapper to the existing repository. Acceptance targets\nare at least 60% cache hits, DB CPU below 50%, and read p95 below 60 ms, with the\nexisting error-rate and correctness SLOs unchanged. This is an internal backend\nchange with no UI, API, schema, pricing, or developer onboarding change.\n\n## Existing contracts retained\n- All reads and writes use this repository in the same process; there are no\n external DB writers. Multi-process operation remains unsupported and startup\n rejects that configuration while caching is enabled.\n- Authentication and authorization run before repository access. Keys encode\n the authenticated tenant ID and validated profile ID without ambiguity.\n Values are immutable profile-summary DTOs; secrets and cache keys are never\n logged. Cached results cannot bypass authorization.\n- The existing LRU adapter supports 1000 entries, a 16 MiB byte cap, and a\n 30-second TTL. Recorded hot data fits those limits. Absent records use a\n distinct sentinel with a 10-second TTL; undefined means a cache miss.\n- Cache operations are synchronous and atomic in the single JS event loop.\n On any cache failure the existing adapter bypasses the cache until an empty\n cache is reinitialized; repository errors keep the current typed API error\n mapping. The existing per-key\n single-flight wrapper coalesces simultaneous misses and releases on failure.\n- A read already in progress when a write commits may return its earlier DB\n snapshot to that caller. Every read begun after that write completes must\n observe the committed version. TTL expiry is not a substitute for this rule.\n **(Consistency invariant, unchanged. Review finding F1 shows the original\n sketch below did not meet it; amendment [A1] repairs the sketch.)**\n\n## Proposed wrapper integration\nKeep the current read-through repository interface and shared adapters.\n\n**Original sketch (superseded by [A1]/[A2], retained for the record).** It\nstated: \"no additional version checks or coordination between a cache fill and\na write are proposed.\"\n\n```javascript\n// ORIGINAL \u2014 violates the consistency invariant (see F1 schedule S2)\nasync function readProfile(key) {\n const cached = cache.get(key);\n if (cached !== undefined) return cached;\n const value = await repository.read(key);\n cache.set(key, value);\n return value;\n}\nasync function writeProfile(key, update) {\n const saved = await repository.write(key, update);\n cache.delete(key);\n return saved;\n}\n```\n\n**Amended ordering rules [A1][A2][A4].** A fill may land only if no write for\nthat key completed after the fill's DB read began. Write completion (success or\nfailure) invalidates, in one synchronous tick: the cache entry, the in-flight\nfill slot, and the single-flight slot, so later callers start a fresh DB read.\n\n```javascript\n/*\n * Fill/write ordering (keep this diagram current with the code):\n *\n * R1 miss \u2500\u2510 await read (V0) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 resolve: slot gone \u2192 DROP fill\n * W \u2502 await write \u2500\u2500 commit V1 \u2500\u2500 delete entry + forget slot (sync)\n * R2 \u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500 begins after W: miss \u2192 fresh read \u2192 V1 \u2713\n */\nasync function readProfile(key) {\n if (!flag.enabledFor(key)) return repository.read(key); // [A4] deterministic per-key bucket\n const cached = cache.get(key);\n if (cached !== undefined) return cached; // includes ABSENT sentinel\n return inflight.run(key, async (slot) => { // existing single-flight, now slot-aware\n const value = await repository.read(key); // may resolve after a commit\n if (inflight.current(key) === slot) cache.set(key, value); // else stale fill dropped, metric++\n else metrics.increment('profile_cache.stale_fill_dropped');\n return value;\n });\n}\n\nasync function writeProfile(key, update) {\n if (!flag.enabledFor(key)) return repository.write(key, update);\n try {\n return await repository.write(key, update);\n } finally { // [A2] success, typed failure, or indeterminate\n cache.delete(key); // same tick: entry,\n inflight.forget(key); // fill slot + single-flight slot\n }\n}\n```\n\n`inflight.forget(key)` is a new method on the existing single-flight wrapper.\nIt drops the current slot so joiners arriving after the write start a fresh\nread; callers already joined keep the in-progress promise (they began before\nthe write completed, which the invariant permits).\n\n## Verification and rollout\nExisting repository contract tests cover tenant isolation, key validation,\nabsence, DB failures, and authorization. New wrapper tests cover hit/miss,\neviction and byte limits, TTL, adapter-failure fallback, successful-write\ninvalidation, ~~failed-write preservation~~ **failed-write invalidation [A2]**,\nand concurrent-miss coalescing.\n\nAdded by review (each is a required assertion, see Section 6):\n- **[A1] Stale-fill ordering tests** with controlled pause/release points for\n schedules S2, S3 and S4 in the Async Ordering record.\n- **[A2] Indeterminate write test**: write rejects after the DB has committed;\n the next read returns the committed value.\n- **[A4] Flag transition tests**: read/write bucket agreement per key; any\n flag change clears entries and in-flight slots; flag evaluation error\n resolves to bypass.\n- **[A5] Clock injection**: TTL and sentinel-TTL tests use an injected clock.\n\nThe rollout uses the existing runtime feature flag: enable for 10% of keys,\nthen 50%, then all keys after one healthy hour at each stage. Bucketing is a\ndeterministic hash of the key, evaluated identically in read and write [A4].\nMonitor hit/miss, eviction, cache bytes, fallback errors, DB CPU, and read p95\nwithout raw IDs. **[A3]** Also emit `stale_fill_dropped`, `set_rejected_oversize`,\n`flag_eval_error`, and the gauge `cache_bypass_active`; alert when bypass is\nactive for more than 5 minutes or hit rate is below 60% for 15 minutes after\nthe 100% stage. Bypass entry logs at WARN with the adapter error class only.\nOn error-rate or latency regression, disable the flag immediately; both reads\nand writes bypass the cache while disabled, and enabling creates an empty cache.\n**[A4]** Any change to the flag value or bucket percentage reinitializes an empty\ncache and clears in-flight slots; a flag evaluation failure resolves to bypass.\nCold starts remain within the existing DB capacity. The service owner monitors\nthe rollout and records the results against the acceptance targets.\n\n## Out of scope\nDistributed caching, cross-process coherence, prewarming, changing consistency\nsemantics, or adding new product surfaces. The repository interface preserves a\nfuture replacement path without introducing a general cache framework now.\n\n---\n\n## CEO Review Record (HOLD SCOPE)\n\nRun conditions: automated execution, no human present. System audit, preamble,\ntelemetry, codebase exploration, learnings search, and brain context were\nskipped per run instructions (no shell available). Every decision point was\nauto-resolved to the skill's recommended option and is recorded below.\nNo repository code was read or changed.\n\n### Step 0\n\n**0A Premise.** Problem is measured, not hypothetical: one week of traces, ~900\nhot keys, DB CPU 70%, p95 120 ms. Doing nothing means the DB saturates with\ngrowth. Acceptance targets measure the real outcome (DB CPU, p95), not a proxy.\nRight problem, most direct path. No change.\n\n**0B Existing code leverage.** Sub-problem to existing code map:\n\n| Sub-problem | Existing | Reused? |\n|---|---|---|\n| Bounded storage, TTL, byte cap | LRU adapter | Yes |\n| Miss stampede | Per-key single-flight wrapper | Yes, extended with `forget` [A1] |\n| Gradual rollout / kill switch | Runtime feature flag | Yes |\n| Error surface | Typed API error mapping | Yes |\n| Tenant isolation, authz | Contract tests, pre-repo authz | Yes |\n\nNothing is rebuilt.\n\n**0C Dream state.**\n```\n CURRENT STATE THIS PLAN 12-MONTH IDEAL\n every read hits DB ---> read-through LRU in-process, ---> same interface, adapter\n DB CPU 70%, p95 120ms invariant-safe fills, swappable to shared cache\n flagged rollout if multi-process arrives\n```\nPlan moves toward the ideal; the retained repository interface is the seam.\n\n**0C-bis Implementation alternatives (D1).**\n\n| | A: Minimal (original sketch) | B: Sketch + fill/slot invalidation | C: Row-version check on fill |\n|---|---|---|---|\n| Effort | S | S | M |\n| Risk | High: violates invariant (F1) | Low | Med |\n| Completeness | 4/10 | 10/10 | 10/10 but needs schema version column |\n| Reuses | adapter, flag, single-flight | same + single-flight extension | same + DB change |\n\nD1 auto-decided: **B**. C is eliminated by the plan's \"no schema change\"\nconstraint. A fails the stated invariant.\n\n**0F Mode (D2).** HOLD SCOPE, set by the user for this run. Not auto-decided.\n\n**0D HOLD analysis.** Files touched: wrapper, single-flight adapter (one\nmethod), flag helper, tests. Under the 8-file smell threshold. Minimum set is\nthe wrapper plus the repairs required to meet the retained invariant; nothing\ndeferrable without breaking a stated requirement.\n\n**0E Temporal interrogation.** Resolved now: where the flag check lives (both\nentry points, per key); fill/write ordering (F1); slot invalidation hook (F1);\nindeterminate write handling (F2); flag transition semantics (F5); test clock\n(F8). Human ~6h / CC ~40 min for the full amended scope.\n\n### Decision Registry (all auto-resolved to recommended option)\n\n| ID | Decision | Options | Chosen | Why |\n|---|---|---|---|---|\n| D1 | Approach | A 4/10, B 10/10, C 10/10 blocked | B | Meets invariant, no schema change |\n| D2 | Mode | 4 modes | HOLD SCOPE | User-specified |\n| D3 | F1 remedy | A drop-stale-fill + slot forget 10/10; B per-key read lock 8/10; C do nothing 3/10 | A \u2192 [A1] | Explicit, bounded state, no added latency |\n| D4 | F2 remedy | A invalidate in `finally` 10/10; B allowlist pre-commit errors 9/10; C keep preservation 5/10 | A \u2192 [A2] | Smallest diff, no error taxonomy coupling |\n| D5 | F4 remedy | A metrics + alerts + WARN log 10/10; B metrics only 6/10 | A \u2192 [A3] | Zero silent failures |\n| D6 | F5 remedy | A clear on any flag change + bypass on eval error 10/10; B document only 4/10 | A \u2192 [A4] | Edge cases over documentation |\n| D7 | F8 remedy | A injected clock 10/10; B real sleeps 5/10 | A \u2192 [A5] | Flakiness is a test defect |\n| D8 | TODOS.md | none proposed | 0 items | All evidenced gaps fixed in scope |\n| D9 | Next review | A eng review; C manual | A recommended | Required gate; not runnable here |\n\nLake Score: 7/7 recommendations chose the complete option.\n\n### Findings Registry\n\n| ID | Sev | Section | Evidence | Remedy | Residual risk | Verification |\n|---|---|---|---|---|---|---|\n| F1 | CRITICAL GAP | 1, 2, 4, 5, 6 | Original sketch: fill after `await repository.read` has no guard; plan text says no fill/write coordination. Schedule S2 makes a post-write reader see V0 for 30 s; S3 does the same via single-flight joiners; S4 caches ABSENT after a create. Violates retained invariant. | [A1] drop fills whose slot was forgotten; write forgets slot + entry in one tick | Lost fill on race costs one extra DB read | Pause/release tests for S2, S3, S4; `stale_fill_dropped` metric |\n| F2 | WARNING | 2 | \"failed-write preservation\" keeps entry when `repository.write` rejects; a timeout after DB commit leaves V0 cached up to 30 s. Plan does not state failures are pre-commit. | [A2] invalidate in `finally` on every outcome | Failed writes evict one entry | Test: write rejects post-commit, next read returns V1 |\n| F3 | OK (noted) | 3 | Sentinel thrash: probing absent IDs fills 1000-entry LRU with sentinels; worst case is today's baseline, bounded by LRU size | None; hit-rate alert [A3] observes it | Degradation to baseline only | Hit-rate alert |\n| F4 | WARNING | 2, 8 | \"Any cache failure\" bypass is a catch-all with no named alert or reinit trigger; \"fallback errors\" monitored but no threshold | [A3] gauge + alerts + WARN log with error class | Bypass reinit policy stays adapter-owned | Alert fires in staging fault-injection |\n| F5 | WARNING | 9 | Rollout by % of keys; plan says enable clears cache but is silent on % changes and flag evaluation failure | [A4] deterministic per-key bucket, clear on any change, eval error \u2192 bypass | None material | Flag transition tests |\n| F6 | OK | 3 | Authz precedes repository; keys tenant-scoped; DTOs immutable; no keys logged | None | \u2014 | Existing contract tests |\n| F7 | OK | 7 | 1000 \u00d7 DTO within 16 MiB; O(1) sync ops; cold start within DB capacity; single-flight caps stampede | None | 100x load is a multi-process problem, out of scope | Rollout metrics |\n| F8 | WARNING | 6 | TTL and sentinel-TTL tests depend on wall clock | [A5] injected clock | None | Tests deterministic |\n\n### Async Ordering Record (Section 4)\n\nShared state: `cache[key]`, `inflight[key]`. Invariant boundary: a read that\n*begins* after `writeProfile` resolves must return the committed version.\n\n```\n Sched | R1 (miss, reads V0) | W (commits V1) | R2 (begins after W) | cache[key] | Result\n ------|----------------------------|-----------------------------|---------------------|------------|-------\n S1 | read\u2192set V0 | write\u2192delete | miss\u2192read V1\u2192set | V1 | OK\n S2* | await read ... | write commits, delete(noop) | | - |\n | resolves V0 \u2192 set V0 | | hit \u2192 V0 | V0 (30 s) | VIOLATION\n S2 A1 | resolves V0, slot gone\u2192drop| delete + forget (one tick) | miss\u2192read V1\u2192set | V1 | OK\n S3* | await read ... | write, delete | joins R1 \u2192 V0 | - | VIOLATION\n S3 A1 | await read ... | delete + forget | new slot\u2192read V1 | V1 | OK\n S4* | miss on absent \u2192 await | create commits | hit ABSENT (10 s) | ABSENT | VIOLATION\n S4 A1 | slot gone \u2192 drop ABSENT | delete + forget | miss\u2192read V1 | V1 | OK\n S5 | begins before W, joins | delete + forget | \u2014 | \u2014 | OK: R1 began before W completed (permitted clause)\n```\n`*` = original sketch. Mechanism preventing S2\u2013S4 after [A1]: the forget and\nthe slot comparison run in synchronous ticks; no await separates `delete` from\n`forget`, and no await separates the slot check from `cache.set`.\n\nShadow paths for the new flow (nil key, empty key, upstream error): nil/empty\nkeys are rejected by existing key validation before the cache; upstream read\nerror releases the slot and maps to the typed API error with no fill; upstream\nwrite error invalidates per [A2]. All three covered by existing contract tests\nplus [A2].\n\nNo user-visible interactions: interaction edge-case table not applicable.\n\n### Section Outcomes\n\n| # | Section | Outcome |\n|---|---|---|\n| 1 | Architecture | 1 issue (F1). Coupling added: wrapper \u2192 single-flight `forget`. Justified. SPOF unchanged (one process, DB). Rollback: flag off, seconds. Diagram below. |\n| 2 | Error & Rescue | 9 paths mapped, 2 GAPS (F1 stale fill, F2 indeterminate write), both remedied. F4 catch-all named and instrumented. Registry below. |\n| 3 | Security | 0 issues High. F3 and F6 evaluated, no change. No new endpoints, params, secrets, or dependencies. |\n| 4 | Data flow / ordering | 5 schedules mapped, 3 violating (S2\u2013S4), 0 unhandled after [A1]. |\n| 5 | Code quality | 1 issue (F1 sketch under-engineered). Sketch amended. Both functions branch \u22643 times. No DRY violation. |\n| 6 | Tests | Diagram below. 4 gaps (F1 ordering, F2 indeterminate, F5 flag transitions, F8 clock), all amended. Test pyramid: unit-heavy, correct. |\n| 7 | Performance | No issues (F7). Slowest new path: miss + fill, p99 \u2248 existing DB read. |\n| 8 | Observability | 1 gap (F4), remedied by [A3]. Runbook: bypass alert \u2192 inspect WARN error class \u2192 reinit or disable flag. |\n| 9 | Deployment | 1 risk (F5), remedied by [A4]. No migration. Old/new code overlap: none (single process). Post-deploy: hit rate rising, bypass gauge 0, p95 falling within 5 min. |\n| 10 | Trajectory | Reversibility 5/5. Debt items: 0 (ordering diagram lives in code comment, maintained with the change). Obvious to a new engineer in 12 months given the comment. |\n| 11 | Design & UX | SKIPPED, justified: no UI scope; plan states no UI, API, or onboarding change. |\n\n### Error & Rescue Registry\n\n| Codepath | What goes wrong | Exception | Rescued | Action | User sees |\n|---|---|---|---|---|---|\n| readProfile / cache.get,set | adapter internal failure | adapter error (named in log) | Y (adapter) | bypass mode, WARN, gauge=1 [A3] | Nothing (DB serves) |\n| readProfile / repository.read | DB timeout, connection | TimeoutError, ConnectionError | Y (existing) | slot released, typed API error | Existing error |\n| readProfile / repository.read | record absent | none (ABSENT sentinel) | n/a | cache sentinel 10 s | Existing not-found |\n| readProfile / fill | write completed during read | none | Y [A1] | drop fill, metric | Nothing |\n| readProfile / cache.set | DTO > 16 MiB | adapter reject | Y (adapter) | no fill, `set_rejected_oversize` [A3] | Nothing |\n| writeProfile / repository.write | validation, authz | ValidationError, AuthorizationError | Y (existing) | invalidate [A2], typed error | Existing error |\n| writeProfile / repository.write | timeout after commit | TimeoutError | Y [A2] | invalidate in `finally` | Existing error |\n| writeProfile / cache.delete | adapter failure | adapter error | Y (adapter) | bypass, WARN [A3] | Nothing |\n| flag.enabledFor | flag store unavailable | flag client error | Y [A4] | bypass, `flag_eval_error` | Nothing |\n| startup | multi-process + cache on | ConfigurationError | Y (existing) | refuse start, log | Deploy fails loudly |\n\n### Failure Modes Registry\n\n```\n CODEPATH | FAILURE MODE | RESCUED? | TEST? | USER SEES? | LOGGED?\n --------------------|---------------------------|----------|-----------|-----------------|--------\n read fill | stale fill after write | Y [A1] | Y [A1] | Nothing | metric\n read via joiner | joins pre-write read | Y [A1] | Y [A1] | Nothing | metric\n read fill | ABSENT cached after create| Y [A1] | Y [A1] | Nothing | metric\n write | indeterminate outcome | Y [A2] | Y [A2] | Existing error | existing\n write | typed pre-commit failure | Y | Y (exist) | Existing error | existing\n cache adapter | internal failure \u2192 bypass | Y | Y (exist) | Nothing | WARN [A3]\n cache adapter | bypass persists silently | Y [A3] | staging | Nothing | alert\n cache set | oversize DTO | Y | Y (exist) | Nothing | metric [A3]\n flag | eval error | Y [A4] | Y [A4] | Nothing | metric\n flag | % change leaves stale | Y [A4] | Y [A4] | Nothing | n/a\n startup | multi-process config | Y | Y (exist) | Deploy fails | Y\n```\nCRITICAL GAPS before review: 1 (F1). Open after accepted remedies: 0.\n\n### Test Diagram (Section 6)\n\n```\n NEW UX FLOWS: none\n NEW DATA FLOWS: read-through fill; write-through invalidate; flag gate\n NEW CODEPATHS: hit; miss+fill; miss+dropped fill; joiner; forget; finally-invalidate;\n flag off; flag eval error; flag change clear\n NEW ASYNC WORK: none (in-loop promises only)\n NEW INTEGRATIONS: none\n NEW ERROR/RESCUE PATHS: see Error & Rescue Registry\n```\nAssertions (unit unless noted): hit returns cached DTO and skips DB (rejects a\nDB call count of 1); miss fills once (rejects 2 DB calls under N concurrent\nmisses); S2/S3/S4 with paused read return V1 to the post-write reader (rejects\nV0 or ABSENT); post-commit write rejection leaves no entry (rejects a hit);\nadapter throw yields DB value and gauge=1 (rejects a thrown error); eviction at\n1001 entries and at 16 MiB + 1 byte; TTL 30 s and sentinel 10 s via injected\nclock; flag off skips both cache calls; flag change empties cache and slots.\n2am test: S2 under load harness. Hostile QA: S3 joiner after write. Chaos:\nadapter throws mid-fill while a write commits. Load test: 900-key replay at\n10x, assert hit rate \u2265 60% and no DB call amplification.\n\n### Diagrams\n\n**1. System architecture**\n```\n caller \u2500\u25b6 authn/authz \u2500\u25b6 readProfile/writeProfile (wrapper, NEW)\n \u2502 \u2502 \u2502\n \u25bc \u25bc \u25bc\n flag.enabledFor LRU adapter single-flight (+forget, NEW)\n \u2502 \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2518\n \u25bc\n repository \u2500\u25b6 DB\n```\n\n**2. Data flow with shadow paths**\n```\n key \u2500\u25b6 validate \u2500\u25b6 flag? \u2500\u25b6 cache.get \u2500\u25b6 [miss] slot \u2500\u25b6 repository.read \u2500\u25b6 slot check \u2500\u25b6 set \u2500\u25b6 DTO\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n nil/empty reject error\u2192bypass hit\u2192return error\u2192release, typed forgotten\u2192drop\n```\n\n**3. State machines**\n```\n entry: (none) \u2500\u2500miss\u2500\u2500\u25b6 FILLING \u2500\u2500resolve & slot ok\u2500\u2500\u25b6 PRESENT|ABSENT \u2500\u2500TTL/evict/write\u2500\u2500\u25b6 (none)\n \u2514\u2500write forget\u2500\u25b6 (none) [set after forget: impossible, slot check]\n adapter: ACTIVE \u2500\u2500any adapter error\u2500\u2500\u25b6 BYPASS \u2500\u2500reinit empty\u2500\u2500\u25b6 ACTIVE\n flag: OFF \u2500\u2500enable\u2500\u2500\u25b6 ON(p%) \u2500\u2500change p\u2500\u2500\u25b6 ON(p'%) (cache cleared) \u2500\u2500disable\u2500\u2500\u25b6 OFF\n```\n\n**4. Error flow**\n```\n adapter error \u2500\u25b6 BYPASS + WARN + gauge \u2500\u25b6 alert >5 min \u2500\u25b6 operator: reinit or flag off\n repo error \u2500\u25b6 release slot \u2500\u25b6 typed API error (unchanged) \u2500\u25b6 write: finally invalidate\n```\n\n**5. Deployment sequence**\n```\n deploy (flag OFF) \u2500\u25b6 10% keys \u25001h healthy\u2500\u25b6 50% \u25001h healthy\u2500\u25b6 100% \u2500\u25b6 record vs targets\n each step: watch hit rate, bypass gauge, stale_fill_dropped, DB CPU, p95\n```\n\n**6. Rollback flowchart**\n```\n regression? \u2500yes\u2500\u25b6 flag OFF (reads+writes bypass, seconds) \u2500\u25b6 still bad? \u2500yes\u2500\u25b6 git revert deploy\n \u2502no \u2502no\n \u25bc \u25bc\n continue ramp investigate WARN error class\n```\n\n### Required Prose Sections\n\n**NOT in scope** (all pre-existing, restated with rationale):\n- Distributed or cross-process cache: single process today; interface seam retained.\n- Prewarming: cold start fits DB capacity per trace.\n- Consistency semantics change: invariant retained as written.\n- Row-version fill check (Approach C): needs schema change, prohibited.\n\n**What already exists.** LRU adapter, single-flight wrapper, runtime flag,\ntyped error mapping, contract tests. All reused; single-flight gains one method.\n\n**Dream state delta.** After this plan the service has a correct, observable,\nflag-controlled local cache behind the unchanged repository interface. The\nremaining gap to the 12-month ideal is only the adapter swap if multi-process\never arrives, which the interface already permits.\n\n**TODOS.md updates.** 0 items. Every evidenced gap was repaired in scope (D8).\n\n**Stale diagram audit.** No existing ASCII diagrams in the plan or named\nfiles. One new diagram is added as a code comment with [A1] and must be kept\ncurrent with the wrapper.\n\n**Outside voice.** `codex_reviews: disabled` in the isolated config. The extra\noutside-review step was skipped entirely, including its native fallback.\nOutside coverage: disabled. The guarded review-log persistence for the disabled\nrecord was not run (no shell in this run).\n\n## Implementation Tasks\nSynthesized from this review's findings. Each task derives from a specific\nfinding above. Run with Claude Code or Codex; checkbox as you ship.\n\n- [ ] **T1 (P1, human: ~2h / CC: ~15min)** \u2014 wrapper + single-flight \u2014 Implement slot-aware fill drop and `forget` on write completion [A1]\n - Surfaced by: Section 4 \u2014 F1, schedules S2\u2013S4\n - Files: profile wrapper, single-flight adapter, ordering diagram comment\n - Verify: pause/release tests for S2, S3, S4 pass; `stale_fill_dropped` increments in S2\n- [ ] **T2 (P1, human: ~30min / CC: ~5min)** \u2014 wrapper \u2014 Invalidate in `finally` on every write outcome [A2]\n - Surfaced by: Section 2 \u2014 F2 indeterminate write\n - Files: profile wrapper, tests (replace failed-write preservation test)\n - Verify: post-commit rejection test returns V1 on next read\n- [ ] **T3 (P1, human: ~1h / CC: ~10min)** \u2014 flag helper \u2014 Deterministic per-key bucket, clear on any flag change, bypass on eval error [A4]\n - Surfaced by: Section 9 \u2014 F5\n - Files: flag helper, wrapper, tests\n - Verify: flag transition tests; `flag_eval_error` metric on injected failure\n- [ ] **T4 (P2, human: ~1h / CC: ~10min)** \u2014 observability \u2014 Metrics, gauge, WARN log with error class, two alerts [A3]\n - Surfaced by: Section 8 \u2014 F4\n - Files: wrapper, adapter bypass hook, alert config\n - Verify: staging fault injection fires bypass alert within 5 min\n- [ ] **T5 (P2, human: ~30min / CC: ~5min)** \u2014 tests \u2014 Injected clock for TTL and sentinel-TTL tests [A5]\n - Surfaced by: Section 6 \u2014 F8\n - Files: wrapper tests\n - Verify: tests pass with no sleeps; run 20x without flake\n- [ ] **T6 (P2, human: ~1h / CC: ~10min)** \u2014 tests \u2014 Load replay of 900 hot keys at 10x asserting hit rate \u2265 60% and no DB amplification\n - Surfaced by: Section 6 \u2014 test ambition check\n - Files: load test harness\n - Verify: harness report against acceptance targets\n\n_No new tasks from Section 3 (Security), Section 7 (Performance), Section 10 (Trajectory), Section 11 (Design, skipped)._\n\nJSONL task artifact: not written (no shell/jq in this run). Re-run the JSONL\nstep from the review sections when a shell is available.\n\n### Completion Summary\n```\n +====================================================================+\n | MEGA PLAN REVIEW \u2014 COMPLETION SUMMARY |\n +====================================================================+\n | Mode selected | HOLD SCOPE (user-specified) |\n | System Audit | SKIPPED per run instructions |\n | Step 0 | Approach B; premise holds; 0 scope changes |\n | Section 1 (Arch) | 1 issue found (F1) |\n | Section 2 (Errors) | 9 error paths mapped, 2 GAPS (remedied) |\n | Section 3 (Security)| 0 issues found, 0 High severity |\n | Section 4 (Data/UX) | 5 schedules mapped, 0 unhandled after A1 |\n | Section 5 (Quality) | 1 issue found (F1 sketch) |\n | Section 6 (Tests) | Diagram produced, 4 gaps (all amended) |\n | Section 7 (Perf) | 0 issues found |\n | Section 8 (Observ) | 1 gap found (F4, remedied) |\n | Section 9 (Deploy) | 1 risk flagged (F5, remedied) |\n | Section 10 (Future) | Reversibility: 5/5, debt items: 0 |\n | Section 11 (Design) | SKIPPED (no UI scope) |\n +--------------------------------------------------------------------+\n | NOT in scope | written (4 items) |\n | What already exists | written |\n | Dream state delta | written |\n | Error/rescue registry| 10 rows, 0 CRITICAL GAPS open |\n | Failure modes | 11 total, 1 CRITICAL GAP found, 0 open |\n | TODOS.md updates | 0 items proposed |\n | Scope proposals | 0 proposed, 0 accepted (HOLD) |\n | CEO plan | skipped (HOLD) |\n | Outside voice | codex: disabled (config), no fallback |\n | Lake Score | 7/7 recommendations chose complete option |\n | Diagrams produced | 7 (arch, data flow, state, error, deploy, |\n | | rollback, async schedule) |\n | Stale diagrams found | 0 |\n | Unresolved decisions | 0 |\n +====================================================================+\n```\n\nSkipped persistence (no shell in this run): `gstack-review-log`,\n`gstack-decision-log`, `gstack-review-read`, telemetry, learnings log,\nhandoff cleanup. No durable learnings this session beyond the plan itself.\n\nNext review: run `/plan-eng-review` (required gate) against this amended plan.\nDesign review not applicable.\n\n## GSTACK REVIEW REPORT\n\n| Review | Trigger | Why | Runs | Status | Findings |\n|--------|---------|-----|------|--------|----------|\n| CEO Review | `/plan-ceo-review` | Scope & strategy | 1 | clean (HOLD_SCOPE) | mode: HOLD_SCOPE, 1 critical gap found and remedied, 0 open; 5 amendments A1\u2013A5 |\n| Outside Review | codex via `/plan-ceo-review` (codex_reviews: disabled) | Independent 2nd opinion | 0 | disabled | \u2014 |\n| Eng Review | `/plan-eng-review` | Architecture & tests (required) | 0 | \u2014 | \u2014 |\n| Design Review | `/plan-design-review` | UI/UX gaps | 0 | \u2014 | \u2014 |\n| DX Review | `/plan-devex-review` | Developer experience gaps | 0 | \u2014 | \u2014 |\n\n- **OUTSIDE COVERAGE:** provider codex, phase plan-review, status disabled by `codex_reviews: disabled`; no outside CLI invoked, no native fallback dispatched; disabled record not persisted (no shell this run).\n- **VERDICT:** CEO CLEARED (HOLD SCOPE, amendments A1\u2013A5 accepted) \u2014 eng review required\n\nNO UNRESOLVED DECISIONS\n",
|
|
"compact": "### Findings Registry\n\n| ID | Sev | Section | Evidence | Remedy | Residual risk | Verification |\n|---|---|---|---|---|---|---|\n| F1 | CRITICAL GAP | 1, 2, 4, 5, 6 | Original sketch: fill after `await repository.read` has no guard; plan text says no fill/write coordination. Schedule S2 makes a post-write reader see V0 for 30 s; S3 does the same via single-flight joiners; S4 caches ABSENT after a create. Violates retained invariant. | [A1] drop fills whose slot was forgotten; write forgets slot + entry in one tick | Lost fill on race costs one extra DB read | Pause/release tests for S2, S3, S4; `stale_fill_dropped` metric |\n| F2 | WARNING | 2 | \"failed-write preservation\" keeps entry when `repository.write` rejects; a timeout after DB commit leaves V0 cached up to 30 s. Plan does not state failures are pre-commit. | [A2] invalidate in `finally` on every outcome | Failed writes evict one entry | Test: write rejects post-commit, next read returns V1 |\n| F3 | OK (noted) | 3 | Sentinel thrash: probing absent IDs fills 1000-entry LRU with sentinels; worst case is today's baseline, bounded by LRU size | None; hit-rate alert [A3] observes it | Degradation to baseline only | Hit-rate alert |\n| F4 | WARNING | 2, 8 | \"Any cache failure\" bypass is a catch-all with no named alert or reinit trigger; \"fallback errors\" monitored but no threshold | [A3] gauge + alerts + WARN log with error class | Bypass reinit policy stays adapter-owned | Alert fires in staging fault-injection |\n| F5 | WARNING | 9 | Rollout by % of keys; plan says enable clears cache but is silent on % changes and flag evaluation failure | [A4] deterministic per-key bucket, clear on any change, eval error \u2192 bypass | None material | Flag transition tests |\n| F6 | OK | 3 | Authz precedes repository; keys tenant-scoped; DTOs immutable; no keys logged | None | \u2014 | Existing contract tests |\n| F7 | OK | 7 | 1000 \u00d7 DTO within 16 MiB; O(1) sync ops; cold start within DB capacity; single-flight caps stampede | None | 100x load is a multi-process problem, out of scope | Rollout metrics |\n| F8 | WARNING | 6 | TTL and sentinel-TTL tests depend on wall clock | [A5] injected clock | None | Tests deterministic |\n\n### Async Ordering Record (Section 4)\n\nShared state: `cache[key]`, `inflight[key]`. Invariant boundary: a read that\n*begins* after `writeProfile` resolves must return the committed version.\n\n```\n Sched | R1 (miss, reads V0) | W (commits V1) | R2 (begins after W) | cache[key] | Result\n ------|----------------------------|-----------------------------|---------------------|------------|-------\n S1 | read\u2192set V0 | write\u2192delete | miss\u2192read V1\u2192set | V1 | OK\n S2* | await read ... | write commits, delete(noop) | | - |\n | resolves V0 \u2192 set V0 | | hit \u2192 V0 | V0 (30 s) | VIOLATION\n S2 A1 | resolves V0, slot gone\u2192drop| delete + forget (one tick) | miss\u2192read V1\u2192set | V1 | OK\n S3* | await read ... | write, delete | joins R1 \u2192 V0 | - | VIOLATION\n S3 A1 | await read ... | delete + forget | new slot\u2192read V1 | V1 | OK\n S4* | miss on absent \u2192 await | create commits | hit ABSENT (10 s) | ABSENT | VIOLATION\n S4 A1 | slot gone \u2192 drop ABSENT | delete + forget | miss\u2192read V1 | V1 | OK\n S5 | begins before W, joins | delete + forget | \u2014 | \u2014 | OK: R1 began before W completed (permitted clause)\n```\n`*` = original sketch. Mechanism preventing S2\u2013S4 after [A1]: the forget and\nthe slot comparison run in synchronous ticks; no await separates `delete` from\n`forget`, and no await separates the slot check from `cache.set`.\n\n"
|
|
}
|