You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
rate-limit degraded warning prescribes "Redis via @objectstack/service-cache", but that adapter refuses to start #25329
Raised by the #24740 card thread (session_01XyLjAesp3Fkx794wqMb4hK) as an out-of-scope finding (class a). The domain:devx seat files it on that thread's behalf and has re-read both sites on origin/main.
The warning gives a fix that does not work. When no cache service is registered, the rate-limit store logs this warning (packages/plugins/plugin-auth/src/rate-limit-storage.ts:217-223):
a multi-node deployment needs a shared cache (Redis via @objectstack/service-cache) or each node enforces the limit independently (ADR-0069 D2)
But that package rejects Redis at startup.CacheServicePlugin.init (packages/services/service-cache/src/cache-service-plugin.ts:80-86) throws when adapter === 'redis':
Redis cache adapter is not yet implemented. Use adapter: "memory" or provide a custom ICacheService via ctx.registerService("cache", impl).
So an operator who follows the warning gets a boot failure. The only working path today is a custom ICacheService registered as cache, which the warning does not mention.
Fix options (for triage)
(a) Change the warning: point to the working path, a custom shared ICacheService registered as cache, and say that the bundled Redis adapter is not implemented yet. This is a small change in one file.
(b) Implement the Redis adapter in service-cache. This is a feature, and the existing warning text becomes correct.
PR #25328 (#24740) already gives the documentation side the current truth: counters live in the kernel cache, which under serve is in-memory and per process. This finding covers only the runtime log line.
Claim: PM loop round 1 · domain:services seat 1 (seat post #6021, project run by the Sales account) · S mechanical card, in-seat subagent · fix option (a), the warning text · 2026-10-23T12:58Z
Session: session_016g7nYP9wdNx1GDa5XDr7Uy
Account: os-sales (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-25329-rate-limit-cache-warning
Worktree: objectstack-issue-25329
Domain: domain:services
Seat: domain:services#1
File surface: packages/plugins/plugin-auth/src/rate-limit-storage.ts (the degraded warning, :218-223), the pins and docs that quote it, and a changeset. Option (b), implementing the Redis adapter, is a feature with no pull and is not taken. ⛔ packages/plugins/plugin-auth/src/auth-manager.ts is off limits (the #25224 split series cuts it serially). Stop on breach; explain in the report.
Container & model: S 级机械卡, mode:subagent (general-purpose subagent loading .claude/agents/os-dev.md as its role file), model: default tier, effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: plugin-auth's own log line prescribes a remedy that service-cache refuses at boot | the working path (a custom shared ICacheService registered as cache) exists, and the warning omits it | operators of multi-node deployments who follow the warning, today
Thread-read: none
Serial constraints cleared: the #25224 PRs touch auth-manager.ts and its split modules, not rate-limit-storage.ts. PR #25328 (#24740, docs side) is checked by the dev for overlap before editing.
Resume-from: none
{
"issue": 25329,
"status": "done",
"branch": "claude/issue-25329-rate-limit-cache-warning",
"pr": "https://github.com/objectstack-ai/objectstack/pull/25434",
"session": "session_016g7nYP9wdNx1GDa5XDr7Uy",
"premise_still_valid": true,
"summary": "Fix option (a). The degraded warning from createLazyCounterStore (plugin-auth rate-limit-storage.ts) no longer prescribes 'Redis via @objectstack/service-cache'. On origin/main 925fd0772c, CacheServicePlugin.init still throws for adapter 'redis'. The warning now names the path that works: an ICacheService backed by a store every node reaches, registered as the `cache` service (ctx.registerService('cache', impl)). It promises no bundled adapter, so it cannot go stale. The ADR-0069 D2 reference and the degradedImpact suffix are kept. Pins and docs were flipped in the same PR: the runtime inbound-rate-limit.test.ts pin quoted the old remedy and now asserts the new one plus a negative, the otp-send-guard.ts doc comment carried the same claim, and a new plugin-auth pin was added. The worktree is based on origin/main 925fd0772c, not the f0fdd45bbc named in the dispatch, because origin/main had moved. auth-manager.ts and packages/spec are untouched. PR #25328 is merged and edits only three docs files, so there is no overlap.",
"tests": "Head ff4e36d9cc. Under the verify lock: (1) built @objectstack/runtime^... plus @objectstack/plugin-auth: VERDICT command-exit 0. The new text is in plugin-auth dist/rate-limit-storage.js, and the old text is in zero dist files. (2) pnpm --filter @objectstack/plugin-auth test: Test Files 189 passed (189), Tests 3580 passed, 10 skipped. plugin-auth typecheck exit 0 (check:test-typecheck OK). pnpm --filter @objectstack/runtime exec vitest run --maxWorkers=2 src/security/inbound-rate-limit.test.ts: 25/25 passed, run against the rebuilt dist through exports. runtime typecheck exit 0. Whole command: VERDICT command-exit 0. Ablation with scripts/ablation-replace.mjs: src remedy reverted to '(Redis via @objectstack/service-cache)', anchor x1 to x0, blob 109b2dec52 to 4a99750711. rate-limit-storage.test.ts went 1 failed / 19 passed, AssertionError on the new toContain. Restore: blob equal to HEAD 109b2dec52 and git diff HEAD empty. test:repo was not run locally (CI Test Core).",
"gates": "Local: the derived list (dispatch-gates --commands, 67 commands) ran at ff4e36d9cc, each exit captured before any pipe. 66 exited 0. check:dual-build-cjs-loads exited 3, PREREQUISITE NOT MET: it needs a whole-workspace dist, so it is NOT MEASURED locally. The --ran reconciliation reads '67 derived, 66 run, 0 NOT-MEASURED, 1 UNRUN', and the unrun one is that gate. PR check-runs at ff4e36d9cc: Lint & Repo Gates success, TypeScript Type Check success, Test Core success, Build Core success, Governed Surface Queue Guard success, Check Changeset success. No check run of the 41 has a failure conclusion.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 relay writes: pr_create (repository_dispatch, run 39960683170, which created PR #25434 as draft with assignee os-sales; body read back byte-identical, 3910 bytes) and this os-dev-report comment through post-stamped.mjs. Plus 2 direct git pushes of the branch (empty, then ff4e36d9cc). Labels: none written (none named, and the changeset is present).",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted in PR Acceptance notes, not filed · read-only text drift, no public-door reproduction: README.md:415 says '@objectstack/service-cache — Cache, in-memory and Redis', and content/docs/kernel/services-checklist.mdx:522 and :543 advertise a Redis adapter. services.mdx:130 and cluster.mdx:720 already say it is a skeleton · dedupe words: service-cache Redis adapter README, services-checklist Redis, cache adapter skeleton docs"
]
}
Activity
objectstack-fleet commentedon Oct 23, 2026
Claim: PM loop round 1 ·
domain:servicesseat 1 (seat post #6021, project run by the Sales account) · S mechanical card, in-seat subagent · fix option (a), the warning text · 2026-10-23T12:58ZSession:
session_016g7nYP9wdNx1GDa5XDr7UyAccount:
os-sales(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-25329-rate-limit-cache-warningWorktree:
objectstack-issue-25329Domain:
domain:servicesSeat:
domain:services#1File surface:
packages/plugins/plugin-auth/src/rate-limit-storage.ts(the degraded warning,:218-223), the pins and docs that quote it, and a changeset. Option (b), implementing the Redis adapter, is a feature with no pull and is not taken. ⛔packages/plugins/plugin-auth/src/auth-manager.tsis off limits (the #25224 split series cuts it serially). Stop on breach; explain in the report.Container & model:
S 级机械卡,mode:subagent(general-purpose subagent loading.claude/agents/os-dev.mdas its role file),model: default tier,effort: mediumClause-②: no
Metadata-protocol: none
Responsibility: plugin-auth's own log line prescribes a remedy that
service-cacherefuses at boot | the working path (a custom sharedICacheServiceregistered ascache) exists, and the warning omits it | operators of multi-node deployments who follow the warning, todayThread-read: none
Serial constraints cleared: the #25224 PRs touch
auth-manager.tsand its split modules, notrate-limit-storage.ts. PR #25328 (#24740, docs side) is checked by the dev for overlap before editing.Resume-from: none
objectstack-fleet commentedon Oct 23, 2026
os-dev-report
{ "issue": 25329, "status": "done", "branch": "claude/issue-25329-rate-limit-cache-warning", "pr": "https://github.com/objectstack-ai/objectstack/pull/25434", "session": "session_016g7nYP9wdNx1GDa5XDr7Uy", "premise_still_valid": true, "summary": "Fix option (a). The degraded warning from createLazyCounterStore (plugin-auth rate-limit-storage.ts) no longer prescribes 'Redis via @objectstack/service-cache'. On origin/main 925fd0772c, CacheServicePlugin.init still throws for adapter 'redis'. The warning now names the path that works: an ICacheService backed by a store every node reaches, registered as the `cache` service (ctx.registerService('cache', impl)). It promises no bundled adapter, so it cannot go stale. The ADR-0069 D2 reference and the degradedImpact suffix are kept. Pins and docs were flipped in the same PR: the runtime inbound-rate-limit.test.ts pin quoted the old remedy and now asserts the new one plus a negative, the otp-send-guard.ts doc comment carried the same claim, and a new plugin-auth pin was added. The worktree is based on origin/main 925fd0772c, not the f0fdd45bbc named in the dispatch, because origin/main had moved. auth-manager.ts and packages/spec are untouched. PR #25328 is merged and edits only three docs files, so there is no overlap.", "tests": "Head ff4e36d9cc. Under the verify lock: (1) built @objectstack/runtime^... plus @objectstack/plugin-auth: VERDICT command-exit 0. The new text is in plugin-auth dist/rate-limit-storage.js, and the old text is in zero dist files. (2) pnpm --filter @objectstack/plugin-auth test: Test Files 189 passed (189), Tests 3580 passed, 10 skipped. plugin-auth typecheck exit 0 (check:test-typecheck OK). pnpm --filter @objectstack/runtime exec vitest run --maxWorkers=2 src/security/inbound-rate-limit.test.ts: 25/25 passed, run against the rebuilt dist through exports. runtime typecheck exit 0. Whole command: VERDICT command-exit 0. Ablation with scripts/ablation-replace.mjs: src remedy reverted to '(Redis via @objectstack/service-cache)', anchor x1 to x0, blob 109b2dec52 to 4a99750711. rate-limit-storage.test.ts went 1 failed / 19 passed, AssertionError on the new toContain. Restore: blob equal to HEAD 109b2dec52 and git diff HEAD empty. test:repo was not run locally (CI Test Core).", "gates": "Local: the derived list (dispatch-gates --commands, 67 commands) ran at ff4e36d9cc, each exit captured before any pipe. 66 exited 0. check:dual-build-cjs-loads exited 3, PREREQUISITE NOT MET: it needs a whole-workspace dist, so it is NOT MEASURED locally. The --ran reconciliation reads '67 derived, 66 run, 0 NOT-MEASURED, 1 UNRUN', and the unrun one is that gate. PR check-runs at ff4e36d9cc: Lint & Repo Gates success, TypeScript Type Check success, Test Core success, Build Core success, Governed Surface Queue Guard success, Check Changeset success. No check run of the 41 has a failure conclusion.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "2 relay writes: pr_create (repository_dispatch, run 39960683170, which created PR #25434 as draft with assignee os-sales; body read back byte-identical, 3910 bytes) and this os-dev-report comment through post-stamped.mjs. Plus 2 direct git pushes of the branch (empty, then ff4e36d9cc). Labels: none written (none named, and the changeset is present).", "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted in PR Acceptance notes, not filed · read-only text drift, no public-door reproduction: README.md:415 says '@objectstack/service-cache — Cache, in-memory and Redis', and content/docs/kernel/services-checklist.mdx:522 and :543 advertise a Redis adapter. services.mdx:130 and cluster.mdx:720 already say it is a skeleton · dedupe words: service-cache Redis adapter README, services-checklist Redis, cache adapter skeleton docs" ] }objectstack-fleet commentedon Oct 23, 2026
Landed ·
domain:servicesseat 1 (seat post #6021) ·os-sales·session_016g7nYP9wdNx1GDa5XDr7Uy· 2026-10-23T14:43Z6366574572), headff4e36d9ccorigin/mainb3f3298d97State: the card was closed by
Fixes #25329.pm:dispatchedis off and the assignee is cleared.Generated by Claude Code