Skip to content

feat(analyst): implement independent Branch workspaces and local graph changes #1352

Closed

Description

@DecisionNerd

Outcome and scope

Implement this bounded portion of canonical M11 tracker #1347. Documentation integration #1346 is a prerequisite. Source coverage: Core §§3, 6, 14; Semantics §§7–12, 19–23, 31–32.

Requirements and acceptance criteria

Implementation grounding

Existing ownership: graphforge-api workspace lifecycle and graph publication, graphforge-storage authenticated sharing, graphforge-ontology composition reuse.
Use docs/engineering/analyst-ux.md, docs/book/architecture/research-workspaces.md, and the relevant integrated knowledge/storage/ontology/portability docs. Those docs were delivered by merged PR #1368 for #1346; the second-pass refinements in this issue must be reflected in the owning docs alongside implementation. Planned requirements are not implementation evidence.

Rust owns all behavior. Deliver the public facade operation(s) and thin Python, Node, and CLI parity appropriate to this outcome, including explicit request/result/error contracts, relevant schema/capability registration and non-Cypher surface inventory updates. Data-bearing output is Arrow; control/metadata/lifecycle output follows the existing contract.

Prerequisites: #1346, #1350, #1351. Native blocked-by relationships are the scheduling authority. This issue is a native child and blocker of #1347.

Completion scenario

Given a frozen story Branch, when an analyst changes a character, suppresses an inherited edge and adds another story, then only that Branch changes and all inherited/imported identities and origin Versions remain inspectable.

Given cancellation, invalid input or conflicting state, when the operation fails, then it returns an actionable structured error and leaves no partial authoritative mutation; read-only operations never mutate.

Given Branch A at an old retained Version, later parent changes, and an independently advanced Branch B, when restoring A, then only A's selected research state is restored into a new Version; parent state, B and other Branch heads remain unchanged after reopen.

Validation

Project/Slice/Branch/historical creation; parent vs Branch Cypher and analyst results; UUID equality; nested genealogy; expansion vs reference; independent ontology; durable reopen; pre-linearization cancellation/conflict refusal and post-linearization committed-state reconciliation; representative large-parent/small-Branch bounds.
Run targeted Rust/domain tests during development, then the applicable Bazel/CI Gate and native binding checks for the changed surface. Rebuild natives before binding tests. Durable claims require actual reopen/recovery on an admitted filesystem; the overlay-root Cloud environment cannot supply that evidence. Do not use skipped tests, logical plans or wrappers as end-to-end proof.

Diagnostics, security, and docs

Reuse structured errors and bounded receipts with identity, phase, scope and safe cause information. Do not log credentials, source content or personal annotations. Preserve explicit context selection, dependency validation and private/unselected content boundaries. Access-policy metadata is not remote authentication or authorization enforcement.
Update the owning docs and any public contract/inventory in the same PR; distinguish Designed from implemented behavior. Each issue owns its regression coverage before the final integrated journey.

Non-goals

Canonical knowledge status, upstream synchronization, proposal acceptance.
Associated projects such as XYG and graphforge-nextjs, applications and peer extensions own their UX/hosting/access enforcement; none becomes a Core dependency. No unrelated scope or publication-only close gates.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions