Conversation
Vercel deployment acceptance is not terminal success. Declare non-terminal deployments as durable async operations, poll the exact deployment ID through the existing Runtime, and settle only on authoritative terminal provider states. The accompanying Spec Kit artifacts preserve the decision and regression contract. Constraint: Reuse the existing Runtime scheduler and settlement path without generic Runtime changes Rejected: Treat accepted or BUILDING deployments as success | loses the authoritative provider result Rejected: Poll deployment lists | cannot prove which deployment owns the operation Confidence: high Scope-risk: narrow Reversibility: clean Directive: Do not reclassify Vercel acceptance as terminal success or replay launch writes from poll continuations Tested: 102 scoped Vercel and Runtime tests; 172 deploy and Tool contract regression tests; scoped Ruff critical rules Not-tested: Live Vercel deployment and long-duration retry termination policy
Tenant and Agent timezone values now enter the scheduler through one IANA validation boundary, while new tenants receive the confirmed Beijing default. Constraint: Agent timezone remains nullable to preserve tenant inheritance. Rejected: Validate against COMMON_TIMEZONES | it is a UI shortlist, not the complete IANA set. Confidence: high Scope-risk: narrow Directive: Do not reintroduce silent UTC fallback for configured Trigger timezones. Tested: backend/tests/test_timezone_validation.py (14 passed); Alembic single-head check. Not-tested: Migration execution against a production-sized tenants table.
The evaluator now owns Cron occurrence calculation in the Agent effective timezone. The daemon, dispatch key, queue record, and Runtime source all consume that same planned instant, with a bounded 30-second grace and creation-time lower bound. Constraint: Keep cooldown_seconds and non-Cron Trigger behavior compatible. Rejected: Persist next_run_at or schedule_effective_from | the accepted design uses current rules plus a bounded grace without new schedule state. Confidence: high Scope-risk: moderate Directive: Do not derive Cron occurrences from last_fired_at or recompute them below evaluator. Tested: 22 scheduling, queue, intake, completion, and A2A tests; scoped Ruff. Not-tested: DST edge behavior and second-level Cron expressions are out of scope.
Scheduled Trigger intake failures now roll back the occurrence instead of persisting a failed receipt that blocks the next daemon scan. Structured logs retain the failure evidence, while webhook receipts preserve their existing synchronous failure contract. Constraint: Retry is only the ordinary 15-second scan while the occurrence remains inside the 30-second grace. Rejected: Add retry counters, backoff jobs, or new schedule fields | outside the confirmed minimal repair. Confidence: high Scope-risk: narrow Directive: A failed scheduled intake must not consume its occurrence identity. Tested: 40 timezone, scheduling, queue, Runtime, A2A, and webhook tests; scoped Ruff. Not-tested: Process termination during the database commit syscall.
Cron creation already rejected malformed expressions, but both existing update boundaries could persist them. Validate before mutation and commit while preserving REST replacement and Agent-tool patch semantics. Constraint: Preserve current Trigger APIs and config compatibility Rejected: Introduce a shared Trigger config abstraction | interface unification remains deferred Confidence: high Scope-risk: narrow Reversibility: clean Directive: Trigger config timezone may remain stored for compatibility but must not define occurrence timezone Tested: Full backend pytest 2162 passed; focused Trigger tests 18 passed; scoped Ruff and git diff checks passed Not-tested: DST-specific and second-level Cron behavior remain out of scope
The scheduler already falls back through Agent and Tenant to Asia/Shanghai, but the Agent detail response still advertised UTC when both stored values were absent. Reuse the platform default so the visible configuration describes the runtime behavior. Constraint: Preserve the existing Agent detail response shape Rejected: Add a new frontend timezone resolution path | the backend already owns effective timezone resolution Confidence: high Scope-risk: narrow Reversibility: clean Directive: Any displayed effective timezone must follow the same Agent to Tenant to platform-default order as scheduling Tested: Full backend pytest 2163 passed; timezone tests 15 passed; scoped Ruff and git diff checks passed Not-tested: Frontend visual regression was unnecessary because the response field shape is unchanged
Current main routes Trigger persistence through query_dao and has advanced the Alembic chain. Preserve those boundaries while replaying the scheduling repair, move Cron imports to the module boundary, and adapt tests to the DAO session contract. Constraint: Publish without rebasing the user's dirty working tree Constraint: New migrations must follow the current single-head and DDL-only rules Rejected: Rebase the checked-out fix branch | unrelated concurrent work makes worktree mutation unsafe Confidence: high Scope-risk: narrow Reversibility: clean Directive: Keep the PR branch based on current upstream main and retain query_dao session ownership Tested: Focused timezone and Trigger regression 33 passed; scoped Ruff passed; Alembic reports one f061 head Not-tested: Full backend suite was interrupted before completion
Persist tenant-scoped bootstrap identity so Morty and Meeseeks are initialized once, while surviving Agent storage remains repairable. Existing deployments lazily backfill stable IDs from the legacy marker or historical rows. Constraint: Existing deployments have no database bootstrap marker and docs are ignored by default. Rejected: Restore the legacy marker early return | it would disable storage drift repair and remains unsafe when storage changes. Confidence: high Scope-risk: moderate Reversibility: clean Directive: Do not use Agent name or runtime status as the default-Agent initialization fact. Tested: 38 scoped pytest cases; Ruff; git diff --check. Not-tested: Real PostgreSQL container startup because the local Docker daemon is unavailable.
The mention picker stopped at eight results and keyboard navigation could move the active candidate outside the visible popup. Keep all filtered members in the bounded list and synchronize its local scroll position with the highlighted option. Constraint: Preserve existing structured mention identity and IME behavior. Rejected: Keep the eight-candidate cap | members beyond the cap would remain unreachable by scrolling. Confidence: high Scope-risk: narrow Reversibility: clean Directive: Keep keyboard highlight changes synchronized with the mention popup scroll position. Tested: Frontend npm test (89 passed); npm run build; Playwright with 12 mocked members, mouse wheel and keyboard scrolling. Not-tested: Live backend WebSocket behavior; unrelated to the local candidate picker.
Bring Draft PR #827 into the local validation branch so its exact provider-settlement path can be tested with the other release candidates. Constraint: Preserve the Draft PR head unchanged inside the merge. Confidence: high Scope-risk: moderate Reversibility: clean Related: #827 Tested: Merge completed without conflicts. Not-tested: Combined branch tests run after all Draft PRs are assembled.
Bring Draft PR #833 into the local validation branch alongside the Vercel settlement repair, preserving both Tool surfaces for combined testing. Constraint: Resolve overlapping agent_tools changes without dropping either Draft PR contract. Confidence: medium Scope-risk: broad Reversibility: clean Related: #833 Tested: Combined tests run after conflict resolution and remaining Draft PR merges. Not-tested: Merge compatibility until conflicts are resolved. # Conflicts: # backend/app/schemas/schemas.py
Bring Draft PR #837 into the local validation branch so bootstrap identity and storage repair behavior can be tested with the other release candidates. Constraint: Preserve the Draft PR head unchanged inside the merge. Confidence: high Scope-risk: moderate Reversibility: clean Related: #837 Tested: Merge completed without conflicts. Not-tested: Combined branch tests run after all Draft PRs are assembled.
Bring Draft PR #927 into the local validation branch so the complete mention picker is included in the release-candidate frontend test pass. Constraint: Preserve structured mention identity and existing IME behavior. Confidence: high Scope-risk: narrow Reversibility: clean Related: #927 Tested: Merge completed without conflicts. Not-tested: Combined branch tests run after all Draft PRs are assembled.
Direct Chat kept both per-session runtime caches and component-wide active state. Project controls through the selected session identity and keep delayed background sends from mutating the visible conversation. Constraint: Preserve background Session execution and WebSocket delivery Rejected: Close the previous Session socket on navigation | long-running Sessions must continue after the user switches away Confidence: high Scope-risk: narrow Reversibility: clean Directive: Never let background Session events update the visible composer without matching Agent and Session identities Tested: Frontend node tests 90 passed; TypeScript and Vite production build passed Not-tested: Live backend-connected multi-Session browser flow
Merge the latest authenticated channel, browser-bound SSO, and image timeout reconciliation fixes from main while preserving the accumulated release candidate repairs. Constraint: Preserve the existing v1.11.4 candidate commit history Rejected: Rebase the release candidate | rewriting the accumulated candidate history would weaken the release audit trail Confidence: high Scope-risk: moderate Reversibility: clean Directive: Re-run release candidate regressions whenever main advances again Tested: 75 focused backend tests passed; frontend node tests 91 passed; TypeScript and Vite production build passed Not-tested: Full backend suite, Docker upgrade paths, or live provider and browser flows
Record the current main baseline, Direct Chat Session isolation scenarios, and the newly merged OAuth, channel authentication, and image timeout reconciliation paths in one executable release-candidate checklist. Constraint: Historical PR evidence cannot replace candidate or live validation Rejected: Keep the previous four-feature checklist | it would omit the latest main security and reconciliation changes Confidence: high Scope-risk: narrow Reversibility: clean Directive: Refresh the baseline SHA, candidate evidence, and affected cases whenever main advances Tested: Markdown structure, referenced paths, 75 focused backend tests, 91 frontend tests, and production frontend build Not-tested: Full backend suite, Docker upgrade paths, and live provider or browser cases
Record the two active Alembic heads and Drone fresh-database duplicate-column failure so the synchronized release candidate cannot be treated as publishable until the main migration graph is repaired and revalidated. Constraint: The Direct Chat PR changes only frontend files and must not absorb an unrelated migration repair Rejected: Ignore the failed check as unrelated | v1.11.4 now contains the same main migration state Confidence: high Scope-risk: narrow Reversibility: clean Directive: Clear this blocker only with fresh and upgrade database evidence on the repaired candidate Tested: Alembic heads inspected; Drone build 486 clone, image build, and migration logs read Not-tested: Repaired fresh or upgrade database path because no repair is present yet
Freeze the model-visible Workset and accepted execution binding in checkpoint state, separate Provider correlation from Runtime identity, and give repairable failures a sanitized model-visible result. Add independent 10/20 repair budgets, operation-specific deadline/cancel/lease controls, and an incremental RegisteredTool compatibility boundary. Constraint: Existing checkpoints and nullable Receipt rows must remain recoverable during mixed-version rollout Rejected: Re-resolve enabled assignments in Tool Step | changes an already accepted model decision Rejected: Reuse Provider-local call IDs as Runtime identity | IDs repeat across Assistant turns Confidence: high Scope-risk: broad Reversibility: clean Directive: Do not remove the legacy resolver until its zero-usage release and rollback-window gate is satisfied Tested: 834 Runtime/Tool pytest cases; 9 migration/contract cases; Alembic f061-f062 offline upgrade and downgrade; scoped Ruff; Architecture Guard; git diff check Not-tested: Live Provider credentials and online migration against an isolated PostgreSQL database
Integrate the checkpoint-stable Tool Runtime repair while preserving the release branch's established SpecKit constitution and trigger fixes. Join the release timezone migration and main-based Tool identity migration with a no-op Alembic merge revision. Constraint: v1.11.4 already carries a sibling f061 timezone migration that is absent from upstream main Rejected: Retarget the feature migration to the release-only head | would make PR #945 diverge from main migration history Rejected: Leave two Alembic heads | release startup and migration gates require one head Confidence: high Scope-risk: broad Reversibility: clean Directive: Keep f063_merge_v1_11_4_heads when rebasing or publishing the release candidate Tested: v1.11.4 import path verified; 834 Runtime/Tool pytest cases; 5 release migration cases; single Alembic head; fatal Ruff; Architecture Guard; git diff check Not-tested: Live Provider credentials and online migration against an isolated PostgreSQL database
Drone clones only the target repository before checking out the fork PR SHA. Publish this no-op descendant to both repositories so the synchronize build can resolve the commit without changing the reviewed tree. Constraint: Drone build 487 failed in clone before any test because the fork-only SHA was absent from dataelement/Clawith Rejected: Ignore the failed required check | would leave PR health ambiguous Confidence: high Scope-risk: narrow Reversibility: clean Directive: This empty commit carries no release behavior and need not be merged separately into v1.11.4 Tested: Underlying tree is identical to 1dbad6d Not-tested: Drone rerun until remote status is observed
Fresh installs create the enterprise_info target shape from current ORM metadata before Alembic replays f061. Inspecting the live schema keeps that replay idempotent while preserving the legacy upgrade path, and the unified-schema assertion now leaves f062-owned Tool identity columns to their dedicated migration contract. Constraint: Fresh bootstrap derives tables from current ORM metadata before replaying historical revisions Rejected: Skip the failing CI migration lane | would leave a documented v1.11.4 P0 release blocker unresolved Confidence: high Scope-risk: narrow Directive: Keep provider_call_id and contract_version owned by f062 rather than backporting them into the unified baseline revision Tested: 836 Runtime, Tool, and migration tests; scoped Ruff; py_compile Not-tested: Fresh PostgreSQL bootstrap locally because Docker is unavailable; Drone will provide that evidence
Merge the CI-proven f061 idempotence repair into the release candidate while retaining the release-only f063 revision that joins the timezone and Tool Runtime migration chains. The regression record now distinguishes the passing fresh path from the still-unverified v1.11.3 upgrade path. Constraint: v1.11.4 must retain one Alembic head across both release migration branches Rejected: Mark the entire database P0 complete | the previous-version upgrade path still lacks real database evidence Confidence: high Scope-risk: moderate Directive: Do not remove f063 or mark A4 passed until a v1.11.3 database snapshot upgrades successfully Tested: 836 Runtime, Tool, and migration tests; scoped Ruff; Alembic single-head check; Architecture Guard P0; Drone #489 fresh PostgreSQL migration Not-tested: Upgrade from a populated v1.11.3 database snapshot
Native group replies already persist human mentions without dispatching work, but the Runtime at preflight rejected every non-Agent participant. Split public mention validation from Agent handoff validation so mixed human and Agent targets remain atomic while child Runs are created only for wakeable Agents. Constraint: Human mentions must remain visible without creating child Runs. Rejected: Strip human IDs during model repair | loses structured mention metadata and contradicts group message behavior. Confidence: high Scope-risk: narrow Directive: Keep public mention targets distinct from wakeable Agent targets. Tested: 232 scoped Runtime and group delivery tests; Ruff check on changed files. Not-tested: Browser rendering and live 3010 mixed-mention E2E pending deployment.
Merge the standalone main-based mention repair into the release candidate so mixed human and Agent targets preserve public message metadata while only wakeable Agents receive child Runs. The automatic merge retains the Tool Runtime contract work already integrated into model_step_service. Constraint: Human participants are valid visible mention targets but are never Runtime handoff targets Rejected: Continue carrying the fix only on the Feishu reimbursement branch | obscures ownership and release ancestry Confidence: high Scope-risk: moderate Directive: Keep visible mention validation separate from wakeable Agent handoff validation Tested: 867 Runtime, Tool, finish-protocol, and migration tests; fatal Ruff; Architecture Guard P0; Alembic single-head check Not-tested: Live mixed-mention E2E on deployed port 3010
Add typed Feishu approval definition, attachment upload, and create tools while binding provider submission to the exact tenant, Run, Tool Ledger receipt, applicant, and in-chat confirmation. Constraint: Approval creation must not depend on a new frontend or legacy ApprovalRequest flow Constraint: Existing user worktree changes remain outside this commit Rejected: Bare yes/no confirmation | stale replies could authorize another request Rejected: Raw approver and CC open IDs | bypasses tenant roster authorization Rejected: Reusable bearer proof | could replay an identical provider write Confidence: high Scope-risk: moderate Reversibility: clean Directive: Do not expose feishu_approval_create outside the receipt-bound Durable Runtime conversation gate Tested: 335 relevant backend tests; scoped Ruff; compileall; diff check; independent code review and verification Not-tested: Live Feishu Provider create and 3010 deployment
Preserve a bounded, sanitized Provider receipt in the Tool outcome and surface HTTP status, business code, message, and response body to the model. Approval reads and writes retain their existing retry classification, while attachment inputs are rejected before confirmation unless they contain stable file-code strings. Constraint: External approval writes must never be replayed after an ambiguous Provider outcome Constraint: Provider response metadata must pass through the Tool Ledger sanitizer before model visibility Rejected: Return only a generic rejection string | leaves the model unable to repair invalid form controls or permissions Rejected: Accept attachment objects in form_data | confirmation would bind an unstable provider payload shape Confidence: high Scope-risk: moderate Directive: Preserve provider receipt bounds and redaction whenever adding new Feishu failure fields Tested: 804 Runtime and Tool tests; 201 approval-focused tests; fatal Ruff; Architecture Guard P0; diff check Not-tested: Live Feishu Provider create and deployed 3010 approval flow
Merge the standalone Feishu approval tools into the release Runtime while retaining stable Tool Call identity, validation, deadlines, cancellation, lease renewal, and repair budgeting. Approval creation now issues its single-use authorization inside the controlled application execution path, after the exact call has been confirmed and reserved. Constraint: Approval writes must remain bound to the tenant, actor, Run, call instance, execution receipt, lease owner, and exact arguments Rejected: Restore the approval branch's direct executor call | would bypass v1.11.4 deadline, cancellation, lease, and Tool contract controls Confidence: high Scope-risk: broad Directive: Keep approval authorization issuance inside _execute_application_with_controls and preserve call_instance_id as the Runtime identity Tested: 941 Runtime, Tool, approval, finish-protocol, and migration tests; fatal Ruff; Architecture Guard P0; Alembic single-head check Not-tested: Live Feishu approval creation and deployed 3010 confirmation flow
Set the existing protocol repair, safe-read replay, and model-visible Tool episode limits to ten while preserving their current independent state and execution semantics. Update focused tests and planning artifacts to make the off-by-one behavior explicit. Constraint: Tool-related retry and repair limits must be ten without restructuring the existing counters Rejected: Unify protocol, Receipt, and model-visible repair state now | counter redesign is intentionally deferred Confidence: high Scope-risk: moderate Directive: Keep the independent counters until the planned repair-control refactor; do not infer identical attempt semantics from the shared numeric limit Tested: 911 Runtime and Tool pytest cases; scoped Ruff; fatal-level caller Ruff; py_compile; git diff --check Not-tested: Live Provider credentials
Merge the main-based Tool Runtime follow-up so the release candidate uses ten for protocol repair, safe-read replay, and model-visible Tool episode limits without restructuring their independent counters. Constraint: v1.11.4 must remain aligned with PR 945 while retaining its release-only approval and mention fixes Rejected: Cherry-pick individual files | merging the reviewed main-based commit preserves its tests and planning evidence Confidence: high Scope-risk: moderate Directive: Keep protocol, Receipt, and model-visible repair state separate until the planned counter refactor Tested: 928 release-combination pytest cases with release PYTHONPATH; scoped Ruff; fatal-level caller Ruff; py_compile; staged diff check Not-tested: Live Provider credentials
Gemini reuses provider call identifiers across assistant turns, so a history-wide lookup allowed later calls to overwrite earlier tool names. Scope name resolution to the active assistant exchange while preserving provider wire identifiers. Constraint: Gemini provider call IDs are not globally unique across turns Rejected: Persist globally unique provider IDs | would alter provider wire identity and conflict with existing Runtime correlation Confidence: high Scope-risk: narrow Directive: Keep Tool Result name resolution exchange-local when modifying Gemini history lowering Tested: backend/tests/test_llm_single_step.py; LLM scoped tests; Ruff Not-tested: Live Gemini API
A resumed reconciliation now carries a structured Workspace decision into Runtime history, and the semantic completion gate treats that authenticated decision as an authoritative amendment to the original goal. Constraint: A keep-source decision must not be undone by completion repair. Rejected: Disable the completion gate after reconciliation | unrelated task requirements still need verification Confidence: high Scope-risk: moderate Directive: Later human reconciliation decisions override conflicting initial file-content requirements, but not unrelated completion requirements. Tested: 141 targeted backend tests; 2433 full backend tests passed; arch-guard P0 passed Not-tested: 2 unrelated html-to-pdf tests require missing local WeasyPrint system libraries
Accept python3 as a canonical Python alias and align Runtime, Sandbox, seeded Tool, source, and Docker defaults at 180 seconds with a 300-second default cap. Upgrade only untouched 30/60 seeded defaults so explicit custom values remain authoritative. Constraint: Existing 3010 Code Executor calls can legitimately exceed 30 seconds while preserving bounded execution. Rejected: Increase only the Runtime deadline | Sandbox would still stop at the old cap and default_timeout would remain ineffective. Confidence: high Scope-risk: moderate Reversibility: clean Directive: Keep Runtime and Sandbox Code Executor defaults aligned when changing either layer. Tested: 194 scoped Pytest cases; scoped Ruff; Docker Compose config; Architecture Guard P0; git diff --check. Not-tested: 3010 deployment and live Provider E2E pending.
Accept python3 as a canonical Python alias and align Runtime, Sandbox, seeded Tool, source, and Docker defaults at 180 seconds with a 300-second default cap. Upgrade only untouched 30/60 seeded defaults so explicit custom values remain authoritative. Constraint: Existing 3010 Code Executor calls can legitimately exceed 30 seconds while preserving bounded execution. Rejected: Increase only the Runtime deadline | Sandbox would still stop at the old cap and default_timeout would remain ineffective. Confidence: high Scope-risk: moderate Reversibility: clean Directive: Keep Runtime and Sandbox Code Executor defaults aligned when changing either layer. Tested: 194 scoped Pytest cases; scoped Ruff; Docker Compose config; Architecture Guard P0; git diff --check. Not-tested: 3010 deployment and live Provider E2E pending.
Query-token downloads authenticate inside the endpoint because browser iframes cannot attach the normal Bearer header. Restore the authenticated user's tenant context only around Agent authorization so tenant-scoped DAO lookup resolves the intended Agent without broadening global query-token handling. Constraint: Untrusted HTML previews must remain in an opaque-origin sandbox. Rejected: Teach TenantContextMiddleware to consume every query token | reset and verification URLs use token parameters for unrelated flows. Confidence: high Scope-risk: narrow Reversibility: clean Directive: Keep query-token tenant binding local to endpoints that fully validate the token and user first. Tested: backend test_agent_files_api.py 5 passed; scoped Ruff; git diff --check Not-tested: 3010 browser preview before deployment
Existing AgentTool rows can persist the legacy 30/60 timeout pair and override the upgraded global Tool defaults. Upgrade only fields that still equal those legacy defaults while preserving any non-default per-Agent value. Constraint: Agent-level Tool config has higher runtime precedence than global Tool config. Rejected: Clear all Agent Tool overrides | would erase intentional sandbox and timeout customization. Confidence: high Scope-risk: narrow Reversibility: clean Directive: Timeout default migrations must cover every persisted configuration precedence layer. Tested: 73 scoped Pytest cases; scoped Ruff; git diff --check; live 3010 evidence reproduced the old Agent override. Not-tested: Redeployed 3010 E2E pending.
Tenant Tool settings sit between global Tool defaults and Agent overrides, so legacy 30/60 values there still constrained existing Agents. Upgrade only the nested legacy values and preserve custom Tenant choices plus unrelated setting metadata. Constraint: Tenant Tool configuration is an authoritative runtime precedence layer. Rejected: Ignore Tenant settings after upgrading global and Agent rows | live 3010 E2E still timed out at 30 seconds. Confidence: high Scope-risk: narrow Reversibility: clean Directive: Seed default migrations must cover Tool, TenantSetting, and AgentTool persistence layers. Tested: 73 scoped Pytest cases; scoped Ruff; git diff --check; live 3010 DB and UI reproduced Tenant override. Not-tested: Redeployed 35-second Runtime E2E pending.
Existing AgentTool rows can persist the legacy 30/60 timeout pair and override the upgraded global Tool defaults. Upgrade only fields that still equal those legacy defaults while preserving any non-default per-Agent value. Constraint: Agent-level Tool config has higher runtime precedence than global Tool config. Rejected: Clear all Agent Tool overrides | would erase intentional sandbox and timeout customization. Confidence: high Scope-risk: narrow Reversibility: clean Directive: Timeout default migrations must cover every persisted configuration precedence layer. Tested: 73 scoped Pytest cases; scoped Ruff; git diff --check; live 3010 evidence reproduced the old Agent override. Not-tested: Redeployed 3010 E2E pending.
Tenant Tool settings sit between global Tool defaults and Agent overrides, so legacy 30/60 values there still constrained existing Agents. Upgrade only the nested legacy values and preserve custom Tenant choices plus unrelated setting metadata. Constraint: Tenant Tool configuration is an authoritative runtime precedence layer. Rejected: Ignore Tenant settings after upgrading global and Agent rows | live 3010 E2E still timed out at 30 seconds. Confidence: high Scope-risk: narrow Reversibility: clean Directive: Seed default migrations must cover Tool, TenantSetting, and AgentTool persistence layers. Tested: 73 scoped Pytest cases; scoped Ruff; git diff --check; live 3010 DB and UI reproduced Tenant override. Not-tested: Redeployed 35-second Runtime E2E pending.
Direct Chat WebSocket Tool packets can arrive while another Session is selected. Cache those packets by Agent and Session, merge them with canonical history on return, and keep stable call IDs from duplicating or downgrading settled cards. Constraint: Background Session events must not mutate the currently selected chat stream. Rejected: Refresh all Session messages for every background Tool event | adds request churn and still races persistence. Confidence: high Scope-risk: moderate Reversibility: clean Directive: Preserve per-Session scoping when changing Direct Chat realtime Tool rendering. Tested: Frontend 102 tests; TypeScript/Vite production build; git diff --check. Not-tested: 3010 multi-Session browser replay pending.
Direct Chat WebSocket Tool packets can arrive while another Session is selected. Cache those packets by Agent and Session, merge them with canonical history on return, and keep stable call IDs from duplicating or downgrading settled cards. Constraint: Background Session events must not mutate the currently selected chat stream. Rejected: Refresh all Session messages for every background Tool event | adds request churn and still races persistence. Confidence: high Scope-risk: moderate Reversibility: clean Directive: Preserve per-Session scoping when changing Direct Chat realtime Tool rendering. Tested: Frontend 102 tests; TypeScript/Vite production build; git diff --check. Not-tested: 3010 multi-Session browser replay pending.
Reuse established Feishu group sessions as stable Directory targets so browser requests and background automations share one authorized delivery contract. Existing human channel targets remain compatible while Schedule and Trigger Runs freeze group delivery through the durable Runtime. Constraint: Only Feishu group targets are in scope; no new Tool or dependency Rejected: Add send_feishu_group_message | would duplicate the external channel Tool surface Rejected: Expose chat_id to the model | bypasses tenant and Agent target authorization Confidence: high Scope-risk: moderate Reversibility: clean Directive: Keep Provider chat IDs behind the scoped group target resolver Tested: backend 2427 passed; scoped 138 passed; frontend 102 passed and build; Architecture Guard; Alembic single head Not-tested: Real Feishu provider delivery and 3010 deployment pending
Merge the verified feature branch so browser-directed sends and background automations can share the existing channel Tool and Runtime delivery path. Constraint: Preserve unrelated dirty documentation in the working tree Confidence: high Scope-risk: moderate Tested: backend 2427 passed; frontend 102 passed and build; Architecture Guard; Alembic single head Not-tested: 3010 deployment and real Feishu provider delivery pending
The feature is merged and deployed to 3010 with source, migration, container, and Tool-schema evidence. Real group delivery remains pending because the live database currently has no registered Feishu group session. Constraint: Do not invent or reuse an unrelated Provider chat ID for live validation Confidence: high Scope-risk: narrow Tested: 3010 backend healthy; restart count 0; Alembic f065 head; deployed marker 7d192de; Tool schema exposes target_recipient_id Not-tested: Real Feishu group receipt requires a trusted inbound group session
Synchronize the groups joined by each configured Bot through Feishu's official chat-list API, then project them into the existing scoped Session target contract. Directory failures remain explicit so missing permissions cannot masquerade as an empty group list. Constraint: Only groups already joined by the configured Bot are discoverable Rejected: Search every visible enterprise group | broadens authorization and misdelivery risk Rejected: Require an inbound group message | prevents browser-first delivery Confidence: high Scope-risk: moderate Directive: Keep Provider chat IDs internal and fail closed on sync or pagination errors Tested: backend 2429 passed; focused Feishu directory tests 44 passed; scoped Ruff Not-tested: Live 3010 Feishu scope and returned group inventory pending deployment
Merge the current upstream release branch into the locally verified Feishu group work so Workspace reconciliation and group discovery ship together without rewriting either history. Constraint: Preserve both upstream Runtime repairs and local Feishu group contracts Rejected: Force-push the local branch | would discard ten upstream commits Confidence: high Scope-risk: moderate Tested: merged backend 2447 passed; frontend 108 passed and build; focused Feishu/automation 95 passed; Alembic single f065 head Not-tested: End-to-end message send to the discovered live group
…dlines Production logs showed empty or truncated Compact output, Code Executor deadlines racing their own sandbox lifecycle, unrecoverable unknown receipts, and provider billing failures being retried until the original cause was hidden. This change gives Compact an independent bounded output contract, freezes one Code Executor timeout across the accepted Workset, resumes audited reconciliation without replaying the Tool, classifies HTTP 402 deterministically, and safely migrates exact legacy HEARTBEAT templates. Constraint: LangGraph checkpoint remains the only execution lifecycle; Tool receipts and product events remain projections. Rejected: Lower model steps to 60 | legitimate business Runs exceed that length. Rejected: Restore commit_thread_summary Tool protocol | v1.11.4 Compact is intentionally tool-free. Rejected: Auto-retry unknown Code Executor outcomes | external side effects cannot be assumed absent. Confidence: high Scope-risk: moderate Reversibility: clean Directive: Never remove the reconciliation gate or let Compact commit partial, empty, filtered, or truncated summaries. Tested: 2498 backend tests; 426 focused tests; Ruff with zero new findings; TypeScript noEmit; Architecture Guard P0; git diff --check. Not-tested: Live JSTI provider canary, migration apply, deployment, and post-deploy Run replay.
Calendar creation could scan the full Feishu directory once per attendee, switch pagination sources before synced results were exhausted, and report failure after an event had already been created. Resolve requested names in one bounded provider traversal, filter synced contacts by provider before pagination, complete lookups before the event write, and preserve the event receipt when attendee invitations fail. Constraint: Raw Feishu open IDs remain private execution facts and never enter model-visible search results. Constraint: Existing unrelated dirty group-runtime and documentation changes remain outside this commit. Rejected: Cache contact scans across Runs | tenant-token scope and directory freshness would be ambiguous. Rejected: Retry calendar creation after attendee failure | the event may already exist. Confidence: high Scope-risk: moderate Reversibility: clean Directive: Keep contact-source pagination stable and preserve Event ID on every post-create failure path. Tested: 2470 backend tests; 111 focused Feishu/directory tests; Ruff with zero new findings; Architecture Guard P0; git diff --check; independent code review approved. Not-tested: Live broad-scope Feishu directory, provider rate limits, deployment, and production calendar canary.
A persisted read watermark can outlive its referenced message. Treat that missing derived marker as no watermark so session listing remains available and all surviving messages are conservatively unread. Constraint: Group session listing must not fail because disposable read-state points at deleted message data. Rejected: Delete the read-state entry during GET | read endpoints should not introduce hidden persistence side effects. Rejected: Keep the tenant-switch token handoff change | live request evidence showed the failing group belongs to the target tenant. Confidence: high Scope-risk: narrow Directive: Malformed watermark values remain hard failures; only a well-formed missing message degrades to unread. Tested: 31 group service/API tests; scoped Ruff; live failure reproduced through Playwright Not-tested: 3010 live behavior before backend deployment
Runtime continuations are bound to the frozen accepted Tool call and carry hidden operation arguments emitted by durable receipt metadata. Applying the Model-facing schema to those continuations rejected Vercel deployment polls before the Tool handler could observe provider state. Constraint: Model-visible Tool schemas must not expose internal poll modes. Rejected: Add operation and deployment_id to the public Vercel schema | would let models invoke an internal continuation surface. Confidence: high Scope-risk: narrow Directive: Keep Runtime async-poll identity bound to the frozen origin call and validate operation-specific arguments in the Tool handler. Tested: 155 scoped Runtime async-poll, Vercel outcome, and Tool outcome tests; scoped Ruff; Architecture Guard P0; git diff --check. Not-tested: Live Vercel deployment after deploying this commit.
A provider-pending deployment is not a failed write, but repeated inability to read its status must not hold a Run forever. Carry a consecutive poll-failure count in Runtime-owned metadata, reset it after any authoritative provider observation, and enter unknown reconciliation after the shared ten-attempt safe-read limit. Constraint: Never replay deployment creation or declare an unobserved external deployment failed. Rejected: Count BUILDING as a failed attempt | normal Vercel builds can exceed twenty seconds. Rejected: Mark retry exhaustion as failed | provider completion remains unknown. Confidence: high Scope-risk: narrow Directive: Keep provider-pending states distinct from status-read transport failures. Tested: 157 scoped Runtime async-poll, Vercel outcome, and Tool outcome tests; scoped Ruff; Ruff fatal rules for agent_tools.py; Architecture Guard P0; git diff --check. Not-tested: Live Vercel transient-failure exhaustion after deployment.
A Vercel exact-deployment READY receipt proves deployment completion even when runtime DNS, SSRF policy, or access protection prevents reading the returned URL. Treat unreadable receipt-bound references as verification warnings so the semantic completion gate can keep its original bounded-repair then deliver-latest-answer contract. Constraint: Unsettled tools, mismatched receipts, missing workspace artifacts, and non-READY deployments remain fail-closed. Rejected: Bypass all unreadable references | would weaken deterministic artifact integrity. Rejected: Make every verification repair fail-open | only the final semantic goal gate owns that policy. Confidence: high Scope-risk: narrow Directive: Provider lifecycle facts and observer accessibility must remain separate verification dimensions. Tested: 78 verifier, finalizer, and node-executor tests; scoped Ruff; Architecture Guard P0; git diff --check. Not-tested: Live completion with a Vercel READY URL blocked by runtime DNS after deployment.
A concurrent or repeated Sandbox publisher can win the conditional write with the exact bytes produced by the current execution. Verify the durable bytes against a stable before/after version and refresh the manifest instead of reporting a false publication conflict. Constraint: Divergent or changing durable content must remain a fail-closed workspace conflict. Rejected: Treat every require-absent conflict as success | would hide real concurrent writes. Confidence: high Scope-risk: narrow Directive: Preserve the stable-version check around byte equality before classifying a lost CAS as converged. Tested: 21 workspace storage tests; Ruff fatal rules; git diff --check. Not-tested: Linux bubblewrap end-to-end publication path.
Feishu group bots can now accept ordinary user messages, freeze each input on a stable external-group lane, retain provider sender identity, and suppress exact NO_REPLY completions before creating an external outbox. Current-conversation replies stay bound to the originating Session, while explicit cross-Session sends require an execution-time confirmation flag. Constraint: Existing Feishu apps require manual im:message.group_msg approval and publication. Rejected: Let models choose a reply group through send_channel_message | directory guesses can send to the wrong Session. Confidence: high Scope-risk: moderate Directive: Keep ordinary replies on the Run delivery target; cross-Session channel sends must remain explicit and validated. Tested: Backend focused pytest suites (113, 90, 66, and 61 passed); scoped Ruff on modified focused files; frontend npm run build; scripts/arch-guard.sh; live 3010 Feishu ordinary-message, NO_REPLY, origin-Session delivery, and calendar E2E. Not-tested: Multi-worker load and high-volume long-running compaction under production traffic.
External group Sessions store the Agent creator as a placeholder user, so user-id-only filtering hid them from the admin-facing Other sessions list. Classify group and Agent sessions by their explicit session metadata before applying direct-session ownership filtering. Constraint: External Feishu groups must remain group_id=NULL and keep the existing placeholder user contract. Rejected: Move external groups into My sessions | that surface is intentionally restricted to writable Direct sessions. Confidence: high Scope-risk: narrow Directive: Do not use ChatSession.user_id to classify external group ownership. Tested: frontend npm test (112 passed); frontend npm run build Not-tested: 3010 deployment and live Feishu group visibility
External Feishu groups share one public Session lane, so a waiting_user checkpoint can block unrelated group traffic and cannot be resumed by the Direct Chat scope contract. Mark the immutable Chat session type in Run input and repair user waits into public clarification replies without enabling native Group handoff tools. Constraint: External Feishu groups use session_type=group with group_id=NULL and must not gain native Clawith Group tools. Rejected: Resume external-group waiting_user Runs | one participant's wait would hold the shared public lane and consume unrelated messages. Confidence: high Scope-risk: narrow Directive: Public group Runs ask clarifying questions in their final reply and release the lane; only Direct Chat may retain waiting_user. Tested: 94 scoped Runtime, Chat intake, Channel, and Feishu tests; scoped Ruff; live 3010 new-Session calendar E2E. Not-tested: Full backend test suite and high-volume concurrent external-group traffic.
Rebuilding a cutoff-scoped external-group context previously dropped the source Agent identity, so the compactor could reject valid history as an Agent mismatch. Carry the immutable Agent ID through the rebuild request. Constraint: Group history remains Session-scoped and must not be compacted under another Agent identity. Rejected: Disable the Agent mismatch check | would weaken cross-Agent context isolation. Confidence: high Scope-risk: narrow Directive: Preserve source_agent_id on every transient group cutoff rebuild. Tested: Group cutoff and completion-focused Runtime tests; scoped Ruff; git diff --check. Not-tested: Live high-volume external-group compaction.
A model-authored waiting_user state can monopolize the serialized lane shared by an external or native public group. Hide the wait Tool from public-group model calls and let a truthful, concrete clarification finish only the current Run while deterministic unsettled Tool checks remain fail-closed. Constraint: External Feishu groups must not gain native Group handoff Tools, and unknown side effects must still reconcile before completion. Rejected: Resume a public-group waiting Run from arbitrary later traffic | would bind unrelated participants to one held Run. Confidence: high Scope-risk: moderate Directive: Public clarification may release a lane but must never claim deferred business work or unsettled side effects completed. Tested: 30 focused group, Completion Gate, and cutoff tests; scoped Ruff; git diff --check. Not-tested: High-volume concurrent external-group traffic.
A read watermark may outlive its message. Count surviving messages conservatively as unread and emit structured identifiers so operators can find and repair the stale derived state without making GET mutate it. Constraint: Malformed watermarks remain errors; only a valid missing message degrades safely. Rejected: Delete stale read state during listing | read endpoints must not introduce hidden writes. Confidence: high Scope-risk: narrow Directive: Preserve the warning when missing watermarks fall back to all-unread semantics. Tested: Focused unread-count tests; scoped Ruff; git diff --check. Not-tested: Live API request against a historical stale watermark.
The event adapter removed provider mention placeholders before Runtime intake, so an Agent could not distinguish a direct group mention from ambient traffic and could incorrectly return NO_REPLY. Restore structured text mentions to visible display names and retain rich-post at tags. Constraint: Provider mention metadata is untrusted text and must not be treated as a native Clawith Group identity. Rejected: Mark every message containing a mention as addressed to this Agent | group-wide subscriptions also deliver mentions of other participants. Confidence: high Scope-risk: narrow Directive: Keep mention names visible to the model without forging native participant IDs or group handoffs. Tested: 10 Feishu Channel Runtime tests; scoped Ruff; git diff --check. Not-tested: Live Feishu event containing multiple named mentions.
The quick-create modal allowed one-character names to reach backend validation and surfaced a global failure dialog. Share the backend-aligned 2-to-100-character rule across both creation surfaces, disable invalid submissions, and show an accessible inline length error. Constraint: Name validation uses trimmed Unicode code-point length, matching the Pydantic string contract used by the API. Rejected: Reuse the stashed api.ts error parser | the current frontend has a newer canonical apiError boundary. Confidence: high Scope-risk: narrow Directive: Keep both Agent creation surfaces and the backend name bounds synchronized through the shared validator. Tested: 113 frontend tests; TypeScript and Vite production build. Not-tested: Manual browser interaction with the modal.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
This release-candidate branch integrates and validates the currently planned v1.11.4 repairs against main:
Why
These changes assemble the pending Runtime, scheduling, Agent lifecycle, chat isolation, mention, and migration repairs into one branch so their interactions can be reviewed and validated as a release candidate instead of relying on isolated PR evidence.
Impact
The branch changes backend Runtime and Tool execution behavior, Trigger scheduling semantics, default Agent bootstrap behavior, group and Direct Chat UI behavior, and the Alembic migration graph. It intentionally keeps existing public APIs and reuses the current Runtime scheduling and settlement paths.
Validation recorded on this branch
Remaining release gates
See V1.11.4_REGRESSION_TEST_CASES.md for the detailed release matrix.