Documentation
¶
Overview ¶
Package application owns SDD's protocol-neutral runtime, public request and result types, and the infrastructure ports implemented by consumers.
Acquired graph reads ¶
Each application read acquires its source through SnapshotReader when the graph store implements it. Branch selection never calls TargetAcquirer. An empty branch selects the runtime's current authority, independently of DefaultBranch. Show, View and Search preserve their request signatures; ReadAttachmentRequest also carries Branch and BranchFromSession. MCP forwards the session branch for attachment pages. Each page is an independent read.
AcquiredSnapshot.Config is the sole source of effective read configuration. A nonnil value supplies committed language and dependency declarations from the acquired revision. Application copies those settings for the operation; it never mutates the source configuration or the shared ProjectRuntime. SnapshotData.Config is retained document data, not an alternative effective configuration input. Hosts populating both must derive them from one source; application does not interpret SnapshotData.Config as runtime settings.
Nil Config explicitly retains runtime configuration, including local overrides. It never represents a configuration read failure. Revision-backed hosts read their selected tree with ReadProjectConfigFS and return missing or malformed configuration as an acquisition error. Credentials, providers, index configuration and write routing remain runtime composition. Read declarations never grant access: each project and dependency is authorized independently.
Stores lacking SnapshotReader retain unpinned current-authority reads only. Named-branch, exact and causal selections fail rather than silently weakening their guarantees. Acquisition failures never trigger a Current fallback. Search preparation still requires pinned sources for all selected projects.
Application owns acquired resources until their last source-dependent read, joining release failures with operation errors. Returned canonical snapshots are materialized immutable values and need no live lease. Show/workflow dependency graphs are materialized before they escape acquisition. Discovery iterators instead borrow the caller's lease until iteration finishes or stops. SearchTarget must be consumed within PrepareSearch; retain descriptors for jobs, never a target or its iterator. Exact indexing retains its existing publication shortcut and fails when the recorded source cannot be acquired.
Writes retain the existing GraphStore.Apply contract, fresh-read revalidation, retry limit and recovery behavior. The preparation revision remains provenance, not a newly imposed write precondition. Acquired read configuration introduces no new write validations or changes to write-time configuration precedence.
InfoRequest.Branch selects the read authority; an empty branch intentionally selects current authority. MCP forwards the session binding for Info.
AttachmentPage.LocalPath is optional source-provided metadata for clients sharing the adapter filesystem. Filesystem sources return their own checkout path under attachment immutability; the hint does not retain that checkout. MCP forwards it only to local clients and never constructs filesystem paths. Compositions using mcpapp.Options.LocalAttachmentPath must remove that callback and supply paths from their attachment reader instead.
Local composition ¶
FilesystemGraphStore pins graph and attachment bytes in memory and deliberately returns nil Config: language/dependency settings and local overrides continue to come from runtime composition. Its revision covers the graph directory, not committed repository configuration. Named local branches resolve registered worktrees through GitWorktreeAcquirer.ReadFactory without mutation acquisition; the local CLI uses its existing configuration resolver for graph-directory overrides and validates project identity. No local configuration precedence changes. An unscoped FilesystemGraphStore still rejects a nonempty branch. Local exact sources survive while retained by that store instance, not process restart. Durable consumers must provide their own reproducible source access.
SearchRequest.SyncMode is required. Without ApplicationOptions.PrepareSearch, SearchSyncNone skips maintenance, SearchSyncLocal reconciles the selected home snapshot, and SearchSyncAll also reconciles searched dependencies. A supplied PrepareSearch callback owns preparation policy for the complete authorized SearchTarget. Its error-only result never asserts coverage. See the SearchTarget examples for synchronous and external composition.
Semantic search derives coverage from published entry versions after preparation. This hashes the target's eligible entries and attachments even with SearchSyncNone. Retrieval verifies returned candidates against those same snapshots. Legacy adapters without SearchIndexEntryStore retain candidate-only verification without coverage metadata or custom preparation. Text-only search requires a mode but skips preparation and embedding coverage.
ProjectRuntime.DiscoverSearchEntries streams revision-bound requirements; ProjectRuntime.IndexSearchEntry publishes one exact-source version atomically. ProjectRuntime.ReconcileSearchIndex remains a synchronous convenience. Consumers own authorization, durable source retention, scheduling and retries. Reconciliation adds versions; it does not watch for subsequent graph changes.
Consumer adoption ¶
Compose authorized project runtimes through the existing access resolver and register PrepareSearch once. MCP uses the same application. Every selected project needs SnapshotReader and SearchIndexEntryStore for custom preparation. For branch-aware hosts, implement SnapshotReader on the runtime's GraphStore for current, named, exact and causal selections; no read factory belongs in the mutation port. Return immutable Config from the same selected source. Acquire graph and attachment access together; an operation's release must not evict resources used by another lease. Cached graphs may be shared by project/revision, but authorization and operation configuration stay separate. Changes to loader settings require a distinct cache identity. Keep source availability for queued work independently of active leases. Preserve SDD's Coverage and readable Notice in the consumer's search response.
In the mutation finalizer or graph-write/recovery adapter, call AppliedMutation.AffectedEntryIDs. An empty result means no discovery job. Before enqueueing, durably retain a reproducible source and its attachments. This may be the finalized Git revision, rather than AppliedMutation.Revision from an earlier workspace apply. AffectedEntryIDs establishes no such guarantee. The consumer's write/recovery protocol must close any crash gap between commit, finalization and durable scheduling; a best-effort finalizer alone is insufficient.
Queue selected IDs for write-triggered discovery and nil for cold search, periodic reconciliation or configuration changes. Acquire the exact retained source, then call DiscoverSearchEntries for either scope. Persist each cursor atomically with durable enqueueing or the record that published work needs no enqueue. Deduplicate indexing by full SearchEntryVersion, and run IndexSearchEntry with source retention through retries. Queue state never establishes coverage.
Consumers own concurrent document batching behind embed.Embedder. Compose query routing separately and provider deadlines and observation per provider call. embed.Batched splits oversized requests; it does not combine callers. Local CLI and MCP indexing share incremental synchronous packing and publish complete entries as batches finish. Chunk preparation retains only active work.
Deploy publication-aware retrieval before asynchronous writers. The derivation schema participates in entry hashes, so prior rows can remain stored while current entries require fresh publication. Embedding configuration changes must change the fingerprint. Existing retention/rebuild tools own old-row cleanup.
Index ¶
- Constants
- Variables
- func AttachmentDirRelPath(entryID string) (string, error)
- func MutationBatchDigest(batch MutationBatch) (string, error)
- func OwnerOnly(_ context.Context, request SessionAccessRequest) error
- func ProcedureRegistry() (*engine.Registry, error)
- func SupportedSessionCodecVersion(version uint32) bool
- type Access
- type AccessResolver
- type AcquiredSnapshot
- type AcquiredTarget
- type Application
- func (a *Application) AbandonWorkflowSession(ctx context.Context, identity RequestIdentity, request WorkflowResumeRequest, ...) (WorkflowAbandonResult, error)
- func (a *Application) ApplyPrepared(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (TransitionResult, error)
- func (a *Application) CollectSessions(ctx context.Context, cmd CollectSessionsCmd) (CollectSessionsResult, error)
- func (a *Application) CreateEntry(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (CreateEntryResult, error)
- func (a *Application) CurrentSnapshot(ctx context.Context, identity RequestIdentity, project ProjectID) (*Snapshot, error)
- func (a *Application) FinishWIP(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (MutationResult, error)
- func (a *Application) Info(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (InfoResult, error)
- func (a *Application) Lint(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (result *types.LintResult, err error)
- func (a *Application) ListRecoveries(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (RecoveryList, error)
- func (a *Application) ListWorkflowSessions(ctx context.Context, identity RequestIdentity, project ProjectID) ([]WorkflowSessionSummary, error)
- func (a *Application) LoadWorkflow(ctx context.Context, identity RequestIdentity, request WorkflowResumeRequest) (*WorkflowSession, error)
- func (a *Application) OpenStagedBlob(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (io.ReadCloser, error)
- func (a *Application) OpenWorkflow(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (*WorkflowSession, *WorkflowServe, error)
- func (a *Application) Procedures(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (ProcedureListResult, error)
- func (a *Application) Projects(ctx context.Context, identity RequestIdentity) (ProjectList, error)
- func (a *Application) ReadAttachment(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (result ReadAttachmentResult, err error)
- func (a *Application) ReconcileMutation(ctx context.Context, identity RequestIdentity, ...) (result RecoveryResult, err error)
- func (a *Application) RecoverMutation(ctx context.Context, identity RequestIdentity, request RecoveryRequest) (result RecoveryResult, err error)
- func (a *Application) ReplaceSummary(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (MutationResult, error)
- func (a *Application) ResumeWorkflow(ctx context.Context, identity RequestIdentity, request WorkflowResumeRequest) (*WorkflowSession, WorkflowResumeResult, error)
- func (a *Application) Search(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (result SearchResult, err error)
- func (a *Application) Show(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (result ShowResult, err error)
- func (a *Application) StageBlob(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (StagedBlob, error)
- func (a *Application) StartWIP(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (string, MutationResult, error)
- func (a *Application) View(ctx context.Context, identity RequestIdentity, project ProjectID, ...) (result ViewResult, err error)
- func (a *Application) Vocabulary(ctx context.Context, identity RequestIdentity, project ProjectID) (string, error)
- func (a *Application) WritingGuideCheck(ctx context.Context, identity RequestIdentity, project ProjectID, ...) ([]GuideFinding, error)
- type ApplicationError
- type ApplicationOptions
- type AppliedMutation
- type ApplyResult
- type ApplyState
- type Attachment
- type AttachmentMaterialization
- type AttachmentPage
- type AttachmentPageReader
- type Author
- type BlobDigest
- type BranchValidator
- type BranchValidatorFunc
- type CanonicalChunk
- type ChooserKind
- type Clock
- type ClockFunc
- type CollectSessionsCmd
- type CollectSessionsResult
- type CreateEntryResult
- type DiscoverSearchEntriesQuery
- type DocumentChange
- type DocumentIssue
- type EntryDocument
- type EntryDraft
- type EntryRef
- type ErrorCode
- type FactIndex
- type FactIndexRow
- type FinalizerOutcome
- type Finding
- type FixedTargetAcquirer
- type GraphStore
- type GuideFinding
- type IndexNamespace
- type IndexSearchEntryCmd
- type IndexedChunk
- type InfoRequest
- type InfoResult
- type MutationBatch
- type MutationFinalizer
- type MutationResult
- type MutationTarget
- type PreparedTransition
- type Principal
- type ProcedureListRequest
- type ProcedureListResult
- type ProjectAction
- type ProjectConfig
- type ProjectConfigDocument
- type ProjectID
- type ProjectList
- type ProjectRef
- type ProjectRuntime
- func (r *ProjectRuntime) DiscoverSearchEntries(ctx context.Context, q DiscoverSearchEntriesQuery) iter.Seq2[SearchEntryRequirement, error]
- func (r *ProjectRuntime) IndexSearchEntry(ctx context.Context, cmd IndexSearchEntryCmd) (err error)
- func (r *ProjectRuntime) Project() ProjectRef
- func (r *ProjectRuntime) ReconcileSearchIndex(ctx context.Context, cmd ReconcileSearchIndexCmd) (err error)
- type ProjectRuntimeOptions
- type ProjectState
- type ProjectSummary
- type ReadAttachmentRequest
- type ReadAttachmentResult
- type ReconcileSearchIndexCmd
- type RecoveryAccessRequest
- type RecoveryAuthorizer
- type RecoveryAuthorizerFunc
- type RecoveryItem
- type RecoveryList
- type RecoveryReason
- type RecoveryReconcileRequest
- type RecoveryRequest
- type RecoveryResult
- type RecoveryState
- type RecoveryVerb
- type RegistryFunction
- type RequestIdentity
- type ScoredChunkHit
- type SearchCoverage
- type SearchDiscoveryCursor
- type SearchEntryDescriptor
- type SearchEntryRequirement
- type SearchEntryVersion
- type SearchIndexEntryManifest
- type SearchIndexEntryStore
- type SearchIndexStore
- type SearchIndexStoreFuncs
- func (f SearchIndexStoreFuncs) Manifest(ctx context.Context, namespace IndexNamespace) ([]StoredChunkRef, error)
- func (f SearchIndexStoreFuncs) Nearest(ctx context.Context, namespaces []IndexNamespace, vector []float32, limit int) ([]ScoredChunkHit, error)
- func (f SearchIndexStoreFuncs) Reconcile(ctx context.Context, namespace IndexNamespace, revision string, ...) error
- type SearchRequest
- type SearchResult
- type SearchSyncMode
- type SearchTarget
- type SearchTargetProject
- type SessionAccessRequest
- type SessionAppend
- type SessionBinding
- type SessionEnd
- type SessionEndAct
- type SessionFilter
- type SessionID
- type SessionMetadata
- type SessionPage
- type SessionRef
- type SessionStore
- type ShowRequest
- type ShowResult
- type Snapshot
- type SnapshotData
- type SnapshotReadQuery
- type SnapshotReader
- type StagedBlob
- type StagedBlobReader
- type StagedBlobStore
- type StagedSessionPage
- type StoredChunkRef
- type StoredEntryRef
- type StoredEvent
- type StoredSession
- type TargetAcquirer
- type TargetAcquirerFunc
- type TransitionResult
- type ValidationError
- type ViewRequest
- type ViewResult
- type WIPDocument
- type WorkflowAbandonResult
- type WorkflowAdvanceRequest
- type WorkflowChooser
- type WorkflowChooserOption
- type WorkflowInstanceSummary
- type WorkflowOpenRequest
- type WorkflowParkResult
- type WorkflowResumeRequest
- type WorkflowResumeResult
- type WorkflowServe
- type WorkflowSession
- func (w *WorkflowSession) Abandon(ctx context.Context, identity RequestIdentity, instance, reason string) (WorkflowAbandonResult, error)
- func (w *WorkflowSession) Advance(ctx context.Context, identity RequestIdentity, request WorkflowAdvanceRequest) (*WorkflowServe, error)
- func (w *WorkflowSession) BindBranch(ctx context.Context, identity RequestIdentity, branch string, clear bool) error
- func (w *WorkflowSession) Binding() SessionBinding
- func (w *WorkflowSession) Branch() string
- func (w *WorkflowSession) EditStagedAttachment(ctx context.Context, identity RequestIdentity, handle string, ...) error
- func (w *WorkflowSession) Finished() bool
- func (w *WorkflowSession) Framing(ctx context.Context, identity RequestIdentity) ([]string, error)
- func (w *WorkflowSession) ID() SessionID
- func (w *WorkflowSession) IsShell(instance string) bool
- func (w *WorkflowSession) LogRead(ctx context.Context, identity RequestIdentity, tool string, ...) error
- func (w *WorkflowSession) OpenInstances() []WorkflowInstanceSummary
- func (w *WorkflowSession) Park(ctx context.Context, identity RequestIdentity, instance, note string) (WorkflowParkResult, error)
- func (w *WorkflowSession) Project() ProjectID
- func (w *WorkflowSession) ReadScope(ctx context.Context, identity RequestIdentity, project ProjectID) (ProjectID, string, bool, error)
- func (w *WorkflowSession) ReadStagedAttachment(ctx context.Context, identity RequestIdentity, handle string, offset int64, ...) (AttachmentPage, []string, error)
- func (w *WorkflowSession) RecordServed(ctx context.Context, identity RequestIdentity, hashes []string) error
- func (w *WorkflowSession) Reorient(ctx context.Context, identity RequestIdentity) error
- func (w *WorkflowSession) ServeAll(ctx context.Context, identity RequestIdentity) (WorkflowResumeResult, error)
- func (w *WorkflowSession) ServeShell(ctx context.Context, identity RequestIdentity) (*WorkflowServe, error)
- func (w *WorkflowSession) ServedBefore(hash string) bool
- func (w *WorkflowSession) StageAttachment(ctx context.Context, identity RequestIdentity, filename string, content []byte) (string, error)
- func (w *WorkflowSession) StagedHandles() []string
- func (w *WorkflowSession) Start(ctx context.Context, identity RequestIdentity, request WorkflowStartRequest) (*WorkflowServe, error)
- type WorkflowSessionSummary
- type WorkflowStartRequest
Examples ¶
Constants ¶
const ( DefaultShowUpDepth = query.DefaultUpDepth DefaultShowDownDepth = query.DefaultDownDepth )
Default show expansion depths favor grounding context while keeping the typically wider consumer side shallow.
const ( SearchSyncNone = query.SearchSyncNone SearchSyncLocal = query.SearchSyncLocal SearchSyncAll = query.SearchSyncAll )
const ( LegacyPreparedTransitionVersion uint32 = 1 PreparedTransitionVersion uint32 = 2 )
const ( WorkflowEventCode = "workflow_event" BranchBoundEventCode = "branchBound" BranchClearedEventCode = "branchCleared" DefaultShellCanonical = "user-dialogue" WorkflowMaxLabelLength = 120 ExecutionForkPreferred = "fork-preferred" )
const FirstSessionCodecVersion uint32 = 1
FirstSessionCodecVersion is the oldest persisted session codec this binary still reads.
const NewSessionNote = "" /* 219-byte string literal not displayed */
NewSessionNote is the single statement of the way on from a dialogue that has ended: concluding is terminal, so continuing means a new session under a new handle rather than a revival of the spent one (d-tac-k4q). It is composed into the conclude serve and into every refusal an ended session answers with, so each surface names the same one path that works.
const SessionCodecVersion uint32 = 1
const SessionRecencyWindow = 15 * time.Minute
SessionRecencyWindow is the single threshold separating an active session from an idle one in listings — a hint derived from the last-activity stamp, never a gate. Erring long is cheap, so it is generous.
Variables ¶
var ErrNotAnSDDProject = errors.New("sdd: no .sdd/config.yaml in the tree")
ErrNotAnSDDProject reports a tree without a committed .sdd/config.yaml.
var ErrSessionNotFound = errors.New("sdd: session not found")
Functions ¶
func AttachmentDirRelPath ¶
AttachmentDirRelPath returns the graph-relative attachment directory for an entry ID.
func MutationBatchDigest ¶
func MutationBatchDigest(batch MutationBatch) (string, error)
MutationBatchDigest returns the SDD-owned digest over a storage-neutral batch. The Digest field itself is excluded.
func OwnerOnly ¶
func OwnerOnly(_ context.Context, request SessionAccessRequest) error
OwnerOnly is the shipped continuation policy: only the principal who opened a session may continue it. Compositions that share sessions replace it.
func ProcedureRegistry ¶
ProcedureRegistry returns the engine registration procedure specs load and size against — the same bounds the runtime serves with (d-tac-rzi). Composition helper for the transitional CLI write path and `sdd lint`; the application's own flows wire it internally.
func SupportedSessionCodecVersion ¶
SupportedSessionCodecVersion reports whether a persisted codec version is one this binary can read. Read-compatibility with every shape sdd has written is permanent (d-cpt-i2x), so the whole range through the current version is accepted and superseded shapes are converted at decode; only a version this binary predates is a migration error.
Types ¶
type AccessResolver ¶
type AccessResolver interface {
ResolvePrincipal(context.Context, RequestIdentity) (Principal, error)
// ResolveParticipant names the graph participant the principal appears as
// in the project — the name framing, authorship, and WIP markers carry. It
// is asked once the project is known, because a person may appear under a
// different name per project (s-cpt-ny6).
ResolveParticipant(context.Context, Principal, ProjectID) (string, error)
ListProjects(context.Context, Principal) (ProjectList, error)
ResolveProject(context.Context, Principal, ProjectID, Access) (*ProjectRuntime, error)
// ResolveDependency maps one dependency the project declares — a repo ID
// from its committed configuration — to the runtime of the project that
// carries it, or refuses. The declared string and the resolved project's
// ID coincide only in the local composition. The application asks per
// declared dependency, on every view over the horizon and on every
// dependency-closure walk; a composition whose answer is costly caches it
// itself, since only it knows when a mapping goes stale.
ResolveDependency(context.Context, Principal, ProjectID, string) (*ProjectRuntime, error)
// AuthorizeSession answers whether the actor may continue the session.
// Membership in the session's home project is asked separately, so a
// shared session never admits anyone into a project they cannot read.
AuthorizeSession(context.Context, SessionAccessRequest) error
}
AccessResolver is the single identity, project-access, session-continuation, and dependency authorization boundary. Implementations must resolve current authorization from ctx on every call; previously returned principals and runtimes are not proof of current access. Every call arrives inside a request: the application never calls the resolver from a connection lifecycle.
type AcquiredSnapshot ¶
type AcquiredSnapshot struct {
Snapshot *Snapshot
Attachments AttachmentPageReader
// Config is immutable committed configuration from this source revision.
// Nil explicitly uses runtime configuration; configuration read failures
// must be returned by the adapter, never converted to nil.
Config *ProjectConfig
Release func() error
}
AcquiredSnapshot reuses the canonical snapshot and attachment paging types. Attachments must remain fixed at Snapshot.Revision until Release. Release is mandatory; the acquirer may share retained objects across many leases.
Example ¶
package main
import (
"context"
"fmt"
"io/fs"
"testing/fstest"
sdd "github.com/networkteam/sdd/pkg/application"
)
type exampleTreeAttachments struct {
tree fs.FS
graphDir string
}
func (r exampleTreeAttachments) ReadAttachmentPage(_ context.Context, entry, name string, offset int64, limit int) (sdd.AttachmentPage, error) {
return sdd.PageAttachment(r.tree, r.graphDir, entry, name, offset, limit)
}
func main() {
// A revision-backed adapter obtains this immutable tree from its storage.
tree := fstest.MapFS{
".sdd/config.yaml": {Data: []byte("repo_id: example\nlanguage: en\n")},
".sdd/graph/2026/01/01-100000-s-tac-aaa.md": {Data: []byte("---\ntype: signal\nkind: fact\nlayer: tactical\nsummary: Source fixture.\n---\n\nSource fixture.")},
".sdd/graph/2026/01/01-100000-s-tac-aaa/note.txt": {Data: []byte("Same revision.")},
}
config, err := sdd.ReadProjectConfigFS(tree)
if err != nil {
panic(err)
}
snapshot, err := sdd.LoadSnapshotFS(context.Background(), "example", "R1", tree, config.GraphDir)
if err != nil {
panic(err)
}
source := &sdd.AcquiredSnapshot{
Snapshot: snapshot, Config: &config, Attachments: exampleTreeAttachments{tree: tree, graphDir: config.GraphDir},
Release: func() error { return nil },
}
page, err := source.Attachments.ReadAttachmentPage(context.Background(), "20260101-100000-s-tac-aaa", "note.txt", 0, 100)
if err != nil {
panic(err)
}
if err := source.Release(); err != nil {
panic(err)
}
fmt.Println(source.Snapshot.Revision(), source.Config.Language, string(page.Content))
}
Output: R1 en Same revision.
type AcquiredTarget ¶
type AcquiredTarget struct {
Target MutationTarget
Graph GraphStore
Finalizers []MutationFinalizer
Release func() error
}
AcquiredTarget contains target-scoped adapters for one short operation. Release is mandatory and is called on every success and failure path.
type Application ¶
type Application struct {
// contains filtered or unexported fields
}
Application resolves current access and dispatches protocol-neutral SDD operations. Every method resolves identity and project afresh; a session-addressed method resolves the session's home project from the session's own record.
func NewApplication ¶
func NewApplication(options ApplicationOptions) (*Application, error)
func (*Application) AbandonWorkflowSession ¶
func (a *Application) AbandonWorkflowSession(ctx context.Context, identity RequestIdentity, request WorkflowResumeRequest, reason string) (WorkflowAbandonResult, error)
AbandonWorkflowSession tears down a session by handle: it replays into a buffering sink (no stamp), abandons the instances, then records the terminal abandon in one final append. A mid-teardown failure returns before that append, so the session stays as it was — honest state, no phantom teardown. Ending a session is a participant act, and holding the handle is what authorizes it (d-cpt-aen).
func (*Application) ApplyPrepared ¶
func (a *Application) ApplyPrepared(ctx context.Context, identity RequestIdentity, project ProjectID, binding SessionBinding, prepared PreparedTransition) (TransitionResult, error)
ApplyPrepared durably records intent before canonical apply and outcome afterward. Unknown apply outcomes retain staged blobs for reconciliation; definitive outcomes release them after all applied finalizers succeed.
func (*Application) CollectSessions ¶
func (a *Application) CollectSessions(ctx context.Context, cmd CollectSessionsCmd) (CollectSessionsResult, error)
CollectSessions removes the sessions that are safe to remove and drains the pending declarations that can never converge. It is an operator act on the composition's stores, without identity or project (d-cpt-yjc); who may trigger it is the composition's to gate.
The pass is lock-free and optimistic. An ended session is never written to again, so two processes starting at once derive the same target set and both simply delete; an already-deleted target is success. The target set is recomputed from scratch every run, so a partially removed session is finished by the next pass and there is nothing to reconcile after an interruption.
What it protects, and the whole of it: it never removes a session that has not ended, one inside its retention window, one an in-flight declaration still claims, or one this binary cannot read — an unreadable log may belong to a newer version, so it is left alone rather than treated as garbage.
One pass walks one page of each store from the cursor; a session the pass keeps does not starve later pages because the cursor moves past it. The two enumerations share the cursor, so Next is the earlier of where they stopped: the later one re-enumerates a few areas next pass, which is idempotent.
func (*Application) CreateEntry ¶
func (a *Application) CreateEntry(ctx context.Context, identity RequestIdentity, project ProjectID, binding SessionBinding, draft EntryDraft) (CreateEntryResult, error)
CreateEntry runs SDD-owned validation and pre-flight, prepares canonical document/blob facts, then enters the durable transition protocol.
func (*Application) CurrentSnapshot ¶
func (a *Application) CurrentSnapshot(ctx context.Context, identity RequestIdentity, project ProjectID) (*Snapshot, error)
CurrentSnapshot resolves current read access and returns the opaque canonical snapshot for protocol adapters that host SDD's engine.
func (*Application) FinishWIP ¶
func (a *Application) FinishWIP(ctx context.Context, identity RequestIdentity, project ProjectID, binding SessionBinding, target MutationTarget, markerID string) (MutationResult, error)
func (*Application) Info ¶
func (a *Application) Info(ctx context.Context, identity RequestIdentity, project ProjectID, request InfoRequest) (InfoResult, error)
func (*Application) Lint ¶
func (a *Application) Lint(ctx context.Context, identity RequestIdentity, project ProjectID, request types.LintQuery) (result *types.LintResult, err error)
Lint runs the categorized lint providers over the project's graph — the composition-root lint query (d-cpt-xc3): shells render the findings by category and derive their exit state from LintResult.Errors alone. Index findings need shell-resolved inputs (IndexLintQuery) and stay a shell concern.
func (*Application) ListRecoveries ¶
func (a *Application) ListRecoveries(ctx context.Context, identity RequestIdentity, project ProjectID, includeClosed bool) (RecoveryList, error)
ListRecoveries is a free read projection. Closed terminal history is included only when requested; actionable states never perform acquisition or replay.
func (*Application) ListWorkflowSessions ¶
func (a *Application) ListWorkflowSessions(ctx context.Context, identity RequestIdentity, project ProjectID) ([]WorkflowSessionSummary, error)
func (*Application) LoadWorkflow ¶
func (a *Application) LoadWorkflow(ctx context.Context, identity RequestIdentity, request WorkflowResumeRequest) (*WorkflowSession, error)
LoadWorkflow loads an existing session by ID: the session's own record names its home project, the composition's continuation policy and current membership in that project gate the load, and an ended session is refused. Possession of the ID is the authorization — no consent, no takeover (d-cpt-aen). Loading stamps which client attached and when, the record staleness is derived from.
func (*Application) OpenStagedBlob ¶
func (a *Application) OpenStagedBlob(ctx context.Context, identity RequestIdentity, project ProjectID, ref SessionRef, blobID string) (io.ReadCloser, error)
OpenStagedBlob resolves read access and session ownership, then streams a staged blob's bytes — the read-side counterpart of StageBlob.
func (*Application) OpenWorkflow ¶
func (a *Application) OpenWorkflow(ctx context.Context, identity RequestIdentity, project ProjectID, request WorkflowOpenRequest) (*WorkflowSession, *WorkflowServe, error)
func (*Application) Procedures ¶
func (a *Application) Procedures(ctx context.Context, identity RequestIdentity, project ProjectID, _ ProcedureListRequest) (ProcedureListResult, error)
func (*Application) Projects ¶
func (a *Application) Projects(ctx context.Context, identity RequestIdentity) (ProjectList, error)
Projects lists the projects the request's principal can reach, with per-project access. It resolves no project: it is the read a shell needs before a project is chosen (d-tac-1z6).
func (*Application) ReadAttachment ¶
func (a *Application) ReadAttachment(ctx context.Context, identity RequestIdentity, project ProjectID, request ReadAttachmentRequest) (result ReadAttachmentResult, err error)
func (*Application) ReconcileMutation ¶
func (a *Application) ReconcileMutation(ctx context.Context, identity RequestIdentity, request RecoveryReconcileRequest) (result RecoveryResult, err error)
ReconcileMutation refreshes one actionable recovery projection without choosing a terminal or graph-affecting verb. It exists for interactive clients that must present actions from current target evidence instead of guessing from a durable projection that may predate reconciliation.
func (*Application) RecoverMutation ¶
func (a *Application) RecoverMutation(ctx context.Context, identity RequestIdentity, request RecoveryRequest) (result RecoveryResult, err error)
RecoverMutation performs exactly one explicitly authorized verb. It always reconciles a freshly acquired concrete target before any graph-affecting or terminal action and never runs from startup, resume, or read surfaces.
func (*Application) ReplaceSummary ¶
func (a *Application) ReplaceSummary(ctx context.Context, identity RequestIdentity, project ProjectID, binding SessionBinding, target MutationTarget, entryID, summary string) (MutationResult, error)
func (*Application) ResumeWorkflow ¶
func (a *Application) ResumeWorkflow(ctx context.Context, identity RequestIdentity, request WorkflowResumeRequest) (*WorkflowSession, WorkflowResumeResult, error)
ResumeWorkflow loads a session and serves its current position: every running instance at its step with the schema to continue it.
func (*Application) Search ¶
func (a *Application) Search(ctx context.Context, identity RequestIdentity, project ProjectID, request SearchRequest) (result SearchResult, err error)
func (*Application) Show ¶
func (a *Application) Show(ctx context.Context, identity RequestIdentity, project ProjectID, request ShowRequest) (result ShowResult, err error)
func (*Application) StageBlob ¶
func (a *Application) StageBlob(ctx context.Context, identity RequestIdentity, project ProjectID, ref SessionRef, filename string, content []byte) (StagedBlob, error)
StageBlob resolves current read access before placing immutable bytes in session-scoped scratch. Canonical write access is checked later at the mutation gate, so read-only principals can still conduct dialogue.
func (*Application) StartWIP ¶
func (a *Application) StartWIP(ctx context.Context, identity RequestIdentity, project ProjectID, binding SessionBinding, target MutationTarget, entryID, description string) (string, MutationResult, error)
func (*Application) View ¶
func (a *Application) View(ctx context.Context, identity RequestIdentity, project ProjectID, request ViewRequest) (result ViewResult, err error)
func (*Application) Vocabulary ¶
func (a *Application) Vocabulary(ctx context.Context, identity RequestIdentity, project ProjectID) (string, error)
func (*Application) WritingGuideCheck ¶
func (a *Application) WritingGuideCheck(ctx context.Context, identity RequestIdentity, project ProjectID, draft EntryDraft) ([]GuideFinding, error)
WritingGuideCheck runs the writing guide against a draft in isolation — the pre-playback half of the capture-guide architecture (d-cpt-20r). The draft's own fields feed the prompt and refs stay unresolved, because the guide's scope is the entry as a stranger reads it. The single exception is the draft's closure edges, described one summary sentence deep: which act an entry performs is not inferable from the body alone, and a guide that cannot see it misreads correct entries (s-tac-fu8). Findings are drafting input for the dialogue, never a gate.
type ApplicationError ¶
type ApplicationError struct {
Code ErrorCode
Message string
Project ProjectRef
Action *ProjectAction
ApplyState ApplyState
Revision string
Version uint32
Cause error
// Ended carries the act that ended the session on an ErrorSessionEnded, so
// the caller can be told who/when/why.
Ended *SessionEnd
}
func (*ApplicationError) Error ¶
func (e *ApplicationError) Error() string
func (*ApplicationError) Unwrap ¶
func (e *ApplicationError) Unwrap() error
type ApplicationOptions ¶
type ApplicationOptions struct {
Access AccessResolver
Sessions SessionStore
StagedBlobs StagedBlobStore
Clock Clock
// PrepareSearch runs once after authorized semantic-search snapshots are
// selected. nil preserves SyncMode preparation. Returning nil claims no
// coverage; SDD reads publication afterwards. Callback failures propagate.
PrepareSearch func(context.Context, SearchTarget) error
}
ApplicationOptions composes the application. Sessions and staged blobs are scaffolding of the composition as a whole, keyed by session ID and namespaced by subject, not of any project (d-cpt-yjc); a nil Clock is the system clock.
type AppliedMutation ¶
type AppliedMutation struct {
Project ProjectID
BatchID string
Revision string
Batch MutationBatch
}
func (AppliedMutation) AffectedEntryIDs ¶
func (m AppliedMutation) AffectedEntryIDs() ([]string, error)
AffectedEntryIDs returns entry selections for post-write discovery, including deleted documents and attachment owners. It does not establish durable source: queue discovery only after the consumer can reacquire its exact finalized revision and attachments. An empty result means no discovery job.
Example ¶
package main
import (
"context"
"fmt"
sdd "github.com/networkteam/sdd/pkg/application"
)
type indexingDiscoveryFinalizer struct {
retainFinalizedSource func(context.Context, sdd.AppliedMutation) (string, error)
enqueueDiscovery func(context.Context, sdd.ProjectID, string, []string) error
}
func (indexingDiscoveryFinalizer) Name() string { return "index-discovery" }
func (f indexingDiscoveryFinalizer) Finalize(ctx context.Context, mutation sdd.AppliedMutation) error {
ids, err := mutation.AffectedEntryIDs()
if err != nil {
return err
}
if len(ids) == 0 {
return nil
}
revision, err := f.retainFinalizedSource(ctx, mutation)
if err != nil {
return err
}
if revision == "" {
return fmt.Errorf("finalized source revision is required")
}
return f.enqueueDiscovery(ctx, mutation.Project, revision, ids)
}
func main() {
mutation := sdd.AppliedMutation{Project: "example", Revision: "workspace-revision", Batch: sdd.MutationBatch{
Attachments: []sdd.AttachmentMaterialization{{LogicalPath: "2026/01/01-100000-s-tac-aaa/evidence.md"}},
}}
// The consumer's durable write/recovery protocol makes these effects
// idempotent and retries a crash between source finalization and enqueueing.
finalizer := indexingDiscoveryFinalizer{
retainFinalizedSource: func(context.Context, sdd.AppliedMutation) (string, error) { return "retained-git-revision", nil },
enqueueDiscovery: func(_ context.Context, project sdd.ProjectID, revision string, ids []string) error {
fmt.Println(project, revision, ids)
return nil
},
}
if err := finalizer.Finalize(context.Background(), mutation); err != nil {
panic(err)
}
}
Output: example retained-git-revision [20260101-100000-s-tac-aaa]
type ApplyResult ¶
type ApplyResult struct {
State ApplyState
Revision string
}
type ApplyState ¶
type ApplyState string
const ( MutationNotApplied ApplyState = "not_applied" MutationApplied ApplyState = "applied" MutationUnknown ApplyState = "unknown" )
type Attachment ¶
type Attachment struct {
Subject string
ClientName string
ClientVersion string
LastActivity time.Time
}
Attachment is the stamp of the client that last attached to the session and when the session was last acted on. It is a record, not a lock: the handle is the capability, integrity comes from CAS on append, and staleness is derived from LastActivity (d-cpt-aen).
type AttachmentMaterialization ¶
type AttachmentMaterialization struct {
BlobID string
Digest BlobDigest
Size int64
SourceName string
LogicalPath string
}
type AttachmentPage ¶
type AttachmentPage struct {
// LocalPath is an optional absolute path supplied by the attachment source
// for clients sharing its filesystem. It does not extend source retention.
LocalPath string
Filename string
Content []byte
Offset int64
NextOffset int64
TotalSize int64
More bool
Digest BlobDigest
}
func PageAttachment ¶
func PageAttachment(fsys fs.FS, graphDir, entryID, filename string, offset int64, maxBytes int) (AttachmentPage, error)
PageAttachment reads one page of an entry's attachment from a graph directory. An empty filename selects the entry's only attachment and fails when there are several. A caller's mistake — bad range, bad name, no attachment to infer — is an ApplicationError with ErrorInvalidArgument; a missing entry directory or file surfaces as the filesystem's fs.ErrNotExist. Paths never leave graphDir: the filename must be a bare name and the resulting path must be valid for fs.FS. Locking and recovery around the read belong to the store that owns the directory.
type AttachmentPageReader ¶
type AttachmentPageReader interface {
ReadAttachmentPage(context.Context, string, string, int64, int) (AttachmentPage, error)
}
AttachmentPageReader reads attachment bytes from one acquired source.
type BlobDigest ¶
type BranchValidator ¶
type BranchValidator interface {
ValidateBranch(context.Context, MutationTarget) error
}
BranchValidator resolves branch authority without opening graph adapters or finalizers. It is the declare-time half of TargetAcquirer: local compositions use the same live checkout rule for both.
type BranchValidatorFunc ¶
type BranchValidatorFunc func(context.Context, MutationTarget) error
BranchValidatorFunc adapts a function to BranchValidator.
func (BranchValidatorFunc) ValidateBranch ¶
func (f BranchValidatorFunc) ValidateBranch(ctx context.Context, target MutationTarget) error
type CanonicalChunk ¶
type CanonicalChunk = types.CanonicalChunk
type ChooserKind ¶
type ChooserKind string
ChooserKind classifies who answers a pending chooser, mirrored from the engine for the served workflow response.
type CollectSessionsCmd ¶
CollectSessionsCmd asks for one reclamation pass over the composition's session store. Retention is how long an ended session is kept; zero means remove as soon as it has ended. Limit bounds the page one pass processes (zero: everything) and After is the cursor a previous pass returned as Next, so the sweep converges over repeated calls instead of loading every session.
type CollectSessionsResult ¶
type CollectSessionsResult struct {
RemovedSessions []SessionID
RemovedStaged []SessionRef
DrainedIntents int
Skipped []SessionID
Next SessionID
}
CollectSessionsResult reports what one pass did. Nothing here is actionable — the pass either removed something or deliberately left it, and the skips say which sessions it could not read so a caller can log them. Next is where the pass stopped: pass it back as After, and stop when it is empty.
type CreateEntryResult ¶
type CreateEntryResult struct {
Project ProjectRef
Binding SessionBinding
EntryID string
Summary string
Findings []Finding
}
type DiscoverSearchEntriesQuery ¶
type DiscoverSearchEntriesQuery struct {
// The caller owns the lease and releases it after consuming the iterator.
Source *AcquiredSnapshot
Cursor SearchDiscoveryCursor
// EntryIDs selects canonical full IDs. Nil means all; nonnil empty is invalid.
EntryIDs []string
}
type DocumentChange ¶
type DocumentChange struct {
LogicalPath string
Document *EntryDocument
CanonicalBytes []byte
Delete bool
}
DocumentChange is storage-neutral. CanonicalBytes are rendered once by SDD; Document is present when the logical artifact has structured entry form.
type DocumentIssue ¶
DocumentIssue names one document a store could not decode: its logical path and the decode error message.
type EntryDocument ¶
type EntryDocument struct {
LogicalPath string
Frontmatter map[string]any
Body string
Attachments []string
}
EntryDocument is the storage-neutral form of an entry. Frontmatter carries the canonical graph schema as structured values; SDD validates and normalizes it before constructing a Snapshot.
type EntryDraft ¶
type EntryDraft struct {
Target MutationTarget
Kind string
Layer string
Intent string
Body string
Refs []EntryRef
Closes []string
Supersedes []string
Participants []string
Confidence string
Topics []string
Index *FactIndex
AttachmentHandles []string
// Canonical and Aliases carry a kind: actor signal's identity; Actor carries
// a kind: role decision's bound actor canonical; Class carries a
// kind: procedure decision's execution role. Mirrors the CLI-side
// NewEntryCmd fields — a value on the wrong kind is a blocking finding at
// the construction boundary.
Canonical string
Aliases []string
Actor string
Class string
// ProcedureSpec carries a kind: procedure decision's workflow declaration
// as one structured document — {params?, state?, steps, framing?} —
// converted strictly at draft-to-entry assembly. Interpretation stays
// with the engine.
ProcedureSpec map[string]any
// FocusActors, FocusWhen, and Involvement carry a kind: focus decision's
// advances list and its focus-level defaults. Mirrors the CLI-side
// NewEntryCmd fields — ignored on other kinds, written onto the entry so
// the model-layer validator sees the required involvement frontmatter.
FocusActors []string
FocusWhen *types.FocusWhen
Involvement []types.Involvement
SkipPreflight bool
}
type ErrorCode ¶
type ErrorCode string
const ( ErrorAuthenticationRequired ErrorCode = "authentication_required" ErrorInvalidArgument ErrorCode = "invalid_argument" ErrorProjectRequired ErrorCode = "project_required" ErrorActionRequired ErrorCode = "action_required" ErrorReadDenied ErrorCode = "read_denied" ErrorWriteDenied ErrorCode = "write_denied" ErrorSessionOwnership ErrorCode = "session_ownership_mismatch" ErrorSessionConflict ErrorCode = "session_conflict" ErrorSessionEnded ErrorCode = "session_ended" ErrorGraphConflict ErrorCode = "graph_conflict" ErrorMigrationRequired ErrorCode = "migration_required" ErrorRecoveryRequired ErrorCode = "recovery_required" )
type FactIndexRow ¶
FactIndexRow is the application-boundary shape of an indexed fact: plain, serializable strings only. Topic carries the canonical slash-joined form (e.g. "cli/view"). ID and Title match the template keys the user-dialogue procedure renders from the factIndex inject result.
type FinalizerOutcome ¶
type FixedTargetAcquirer ¶
type FixedTargetAcquirer struct {
Target MutationTarget
Graph GraphStore
Finalizers []MutationFinalizer
}
FixedTargetAcquirer is a small composition adapter for stores whose one configured runtime already represents a concrete target. It exact-matches the target and never interprets cwd.
func (FixedTargetAcquirer) Acquire ¶
func (a FixedTargetAcquirer) Acquire(_ context.Context, target MutationTarget) (*AcquiredTarget, error)
type GraphStore ¶
type GraphStore interface {
Current(context.Context) (*Snapshot, error)
Apply(context.Context, string, MutationBatch, StagedBlobReader) (ApplyResult, error)
Reconcile(context.Context, string, string) (ApplyResult, error)
ReadAttachmentPage(context.Context, string, string, int64, int) (AttachmentPage, error)
}
GraphStore is the canonical graph authority: snapshot reads, atomic mutation, reconciliation, and canonical attachment bytes.
type GuideFinding ¶
type GuideFinding struct {
Reasoning string
Axis string
Quote string
Repair string
Severity string
}
GuideFinding mirrors query.GuideFinding at the API boundary.
type IndexNamespace ¶
type IndexNamespace = types.IndexNamespace
type IndexSearchEntryCmd ¶
type IndexSearchEntryCmd = command.IndexSearchEntryCmd
type IndexedChunk ¶
type IndexedChunk = types.IndexedChunk
type InfoRequest ¶
InfoRequest selects current read authority when Branch is empty. A selected branch that cannot be acquired returns an error.
type InfoResult ¶
type InfoResult struct {
Project ProjectRef
Participant string
Language string
Search string
Recovery string
}
type MutationBatch ¶
type MutationBatch struct {
ID string
Digest string
Changes []DocumentChange
Attachments []AttachmentMaterialization
Message string
Author Author
}
type MutationFinalizer ¶
type MutationFinalizer interface {
Name() string
Finalize(context.Context, AppliedMutation) error
}
MutationFinalizer is a named, idempotent post-apply effect. It cannot redefine or roll back the canonical MutationBatch.
type MutationResult ¶
type MutationResult struct {
Project ProjectRef
Binding SessionBinding
}
type MutationTarget ¶
MutationTarget is the immutable canonical authority for one graph mutation. Project identifies the project; Branch names its logical write authority. Adapters resolve that authority to their storage.
func (MutationTarget) Validate ¶
func (t MutationTarget) Validate(project ProjectID) error
type PreparedTransition ¶
type PreparedTransition struct {
Version uint32
Target MutationTarget
// ExpectedGraphRevision is prepare-time provenance only. The apply CAS
// operand is the freshly revalidated revision (see applyOnAcquired), so a
// concurrent unrelated append merges cleanly instead of failing the pin.
ExpectedGraphRevision string
Batch MutationBatch
// Staged keeps its persisted name so an in-flight intent stays replayable
// across an upgrade.
Staged SessionRef `json:"BlobOwner"`
BlobIDs []string
}
PreparedTransition is the storage-neutral write-gate output. It contains only pinned v1 facts; adapters never reconstruct application intent.
type Principal ¶
type Principal struct {
Subject string
}
Principal is the stable identity resolved from a current request. It is binding and audit data, never cached authorization. The participant the subject appears as is resolved separately, per project (s-cpt-ny6).
type ProcedureListRequest ¶
type ProcedureListRequest struct{}
type ProcedureListResult ¶
type ProcedureListResult struct {
Project ProjectRef
Procedures string
}
type ProjectAction ¶
type ProjectAction struct {
ID string
DisplayName string
State ProjectState
ActionURL string
Reason string
}
type ProjectConfig ¶
type ProjectConfig struct {
RepoID string
Dependencies []string
DefaultBranch string
Language string
// GraphDir is repository-relative, .sdd/graph when the file leaves it unset.
GraphDir string
}
ProjectConfig is the committed .sdd/config.yaml as a composition reads it: the identity, horizon, and layout facts every checkout shares, never the machine-local overlay.
func ReadProjectConfigFS ¶
func ReadProjectConfigFS(fsys fs.FS) (ProjectConfig, error)
ReadProjectConfigFS reads the committed configuration from a repository root. It shares the parser with the CLI's own config resolution, so both read one schema; a composition that also needs the local overlay or the tool settings is holding a checkout of its own and uses the CLI.
type ProjectConfigDocument ¶
type ProjectList ¶
type ProjectList struct {
Actions []ProjectAction
Projects []ProjectSummary
}
type ProjectRef ¶
ProjectRef is the only project identity exposed in project-scoped results.
type ProjectRuntime ¶
type ProjectRuntime struct {
// contains filtered or unexported fields
}
ProjectRuntime owns the immutable ports and project configuration resolved for one application operation.
func NewProjectRuntime ¶
func NewProjectRuntime(options ProjectRuntimeOptions) (*ProjectRuntime, error)
func (*ProjectRuntime) DiscoverSearchEntries ¶
func (r *ProjectRuntime) DiscoverSearchEntries(ctx context.Context, q DiscoverSearchEntriesQuery) iter.Seq2[SearchEntryRequirement, error]
DiscoverSearchEntries hashes at most the current entry and never prepares chunks. Stop iteration to stop I/O. A returned error ends the sequence. Save each cursor atomically with enqueueing its missing descriptor. Cursors bind revision, index namespace and the canonical selected ID set. Reordered or duplicated IDs preserve scope; nil differs from every explicit selection. Malformed IDs fail; valid absent or ineligible IDs yield no requirement. Missing attachment bytes and other source/read failures remain errors.
func (*ProjectRuntime) IndexSearchEntry ¶
func (r *ProjectRuntime) IndexSearchEntry(ctx context.Context, cmd IndexSearchEntryCmd) (err error)
IndexSearchEntry indexes exact retained source, never the current branch. Hosts authorize calls and retry failures. Already published work requires neither a source lease nor embedding, including after a lost acknowledgement.
func (*ProjectRuntime) Project ¶
func (r *ProjectRuntime) Project() ProjectRef
func (*ProjectRuntime) ReconcileSearchIndex ¶
func (r *ProjectRuntime) ReconcileSearchIndex(ctx context.Context, cmd ReconcileSearchIndexCmd) (err error)
ReconcileSearchIndex maintains the runtime's current graph index. The host authorizes the call; this operation does not resolve a request identity.
type ProjectRuntimeOptions ¶
type ProjectRuntimeOptions struct {
Project ProjectRef
DefaultBranch string
Language string
Dependencies []string
Graph GraphStore
Targets TargetAcquirer
Branches BranchValidator
Recovery RecoveryAuthorizer
// Embedder and LLM are the two model dependencies, each a pkg/llm port
// injected as an instance that arrives already composed — observed,
// bounded, and rate-limited by the host's decorators. Routing, deadlines,
// and recording are the host's composition duty (20260830-234501-d-cpt-q6n,
// 20260902-114838-d-tac-cov); application contributes only the facts it
// alone holds: the Purpose and the prompts, or the texts.
Embedder embed.Embedder
SearchIndex SearchIndexStore
LLM llm.Runner
Finalizers []MutationFinalizer
// ExcludeEmbeddedFromIndex mirrors the CLI's excludeEmbedded semantics for
// the vector index: connected-repo runtimes set it so binary-shipped base
// entries embed once per machine (in the base store) rather than once per
// connected repo. The base runtime leaves it false — its store includes
// embedded entries. The rule is applied identically at index and read time.
ExcludeEmbeddedFromIndex bool
}
type ProjectState ¶
type ProjectState string
ProjectState describes whether a listed project can be used immediately.
const ( ProjectReady ProjectState = "ready" ProjectActionRequired ProjectState = "action_required" )
type ProjectSummary ¶
type ProjectSummary struct {
ProjectRef
SourceID string
CanRead bool
CanWrite bool
State ProjectState
}
type ReadAttachmentRequest ¶
type ReadAttachmentResult ¶
type ReadAttachmentResult struct {
Project ProjectRef
Page AttachmentPage
Available []string
}
type ReconcileSearchIndexCmd ¶
type ReconcileSearchIndexCmd = command.ReconcileSearchIndexCmd
type RecoveryAccessRequest ¶
type RecoveryAccessRequest struct {
Actor Principal
Target MutationTarget
Verb RecoveryVerb
OriginalSubject string
OriginalSession SessionID
}
type RecoveryAuthorizer ¶
type RecoveryAuthorizer interface {
AuthorizeRecovery(context.Context, RecoveryAccessRequest) error
}
type RecoveryAuthorizerFunc ¶
type RecoveryAuthorizerFunc func(context.Context, RecoveryAccessRequest) error
func (RecoveryAuthorizerFunc) AuthorizeRecovery ¶
func (f RecoveryAuthorizerFunc) AuthorizeRecovery(ctx context.Context, request RecoveryAccessRequest) error
type RecoveryItem ¶
type RecoveryItem struct {
Session SessionID
MutationID string
Digest string
Target MutationTarget
OriginalSubject string
State RecoveryState
// Reason qualifies State: what delivery waits on while pending, or which
// decision ended it while abandoned. Empty when delivered.
Reason RecoveryReason
// Recovered records that recovery machinery touched this mutation — a
// reconciliation or a verb. It is provenance, not state: a recovered write is
// delivered exactly like one that never needed help.
Recovered bool
LegacyUnroutable bool
EntryIDs []string
LastEvidence string
// Cause is the terminal's structured cause (e.g. graph-contention for an
// engine-recorded discard), empty for participant decisions and open items.
Cause string
}
func (RecoveryItem) Actionable ¶
func (i RecoveryItem) Actionable() bool
Actionable reports whether this item awaits a recovery decision. It is derived from State rather than stored beside it, so the two cannot disagree.
type RecoveryList ¶
type RecoveryList struct {
Project ProjectRef
Items []RecoveryItem
}
type RecoveryReason ¶
type RecoveryReason string
RecoveryReason qualifies a state that does not explain itself: what delivery is waiting on, or which decision ended it.
const ( RecoveryReasonOutcomeUnknown RecoveryReason = "outcome-unknown" RecoveryReasonNotApplied RecoveryReason = "not-applied" RecoveryReasonFinalizationOwed RecoveryReason = "finalization-owed" RecoveryReasonDiscarded RecoveryReason = "discarded" RecoveryReasonAbandonedUnknown RecoveryReason = "abandoned-unknown" )
type RecoveryRequest ¶
type RecoveryRequest struct {
Session SessionID
MutationID string
Verb RecoveryVerb
Reason string
Target MutationTarget
}
type RecoveryResult ¶
type RecoveryResult struct {
Project ProjectRef
Item RecoveryItem
Transition TransitionResult
}
type RecoveryState ¶
type RecoveryState string
const ( // RecoveryDelivered means the write reached its desired state: the batch // applied and finalization is proven. Nothing is owed. RecoveryDelivered RecoveryState = "delivered" // RecoveryPending means delivery is not proven yet. Pending is exactly the // actionable condition, and Reason names what is owed. RecoveryPending RecoveryState = "pending" // RecoveryAbandoned means a participant decided to stop pursuing delivery. // Reason names the decision. RecoveryAbandoned RecoveryState = "abandoned" )
State answers one question — has delivery been reached — so it carries the two durable conditions of the delivery contract plus the one outcome that is a participant's decision rather than a delivery result.
type RecoveryVerb ¶
type RecoveryVerb string
RecoveryVerb is deliberately finer-grained than write access. Runtime compositions authorize each recovery action and the nonterminal reconcile refresh afresh.
const ( RecoveryReconcile RecoveryVerb = "reconcile" RecoveryApply RecoveryVerb = "apply" RecoveryDiscard RecoveryVerb = "discard" RecoveryFinalizeRetry RecoveryVerb = "finalize-retry" RecoveryAbandonUnknown RecoveryVerb = "abandon-unknown" RecoveryBindTarget RecoveryVerb = "bind-target" )
type RegistryFunction ¶
func WorkflowRegistryDocs ¶
func WorkflowRegistryDocs(class string) ([]RegistryFunction, error)
type RequestIdentity ¶
RequestIdentity is current-request authentication material supplied by a transport composition. SDD treats Subject as opaque and does not interpret application-specific roles.
type ScoredChunkHit ¶
type ScoredChunkHit = types.ScoredChunkHit
type SearchCoverage ¶
type SearchCoverage struct {
Project ProjectID `json:"project"`
Revision string `json:"revision"`
Required int `json:"required"`
Published int `json:"published"`
Complete bool `json:"complete"`
}
SearchCoverage reports SDD's post-preparation publication read for one fixed project snapshot. It contains no consumer queue or retry state.
type SearchDiscoveryCursor ¶
type SearchDiscoveryCursor = query.SearchDiscoveryCursor
type SearchEntryDescriptor ¶
type SearchEntryDescriptor = types.SearchEntryDescriptor
type SearchEntryRequirement ¶
type SearchEntryRequirement = query.SearchEntryRequirement
type SearchEntryVersion ¶
type SearchEntryVersion = types.SearchEntryVersion
type SearchIndexEntryManifest ¶
type SearchIndexEntryManifest interface {
IndexedEntries(context.Context, IndexNamespace) ([]StoredEntryRef, error)
}
SearchIndexEntryManifest is an optional capability a persistent store implements so the application can reconcile on entry presence (monotonic accumulation of immutable-entry chunks) instead of chunk-identity comparison. A store that does not implement it falls back to the compatibility reconciliation path in vector search.
type SearchIndexEntryStore ¶
type SearchIndexEntryStore interface {
EntryPublished(context.Context, SearchEntryVersion) (bool, error)
PublishEntry(context.Context, SearchEntryVersion, []IndexedChunk) error
}
SearchIndexEntryStore publishes complete entry versions, including versions with no chunks. Unpublished chunks must be invisible to both EntryPublished and Nearest. Publication is atomic, durable on success, and idempotent under concurrent calls. A returned error may have committed; callers recheck. Implementations validate all identities and vectors before publication.
type SearchIndexStore ¶
type SearchIndexStore interface {
Manifest(context.Context, IndexNamespace) ([]StoredChunkRef, error)
Reconcile(context.Context, IndexNamespace, string, []IndexedChunk, []string) error
Nearest(context.Context, []IndexNamespace, []float32, int) ([]ScoredChunkHit, error)
}
type SearchIndexStoreFuncs ¶
type SearchIndexStoreFuncs struct {
ManifestFunc func(context.Context, IndexNamespace) ([]StoredChunkRef, error)
ReconcileFunc func(context.Context, IndexNamespace, string, []IndexedChunk, []string) error
NearestFunc func(context.Context, []IndexNamespace, []float32, int) ([]ScoredChunkHit, error)
}
SearchIndexStoreFuncs adapts an index implementation while SDD retains chunking, embedding input, reconciliation decisions, filtering, and ranking.
func (SearchIndexStoreFuncs) Manifest ¶
func (f SearchIndexStoreFuncs) Manifest(ctx context.Context, namespace IndexNamespace) ([]StoredChunkRef, error)
func (SearchIndexStoreFuncs) Nearest ¶
func (f SearchIndexStoreFuncs) Nearest(ctx context.Context, namespaces []IndexNamespace, vector []float32, limit int) ([]ScoredChunkHit, error)
func (SearchIndexStoreFuncs) Reconcile ¶
func (f SearchIndexStoreFuncs) Reconcile(ctx context.Context, namespace IndexNamespace, revision string, upserts []IndexedChunk, deletes []string) error
type SearchRequest ¶
type SearchRequest struct {
// IncludesRevision asks the source to observe a revision containing this write.
IncludesRevision string
// SyncMode is required, including for text-only requests.
SyncMode SearchSyncMode
Terms []string
Phrase string
Branch string
BranchFromSession bool
Type string
Layer string
Kind string
IncludeSuperseded bool
Limit int
MaxCitations int
Repos []string
AllRepos bool
}
type SearchResult ¶
type SearchResult struct {
Coverage []SearchCoverage
Notice string
Project ProjectRef
Results string
EntryIDs []string
}
type SearchSyncMode ¶
type SearchSyncMode = query.SearchSyncMode
type SearchTarget ¶
type SearchTarget struct {
// contains filtered or unexported fields
}
SearchTarget is the fixed, authorized selection passed to PrepareSearch. Its read capabilities expire when Search returns; retain descriptors, not this value, for durable jobs. Source retention remains the consumer's duty.
Example (ExternalConsumer) ¶
package main
import (
"context"
sdd "github.com/networkteam/sdd/pkg/application"
)
func main() {
// These functions belong to the consumer's durable scheduling protocol.
var enqueue func(context.Context, sdd.SearchEntryDescriptor, sdd.SearchDiscoveryCursor) error
var waitWithinBudget func(context.Context, []sdd.SearchTargetProject) error
options := sdd.ApplicationOptions{
PrepareSearch: func(ctx context.Context, target sdd.SearchTarget) error {
for requirement, err := range target.Entries(ctx) {
if err != nil {
return err
}
if requirement.Published {
continue
}
if err := enqueue(ctx, requirement.Entry, requirement.Cursor); err != nil {
return err
}
}
// Ordinary budget expiry returns nil. Parent cancellation and preparation
// failures return errors. SDD determines coverage after this returns.
return waitWithinBudget(ctx, target.Projects())
},
}
_ = options
}
Output:
Example (Local) ¶
package main
import (
"context"
sdd "github.com/networkteam/sdd/pkg/application"
)
func main() {
// The composition root supplies runtimes for the projects it authorizes.
var runtimes map[sdd.ProjectID]*sdd.ProjectRuntime
options := sdd.ApplicationOptions{
PrepareSearch: func(ctx context.Context, target sdd.SearchTarget) error {
for requirement, err := range target.Entries(ctx) {
if err != nil {
return err
}
if requirement.Published {
continue
}
runtime := runtimes[requirement.Entry.Version.Namespace.Project]
if err := runtime.IndexSearchEntry(ctx, sdd.IndexSearchEntryCmd{Entry: requirement.Entry}); err != nil {
return err
}
}
return nil
},
}
_ = options // Pass to NewApplication with the other required capabilities.
}
Output:
func (SearchTarget) Entries ¶
func (t SearchTarget) Entries(ctx context.Context) iter.Seq2[SearchEntryRequirement, error]
Entries lazily derives required versions, including attachments, and reads published presence. Errors terminate iteration and must be propagated by preparation callbacks. A Published hint may advance after it was yielded; SDD always reads publication again after preparation. Partial iteration does not narrow the target whose coverage SDD will check.
func (SearchTarget) Projects ¶
func (t SearchTarget) Projects() []SearchTargetProject
func (SearchTarget) SyncMode ¶
func (t SearchTarget) SyncMode() SearchSyncMode
type SearchTargetProject ¶
type SessionAccessRequest ¶
type SessionAccessRequest struct {
Actor Principal
Owner Principal
Session SessionID
Project ProjectID
}
SessionAccessRequest carries what a continuation policy needs to answer whether Actor may continue the session Owner opened. The application has just loaded the session; the composition is not asked to load it again. It names no verb: continuing a dialogue is one act (d-cpt-yjc).
type SessionAppend ¶
type SessionAppend struct {
Metadata *SessionMetadata
Events []StoredEvent
}
type SessionBinding ¶
SessionBinding is a loaded session's write token: identity plus the version it last observed. Append CAS on the version is the sole integrity mechanism; possession of the handle is the whole authorization (d-cpt-aen).
type SessionEnd ¶
type SessionEnd struct {
Act SessionEndAct
EndedAt time.Time
Reason string `json:",omitempty"`
}
SessionEnd records the participant act that ended a session, written once and never revised. Reason records the abandon note, so a displaced writer's next call can be told why. Who ended it is the session's own participant; the ending client's stamp is transport and does not enter the durable record.
type SessionEndAct ¶
type SessionEndAct string
SessionEndAct is the closed set of participant acts that end a dialogue.
const ( SessionConcluded SessionEndAct = "concluded" SessionAbandoned SessionEndAct = "abandoned" )
type SessionFilter ¶
type SessionFilter struct {
Subject string
Project ProjectID
EndedBefore *time.Time
After SessionID
Limit int
}
SessionFilter selects the sessions List returns. Subject and Project match metadata; EndedBefore selects sessions whose recorded ending lies before the instant, from metadata alone. After and Limit page the result in session-ID order — IDs are time-prefixed and unique, so ID order is a cursor every store honors; a zero Limit means every match.
func (SessionFilter) Matches ¶
func (f SessionFilter) Matches(m SessionMetadata) bool
Matches reports whether metadata passes the filter's selection — the part a store applies per session, leaving After and Limit to its enumeration.
type SessionMetadata ¶
type SessionMetadata struct {
ID SessionID
Subject string
Project ProjectID
Participant string
Label string
// Branch is the session's explicit branch binding. Empty means unbound;
// compositions without a branch concept leave it empty.
Branch string `json:"branch,omitempty"`
Attachment *Attachment
// Ended is the session's single terminal record. Its presence is what makes
// a session ended; nothing else about a session ends it (d-cpt-rw7).
Ended *SessionEnd `json:",omitempty"`
UpdatedAt time.Time
}
SessionMetadata is structured routing and ownership data. Dialogue events remain opaque to the store. The type itself is the metadata contract: its evolution is the Go type's own, and how a store survives that is the adapter's concern — schema migrations, or format discrimination in its persisted record (d-tac-8js).
func (*SessionMetadata) UnmarshalJSON ¶
func (m *SessionMetadata) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes stored metadata, recovering the terminal record from the attachment history superseded shapes carried it in. Decoding stays lenient about every other field in both directions (d-cpt-i2x).
type SessionPage ¶
type SessionPage struct {
Sessions []StoredSession
Next SessionID
}
SessionPage is one List result. Next is the cursor to continue from, empty once the store is exhausted. A page may hold fewer sessions than Limit, or none, while Next is still set: the store stopped at Limit before the filter admitted enough, so a consumer loops until Next is empty rather than reading exhaustion off the page length.
type SessionRef ¶
SessionRef addresses one session inside a subject's namespace. Staged blobs are scoped to a session, so this is what names their area — there is no owner entity, just the two fields that identify whose scaffolding this is.
func (SessionRef) AtOrBefore ¶
func (r SessionRef) AtOrBefore(cursor SessionRef) bool
AtOrBefore reports whether r lies at or before cursor in enumeration order, which is what a paged StagedSessions skips. A cursor naming only a session covers every subject of that session.
func (SessionRef) Compare ¶
func (r SessionRef) Compare(other SessionRef) int
Compare orders refs by session, then subject — the order StagedSessions enumerates in, so a session-ID cursor from the session store lines up.
type SessionStore ¶
type SessionStore interface {
Create(context.Context, SessionMetadata) (StoredSession, error)
Load(context.Context, SessionID) (StoredSession, error)
List(context.Context, SessionFilter) (SessionPage, error)
Append(context.Context, SessionID, uint64, SessionAppend) (uint64, error)
Delete(context.Context, SessionID) error
}
SessionStore persists structured metadata plus ordered opaque events. Append is the sole mutation primitive and must compare ExpectedVersion atomically.
Compositions must not run mixed engine versions against one session store: metadata carries no version guard (d-tac-8js), so an older engine reading metadata a newer one wrote is undetected there — only a session the newer engine actually advanced fails closed, through StoredEvent.CodecVersion.
List is also the enumeration collection sweeps over, paged by the filter's cursor so a sweep converges over repeated calls instead of loading every session, and Delete is what makes sweeps possible against any implementation rather than only the local one. Delete must be idempotent: removing a session that is already gone is success, since two sweeps may derive the same target set.
type ShowRequest ¶
type ShowResult ¶
type ShowResult struct {
Project ProjectRef
Entries string
FullIDs []string
SummaryIDs []string
}
type Snapshot ¶
type Snapshot struct {
// contains filtered or unexported fields
}
Snapshot is an immutable, validated SDD graph snapshot. Its indexed model remains private; structured and filesystem stores both enter through SnapshotData. The finder is the shared read authority over the snapshot's graph; the private graph field mirrors it so in-package seams (write-side resolution, the engine graph provider) keep reading a *model.Graph directly.
func BuildSnapshot ¶
func BuildSnapshot(_ context.Context, data SnapshotData) (*Snapshot, error)
BuildSnapshot is the single in-memory graph construction path. It adapts the canonical documents into a storage-neutral source and hands them to the shared GraphFinder, which applies the one semantic gate (parse, embedded-base merge, partial-read load issues) and holds the resulting graph. A malformed entry document no longer aborts the build — it surfaces as a load issue on the snapshot's graph (Snapshot.Health). Structural failures stay hard: missing project/revision, a malformed logical path, a WIP document outside wip/, and base-entry assembly.
func LoadSnapshotFS ¶
func LoadSnapshotFS(ctx context.Context, project ProjectID, revision string, fsys fs.FS, graphDir string) (*Snapshot, error)
LoadSnapshotFS parses canonical filesystem documents into SnapshotData and delegates all validation and indexing to BuildSnapshot.
func (*Snapshot) Health ¶
func (s *Snapshot) Health() types.GraphHealth
Health reports the snapshot graph's integrity problems — parse-failed (unreadable) documents and per-entry validation warnings — so external hosts can render graph health without reaching into the private model. A clean graph reports zero of each.
type SnapshotData ¶
type SnapshotData struct {
Project ProjectID
Revision string
// Config retains stored document data only. Effective read configuration
// comes exclusively from AcquiredSnapshot.Config or explicit runtime compatibility.
Config ProjectConfigDocument
Entries []EntryDocument
WIP []WIPDocument
// Unreadable records documents a store could not decode into structured
// form — a file whose YAML frontmatter would not parse, for example. They
// are carried as data rather than aborting the load: BuildSnapshot turns
// each into a graph load issue surfaced through Snapshot.Health, so one
// malformed file no longer makes an entire graph (and every session over
// it) unopenable.
Unreadable []DocumentIssue
}
SnapshotData contains canonical stored document facts, never derived graph indexes, status, or traversal state.
type SnapshotReadQuery ¶
SnapshotReadQuery separates exact job input from causal search freshness. ExactRevision selects precisely that revision. IncludesRevision selects a branch revision containing the write, which may be newer. They are exclusive.
type SnapshotReader ¶
type SnapshotReader interface {
AcquireSnapshot(context.Context, SnapshotReadQuery) (*AcquiredSnapshot, error)
}
SnapshotReader is an optional GraphStore capability for pinned reads. Hosts retain exact revisions independently of lease lifetime for durable jobs. IncludesRevision is a causal guarantee, never lexical revision comparison. Readers must honor Branch or reject it; an empty branch selects their current authority. Target-scoped readers must validate nonempty branch requests.
type StagedBlob ¶
type StagedBlob struct {
ID string
Session SessionRef
Digest BlobDigest
Size int64
Filename string
CreatedAt time.Time
}
type StagedBlobReader ¶
StagedBlobReader limits Apply to the blobs named by its prepared batch.
type StagedBlobStore ¶
type StagedBlobStore interface {
Stage(context.Context, SessionRef, string, io.Reader) (StagedBlob, error)
Stat(context.Context, SessionRef, string) (StagedBlob, error)
Open(context.Context, SessionRef, string) (io.ReadCloser, error)
Retain(context.Context, SessionRef, string, []string) error
Release(context.Context, SessionRef, string) error
StagedSessions(ctx context.Context, after SessionRef, limit int) (StagedSessionPage, error)
DeleteStaged(context.Context, SessionRef) error
}
StagedBlobStore owns immutable session-scoped scratch bytes and the retentions holding them. Nothing here is durable: a staged blob lives as long as its session does, and durability is earned only by a captured entry.
StagedSessions and DeleteStaged put reclamation inside the published contract, so a sweep enumerates staging areas and drops the ones whose session is gone through this interface rather than through local-only code. StagedSessions pages in SessionRef order after the cursor (SessionRef.AtOrBefore), a zero limit meaning every area. DeleteStaged must be idempotent, and removes a session's blobs together with its retentions.
type StagedSessionPage ¶
type StagedSessionPage struct {
Sessions []SessionRef
Next SessionRef
}
StagedSessionPage is one StagedSessions result. Next is the cursor to continue from, empty once the store is exhausted.
type StoredChunkRef ¶
type StoredChunkRef = types.StoredChunkRef
type StoredEntryRef ¶
type StoredEntryRef = types.StoredEntryRef
type StoredEvent ¶
type StoredEvent struct {
CodecVersion uint32
Code string
Payload json.RawMessage
}
type StoredSession ¶
type StoredSession struct {
Metadata SessionMetadata
Version uint64
Events []StoredEvent
}
type TargetAcquirer ¶
type TargetAcquirer interface {
Acquire(context.Context, MutationTarget) (*AcquiredTarget, error)
}
TargetAcquirer resolves a concrete mutation authority to short-lived, target-scoped graph and finalizer adapters. Implementations rediscover the target on every call; checkout paths are not durable intent.
type TargetAcquirerFunc ¶
type TargetAcquirerFunc func(context.Context, MutationTarget) (*AcquiredTarget, error)
TargetAcquirerFunc adapts a function to TargetAcquirer.
func (TargetAcquirerFunc) Acquire ¶
func (f TargetAcquirerFunc) Acquire(ctx context.Context, target MutationTarget) (*AcquiredTarget, error)
type TransitionResult ¶
type TransitionResult struct {
Project ProjectRef
Binding SessionBinding
Apply ApplyResult
Finalizers []FinalizerOutcome
}
type ValidationError ¶
ValidationError reports that model.ValidateEntry rejected a draft at the write gate. It carries the structural warnings so the workflow gate can re-serve them as actionable findings — naming the violated rule and the field — and route the instance back to a step that can fix it, rather than wedging behind an opaque hard error (closes half of s-prc-g0j).
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
type ViewRequest ¶
type ViewRequest struct {
Layout string
Branch string
BranchFromSession bool
Repos []string
AllRepos bool
// Budget bounds the view's scaling parts on the serve path; the zero
// value is unbounded — explicit pulls arrive complete (d-tac-rzi).
Budget types.ViewBudget
// OmitRecovery skips the appended recovery notices — for injected lanes
// whose session already carries them via sessionInfo, so a pending
// recovery is served once, not once per lane.
OmitRecovery bool
}
type ViewResult ¶
type ViewResult struct {
Project ProjectRef
Sections string
// MatchedCount is the total primary units the layout produced across the
// local graph and any queried dependency repos. Zero means the pipeline
// matched nothing — surfaces distinguish an empty result from a failure
// (an agent over MCP cannot tell a blank string from a broken call).
MatchedCount int
// KnownParticipants names the graph's canonical participants, populated
// only when the result was empty and the layout carried a participant
// filter — so an empty participant() view can say what names exist rather
// than leaving an exact-match miss indistinguishable from no data.
KnownParticipants []string
}
type WIPDocument ¶
type WorkflowAbandonResult ¶
type WorkflowAbandonResult struct {
Abandoned bool
Session SessionID
Label string
Discarded []WorkflowInstanceSummary
HeldMarkers []string
Base *WorkflowServe
}
type WorkflowAdvanceRequest ¶
type WorkflowChooser ¶
type WorkflowChooser struct {
Chooser string
Kind ChooserKind
Options []WorkflowChooserOption
}
type WorkflowChooserOption ¶
type WorkflowInstanceSummary ¶
type WorkflowOpenRequest ¶
type WorkflowParkResult ¶
type WorkflowParkResult struct {
Instance string
Procedure string
Step string
Base *WorkflowServe
}
type WorkflowResumeRequest ¶
WorkflowResumeRequest names the session to load by its ID and the client loading it. Possession of the ID within the principal's scope is the whole authorization (d-cpt-aen).
type WorkflowResumeResult ¶
type WorkflowServe ¶
type WorkflowServe struct {
Session SessionID
// Project is the project the served instance targets — the home project
// unless the move was started in a dependency (d-cpt-yjc).
Project ProjectID
Branch string
Instance string
Procedure string
Status string
Step string
Goal string
Instructions string
Missing []string
ReportSchema map[string]any
PendingChooser *WorkflowChooser
Execution string
Produced map[string]any
Diagnostics []string
// InstructionLanes are the unit's rendered lanes in order — what the MCP
// layer dedups independently; Instructions is their join plus diagnostics.
InstructionLanes []types.ServeLane
// Sizes is the engine's per-part byte accounting for this serve, read by
// the serve-budget measurement (d-tac-qwc).
Sizes []types.PartSize
Base *WorkflowServe
// Collected is the instance's already-gathered param and state values,
// projected only onto resume serves so a newly attached or reoriented
// agent sees what this instance holds — the anchor, chosen scope, and
// reported judgments that persist across a handover (d-cpt-0tm). Empty on
// door, next, and base-junction serves, which stay unchanged.
Collected map[string]any
}
func (*WorkflowServe) ComposeInstructions ¶
func (s *WorkflowServe) ComposeInstructions(unitText string) string
ComposeInstructions joins host-recomposed unit text (e.g. the deduped lane subset) with this serve's diagnostics — the engine's one composition rule applied host-side.
func (*WorkflowServe) ReminderInstructions ¶
func (s *WorkflowServe) ReminderInstructions() string
ReminderInstructions composes the short reminder used when a host has already served this instruction unit, while retaining any gate diagnostics. The stub assumes the caller still holds the earlier full text; if a context compaction dropped it, the breadcrumb names the one-shot escape so an amnesiac agent is not left following instructions it no longer has.
type WorkflowSession ¶
type WorkflowSession struct {
// contains filtered or unexported fields
}
WorkflowSession is a protocol-neutral, durable engine session. It stores no authorization proof: every operation receives the current request identity and resolves access again before touching project state.
func (*WorkflowSession) Abandon ¶
func (w *WorkflowSession) Abandon(ctx context.Context, identity RequestIdentity, instance, reason string) (WorkflowAbandonResult, error)
func (*WorkflowSession) Advance ¶
func (w *WorkflowSession) Advance(ctx context.Context, identity RequestIdentity, request WorkflowAdvanceRequest) (*WorkflowServe, error)
func (*WorkflowSession) BindBranch ¶
func (w *WorkflowSession) BindBranch(ctx context.Context, identity RequestIdentity, branch string, clear bool) error
BindBranch changes the durable session-level branch declaration. Setting a binding resolves the branch against the runtime's live branch capability before the CAS append; clearing is store-only and works without that capability.
func (*WorkflowSession) Binding ¶
func (w *WorkflowSession) Binding() SessionBinding
func (*WorkflowSession) Branch ¶
func (w *WorkflowSession) Branch() string
func (*WorkflowSession) EditStagedAttachment ¶
func (w *WorkflowSession) EditStagedAttachment(ctx context.Context, identity RequestIdentity, handle string, pairs []types.PatchPair) error
EditStagedAttachment applies ordered exact search-replace pairs to a staged file addressed by its handle and stages the result under the same handle, so a small correction costs neither a full re-stage nor a full re-read (20260826-120330-d-tac-8f8). Atomic: a failing pair names itself and the staged file stays unchanged.
func (*WorkflowSession) Finished ¶
func (w *WorkflowSession) Finished() bool
Finished reports whether this dialogue is over: the shell has left running, which is the act that wrote the terminal record. A finished session is spent — the door opens a new one rather than re-serving it, and no move may carry it on.
func (*WorkflowSession) Framing ¶
func (w *WorkflowSession) Framing(ctx context.Context, identity RequestIdentity) ([]string, error)
Framing composes the session framing as ordered, independently dedupable blocks: the engine-supplied info block (participant, language, search modes) first, then one block per declared shell lane, rendered through the injection mechanism. Returning the lanes as separate blocks — not one joined string — lets the host dedup each on its own, so a graph write that changes only the recent-moves lane re-serves that lane alone, never the stable aspirations or directives (I6, A1). A shell with no declared lanes yields the info block alone; there is no Go-constant fallback.
func (*WorkflowSession) ID ¶
func (w *WorkflowSession) ID() SessionID
func (*WorkflowSession) IsShell ¶
func (w *WorkflowSession) IsShell(instance string) bool
func (*WorkflowSession) LogRead ¶
func (w *WorkflowSession) LogRead(ctx context.Context, identity RequestIdentity, tool string, full, summary []string) error
func (*WorkflowSession) OpenInstances ¶
func (w *WorkflowSession) OpenInstances() []WorkflowInstanceSummary
func (*WorkflowSession) Park ¶
func (w *WorkflowSession) Park(ctx context.Context, identity RequestIdentity, instance, note string) (WorkflowParkResult, error)
func (*WorkflowSession) Project ¶
func (w *WorkflowSession) Project() ProjectID
func (*WorkflowSession) ReadScope ¶
func (w *WorkflowSession) ReadScope(ctx context.Context, identity RequestIdentity, project ProjectID) (ProjectID, string, bool, error)
ReadScope resolves where a free read runs: the home project on the session's branch binding by default, or another project the session may work in — on that project's configured default, since the binding is a fact about the home checkout alone.
func (*WorkflowSession) ReadStagedAttachment ¶
func (w *WorkflowSession) ReadStagedAttachment(ctx context.Context, identity RequestIdentity, handle string, offset int64, maxBytes int) (AttachmentPage, []string, error)
ReadStagedAttachment returns one bounded page of a staged file by handle, plus the session's staged handles as the discovery surface.
func (*WorkflowSession) RecordServed ¶
func (w *WorkflowSession) RecordServed(ctx context.Context, identity RequestIdentity, hashes []string) error
RecordServed logs the content hashes of blocks just served in full. A finished session records nothing: its last serve is the one that ended it.
func (*WorkflowSession) Reorient ¶
func (w *WorkflowSession) Reorient(ctx context.Context, identity RequestIdentity) error
Reorient records the consumer's request for the session's position and resets the served set, so the position re-serves in full.
func (*WorkflowSession) ServeAll ¶
func (w *WorkflowSession) ServeAll(ctx context.Context, identity RequestIdentity) (WorkflowResumeResult, error)
func (*WorkflowSession) ServeShell ¶
func (w *WorkflowSession) ServeShell(ctx context.Context, identity RequestIdentity) (*WorkflowServe, error)
func (*WorkflowSession) ServedBefore ¶
func (w *WorkflowSession) ServedBefore(hash string) bool
ServedBefore reports whether the session's consumer already holds a block with this content hash, derived from the session ledger (d-cpt-aen).
func (*WorkflowSession) StageAttachment ¶
func (w *WorkflowSession) StageAttachment(ctx context.Context, identity RequestIdentity, filename string, content []byte) (string, error)
func (*WorkflowSession) StagedHandles ¶
func (w *WorkflowSession) StagedHandles() []string
StagedHandles lists the session's staged file handles, sorted.
func (*WorkflowSession) Start ¶
func (w *WorkflowSession) Start(ctx context.Context, identity RequestIdentity, request WorkflowStartRequest) (*WorkflowServe, error)
type WorkflowSessionSummary ¶
type WorkflowSessionSummary struct {
Session SessionID
Label string
Participant string
Branch string
Anchor string
Open []WorkflowInstanceSummary
LastActivity time.Time
Attachment *Attachment
Active bool
}
Source Files
¶
- application.go
- attachment.go
- blobstore.go
- collect.go
- doc.go
- errors.go
- functional_adapters.go
- graphstore.go
- identity.go
- mutation_entries.go
- project_config.go
- read_api.go
- read_snapshot.go
- recovery.go
- revalidation.go
- runtime.go
- search_entries.go
- search_index.go
- search_ports.go
- search_preparation.go
- session_runtime.go
- sessionstore.go
- snapshot.go
- target.go
- transition.go
- vector_search.go
- workflow.go
- workflow_project.go
- workflow_registry.go
- write_api.go
- writingguide_api.go