Commit Graph
80 Commits
Author SHA1 Message Date
weichen c50f9f07e8 Guard source previews against content version substitution
Why: Opening a processed source must not show changed current bytes as the quoted version.

Evidence: SELF TaskSourceContent regression fails before and passes after expected-hash enforcement; artifact regressions and live compilation pass.

Impact: Optional content hash narrows the existing authorized artifact read; controlled fixtures select a genuinely provided quotation.

Refs: fast-slow-u2-u3 source-version acceptance
2026-10-13 02:51:07 +00:00
weichen c2851d498f Use repository prompt recipes in controlled model comparison
Why: Baseline and candidate must exercise their actual default prompts with identical route and resource limits.

Evidence: SELF live-tag compilation passes.

Impact: Evaluation harness only; normal automatic notice quality remains outside the controlled comparison.

Refs: fast-slow-u2-u3 Task 7
2026-10-13 02:41:16 +00:00
weichen 4184430d6d Keep source changes visible and bound evaluation calls consistently
Why: Updated or missing sources must remain visible as limitations, and comparison calls need stable prompt grouping.

Evidence: SELF card/server suites and live-tag compilation pass.

Impact: Adds neutral source limitations and refines test-only provider accounting.

Refs: fast-slow-u2-u3 Tasks 6 and 7
2026-10-13 02:36:57 +00:00
weichen d7597fea05 Build the isolated evaluator with the native provider client
Why: The live harness must use the actual client constructor and preserve MiniMax reasoning separation.

Evidence: SELF live-tag compilation passes without provider calls.

Impact: Test harness only; no production route changes.

Refs: fast-slow-u2-u3 Task 7
2026-10-13 02:31:10 +00:00
weichen 13e880feec Publish validated material findings during background work
Why: Real source-backed discoveries should reach the same task card before the slow channel completes.

Evidence: SELF receipts record runtime and manager checkpoint red-green tests, scoped source/version checks, privacy filtering, quota corrections, and SQLite/PG regressions; fixed composition and live comparison follow.

Impact: Adds a local material-only checkpoint sink with no summary model calls, uses version witnesses for source commits, and preserves existing reading and notification paths.

Refs: fast-slow-u2-u3 Tasks 6 and 7; test-only live HTTP harness bounds shared provider requests without approving HITL
2026-10-13 02:29:23 +00:00
weichen dd0c3ce7d0 Persist task projections and replay cursors atomically
Why: Background work needs consistent cards, events, and user reading state.

Evidence: SELF make evidence records SQLite rollback, projection, pin, and regression checks; PostgreSQL replay is pending the composition gate.

Impact: Adds an optional atomic task path and a consistent card replay cursor without schema changes.

Refs: Agent-System-Dev fast-slow-u2-u3 plan Task 3
2026-10-13 01:31:46 +00:00
weichen f9daf64cf3 Identify materials by content and register grounded source blocks
Why: equal-length edits and parser changes must not reuse prior results.

Evidence: content identity and provided-source tests RED to GREEN; backend suite recorded through evidence.

Impact: trusted optional document origins, content keys and source catalog; no new routing or DB schema.

Refs: U2/U3 Task2
2026-10-13 01:16:44 +00:00
weichen 19d4e1ef0d Consult resource-level authorizer on all shared read paths
ci / vet-and-test (pull_request) Successful in 46s
Why: 方案 r1 U9 第二切片——EXT-8b 契约落地后,读面(下载/清单/建会话/SSE 订阅/检索过滤/动作矩阵 read 回落)仍走 V1 owner×project 布尔,资源粒度与受信六要素未消费。
Evidence: 红测(SetResourceAuthorizerV2 未定义编译红,head 见任务收据);绿测三件:六要素查询断言(download=artifact×ID×Owner=alice×ProjectID、list/read=project×pid)、V2 拒绝压过 V1 放行(404 不泄露)、V2 缺席回落 V1(现行兼容);go test ./... 全绿。
Impact: Server 增 ProjectAuthzV2 槽与 SetResourceAuthorizerV2;authorizeSharedResource(六要素受信构造、字段缺失/出错一律 false)替换六处读路径的 V1 直调(artifactContent/getArtifact/sharedArtifactGet=listArtifacts/createConversation/SSE subscribe/检索 allow-fn/authorizeProjectAction read 回落);app.go 组合根注入 authzSlot.AuthorizeResource。V2 未注册时全部回落 V1,RDM 现网行为不变。
Refs: Backend#178;方案 r1 U9/KTD2
2026-10-12 12:08:14 +00:00
weichen 430caa6296 Add red tests for EXT-8b read-path consumption
Why: U9 第二切片——server 读面须按资源级六要素咨询 V2(红:SetResourceAuthorizerV2 未定义)。
Evidence: go vet 编译红(槽位/消费缺失);断言下载/list/建会话三路径查询要素、V2 拒绝压过 V1、V2 缺席回落 V1。
Impact: 仅测试。
Refs: Backend#178;方案 r1 U9
2026-10-12 12:04:43 +00:00
weichenandCursor 47463a9623 Align admin account e2e with must-change password gate
ci / vet-and-test (pull_request) Failing after 1m25s
Why: U4 middleware restricts must_change sessions to me/password/logout;
the legacy e2e expected admin create before first password change.
Evidence: go test ./internal/store/ ./internal/server/ ./internal/app/
Impact: TestAdminAccountFlow matches set-password + reloginRequired.
Refs: docs/svc-deploy/u4-one-time-login-key.md §5–6

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 03:54:59 +00:00
weichenandCursor 1ba7225e83 Add one-time login keys, restricted sessions, and OpenExisting
ci / vet-and-test (pull_request) Failing after 56s
Why: passwordless activation/recovery must redeem only into a
set-password session; account ops must not create empty stores.
Evidence: SELF go test store/server login-key and OpenExisting cases.
Impact: auth middleware gates; CLI user create defaults to activate key.
Refs: docs/svc-deploy/u4-one-time-login-key.md

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 03:44:16 +00:00
weichen ba619747c5 Merge authoritative main into the B-class branch
ci / vet-and-test (pull_request) Successful in 1m12s
2026-10-12 03:23:43 +00:00
weichenandCursor 5e0077dc11 Whitelist B-class surface actions for help and intent
ci / vet-and-test (pull_request) Successful in 48s
Why: Generative UI U5 left the B-class action allowlist empty; owner
authorized first entries builtin.help and system.intent.
Evidence: go test ./internal/genui/ ./internal/surfacesvc/ ./internal/server/
Impact: Surface buttons may bind help/intent; button-entrance intent
matches only and does not nest-dispatch write commands.
Refs: docs/proposals/2026-10-12-generative-ui-bclass-help-intent.md

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 03:18:57 +00:00
weichen 58598df095 Merge remote-tracking branch 'origin/main' into feature/u7-load-fault-release
ci / vet-and-test (pull_request) Successful in 51s
2026-10-12 03:07:33 +00:00
weichen 1719b5f668 Merge authoritative main into the admin-zone branch
ci / vet-and-test (pull_request) Successful in 49s
2026-10-12 02:37:57 +00:00
weichen 62bfc6068a Declare admin-zone sections from compiled plugins (surface 2.9.0)
ci / vet-and-test (pull_request) Successful in 46s
Why: the admin zone could not host plugin-declared partitions - KTD4
requires the RDM audit partition to be reachable by RDM domain admins and
base superadmins without hardcoding RDM into the base AdminZone.
Evidence: go test ./internal/app ./internal/server ./pkg/extension green
incl. new admin-zone recording/endpoint tests; surface snapshot test
green after surface.txt update; CI (Dev composite) is authoritative.
Impact: extension surface 2.8.0 -> 2.9.0 (Registry.AddAdminZone +
AdminZoneSpec, fail-closed on invalid specs); applyCompiled records
declarations into the plugin summary; new authenticated GET
/api/admin-zone/sections returns the flattened, ordered declaration list.
Entry visibility stays metadata-only - data capability remains enforced
by each section's own command surface (fail-closed).
Refs: WP3-I3/KTD4; task card feature-adminzone-plugin-sections.
2026-10-12 02:28:51 +00:00
weichen 0a7413903d Harden cross-instance HITL/cancel command paths and add disk-full rejection tests (U7)
ci / vet-and-test (pull_request) Successful in 48s
Why: two-process HTTP acceptance (Dev tests/integration/multi-instance, added in
the matching Dev-side change) exposed three real cross-instance defects that the
U5 library-level tests bypassed via direct Manager calls, plus the U7 fault
matrix needs explicit disk-full rejection evidence.
Evidence: go test ./... green on SQLite and real PG (AGENT_PG_TEST_DSN);
new regressions TestCrossInstanceResolveDoesNotSettleCard (runmgr, PG-gated),
TestUploadRejectsCleanlyWhenObjectDirUnwritable and
TestArtifactOverwriteRejectsCleanlyWhenObjectDirUnwritable (server).
Impact: ResolveHITL no longer settles the card when the run executes on another
instance (command-bus fallback stays available); cancelRun enqueues the command
with the real conversation id and no longer reports a false local success;
object-store failures now provably leave zero DB/object residue.
Refs: collaboration storage proposal U7 (sections 3/5/7); task card
feature/u7-load-fault-release.
2026-10-12 02:28:48 +00:00
weichen add1fbb045 Add project-level surface aggregation and task-phase guidance (U6)
ci / vet-and-test (pull_request) Successful in 54s
Why: U6 extends pages from conversations into the task/project
workspace - surfaces aggregate across conversations under the owner's
project scope (project resolved authoritatively from the conversation
row, never self-reported by the model), and the catalog guidance now
organizes pages by task phase (requirements/execution/acceptance)
while stating that task facts come only from real task records.

Evidence: build/vet clean; surfacesvc suite green incl. the new
project-aggregation test (owner isolation, cross-owner zero, history
retained post-disable); genui/store suites green.

Impact: New endpoint GET /api/projects/{id}/surfaces; Submit resolves
project from conversation; catalog text guidance. Existing endpoints
unchanged.

Refs: proposal r2 U6; Dev task feature/generative-ui-u6
2026-10-12 02:12:42 +00:00
weichen 9aa51e5250 List compiled plugins in /api/plugins
ci / vet-and-test (pull_request) Successful in 47s
Why: compiled-in plugins (generative-ui, rdm) never appeared in the admin
plugins list: GET /api/plugins only scanned the directory host, so binary-
level capabilities were invisible to operators (user-reported gap).
Evidence: go test ./internal/app/ ./internal/server/ green locally incl.
new TestApplyCompiledRecordsSummary and TestListPluginsMergesCompiled;
CI (make test) is authoritative.
Impact: applyCompiled records each plugin's registered commands/intents/
skills into a summary handed to the server; /api/plugins merges synthesized
inproc entries (backend.mode=inproc, apiVersion=extension surface version,
provides from the registration record). Directory entries win on id
collision. No public extension-surface change.
Refs: WP3-I4; task card feature-plugins-compiled-listing.
2026-10-12 01:44:56 +00:00
weichen 4ae125a3ef Add AdminProvider capability and HostProjectID context (EXT-18)
ci / vet-and-test (pull_request) Successful in 57s
Why: RDM KTD4 dual-layer admin requires base isAdmin visibility (superuser slot); KTD5 host-project binding needs trusted current-project context.

Evidence: SELF 4 ext18 tests pass + surface snapshot regenerated + full pkg/extension + internal/app suites green.

Impact: extension.Request gains HostProjectID; optional AdminProvider interface (EXT-17 pattern); inprocHost implements IsAdmin via GetUserAuthState; three dispatch sites set HostProjectID from conversation.

Refs: RDM docs/proposals U1 base extension requests
2026-10-11 16:23:15 +00:00
weichen f5eb27df86 Add the surface action pipeline: ledger, guards, dispatch, submit (U5)
ci / vet-and-test (pull_request) Successful in 1m10s
Why: The approved U5 scope needs the action half of the loop: an
idempotent ledger (migration v24), a single-choke SubmitAction (plugin
activation, current-revision, action whitelist, params-hash
idempotency), dispatch through the command bus so DangerHigh lands on
the existing inline confirm card with no Confirmed passthrough (the
endpoint does not even bind the field), the button-only
generative-ui.submit storing form data in the plugin KV ledger, and
catalog discipline rejecting unknown action ids at present time.

Evidence: go build/vet clean; full go test ./... green; surfacesvc/
genui/store suites also green under AGENT_PG_TEST_DSN; red matrix
covers disabled/stale-revision/cross-owner/unknown-action/idempotent
same-and-different-params/danger-high-await-confirm and the endpoint
forged-confirmed case.

Impact: Additive migration v24 + new endpoint/command; existing
endpoints and command semantics untouched (B-class whitelist starts
empty per the approved scope).

Refs: U5 action-scope r2 (approved, Documents #71); UI #46/#47;
Frontend #56; Dev task feature/generative-ui-u5
2026-10-11 14:24:31 +00:00
weichen 6681c3b47c Fall back to session cookie on stale Bearer key and report authVia
ci / vet-and-test (pull_request) Successful in 44s
Why: a browser holding a revoked API key in localStorage sent the Bearer
header on every request; key precedence 401'd all APIs despite a valid
login session, locking admins out of user management. /api/me also
reported mustChangePassword for key principals, who cannot change
passwords (session-owned), dead-ending the forced-change gate.

Evidence: new TestStaleKeySessionFallback covers fallback and authVia;
TestAuthMiddleware/TestAdminAccountFlow unchanged and green; full
go test ./... green.

Impact: invalid key falls back to a valid session cookie before 401
(cookie-less programmatic clients unaffected); /api/me gains
authVia ("key"|"session"|""), letting the frontend keep key holders
out of the change-password gate.

Refs: Dev task feature/admin-auth-gate-fix.
2026-10-11 13:45:52 +00:00
weichen 603f1c0fa4 Add execution ownership leases with epoch fencing and persistent run commands (U5)
ci / vet-and-test (pull_request) Successful in 57s
Why: plan U5/KTD4+KTD5 - before a second instance may serve writes, conversation execution must have a single valid owner (DB lease, epoch increments on takeover), stale owners must not settle (in-transaction fence check), and cancel/HITL must reach the executing instance via a persistent command inbox.

Evidence: full suite green twice-relevant on SQLite and real PostgreSQL 18.6 (35 packages each tier) - lease tests (claim/contention/re-claim/renew fencing/expiry takeover/monotonic epoch, command inbox idempotent enqueue, atomic concurrent claim) and multi-instance tests (same-conversation contention rejected, stale-owner settle fenced with run unchanged, cross-instance cancel consumed exactly once by the owner instance, non-owner does not consume).

Impact: v23 migration (conversation_executions + run_commands); ClaimConversation stacks a DB lease on PG tiers (15min, release on conversation release); settle path fenced (fenced runs emit run.fenced, no terminal write); StartCommandConsumer polls the inbox for commands on locally-owned executions (cancel routes to local cascade or DB-level close-out; HITL revalidates gate and rejects expired explicitly); server cancel/HITL fall back to command enqueue with 202 when the run is not local; app wires instance identity (host:addr on PG tiers) and starts the consumer.

Refs: proposals/2026-10-11-collaboration-storage-and-distribution.md U5 KTD4/KTD5; R4/R10.
2026-10-11 12:25:31 +00:00
weichen 75829fa442 Add the Surface store, activation guard, and EXT-17 host capability
ci / vet-and-test (pull_request) Successful in 40s
Why: Generative UI proposal U2 needs the host side of the contract:
owner-isolated surface storage with revision CAS, an execution-level
enable/disable ledger (default-off, epoch bumped on every transition so
in-flight submits after a disable are rejected), a single-choke-point
service that validates specs (strict decode + catalog rules) before
saving, event publish with pending recovery, the optional SurfaceHost
extension capability, and direct API endpoints that share the same
guard (no bypass by entrance).

Evidence: go build/vet clean; full go test ./... passes (SQLite);
surface store tests also pass under AGENT_PG_TEST_DSN (PostgreSQL);
surface.txt regenerated via the AST snapshot test.

Impact: Additive migration v22 (new tables only); existing endpoints and
plugin_grants semantics untouched; old consumers unaffected. U3+ (data
binding, actions, frontend) deliberately out of scope.

Refs: Documents proposal 2026-10-10-generative-ui-plugin.md (r2 U2);
Core PR #25; Dev task feature/generative-ui-u2
2026-10-11 08:26:24 +00:00
weichen f84733d128 Add shared execution budgets and the action-authz matrix (U3 slice 2)
ci / vet-and-test (pull_request) Successful in 43s
Why: plan U3 remainder (R8/KTD13) - execution admission must be bounded and shared (leases in the database, parents yield while waiting so budgets cannot deadlock parent-child), and project authorization must distinguish read/edit/approve/execute/admin with default-deny for unconfigured actions.

Evidence: full suite green on SQLite and against real PostgreSQL 18.6 + Redis (isolated instance); new tests - admission_pg_test (enforcement, per-user, concurrent no-oversell), runmgr admission tests (saturated-budget sync spawn progresses, background children share the budget, bounded queue 429), server action-matrix tests (default deny, legacy adapter read-only, action-aware authoritative + fail-closed).

Impact: admission_leases (v21) with atomic lease accounting under an advisory lock; runtime.execBudgetGlobal/PerUser/execQueueMax settings (all zero = off, historical behavior preserved); conversation turns, background and sync subagents share the pool, parents yield around synchronous children and HITL waits; queue-full rejects 429 before writing; server gains ProjectAction matrix + SetProjectActionAuthorizer with legacy EXT-8 read fallback.

Refs: proposals/2026-10-11-collaboration-storage-and-distribution.md U3 R8/KTD13; docs/guides/team-storage.md section 9.
2026-10-11 05:18:12 +00:00
weichen 5cd67be982 Close request atomicity: locked message append, card versions, atomic rate limit, recovery holds (U3 slice 1)
ci / vet-and-test (pull_request) Successful in 41s
Why: the approved plan U3 (KTD3/KTD7/KTD10 plus minimal recovery isolation) requires concurrent submits to not silently overwrite, unknown-side-effect runs to never auto-resume, and the shared rate limiter to degrade conservatively instead of failing open.

Evidence: full backend suite green twice-relevant paths against real PostgreSQL 18.6 and Redis (isolated instance) and on SQLite; new tests - card_version_test (concurrent single winner), recovery_hold_test + recovery_holds_test (skip/release/fail-closed CRUD), ratelimit atomic-window and degraded-fallback tests.

Impact: AppendMessageWithRequest now allocates seq under the conversation advisory lock in one transaction; activity_cards gain version (v19) with SaveCardVersioned/GetCardVersion/CardVersion and cardsvc user mutations (status/pin/action/resolve-by-ref) return 409-mapped conflicts while system mirrors keep blind writes; recovery_holds (v20) with admin list/release endpoints and fail-closed resume skip; Redis limiter uses one Lua INCR+PEXPIRE script and falls back to a per-instance limit with a Degraded counter.

Refs: proposals/2026-10-11-collaboration-storage-and-distribution.md U3 KTD3/KTD7/KTD10; R3/R6/R7/R8.
2026-10-11 04:37:50 +00:00
weichen c802be812d Merge origin/main into feature/agent-quality-phase05
ci / vet-and-test (pull_request) Successful in 40s
2026-10-10 00:30:05 +00:00
weichen 9786dc1456 Wire plugin slash aliases and the intent declaration surface (G2-2)
Why: plan G2-2 requires plugin commands reachable via slash aliases
through the same bus and audit envelope (EXT-10②), and a natural-
language routing entry so '帮我写项目建议书' can reach the compile
flow. The agent-command lib now carries a validated Slash field
(lib PR #6, pin bumped to 4f583ca); the bus binds plugin-spec aliases
into the same slash table; intents are declared via the extension
registry and routed deterministically (normalized containment, longest
phrase first) to commands through the bus — the system.intent builtin
(/intent) is the chat-entrance dispatch point with a candidate list on
miss.

Evidence: TestPluginSlashAliasBindsAndDispatches — alias binds, case/
whitespace-normalized resolution, slash and button entrances hit the
same command handler with committed receipts; TestIntentDeclareMatch
Route — declare/validate, miss on unrelated text, normalized hit,
bus-dispatch through the chat entrance, longest-phrase priority;
server suite green with the dual-entry pair registered; full go test
./... 31/31 packages green.

Impact: cmdbus plugin-spec slash binding + IntentStore; extension
Registry.AddIntent + IntentSpec (SurfaceVersion 2.7.0-experimental);
pluginRegistry.AddIntent wires plugin-declared intents; server
builtin system.intent; command-pairs fixture extended.

Refs: plan G2-2 (line 366); EXT-10②; lib PR #6 (4f583ca).
2026-10-10 00:15:21 +00:00
weichen ef060d4ee5 Keep only hard facts in the blocking gate and add fact-consistency checks
ci / vet-and-test (pull_request) Successful in 40s
Why: User rulings 4/5 plus the P2-P4 live evidence. Keyword scoring dimensions
(readability, actionability) kept failing valid documents - normal Chinese
section headings flagged as column titles, loops of 4 corrections - because
they grade writing preferences, not verifiable facts. Unverified numbers
(~10-13 per run) remained the largest quality leak through every phase.
And the verifier runs on the same model as the worker (lightweight falls back
to chat), so "independent" verification was self-review. Separately, svc
seeding after boot never registered the tavily tools until a restart because
keys were snapshotted at startup.

Changes: quality.HardFacts (lint actually ran + zero errors) replaces the
full ScoreBytes projection in CheckArtifacts - keyword dimensions remain in
ScoreBytes for eval visibility only. New fact-consistency check
(runtime.factCheck, default on): extract percentages/dates/large numbers from
deliverable text, trace each against the material corpus (attachment text +
tool evidence); misses get exactly one correction round (fix, drop, or mark
as target/estimate), never a loop. runVerifier skips same-source model
verification unless runtime.verifierSameModel is set (hard facts + fact check
still run). Search tools now register lazily, reading tavily keys per call
(settings/seeding take effect immediately).

Evidence: SELF - TestHardFactsIgnoresKeywordDimensions,
TestHardFactsKeepsLintUnavailableBlocking, TestUnverifiedFactsAndNotice,
TestFactCheckContinuationOnce (fact note fires, corrected run passes);
go vet + go test ./... pass; live before/after on the golden task set
recorded on the phase05 task card per the policy clause.

Impact: Gate stops rejecting valid documents on stylistic grounds; invented
figures get one forced correction round; same-model verification no longer
pretends to be independent; tavily config is hot. No contract or storage
changes.
2026-10-10 00:04:57 +00:00
weichen 439865616a Share retrieval inside runs and open project listing/conversations to members (EXT-13/15)
ci / vet-and-test (pull_request) Failing after 44s
Why: A member's agent cannot see published project knowledge inside a run
(runCtx.Retrieve and hostcaps.search are owner-only), and members can
neither see shared projects nor open conversations in them - both are P0
prerequisites for RDM G1 (EXT-13/EXT-15, proposal
2026-10-09-ext-g1-b1-b3-exec-backend).
Evidence: Red tests first - TestRunContextRetrieveShared (undefined
SetSharedKnowledgeAllow), TestInprocHostKnowledgeSearchShared (0 shared
hits), TestSharedProjectListAndConversation (empty list) all failed before
and pass after; go test ./... 32/32 packages ok.
Impact: runmgr gains SetSharedKnowledgeAllow and routes Retrieve through
RetrieveShared when the predicate is registered (nil = unchanged); hostcaps
search consults the same EXT-8 slot; GET /api/projects appends
adapter-authorized shared projects (projectView with shared flag, deduped);
POST /api/projects/{id}/conversations falls back to
CreateConversationInProject when the own-project path misses and the
adapter authorizes; store gains ListAllProjects (candidates only, callers
must filter through the adapter) and CreateConversationInProject.
Revocation takes effect immediately on both paths; absence of an adapter
is byte-for-byte the previous behavior. No pkg/extension surface change.
Refs: docs/proposals/2026-10-09-ext-g1-b1-b3-exec-backend.md (EXT-13, EXT-15)
2026-10-09 15:44:48 +00:00
weichen 68c1a7272a Keep tracked-change and hyperlink text in DOCX and add an exec hard switch
ci / vet-and-test (pull_request) Successful in 43s
Why: The DOCX parser only read w:r runs that were direct children of w:p, so
text inside w:ins, w:hyperlink and w:fldSimple was dropped with no warning,
violating the no-silent-degradation rule. Separately, runtime.exec is a
user-writable setting, so multi-user deployments could not reliably turn the
exec primitives off.
Evidence: SELF - red tests TestParseDocxTrackedChangesAndHyperlinks and
TestExecHardDisabledOverridesSettings failed before and pass after; backend
go test ./... (32 packages) passes; a mock-mode binary started with
--disable-exec-tools hides run_shell/run_python/register_artifact from
/api/tools even after the user sets runtime.exec=true.
Impact: DOCX paragraphs are decoded from the token stream at any depth;
deleted/moved-from text, field codes and mc:Fallback are excluded and
revised documents carry an explicit warning. New Options.DisableExecTools
(SurfaceVersion 2.5.0-experimental), CLI --disable-exec-tools, config key
disableExecTools and env AGENT_SYSTEM_DISABLE_EXEC_TOOLS; zero value keeps
current behavior.
Refs: Agent-System-RDM docs/proposals/2026-10-09-V22-review-and-implementation-plan.md (G0-7, B-5)
2026-10-09 10:36:02 +00:00
weichen 92ede3b970 Close the EXT-8 remaining blocks: vector sharing, hostapi face, citation consistency
ci / vet-and-test (pull_request) Successful in 37s
Why: EXT-8 closure needs the vector channel shared (not just fulltext), the /host/v1 knowledge face honoring the authorizer, and citation-ref-to-artifact consistency pinned as an acceptance test.
Evidence: TestRetrieveSharedVectorChannel (hash embedder: authorized shared vector hit retrievable, denied yields zero), TestSharedSearchFace (hostapi switches to SharedSearch when wired), TestSharedCitationRefDownloadable (shared hit -> Ref -> artifact content download for the authorized member); go test ./... 32/32 packages ok.
Impact: store.SearchKnowledgeVectorsShared; rag.Pipeline.RetrieveShared (own + shared fulltext + shared vector, RRF-merged); server searchKnowledge prefers RetrieveShared when the retriever implements it; hostapi Server.SharedSearch wired in the composition root through the same authorizer slot. Default behavior unchanged.
Refs: EXT-8 proposal acceptance; slices 1-2.
2026-10-08 17:16:10 +00:00
weichen 1de663a8d3 Implement shared knowledge retrieval, card mirror switch, and SSE project gate
ci / vet-and-test (pull_request) Successful in 40s
Why: The three pinned reds define EXT-8 slice 2 - adapter-granted cross-owner knowledge must be retrievable, conversation cards must stay out of public project streams when the host opts out, and project-stream subscription must honor the authorizer.
Evidence: TestConvCardMirrorSwitch, TestSharedKnowledgeRetrieval, TestProjectSSEScopeGate green; go test ./... 32/32 packages ok; rows follow on the task card.
Impact: store gains predicate-based SearchKnowledgeShared (FTS/LIKE shared variants + PG); searchKnowledge appends adapter-authorized hits; cardsvc emit gate (no publish = no persistence = clean replay); events project scope consults authorizeSharedProject. Default behavior unchanged everywhere.
Refs: EXT-8/EXT-12 proposals; red run at surface commit.
2026-10-08 16:18:07 +00:00
weichen d3381b208b Add the EXT-12 mirror switch surface and slice-2 red tests
Why: Knowledge retrieval cross-owner and conversation-card mirroring are the registered EXT-8 slice-2 items; the fields/wiring land with the acceptance reds pinned first.
Evidence: mirror red (project channel still emitted with switch off); shared-retrieval red (grant yields 0 hits); SSE-scope red (grant yields non-200); rows follow on the task card.
Impact: Options.DisableConvCardMirror passthrough (extension/link/app); cardsvc.MirrorConvCards (default true = current behavior); SurfaceVersion 2.3.0-experimental. Behavior unchanged.
Refs: EXT-8/EXT-12 proposals; task card.
2026-10-08 16:08:20 +00:00
weichen fbc924c240 Implement EXT-9 idempotent publish, prefix-enforced revoke, and the upload index switch
ci / vet-and-test (pull_request) Successful in 41s
Why: The red acceptance tests pin the EXT-9 semantics - held material must not enter retrieval until published, revoke must stop retrieval immediately and idempotently, manual sources must stay out of plugin reach.
Evidence: TestKnowledgePublishIdempotentAndRevoke and TestUploadPreIndexSwitch green; go test ./... 32/32 packages ok; rows follow on the task card.
Impact: hostcaps KnowledgePublish (per-ref row+vector cleanup then existing write path) and KnowledgeDelete (plugin:<id> prefix enforced); store DeleteKnowledgeBySource with vector cleanup; upload indexing gated by DisableUploadIndexing (default false = unchanged).
Refs: EXT-9 proposal; red run at surface commit.
2026-10-08 15:55:02 +00:00
weichen 1ee32822c3 Add the EXT-9 publish/revoke surface and red acceptance tests
Why: EXT-9 is the other step-4 hard prerequisite; the surface (Options.DisableUploadIndexing passthrough, Host.KnowledgePublish idempotent replace, Host.KnowledgeDelete prefix-enforced revoke, SurfaceVersion 2.2.0-experimental) must land with the acceptance reds pinned before implementation.
Evidence: app red = publish not implemented; server red = switch-on still indexes (hits=1); rows recorded on the task card.
Impact: pkg/extension additive surface (surface.txt updated); internal Options passthrough; Server.DisableUploadIndexing field; host method stubs. Behavior unchanged.
Refs: EXT-9 proposal; task card.
2026-10-08 15:53:39 +00:00
weichen a4783d18e7 Consult the EXT-8 authorizer in project artifact read paths
ci / vet-and-test (pull_request) Successful in 41s
Why: With the surface and injection seam in place, the read endpoints must fall back to the adapter when owner-scoped lookup misses, keeping default-deny and fail-closed semantics.
Evidence: TestProjectResourceAuthorizerSharesReads green (default deny, shared list/meta/content via adapter, third-party denied, authorizer error fail-closed); go test ./... 32/32 packages ok.
Impact: listArtifacts/getArtifact/artifactContent consult authorizeSharedProject; store gains gated helpers (GetArtifactByID/ArtifactContentByID/ListProjectArtifactsAll) documented internal-only; writes untouched; SSE project stream and project card aggregate deliberately deferred to EXT-12 (conversation-card mirroring privacy).
Refs: EXT-8; red run at d89e748; task card.
2026-10-08 15:34:18 +00:00
weichen d89e74880b Add the EXT-8 authorizer surface and a red sharing test
Why: EXT-8 is accepted (Documents #49); the surface (Registry.RegisterResourceAuthorizer, ResourceAuthorizer, SurfaceVersion 2.1.0-experimental) plus the Server injection seam must land before the read-path consultation, and the behavioral red run proves the gap.
Evidence: go test ./internal/server -run TestProjectResourceAuthorizerSharesReads FAIL (shared read 404 with adapter set); default-deny section passes; row recorded on the task card.
Impact: pkg/extension additive surface (surface.txt updated); projectAuthz slot in hostcaps; Server.ProjectAuthz + setter; app wiring after compiled load; declarative registry fails closed. Read behavior unchanged.
Refs: EXT-8 in Documents 2026-10-08-ext-c1-c7-rdm-shared-contracts; task card.
2026-10-08 15:32:04 +00:00
weichen e0b1c27f1f Scope command audit storage and queries to the requesting owner
ci / vet-and-test (pull_request) Successful in 42s
Why: GET /api/commands/audit leaked every tenant's audit rows (command ids, entrances, conversation ids, param digests) to any authenticated user; owner was never recorded nor filtered.
Evidence: Red run at a7cc69b FAIL (alice sees bob's row); after fix go test ./... 32/32 packages ok, including TestCommandAuditOwnerScoping and the v18 backfill test (rows recorded on the task card).
Impact: v18 migration adds command_audit.owner with actor-based backfill (empty-actor rows stay invisible via API, kept in-table); AppendAudit/ListAudits gain owner params; cmdbus port and fakes updated; handler passes authenticated owner. No public extension surface change.
Refs: Task card R1; U0 proposal section 5 C7 finding.
2026-10-08 14:02:19 +00:00
weichen a7cc69b61e Add a red test for cross-tenant command audit leakage
Why: GET /api/commands/audit returns every tenant's audit rows; the regression test pins the desired owner-scoped behavior before the fix.
Evidence: go test ./internal/server -run TestCommandAuditOwnerScoping FAIL (owner alice sees bob's row; output recorded on the task card).
Impact: Test only; suite red on this commit by design.
Refs: Task card R1; U0 proposal section 5 C7 security finding.
2026-10-08 13:57:30 +00:00
weichen 70afe40b00 Retire the legacy workflow executor and switch squad steps to agent-native (Q3 WP2)
ci / vet-and-test (pull_request) Successful in 47s
Why: Q3 WP2 retires the SpawnSubagent-compression execution path: all
WorkflowDef execution now goes through the wfcompile compiled graph, and
squad steps run on the agent-native kernel backend instead of the
agent-system step backend.

Evidence: runtime-level P4 parity tests (workflow_compiled_test.go):
registered branch lookup/errors, planned branch confirmation gate +
dynamic 8-step cap fail-closed before any HITL, model script switch
default-off, missing-slot HITL collection with compile-time rendering,
judge stream routed to the configured lightweight model (nil = fail-closed
verifier-unavailable). squadadapter TestOrchestrateRunsOnKernelStub:
four-phase skeleton runs end-to-end on the kernel stub (write_file
materialization, seeded skills, exec allowlist). server TestSquadOrchestration
reworked: kernel steps run in-process (no subagent child runs). Full
backend suite green; wfcompile/squadadapter/runmgr green with -race
(pre-existing llm_test fake race on main recorded as debt, CI does not
gate -race).

Impact: DELETED runtime/workflow.go + workflow_script.go (legacy step loop,
critic, script host) and their tests; squadadapter stepBackend
'agent-system' + profileForRole deleted; BuildBackends exported and
registers only agent-native; Orchestrate DefaultBackend -> agent-native;
builtin roles declare agent-native with write_file added to allowlists and
writer run_shell -> run_command (kernel tool name); runmgr default workflow
runner -> CompiledWorkflowRunner; mock #workflow demo runs compiled
(host-only steps). Model script branch keeps the single script-level
confirmation (no extra plan confirmation), matching legacy.

Refs: Q3 plan WP2 (2026-10-07-agent-stack-q2q3-plans.md); task card
.task/feature-agent-stack-q3.md
2026-10-08 03:24:30 +00:00
weichen 26bd9286ad Make the rewind happy test tolerant of the settle-release window
ci / vet-and-test (pull_request) Successful in 41s
Why: run terminal status persists before the conversation claim is
released; on the slow CI runner the rewind POST landed inside that
window and got a 409. Retry the POST until the claim frees (bounded).
Evidence: go test -count=5 ./internal/server/ -run TestRewindFilesHTTPHappy
green; full suite green.
Impact: test-only.
Refs: Agent-System-Backend#94 #97
2026-10-07 18:04:08 +00:00
weichen f862892544 Take the checkpoint closure: retention on rewind, HTTP tests, eligibility pin (N3 WP3)
ci / vet-and-test (pull_request) Successful in 42s
Why: the library now pins eligibility, guards symlinks, reports partial
restores, and bounds the log (Agent-Native#33); the product wires
retention after successful rewinds and needed the HTTP-layer and
eligibility evidence.
Evidence: go test -count=1 ./... green; TestRewindFilesHTTPHappy and
TestRewindFilesHTTPBusy409 (HTTP happy + conflict),
TestBackendCheckpointEligibilityIsWriteFileOnly (the product surface
checkpoints exactly {fs_write_file}).
Impact: checkpoints.jsonl is compacted to the latest 200 anchors after
each successful rewind.
Refs: Agent-Native#33, Agent-Squad#37, N3 plan WP3
2026-10-07 15:59:14 +00:00
weichen ff43c7c9aa Unify intent routing behind the route package and enable NFKC
ci / vet-and-test (pull_request) Successful in 41s
Why: I1 WP3 - chat routing and the HITL free-text pivot now share one
router consuming the library's command list, and both intent hosts
fold compatibility-equivalent input.

Evidence: go vet clean; go test ./... 30 packages ok, including the
existing workflow-route and server e2e suites unchanged (behavior
parity) and the new route package tests.

Impact: new internal/route package (unique router with explicit
priority rules); intentgate carries Commands and folds NFKC;
server.go and runmgr.go route through it; nested pins at intent
2554b50 and squad 6b7a991. Blueprint actions resolve to a squad
decision at the router level; per-run squad entry stays a recorded
follow-up (no silent misrouting).

Refs: Documents proposal 2026-10-07-agent-stack-n1q1i1-plans.md I1 WP3/WP4
2026-10-07 07:44:31 +00:00
weichen 727f3702d0 Expose builtin document parsing through the host handle
ci / vet-and-test (pull_request) Successful in 46s
Why: downstream parsers are unreachable via extension.Host and the base lacked xlsx/pptx parsers; MS1 needs Excel and PPT ingest (EXT-5 request, documents proposal 2026-10-06-ext-5-host-parse-document).

Evidence: local GOWORK=off go test ./... all 29 packages pass incl. new ooxml_test (hand-built parts), ooxml_python_test (openpyxl/python-pptx round-trip), inproc owner-scope and limit tests, xlsx upload e2e; go vet clean; recorded as SELF on the Dev task card, PR CI to confirm.

Impact: Host gains ParseDocument (pure compute; errors only on ctx cancel or >100MiB input); builtin:xlsx (sheet order via workbook.xml rels, rich-text shared strings, formula cache, 1900/1904 dates, sparse cells) and builtin:pptx (sldIdLst order, titles, group shapes, AlternateContent Choice, tables, notes) added with 200k-cell/64MiB-part caps; legacy doc/xls/ppt get an actionable hint; ParsersDescription gains xlsx/pptx and the missing text ext; surface snapshot now records exported interface methods; docx part reads share the 64MiB cap.

Refs: documents 2026-10-06-ext-5-host-parse-document.md; EXT-1 host.go precedent.
2026-10-06 14:59:38 +00:00
weichen 42cca8fade Store secrets apart from settings and assemble context at the end
Why: Masks must not be the only copy of a key, and personal instructions, lore hits, and candidate replies have to reach the model without rewriting the system prefix or deleting history.
Evidence: go test ./internal/store ./internal/ctxasm ./internal/settings ./internal/runtime ./internal/server. Migration v16 upgrades and rolls back. Startup snapshots settings before moving raw keys.
Impact: One labeled key is active per service. Excluding a message hides its whole run from the model. Regenerating appends another candidate and rewinds files to the user turn. User slash commands expand to prompt text and do not fire on their own.
Refs: docs/records/2026-10-04-sillytavern-review.md
2026-10-04 18:20:10 +00:00
weichenandCursor 8eda35f365 Refuse open listeners and cross-site writes without auth
Why: The embedded tier starts without auth, and nothing checked Origin or Host, so a public bind or a foreign page could call write APIs.
Evidence: go test ./internal/config ./internal/server covering listen policy, origin rejection, and response headers.
Impact: Non-loopback without auth exits before opening the database. HTML artifacts get a sandbox CSP. Reverse proxies must list their public host in allowedHosts.
Refs: feature/sillytavern-review
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-04 17:28:46 +00:00
weichenandCursor d90b9c045b Expand dotted setting keys and mask secret pools
ci / vet-and-test (pull_request) Successful in 52s
Why: A dotted-key PUT was stored beside the nested object and never read, so replacing a key kept the old pool. GET also returned tools.tavily.apiKeys in clear text, and saving settings would write the mask placeholder back over a real key.
Evidence: go test ./...
Impact: Dotted writes take effect on the next read. Startup expands stored dotted keys, and the existing nested value wins when both forms exist. GET masks schema secrets, including apiKeys. Writing the mask placeholder no longer overwrites a stored secret.
Refs: fix/settings-dotted-keys
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-04 13:01:38 +00:00
weichenandCursor bead03374e Rewind tracked files and fall back before the first token
ci / vet-and-test (pull_request) Successful in 39s
Why: workspace writes had no checkpoint, and a 5xx before any output stopped the turn instead of trying the next configured model.
Evidence: GOWORK=off go test ./internal/runtime/ ./internal/runmgr/ ./internal/tools/ ./internal/settings/ ./internal/server/ ./internal/app/
Impact: models.chat.fallbacks defaults to empty, so existing runs keep their model. Rewind restores only tracked writes and appends a system note. Usage records the model that served.
Refs: feature/durable-rewind
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 17:31:56 +00:00
weichenandCursor 6b0ff49f34 Gate tools by session mode and show confirmation details
Why: Plan mode has to block writes, confirmations dropped the argument preview, and direct chat did not share its stop gate with squad members.
Evidence: GOWORK=off go test ./internal/store/ ./internal/tools/ ./internal/runmgr/ ./internal/runtime/ ./internal/server/ passed. Default mode still runs write_artifact; plan mode rejects it.
Impact: Empty permission mode keeps the profile allow, deny, and confirm lists. High-risk shell commands now ask. There is no bypass-all mode.
Refs: feature/permission-hooks
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 17:01:46 +00:00