Skip to content

feat(context): 层级项目指令、长期记忆与恢复点浏览 - #108

Merged
Qiyuanqiii merged 2 commits into
mainfrom
codex/issue-106-context-continuity
Aug 18, 2026
Merged

Qiyuanqiii merged 2 commits into
mainfrom
codex/issue-106-context-continuity

Conversation

@Qiyuanqiii

@Qiyuanqiii Qiyuanqiii commented Aug 18, 2026 •

Copy link
Copy Markdown
Member

Summary

  • add deterministic, hierarchical project-instruction discovery for AGENTS.md, CLAUDE.md, .prayu/instructions.md, and .prayu/rules/**/*.md, including root-to-target inheritance, closest-scope precedence, stable fingerprints, source hashes/scopes, conflict explanations, ignore rules, and fail-closed path/size/depth/concurrency checks
  • pin the complete instruction snapshot into each Run and persist immutable revisions; disk drift is inspectable but cannot affect an active Run until an operator confirms both the currently pinned fingerprint and the exact live fingerprint they reviewed
  • add explicit user/project long-term memory with provenance, references, optimistic versions, retention, enable/disable, export, redaction, and physical deletion; there is no model/tool/file/compaction auto-write path
  • add immutable root/checkpoint/fork/resume continuity nodes and a branch-aware session tree that projects compaction summaries, decisions, Artifacts, Delivery checkpoints, memory drift, project configuration/instruction fingerprints, and exact Git branch/full HEAD
  • expose the same bounded state and controls through Desktop, CLI, and strict OpenAPI endpoints; add schema v114, bilingual operational/privacy documentation, and ADR 0115

Closes #106.

Project instructions and precedence

  • discovery is confined to the registered Workspace and walks from its root to the requested target; same-directory order is AGENTS.md, CLAUDE.md, .prayu/instructions.md, then lexically sorted .prayu/rules/**/*.md
  • every source records canonical relative path, content SHA-256, scope/depth/precedence, load time, trust, target applicability, redaction state, and why_effective; conflicts remain visible and explain why the closest directory wins
  • .prayu/instructions.ignore supports bounded canonical relative-path globs; absolute paths, .. escape, NUL/invalid UTF-8, empty/special files, symlinks/junctions/reparse points, concurrent replacement, malformed ignore input, and configured count/size/depth overflow fail closed
  • bounds are 64 files, 64 KiB per file, 256 KiB total, target/rule depth 32, and 16 KiB/128 rules for the ignore file; Windows canonical comparisons are case-insensitive while POSIX retains case
  • Run creation pins the full project_instruction_snapshot.v1; refresh appends a new immutable revision only after a diff and explicit dual-fingerprint confirmation, preventing stale-UI/time-of-check replacement

The fixed precedence is system/operator input > Go-owned runtime safety policy and current authority > explicit Run selections > pinned project instructions and explicit memory > ordinary files/history/tool output. Project text may influence workflow, formatting, and validation advice only. Its authority projection is always false for tools, network, secrets, Debug, plugins, hooks, MCP, policy overrides, and every other capability.

Explicit memory lifecycle

  • context_memory.v1 supports user (local-user) and Workspace-bound project scopes with title/content hash, status, source provenance, deduplicated references, optional retention, redaction state, operator identities, timestamps, and an optimistic version
  • creation and mutation require an explicit operator surface; actor validation rejects model, agent, tool, system, repository, and automatic identities
  • Secret-like content is rejected unless the operator explicitly requests redaction; sensitive provenance/references such as credentials, private keys, .env, stdin, terminal input, and keystrokes are always rejected
  • disabled or expired entries do not enter new prompts; retention is bounded to ten years, content is bounded to 16 KiB, and references are bounded to 32 entries of 512 bytes each
  • delete physically removes the current version and returns recoverable=false; immutable checkpoints retain only memory ID/version/hash, never the memory body, and report disabled/expired/deleted/version drift
  • documentation calls out that independent exports, backups, logs, and text previously sent to a Provider are outside SQLite deletion and remain governed by their own retention policy

Checkpoint, Fork, Resume, and browsing

  • every new Workspace-bound Run receives an immutable root node; explicit checkpoints capture bounded/redacted compaction context, at most 20 provenance-bearing recent messages, at most 200 active memory references, pinned config/instruction fingerprints, Git branch/full HEAD, and an explicit inheritance list
  • Fork and Resume atomically create a fresh Mission, Run, Session, and branch marker with the selected continuity_snapshot.v1 pinned into the new Run
  • the new Run inherits only the listed bounded context, current memory references, pinned project snapshots, task budget, and mode; it starts from normal created state and newly constructed non-authorizing execution snapshots
  • approvals, capability grants, credentials, Debug sessions, execution/network authorization, processes, terminal leases, and execution profiles are explicitly absent and cannot be resurrected from durable data
  • the Desktop Context tab explains pinned/live instruction state, source conflicts, memory lifecycle/expiry, checkpoints and branch actions, and side-by-side context/config/instruction/Git identity; CLI JSON and OpenAPI expose equivalent machine-readable views

CLI additions include context instructions, full context memory lifecycle/export commands, and session tree|checkpoint|fork|resume. HTTP adds read routes for memories/export, Run project instructions, and session trees plus control-bearer-protected create/edit/delete/refresh/checkpoint/fork/resume routes with strict JSON, query, size, duplicate-field, and unknown-field validation.

Schema, restart, and compatibility

  • schema v114 transactionally creates context_memories, run_instruction_snapshots, and session_continuity_nodes with indexes, validation constraints, foreign keys, and immutability triggers
  • the historical migration-removal chain now includes v114, and the v112 -> v113 Supervisor ledger preservation fixture creates genuinely v112-compatible data before reopening through v113/v114
  • existing messages, Run notes, compaction summaries, and Supervisor calls are not rewritten; legacy Runs without instructions can inspect live state and explicitly create revision 1
  • durable context survives SQLite restart as data only; no runtime process, credential, bearer, lease, approval, or capability is reconstructed
  • protocol/source validation binds node workspace/run/session identities and user-memory references, while tree projections retain config/instruction/Git identities needed to explain drift

Security and compatibility boundaries

  • repository instructions and durable memory are always untrusted context, never an authorization source
  • discovery rejects path escape, symlink/reparse traversal, special files, unstable reads, invalid encoding, and resource exhaustion instead of falling back to a partial set
  • instruction refresh binds both the pinned revision and reviewed live state; concurrent disk or Run changes return a precondition/conflict error
  • memory writes are explicit, versioned, provenance-bearing, and Secret/path screened; there is no silent extraction from conversations, files, terminal input, or tool output
  • continuity snapshots are bounded, redacted, fingerprinted, and authority-free; browsing-only derived nodes cannot be used as Fork/Resume authority
  • restart and migration tests verify persistence without authority restoration; Windows behavior is executed locally and Linux amd64 has clean cross-build coverage, with Linux runtime path/symlink execution left to CI while this PR remains Draft

Validation

  • clean detached-worktree go test -timeout 20m -count=1 ./...
  • go test ./internal/store -count=1 -timeout 20m — full v1-v114 migration/store suite passed in 1025.416s
  • go test ./internal/app ./internal/application ./internal/contextmgr ./internal/domain ./internal/events ./internal/httpapi ./internal/projectconfig ./internal/repository -count=1 -timeout 10m
  • go test -race ./internal/contextmgr ./internal/projectconfig -count=1 -timeout 10m
  • clean detached-worktree go vet ./...
  • clean detached-worktree Linux amd64/CGO-off go build ./...
  • go mod verify and go mod tidy -diff
  • npm test -- --run — 60 files / 246 tests passed
  • npm run typecheck, npm run check:api, and npm run build
  • npm audit --audit-level=high — 0 vulnerabilities
  • relevant CLI parser/service tests cover discovery/refresh, memory lifecycle, tree export, checkpoint, Fork, and Resume

Audit

  • No credentials, local databases, generated runtime output, or unrelated working-tree changes are included.
  • Instruction precedence, memory provenance/deletion, Workspace/path confinement, immutable snapshots, and non-authority restore boundaries were reviewed and covered by focused tests.
  • README.md, README.en.md, usage/architecture/HTTP docs, bilingual lifecycle/threat-model guidance, OpenAPI artifacts, and ADR 0115 were updated.

Manual evidence still required

The PR is intentionally Draft. CI should execute the Linux path/symlink cases on a real Linux filesystem, and the Desktop Context tab still needs reviewer-facing screenshots/manual interaction evidence for instruction drift confirmation, memory deletion, checkpoint creation, branch comparison, Fork, and Resume before merge.

CI follow-up

The first Actions attempt exposed the same Desktop test-fixture failure in three jobs: Windows Desktop shell, macOS Desktop shell, and the Portable ZIP reproducibility build (which runs the Desktop boundary suite before comparing artifacts). Both failing tests wrote a raw t.TempDir() path directly into the workspace store, bypassing the production RegisterWorkspaceDirectory canonicalization path; hosted-runner temp roots may traverse a platform alias/junction, so project-instruction discovery correctly failed closed with HTTP 412.

Commit e4941e0 changes only those two fixtures to register their temporary Workspace through the real production boundary. It does not relax symlink/junction rejection. The exact Windows CI command and both focused cases pass locally:

  • go test -tags "desktop,wv2runtime.error" -count=1 ./cmd/cyberagent-desktop ./internal/desktop ./internal/webui -timeout 10m
  • go test ./internal/desktop -count=1 -timeout 10m

@Qiyuanqiii
Qiyuanqiii marked this pull request as ready for review August 18, 2026 18:36
@Qiyuanqiii
Qiyuanqiii merged commit 2cea758 into main Aug 18, 2026
8 checks passed
@Qiyuanqiii
Qiyuanqiii deleted the codex/issue-106-context-continuity branch August 18, 2026 18:36
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.

feat(context): 层级项目指令、长期记忆与恢复点浏览

1 participant