-
Notifications
You must be signed in to change notification settings - Fork 2
plat 325
| Coordination | Value |
|---|---|
| Assigned agent | Claude Code |
| Ticket state |
implemented; not deployed — build/test verified locally, RTS deployment pending |
| Last synchronized | 2026-09-17 |
| Implementation commits |
58f5a341c (backend), 43f6c7118 (frontend + docs) |
| Related | PLAT-310 — the read-only feature this extends. Base ticket's own "Later extensions" section named this exact gap: "Shared contribution would require an explicit contribution mode, eligible writers, notes-only write paths, provenance, conflict handling, and serialization keyed to the source KB across workflows." |
PLAT-310 shipped read-only cross-workflow KB attachment
(knowledgebase_sources, access: "read" only). Read-only was too narrow: a
workflow that discovers something useful while reading another's KB had no
way to contribute it back. This ticket adds access: "write", confined to
the same notes/ boundary local KB writes already use, gated by explicit
two-sided consent rather than the audience-overlap check that governs read.
Full design, configuration, runtime mechanics, and acceptance criteria are
maintained in docs/workflow/shared_knowledgebase_sources.md
(updated in place for this ticket, not duplicated here) — see its "Write
access" section. This ticket file covers the incident/investigation trail
and disposition; the design doc is the living contract.
Two design questions were resolved by direct code investigation before writing anything:
-
Does the existing local-write boundary generalize? Yes — local KB
writes were already confined to exactly
knowledgebase/notes/(never the KB root, nevercontext/) via three separate folder-guard builders (setupExecutionFolderGuard,setupMessageSequenceFolderGuard,setupOrchestratorFolderGuard— one per execution shape, all gated by the samekbAccessAllowsWritecheck). Extending cross-workflow write reuses the identical mechanism, pointed at a resolved external path instead of the local one — no new write primitive needed. -
Is concurrent writing from multiple workflows' sessions safe today?
No — KB writes are plain
diff_patch_workspace_file/update_workspace_filecalls with zero locking, fine for one workflow's own sequential turns, unsafe once a second workflow's session can write into the same folder concurrently. Explicitly scoped out of this pass by user decision — see "Deliberately not done" below.
Also checked: PLAT-272 shared workflow secrets, considered as a possible
precedent for a "workflow grants another workflow X" consent pattern. It
isn't one — it's cross-user, same-workflow secret sharing, not
cross-workflow consent. No existing target-side allowlist pattern existed
anywhere in the codebase; WorkflowAccess.AllowedKBWriters is new.
-
Schema:
KnowledgebaseSource.Accessaccepts"write"(implies read) alongside"read". NewWorkflowAccess.AllowedKBWriters []string(workflow IDs) on the target's manifest — the consent step a consumer's write source depends on. -
Authorization:
workflowkb.AudienceCanWriterequires both the ordinary read-audience check (AudienceCanRead) and explicit membership in the target'sAllowedKBWriters. Audience overlap alone, sufficient for read, is not sufficient consent to mutate another workflow's KB. -
Runtime: all three folder-guard builders now also append the resolved
external write source's
notes/path, behind the exact samekbAccessAllowsWritegate as the local grant — no separate bypass. -
Config surface:
update_workflow_config(knowledgebase_sources=...)for the consumer side,update_workflow_config(kb_write_grants=...)for the grantor side (new), both mirrored in the workflow manifest HTTP API and theKnowledgebaseSources.tsxfrontend (attach-with-write-choice, badges, and a new grantor-sideKBWriteGrantspanel). - Provenance: the KB-sources prompt now requires a contributed note to tag the writing workflow's ID.
-
Concurrency/locking. By explicit user decision, not built in this
pass. Two workflows' sessions writing into the same target
notes/folder at the same moment can race at the OS file-write level.learningsGlobalFileMutex(agent_go/pkg/orchestrator/agents/workflow/step_based_workflow/learnings_direct.go) is the precedent to mirror if this needs solving later: an in-process mutex keyed by the target's canonicalnotes/path (not one global lock), held for the duration of the write turn the same wayprepareDirectLearningTurnholds its mutex. That mutex's own doc comment already discloses the same in-process-only limitation, which is why it's the right precedent rather than something to invent fresh. -
A hard hard-gate forcing message_sequence steps to load plan-design
guidance before authoring their first step — unrelated tangent explored
in the same session, explicitly abandoned: it would require modifying
mcpagent(shared cross-product runtime, not contained to this repo) to track tool-call history, and a rigid rule would itself be wrong sometimes (a deterministic fetch-first step is legitimately correct). Not part of this ticket's scope; noted here only because it was investigated adjacent to this work and explicitly rejected as its own path.
- New Go tests:
TestSourcesWriteAccessRequiresExplicitGrant(pkg/workflowkb) — no-access-block, audience-overlap-without-allowlist, explicit-grant, and revocation cases.TestKBSourcesWriteGrantAppliesToAllThreeFolderGuards(step_based_workflow) — proves all three folder-guard builders grant the external write path once granted, and that a read-only step's ownkbAccessstill blocks it (no separate bypass). -
go build ./...andgo test ./...clean acrosspkg/workflowkb,pkg/workflowtypes,pkg/orchestrator/agents/workflow/step_based_workflow,cmd/server,cmd/server/guidance. -
npx tsc -b --forceclean; existingKnowledgebaseSources.test.tsxsuite passes (one interaction bug caught and fixed during this work: the newKBWriteGrantsform's DOM position initially preceded the existing attach-source form, breaking a test'squerySelector("form")assumption — reordered so the pre-existing form stays first in document order). - Not yet done: live end-to-end verification with two real workflows on a deployed host (grant, attach, write, confirm provenance tag, confirm a non-granted third workflow is refused).
-
access: "write"accepted by schema validation;"read"still the default and still read-only. - Write requires explicit
kb_write_grantsfrom the target; audience overlap alone is not sufficient (verified: revoking the grant while audience overlap remains intact revokes write). - Write confined to
notes/; KB root andcontext/remain untouched by this grant. - All three execution shapes (plain step, message_sequence item, orchestrator's own turn) honor the grant identically.
- Live: two real workflows on a deployed host, end-to-end grant → attach → write → read-back cycle.
- Concurrency/locking — explicitly deferred, not an acceptance item for this ticket.
Auto-synced from docs/ on main. Edit there, not here.