Repository navigation
Fix/context federation hardening rebased - #119
Merged
Merged
Conversation
Release gate on the durable authority cutover is green (5006 tests, 0 fail). Fixes three real production defects surfaced by the gate: - permission reply in durable mode lost the in-memory reject/always fan-out for same-session pending requests on turns without an admitted activity, so those requests never settled; - Identifier 6-byte timestamps wrap every 2^36 ms (~795 days; wrapped 2026-08-14), which broke truncation cleanup retention comparisons; - location-index shadow recorded the 'global' sentinel project id into scope identity while released-knowledge scope guards demand the canonical durable project id (location-index now records projectIdForWorkspace; releasedScope self-heals pre-existing rows). Also: accept the openai-compatible-responses route for /responses/compact (DeepSeek verified per UPD-005), register new owning sources in the live-llm route manifest, rewrite durable turn fixtures to walk the full receipt/attempt lifecycle, and harden load-sensitive sync/SDK test assertions (semantic ordering, wider wait windows). Consolidates the verified batch gated here: session snapshot export/import with durable authority, model enable/disable server truth, UPD-005 remote compaction groundwork, activity facade tools, event multiprocess extensions, context reconciliation, packs/profile authority, and the QUAL fixture/typecheck gates. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…e only path Release gate passed (5006 tests / 0 fail, DeepSeek live smoke, migration dual-path on the production copy), so the staged cutover completes: DEEPAGENT_CODE_ACTIVITY_AUTHORITY and every legacy branch are removed. permission keeps only the durable authority (heartbeat/lease, durable rules, DB fan-out + reconciliation, in-memory fan-out for activity-less turns); the processor keeps only the durable turn observation and the tracker/no-progress doom path; legacy doom_loop permission prompts are deleted. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
Full-suite load pushes the workspace-routing proxy round-trip past its 2s timeout and the server-backed session-diff tests past their 15s per-test ceilings; both pass reliably in isolation. Widen the ceilings only (10s proxy, 30s per-test) without changing any assertion semantics. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…que IDs BUG-407-012 root cause B. The 36-bit ID timestamp wrapped on 2026-08-14, so new msg_00... IDs sort lexicographically before old msg_ff... IDs; ID order is no longer chronological. The server already returns (time_created, id) order; the app must not re-sort by ID. Add a compound (time, id) order utility (message/part comparators, fixed-width order keys for binary search, identity fallbacks for bare-ID events) and switch every timeline sort / binary location / latest-message decision in directory-sync, event-reducer and session revert to it. Non-timeline ID ordering (permissions/questions/etc.) is untouched. Adds wrap regression tests using the real incident IDs. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…when the lease is fenced BUG-407-012 root cause A. After macOS sleep exceeds the 30s lease, the old owner token is correctly fenced, but the runtime latched healthy=false forever and every prompt died with HTTP 500. The maintenance loop now rotates: on provider_owner_lease_not_live it registers a fresh successor token (gen+1), swaps the process-level owner Ref and keeps heartbeating; healthy stays true. All ten token consumers in prompt.ts (attempt/receipt admission, transitions, rejection path) and the diagnostics recovery owner read the current generation at use time inside their transactions. The fenced token is never revived or released; core fencing/clock guards are unchanged. Adds rotation tests including a real-store fence/rotate/heartbeat cycle. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…t state contract BUG-405-003 residual P1 (release-closing condition). The durable contract in docs/bug-405-003.md §12.1 defines eight intent states, but the DB CHECK only admitted six. SQLite cannot alter CHECK in place and session_activity_admission chains seven FK-dependent tables, so the migration detaches the legacy activity chain into temp backups (precedent 20260812120000), rebuilds session_intent with the widened CHECK from captured sqlite_master DDL (merged-lineage safe), then restores tables/indexes/data and recreates triggers after data restore. No state-transition code is invented; drizzle schema and Receipt.state widen to match. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
FEATURE-003-407 residual. tickCommand wrote the sessionID into the durable event row's workspace_id while the real workspace only travelled in the payload; the bus routes workspace-bound consumer groups by that column, so the events misrouted to zero tenants. Stamp request.workspaceID (goal-manager also re-stamps it on resume, where it was dropped entirely) and fall back to the bus global semantics (") when genuinely unknown. Adds routing tests including a workspace-bound consumer group owing only its own workspace's ticks.
Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…-407-011 residual) Verified the residual branch of BUG-407-011: with experimental.continue_loop_on_deny a question rejection is a tool failure that keeps the run alive; the run still terminalizes the activity through the normal/finalizer paths and the next prompt is admitted without recovery. Adds an end-to-end regression test covering loop continuation, terminal states and the following admission. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…and remote compaction mode Gap 1: new session_compaction_encrypted_content table (1:1 per session, latest-only upsert, provider/model/run attribution, cascade on session delete); EncryptedContentStore swaps the in-memory Map for DB-backed get/set/clear with unchanged signatures, so encrypted context now survives restarts instead of silently degrading. Gap 2: compaction_run gains compaction_mode + encrypted_content_session; the commit-binding trigger is rebuilt in the same migration to admit remote_compact commits with summary_text NULL (local_summary validation is preserved verbatim); the state machine branches on supportsRemoteCompaction, commits remote runs without a TEXT summary/marker, exempts them from the information-hole check, and falls back to the untouched local path on any remote unavailability. Adds same-provider replay validation and capability-loss blob clearing per design §4.3. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…chdog (BUG-407-012 gap C) A claimed activity/run that never reaches a terminal state could not be attributed: nothing durable recorded how far the turn got. Add session_turn_stage_evidence (one row per session/activity, forward-only upsert, never interrupts the turn) covering activity_claimed, snapshot_started/finished/degraded, history_loaded, request_prepared (written inside the receipt transaction), provider_dispatch_started and terminal settlement (record-only, settlement timing unchanged). Snapshot budget overruns now carry session/activity attribution. Diagnostics exposes the latest stage evidence for incident triage. Adds the conservative pre-dispatch watchdog (flag OFF by default, 10min deadline): it only fails an active activity through the existing terminalization path when there is no live run, no receipt, no post-request_prepared stage and a ready input boundary; anything with dispatch evidence is left to the existing outcome-unknown recovery. Also annotates the warp-recovery fixture receipt insert for the fixture gate. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…overy budget, transfer fence) Giant-message regression: 20 consecutive updates of a message carrying 500 inline diffs must not multiply event bytes — every message.updated event stays patch-free, far under the 4MiB wire gate, and 20 events together stay smaller than a single inline patch body while the durable message keeps the full summary. Discovery budget: a 4500-file incident-scale snapshot trips candidate_file_limit deterministically (truncated manifest, exact totals, bounded bytes). Transfer fence: after an admitted transfer write-fence, replay and publish die closed with zero new events on the aggregate. REL-001 capability fence and quarantined/resolved-abandoned telemetry were audited and confirmed already closed by existing locks. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…nonicalizer daemon, snapshot bundle ① Runtime diff-artifact writer: updateMessage converges user messages carrying inline summary.diffs onto the session_diff_artifact authority in one transaction (artifact+chunks, prepared receipt, file rows, message CAS rewrite to a compact descriptor, committed receipt); best-effort by design — failures only log and never break the turn. ④ Legacy event canonicalizer daemon behind DEEPAGENT_CODE_LEGACY_EVENT_CANONICALIZER (default OFF): 5-minute cadence, bounded per tick, evidence-style (never deletes events), failures only warn. ⑤ Portable aggregate snapshot bundle (aggregate-snapshot-bundle.v1): export/import with hash-sealed header+rows+chunks, byte budgets, CAS staging guards preserved, typed invalid-bundle errors. ⑧ audited closed (event_dedupe receipts are written bounded with source_data nulled before event deletion); ⑩ deferred to the REL-001 capability fence. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…07-005) Immutable per-gate evidence manifests under release-evidence/v4.1/<commit>/<gate>/ with a JSON Schema (deepagent.release_evidence.v1): typed evidence kinds aligned to R1/R2/R3/M classifications, file evidence with SHA-256, and signature placeholders. script/release-evidence.ts archives a gate (deterministic serialization, refuses to overwrite an existing gate) and verifies manifests (--check detects tampering or missing files). The 2026-08-19 release gate is archived as the first manifest (full suite 4967/0/5006, migration dual-path on the production replica, DeepSeek live smoke), bound to the current branch HEAD pending re-binding to the final release commit. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…gister stage-evidence sources The RISK-003 ① runtime capture rewrote message storage on every updateMessage carrying inline diffs, colliding with the bug-407-010 hotfix contract (bound at read, storage untouched) that four regression suites lock — and the diff read path does not serve artifact descriptors yet. Per the §14 governance order (evidence chain before convergence), the wiring is staged behind DEEPAGENT_CODE_SESSION_DIFF_ARTIFACT_CAPTURE (default OFF); the capture test now invokes capture directly against the committed message.updated event to lock the converged path, and the descriptor-idempotence test covers the default-OFF behavior. Also registers turn-stage-evidence/turn-deadline-watchdog in the live-llm route manifest. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
Final gate after all 2026-08-19/20 batches: full suite 5001 pass / 0 fail (5040 tests / 468 files, durable default mode), migration dual-path on the production replica including the two 20260820 migrations with no schema drift, DeepSeek live smoke (cli-headless + structured-legacy). Signature slots remain open for the release window. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…rotocol 3 BUG-407-009 REL-001: registering a provider-owner successor generation now atomically installs the provider_owner_successor_v1 capability row (protocol 3) in the same lease transaction, and the runtime's supported protocol moves to 3 — so the original 1.4.5 binary refuses to open a database carrying successor state instead of re-quarantining the chain. Rollback stays backup-only by design. Adds the REL-001 drill script: against a production-snapshot copy it verifies the incident sessions, resolves both real incident receipts with decision=abandoned under a die-on-invoke LLM (0 provider invocations), then runs fork smoke and a post-recovery message write. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
… data governance) Drives BUG-407-010 §14 governance on a production-snapshot COPY only (basename must contain drill): sync-index backfill to completion, message diff backfill (②③), per-aggregate snapshot checkpoint + floor parity + crash-safe batched physical deletion via compact (⑥⑦), quick_check integrity, then VACUUM + incident-session acceptance (⑪). Every gate prints MiB/count evidence before and after; any failure stops before the next irreversible step. Full drill on the 5.1GB production copy: 33,168 events deleted (4027.9 → 3307.8 MiB) and VACUUM 5075.0 → 4311.2 MiB with integrity ok. Also makes the REL-001 drill explicitly merge the EventV2 provider so the oracle stack stays complete. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…s on SQLite 3.51 The 20260819120000 migration renames session_intent_rebuilt back to session_intent after dropping the legacy activity chain. SQLite >= 3.25 (node:sqlite / desktop runtime) rewrites referencing trigger bodies during RENAME when foreign_keys is ON; session_tool_request_resolution_validate_insert references the still-dropped session_activity_progress, so the rewrite fails with 'no such table' and desktop startup dies. The rename target has the same name as the original table, so no reference rewrite is needed: run this single statement under legacy_alter_table=ON. bun:sqlite's engine lacks the rewrite behavior, which is why tests and bun-driven drills were green. Also hardens the migration runner: transient SQLITE_LOCKED/SQLITE_BUSY failures from a competing connection (second desktop instance, lingering daemon) now retry for up to 60s before failing, instead of killing startup on a schema-lock race. Verified: node:sqlite repro fails before and passes after; full 137->146 pipeline clean on a production-snapshot copy. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…op on desktop startup The incident sessions carry committed compaction runs with continuation_state pending. Every instance initialization re-woke them through the full prompt loop; the v2 owner died with 'no assistant message' (legacy sessions have no v2 projection), the failure was only logged, and the runs stayed pending — so the desktop flooded the log with a recovery-failure pair every ~500ms forever. Two fixes: (1) new migration 20260820130000 widens the continuation state machine with pending → failed, exempt from admission/response bindings, so recovery failures can be recorded fail-closed (BUG-407-009 §10.1); (2) the wake now transitions a failed recovery to failed via SessionCompaction.failContinuationClosed, so recoverableContinuations stops re-advertising the run. Real continuation recovery remains a Maintenance deliverable. Verified end-to-end on a production-snapshot copy with bun dev:desktop: errors drop from an unbounded loop to one per run, both runs land in failed, startup completes cleanly. Also relaxes the stage-evidence ordering test to migrations registered before it. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
…e fail-closed log Recursive instance loads (loop() redirects through instances.load when the event route differs, which re-runs the instance initializer) could fork duplicate recovery loops for the same continuation before the fail-closed transition landed, producing bursts of ERROR lines on startup. Recovery attempts per session now serialize through a keyed mutex with a re-check of recoverability inside the lock, and the expected fail-closed outcome logs as a warning instead of an error. Verified with bun dev:desktop on a production-snapshot copy: exactly one warning per run (2 total), zero errors, both runs land in failed, no further growth after startup. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
desktop/app 1.4.7, core 4.0.8. Release gate state: full suite 5001/0, REL-001 drill + RISK-003 governance drills green on production-snapshot copies, desktop startup migration fixes and continuation fail-closed loop fix verified with bun dev:desktop. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
|
Hey! Your PR title Please update it to start with one of:
Where See CONTRIBUTING.md for details. |
|
This PR doesn't fully meet our contributing guidelines and PR template. What needs to be fixed:
Please edit this PR description to address the above within 2 hours, or it will be automatically closed. If you believe this was flagged incorrectly, please let a maintainer know. |
Add the 1.4.7/4.0.8 changelog entry covering the release gate, incident recovery, startup fixes, compaction persistence, and RISK-003 governance; bump github/VERSION to 1.4.7; point workflow, cli template, and doc-site references at github-v1.4.7 across 18 localized docs. Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
English readme links the Chinese version as 中文; the Chinese readme already links the English version as English. Both readmes stay version-free and section-synchronized (14 matching sections). Co-authored-by: deepagent-code <deepagent-code@deepagent.ltd>
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.
Issue for this PR
Closes #
Type of change
What does this PR do?
Please provide a description of the issue, the changes you made to fix it, and why they work. It is expected that you understand why your changes work and if you do not understand why at least say as much so a maintainer knows how much to value the PR.
If you paste a large clearly AI generated description here your PR may be IGNORED or CLOSED!
How did you verify your code works?
Screenshots / recordings
If this is a UI change, please include a screenshot or recording.
Checklist
If you do not follow this template your PR will be automatically rejected.