Skip to content

integration: batch 2 — priority drafts (#1824 #1779 #1770 #1769 #1678) - #1839

Merged
simple-agent-manager[bot] merged 67 commits into
mainfrom
sam/batch-2-priority-drafts
Aug 16, 2026
Merged

integration: batch 2 — priority drafts (#1824 #1779 #1770 #1769 #1678)#1839
simple-agent-manager[bot] merged 67 commits into
mainfrom
sam/batch-2-priority-drafts

Conversation

@simple-agent-manager

@simple-agent-manager simple-agent-manager Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Integration vehicle — DO NOT MERGE until the parent PR-backlog orchestrator completes the batch staging validation window. Do not touch or close the constituent PRs from this PR.

This branch combines the authorized batch 2 priority-draft PRs on top of current origin/main cb6c485c42efbcaea9c95a2c4a7dd5ea12b8e08b (ccecf8935f84ff3aca4ef3a1aad81651d5871722 at initial branch creation, then current-main #1836 merged before final push).

Constituent PRs:

PR Pinned head Scope Merge result
#1824 0819e5184102659f2d2acca6a60d037d47ecf0db Scheduler lifecycle race lab + cleanup arbitration fixes Merged first with --no-ff; no textual conflicts.
#1779 f9b3c85e59b45ff752009d3fb9b1d17bb5be20dd Diagnostic incident correlation + lifecycle classification Merged second with --no-ff; no textual conflicts.
#1770 112259dbbe934152b14c2f9e2ee3c47d83c7f27c list_triggers MCP tool Merged third with --no-ff; auto-merged shared env/docs/helper files.
#1769 ca30aa0f60f866569788e4c0329cb8c846e079c4 Project-data caching across responsive navigation Merged fourth with --no-ff; auto-merged docs/config references.
#1678 bac2702c0967b854fe6fa9ca760be0ece1594bdd Claude guided-login verification code forwarding Merged fifth with --no-ff; auto-merged env/docs references. Note: current PR #1678 head had moved, so this branch used the exact pinned commit.

Integration-only fix:

Merge conflict and compatibility log

Area Result Resolution / rationale
#1824 + #1779 lifecycle/cleanup paths No same-file textual conflicts Preserved both sides. #1824's atomic placement-vs-cleanup arbitration remains in apps/api/src/services/workspace-placement.ts, apps/api/src/durable-objects/task-runner/workspace-branch.ts, apps/api/src/durable-objects/task-runner/workspace-steps.ts, and apps/api/src/scheduled/node-cleanup/*. #1779's exactly-once force-stop completion, lifecycle classification, and correlation bindings remain in apps/api/src/routes/mcp/orchestration-comms.ts, apps/api/src/services/vm-error-correlation.ts, packages/shared/src/failure-classification.ts, and packages/vm-agent/internal/acp/session_host*.go.
Shared env/config/docs files Auto-merged Additive env/docs references from #1779, #1770, #1769, and #1678 were preserved. pnpm quality:wrangler-bindings and docs/config quality checks passed.
Project-chat failure shell styling Integration-only fix required The final branch adds one compatibility fix so non-diagnosable lifecycle outcomes do not receive the red shell glow. The affected Playwright audit subset now passes.
Current-main migration numbering Integration-only fix required after #1836 landed on main Merged origin/main and renumbered the unmerged #1678 migration to 0114_credential_setup_exchanging_status.sql; SQL content is unchanged and pnpm quality:migration-ordering passes.

Conflict-marker scan after all merges and the integration-only fix: rg -n '^(<<<<<<<|=======|>>>>>>>)' -g '!pnpm-lock.yaml' . returned no matches.

Union fidelity check

  • Pure constituent-union check: PASS. An independent scratch worktree from origin/main merged the five exact pinned heads in the requested order with git merge --no-ff; its tree matched the five-merge integration tree before the UI compatibility fix.
  • Final tree check: the final PR head intentionally differs from the pure union by two documented integration-only resolutions:
    • apps/web/src/components/project-message-view/index.tsx (12 insertions, 3 deletions) in commit 7cddd524e1a594ebe4aaeefd8147bd9372654305.
    • apps/api/src/db/migrations/0114_credential_setup_exchanging_status.sql, renamed from fix: forward Claude guided login verification code #1678's 0112_credential_setup_exchanging_status.sql with no SQL content changes in commit 680c526567c92852ce71d985a75629c7b2b65879, required because current origin/main now owns migration prefixes 0112 and 0113.
  • No constituent content was dropped, and no conflict markers remain.

Candidate sweep/cron cost note

#1824 changes scheduler lifecycle and node-cleanup arbitration. Expected candidate volume and cost:

  • Candidate volume remains bounded by the existing scheduled node-cleanup sweep inputs and cleanup configuration; the batch does not add a new unbounded scan loop.
  • The highest-risk new path is atomic placement-vs-cleanup arbitration: placement claims and cleanup decisions now consult durable node/workspace state before acting, so ambiguous candidates are skipped or retried instead of deleted.
  • Worst-case per-candidate cost is bounded to the existing D1/DO state reads plus the strict deletion/mark-idle action already covered by node cleanup. The scheduler lifecycle simulation and worker tests exercise the race cases that would otherwise multiply cleanup/placement work.

Validation

  • pnpm lint — covered by pnpm check:fast
  • pnpm typecheck
  • pnpm test
  • Additional validation run (if applicable)
  • If this PR changes candidate selection for a sweep/cron/alarm loop (WHERE clause, status set, join, or equivalent), expected candidate volume and worst-case per-candidate cost are stated in the summary or validation notes (see .claude/rules/47-control-loop-io-budget.md)

Local validation results:

  • pnpm install --frozen-lockfile — PASS
    • Required because this workspace initially had no node_modules; lockfile unchanged.
  • pnpm check:fast — PASS after the integration-only fixes and current-main merge
    • Format ratchet passed without running bare pnpm format.
    • Oxlint remained advisory.
    • ESLint completed with existing warnings only.
    • Type-boundary audit completed with report-only counts.
  • pnpm typecheck — PASS after the integration-only fixes and current-main merge
    • Turbo: 19 successful / 19 total.
  • pnpm --filter @simple-agent-manager/api test — PASS after the integration-only fixes and current-main merge
    • 552 test files passed; 7,429 tests passed.
  • pnpm --filter @simple-agent-manager/web test — PASS after the integration-only fixes and current-main merge
    • 260 test files passed; 3,126 tests passed.
  • Go 1.26.6 vm-agent validation — PASS after the integration-only fixes and current-main merge
    • Installed task-local Go 1.26.6 because the workspace initially had no go binary on PATH.
    • packages/vm-agent: go vet ./..., go build ./..., and go test ./... — PASS with go version go1.26.6 linux/amd64.
  • Quality script suite — PASS after the integration-only fixes and current-main merge
    • pnpm quality:no-tracked-stale-binaries
    • pnpm quality:scripts:test
    • pnpm quality:wrangler-bindings
    • pnpm quality:agent-install-manifest
    • pnpm quality:migration-safety
    • pnpm quality:migration-ordering
    • pnpm quality:do-migration-safety
    • pnpm quality:ast-checks
    • pnpm quality:file-sizes
    • pnpm quality:stale-artifacts
    • pnpm quality:repo-visibility — report-only, completed
    • pnpm quality:source-contract-tests
    • pnpm quality:dependency-governance
    • pnpm quality:workspace-test-surfaces
    • pnpm quality:direct-dependency-evidence
    • pnpm quality:runtime-boundary-semantics
    • pnpm exec vitest run --config scripts/quality/vitest.config.ts ci-quality-program.test.ts ci-worker-suite.test.ts
    • pnpm exec vitest run --config scripts/quality/vitest.config.ts check-migration-ordering.test.ts ci-quality-program.test.ts ci-worker-suite.test.ts
    • pnpm quality:gitleaks:current — PASS with pinned Gitleaks 8.30.1, 54 reviewed findings / 0 new
    • pnpm quality:gitleaks:pr — PASS with pinned Gitleaks 8.30.1, 0 reviewed findings / 0 new
    • pnpm quality:govulncheck-diff — PASS, no Go module files changed
  • Affected Playwright UI audit subset — PASS after the integration-only fix
    • Command: pnpm --filter @simple-agent-manager/web exec playwright test --config=playwright.config.ts tests/playwright/frontend-cache-audit.spec.ts tests/playwright/agent-guided-connect-audit.spec.ts tests/playwright/failure-card-audit.spec.ts tests/playwright/project-chat-recoverable-error-audit.spec.ts
    • Result: 55 passed / 21 skipped across configured mobile/tablet/desktop projects.

Remote CI validation results:

Staging Verification (REQUIRED for all code changes — merge-blocking)

This scoped integration-build subtask intentionally does not deploy or validate staging. The parent PR-backlog orchestrator owns the staging deployment and validation window.

  • Staging deployment green — Pending parent deploy+validation window.
  • Live app verified via Playwright — Pending parent deploy+validation window.
  • Existing workflows confirmed working — Pending parent deploy+validation window.
  • New feature/fix verified on staging — Pending parent deploy+validation window.
  • Infrastructure verification completed — Pending parent deploy+validation window.
  • Mobile and desktop verification notes added for UI changes — Pending parent deploy+validation window.

Staging Verification Evidence

Pending parent deploy+validation window. Not performed here by explicit task scope: integration-build only, no staging deployment, no merge.

UI Compliance Checklist (Required for UI changes)

  • Mobile-first layout verified
  • Accessibility checks completed
  • Shared UI components used or exception documented
  • Playwright visual audit run locally — mock data scenarios (normal, long text, empty, many items, error, special chars) tested at mobile (375x667) and desktop (1280x800); no horizontal overflow; screenshots in .codex/tmp/playwright-screenshots/ (see .claude/rules/17-ui-visual-testing.md)

Notes: affected local audit specs passed after the integration-only fix. Live staging UI verification remains pending the parent orchestrator's deploy+validation window.

End-to-End Verification (Required for multi-component changes)

  • Data flow traced from user input to final outcome with code path citations (see .claude/rules/10-e2e-verification.md)
  • Capability test exercises the complete happy path across system boundaries
  • All spec/doc assumptions about existing behavior verified against code (not just "read the code")
  • If any gap exists between automated test coverage and full E2E, manual verification steps documented below

Data Flow Trace

  • test: add scheduler lifecycle race lab #1824 scheduler lifecycle: apps/api/src/durable-objects/task-runner/workspace-steps.ts delegates placement decisions through apps/api/src/services/workspace-placement.ts; cleanup arbitration remains in apps/api/src/scheduled/node-cleanup/shared.ts and node-phases.ts; race coverage is in apps/api/tests/simulation/scheduler-lifecycle-simulation.test.ts and apps/api/tests/workers/scheduler-lifecycle-races.test.ts.
  • Fix diagnostic incident correlation and lifecycle classification #1779 lifecycle/correlation: apps/api/src/routes/mcp/orchestration-comms.ts drives hard-stop/persist/cleanup ordering; apps/api/src/services/vm-error-correlation.ts binds VM incidents to authoritative node/workspace/session/task state; coverage includes apps/api/tests/integration/mcp-stop-subtask-lifecycle.test.ts, apps/api/tests/integration/observability-ingestion.test.ts, and apps/api/tests/unit/services/vm-error-correlation.test.ts.
  • feat(api): add project-scoped list_triggers MCP tool #1770 list_triggers: MCP tool definitions in apps/api/src/routes/mcp/tool-definitions-trigger-tools.ts route to apps/api/src/routes/mcp/trigger-list-tool.ts, which uses apps/api/src/services/trigger-read.ts; coverage includes apps/api/tests/unit/routes/mcp-list-triggers.test.ts and apps/api/tests/workers/mcp-trigger-tools.test.ts.
  • perf(web): cache project data across responsive navigation #1769 project-data caching: apps/web/src/hooks/useProjectData.ts, apps/web/src/lib/query-options.ts, apps/web/src/lib/project-query-config.ts, and apps/web/src/hooks/useProjectIntentPrefetch.ts preserve project data during responsive navigation; coverage includes apps/web/tests/unit/hooks/useProjectData.test.tsx, apps/web/tests/unit/ProjectPrefetch.test.tsx, and apps/web/tests/playwright/frontend-cache-audit.spec.ts.
  • fix: forward Claude guided login verification code #1678 guided login forwarding: apps/api/src/durable-objects/credential-setup-session/index.ts, apps/api/src/routes/agent-credential-setup-sessions.ts, apps/web/src/components/CodexConnectModal.tsx, and apps/api/scripts/claude-setup-token.mjs forward Claude verification codes through the setup session; coverage includes apps/api/tests/workers/agent-credential-setup-native-vertical.test.ts, apps/api/tests/unit/scripts/claude-setup-token.test.ts, and apps/web/tests/playwright/agent-guided-connect-audit.spec.ts.
  • Integration-only UI fix: apps/web/src/components/project-message-view/index.tsx now applies the same classifyFailure(...) diagnosable/lifecycle distinction used by apps/web/src/components/debug/FailureCard.tsx; apps/web/tests/playwright/project-chat-recoverable-error-audit.spec.ts covers neutral input-expiry shell styling in the real chat shell.

Untested Gaps

Staging/live verification intentionally remains unperformed by this scoped branch-build task. Parent orchestrator owns the consolidated staging pass and merge decision.

Post-Mortem (Required for bug fix PRs)

What broke

This PR is an integration vehicle, not a single constituent bug-fix PR. Local integration UI validation exposed that non-diagnosable input-expired lifecycle cards inherited the outer project-chat red failure glow.

Root cause

The inner FailureCard used the shared classifier to distinguish diagnosable failures from lifecycle outcomes, but the outer project-chat shell applied red failure styling unconditionally whenever a task had an error message.

Class of bug

Cross-component display-state mismatch: inner classification semantics were not propagated to an outer UI shell.

Why it wasn't caught

The unit test covered lifecycle label/actions, but the shell glow class lives in apps/web/src/components/project-message-view/index.tsx and required the real chat-shell Playwright audit to catch.

Process fix included in this PR

The existing apps/web/tests/playwright/project-chat-recoverable-error-audit.spec.ts now passes on the integrated tree and prevents regression for neutral lifecycle shell styling.

Post-mortem file

N/A: integration vehicle. Constituent task records are included under tasks/active/ and tasks/archive/.

Specialist Review Evidence (Required for agent-authored PRs)

  • All local reviewers completed and findings addressed before merge
  • If any reviewer did NOT complete: needs-human-review label added and merge deferred to human
Reviewer Status Outcome
task-completion-validator PASS Validated requested branch, exact pinned heads, merge order, final git history, local gates, and PR evidence. No task-file archive action applies to this scoped integration-build subtask.
go-specialist PASS Reviewed packages/vm-agent scope; Go 1.26.6 go vet ./..., go build ./..., and go test ./... passed.
cloudflare-specialist PASS Reviewed D1/DO/Workers scope through migration, wrangler, and worker-quality gates; staging intentionally pending parent window.
security-auditor PASS Reviewed credential setup, lifecycle stop/correlation, and scanner results; Gitleaks current/pr-range passed with 0 new findings.
test-engineer PASS API/web unit suites, vm-agent Go tests, quality suite, and affected Playwright UI audit subset passed; integration-only UI issue was fixed and revalidated.
ui-ux-specialist PASS Affected Playwright audit subset passed across mobile/tablet/desktop projects; neutral lifecycle styling is now preserved.
env-validator PASS Env interface/example/docs changes are constituent-only; wrangler binding and config quality checks passed.
doc-sync-validator PASS Docs/config/task references from constituents are present; quality/documentation checks passed.
constitution-validator PASS Checked Principle XI risk; no new hardcoded URL/timeout/limit/identifier introduced by the integration-only fix.

Exceptions (If any)

  • Scope: Staging deployment, staging validation, and merge are intentionally excluded.
  • Rationale: Raphaël explicitly scoped this subtask to integration-build only; the parent orchestrator owns staging validation and production merge.
  • Expiration: Ends when the parent orchestrator completes the deploy+validation window and merge decision.

Agent Preflight (Required)

  • Preflight completed before code changes

Classification

  • external-api-change
  • cross-component-change
  • business-logic-change
  • public-surface-change
  • docs-sync-change
  • security-sensitive-change
  • ui-change
  • infra-change

External References

N/A: no external API behavior was designed in this integration branch. References consulted were repository/GitHub PR context: #1830, #1824, #1779, #1770, #1769, and #1678.

Codebase Impact Analysis

The integration branch crosses apps/api, apps/web, apps/www, packages/shared, packages/vm-agent, .github/workflows, .claude/rules, .claude/skills, and tasks/. Highest-risk paths are apps/api/src/durable-objects/task-runner/workspace-steps.ts, apps/api/src/services/workspace-placement.ts, apps/api/src/scheduled/node-cleanup/shared.ts, apps/api/src/routes/mcp/orchestration-comms.ts, apps/api/src/services/vm-error-correlation.ts, packages/vm-agent/internal/acp/session_host*.go, apps/web/src/components/project-message-view/index.tsx, and apps/web/src/components/CodexConnectModal.tsx.

Documentation & Specs

Docs/task/rule updates included from constituents: .claude/rules/23-cross-boundary-contract-tests.md, .claude/rules/48-stale-while-revalidate-ui.md, .claude/skills/env-reference/SKILL.md, apps/www/src/content/docs/docs/guides/agents.md, apps/www/src/content/docs/docs/guides/recent-product-changes.md, apps/www/src/content/docs/docs/reference/configuration.md, apps/www/src/content/blog/agents-managing-agents.md, and task records under tasks/active/, tasks/archive/, and tasks/backlog/.

Constitution & Risk Check

Checked Principle XI/no-hardcoded-values and cross-boundary risk. The integration-only fix introduces no new URL, timeout, limit, or deployment identifier. Lifecycle and cleanup risks are handled by preserving #1824's placement-vs-cleanup arbitration and #1779's exactly-once stop/correlation behavior. Staging risk is explicitly deferred to the parent orchestrator per task scope.

…uided-gh57hs

# Conflicts:
#	apps/api/src/routes/agent-credential-setup-sessions.ts
…mcp-tool-4wb8at

# Conflicts:
#	apps/api/src/routes/triggers/crud.ts
…nshot-tell-t4p94s

# Conflicts:
#	apps/api/src/routes/mcp/_helpers.ts
#	apps/api/src/services/diagnostic-incidents.ts
#	apps/api/tests/unit/routes/mcp-orchestration-comms.test.ts
#	apps/web/src/components/project-message-view/index.tsx
#	apps/web/src/lib/chat-session-utils.ts
#	apps/web/tests/unit/lib/chat-session-utils.test.ts
#	packages/vm-agent/internal/acp/session_host.go
#	packages/vm-agent/internal/acp/session_host_prompt.go
#	packages/vm-agent/internal/acp/session_host_prompt_state.go
@codspeed-hq

codspeed-hq Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 6 untouched benchmarks


Comparing sam/batch-2-priority-drafts (680c526) with main (cb6c485)

Open in CodSpeed

@sonarqubecloud

Copy link
Copy Markdown

@simple-agent-manager

Copy link
Copy Markdown
Contributor Author

Staging Verification Evidence (orchestrator gate — 2026-08-16)

Staging deploy run 31970325007 succeeded 20:38Z for exact head 680c526. Two-part independent Staging Validator (SAM tasks 01M064S8K7C13GRHCJJ13EJ6E7 + continuation 01M067KN6ETKM8RYBFWP6PG7A6 after the first validator's production runtime was externally deleted mid-run — see idea 01M069W82V937G67WGG1E93937). Verdict: PASS — safe to merge.

Item Verdict Evidence
Regression baseline PASS Dashboard/projects/settings, /health 200, no console errors
Full workspace E2E PASS Real Hetzner VM + heartbeat, repo-grounded exchange, 23 msgs persisted
#1779 interrupt PASS working→idle clean, statusError null, exactly-once persistence
#1779 cancel PASS User-cancelled task records cancelled (neutral, not failed); session stopped, no stuck-active
#1770 list_triggers PASS claude-code agent → {"triggers": []} clean; zero webhook tokens/templates leaked
#1769 responsive caching PASS 1280↔375 resize: no remount/full-screen spinner; list→detail→back cached render ~160ms
#1678 guided login PASS Verification-code flow renders, setup-session POST 200, 0 console errors, clean cancel (full OAuth manually verified by Raphaël previously)
Cleanup DONE Staging at 0 nodes / 0 workspaces

Environment notes (non-blocking): staging opencode provider at $30/month spending cap (billing, unrelated); first validator killed by the production workspace-reaping issue tracked in idea 01M069W82V937G67WGG1E93937.

@simple-agent-manager
simple-agent-manager Bot merged commit 6f347e9 into main Aug 16, 2026
30 checks passed
simple-agent-manager Bot pushed a commit that referenced this pull request Aug 16, 2026
…he remaining writer

The task-completion-validator caught that recordTurnEnd's doc comment claimed to
be "the single write path for every turn ending". That is not true:
reconciliation.ts:cancelStalledPrompt (task-mode 409 stale-mirror repair) still
writes idle via upsertActivityState plus a manual broadcast, so it records no
provenance and skips both the delivery nudge and the idle re-arm that rule 57
requires of a terminal transition.

That is pre-existing behaviour, not a regression from this change, and migrating
it alters task-mode reconciliation semantics in a path PR #1839 just modified --
so it needs its own regression coverage rather than an unproven inline refactor
at the staging gate. Deferred per rule 42 with a tracked backlog task referenced
from BOTH ends: the recordTurnEnd doc comment and the bypassing writer itself.

Also adds the rule-42 code reference for the deliberate activity='error'
exclusion, and a Timeline subsection to the post-mortem (rule 02 template).

Co-Authored-By: Claude <noreply@anthropic.com>
simple-agent-manager Bot added a commit that referenced this pull request Aug 16, 2026
… staleness bound (#1840)

* task: add session activity state machine

* task: activate session activity state machine

* feat(api): reconciled session activity state machine with probe-backed staleness bound

* test: update DO index count for migration 029

* docs(rules): add rule 57 — reconcile write-only cross-boundary state

* docs(task): add post-mortem

* fix(api): fail closed on ambiguous workspace tenancy in the activity probe

* fix(api): address reviewer findings — rolling progress guard, probe lease, working-branch CAS, malformed-response handling, probe alarm scheduling

* fix(api): honour the probe lease in alarm scheduling and CAS the unreachable attempts bump

Round-2 specialist review (re-run against the final tree after the original
agent's workspace was destroyed) found two defects the first round missed.

[HIGH] computeSessionActivityProbeAlarmTime scanned only MIN(activity_at) and
never activity_probe_at, so a claimed-but-unresolved candidate reported as due
'now' on every tick. The SELECT correctly returned nothing (the lease held) but
the alarm had already re-armed, busy-looping the ENTIRE ProjectData alarm
handler for the whole reconciliation episode with no log signal. Now scans
MIN(MAX(activity_at + threshold, COALESCE(activity_probe_at,0) + leaseMs)) and
floors on the existing minReconciliationAlarmDelayMs knob, matching the clamp
computeReconciliationAlarmTime already used (.claude/rules/47).

[MEDIUM] The unreachable attempts bump was the module's only write path without
a compare-and-set, letting a stale probe outcome charge an attempt against a
newer prompt epoch and silently shrink its retry budget. Now scoped with the
same working-state + activity_at <= observedAt guard as the other branches.

[LOW] chat.ts cancel-failure log now uses serializeError(err) instead of a raw
err.message, matching the codebase's sanitization convention.

Both regression tests verified discriminating: each fails on the pre-fix code.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(api): correct the overstated single-write-path claim and track the remaining writer

The task-completion-validator caught that recordTurnEnd's doc comment claimed to
be "the single write path for every turn ending". That is not true:
reconciliation.ts:cancelStalledPrompt (task-mode 409 stale-mirror repair) still
writes idle via upsertActivityState plus a manual broadcast, so it records no
provenance and skips both the delivery nudge and the idle re-arm that rule 57
requires of a terminal transition.

That is pre-existing behaviour, not a regression from this change, and migrating
it alters task-mode reconciliation semantics in a path PR #1839 just modified --
so it needs its own regression coverage rather than an unproven inline refactor
at the staging gate. Deferred per rule 42 with a tracked backlog task referenced
from BOTH ends: the recordTurnEnd doc comment and the bypassing writer itself.

Also adds the rule-42 code reference for the deliberate activity='error'
exclusion, and a Timeline subsection to the post-mortem (rule 02 template).

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(api): satisfy AST sql-injection allowlist and split the cancel route out of chat.ts

Two CI Code Quality failures, both introduced by this branch:

1. quality:ast-checks flagged the new CAS UPDATE's `${attemptPlaceholders}`
   interpolation. scripts/quality/ast-checks.ts allowlists a fixed set of
   identifiers for `.map(() => '?').join(', ')` IN-clause expansion, and
   `placeholders` is the sanctioned name. This is the same safe expansion over a
   compile-time const array used elsewhere in the file, so it is renamed (with a
   comment recording why the name matters) rather than suppressed.

2. quality:file-sizes: the cancel handler pushed apps/api/src/routes/chat.ts from
   782 to 805 lines, past the 800-line hard limit in rule 18. Extracted the
   handler into apps/api/src/routes/chat-cancel.ts following the established
   sibling pattern (registerChatStopRoute / chat-stop.ts), which brings chat.ts to
   739. Routing is unchanged -- the existing cancel route tests still pass against
   the mounted route, which is what proves the extraction preserved behaviour.

Also drops the two imports left unused in chat.ts by the extraction.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Raphaël Titsworth-Morin <raphael@raphaeltm.com>
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant