Documentation
¶
Overview ¶
Package filetrack records file changes made by agent tools so sessions can expose a cumulative diff (baseline = file state at first touch in a session). Bulky before/after contents live in a dedicated SQLite database as content-addressed compressed blobs, keeping the main sessions DB slim.
Index ¶
- Constants
- Variables
- func CountAddsDels(oldContent, newContent []byte) (adds, dels int)
- func IsRenderableText(data []byte) bool
- func LineCount(content []byte) int
- type Change
- type ChangeRecord
- type CumulativeChange
- type DiffLine
- type FileDiffContent
- type FileDiffSide
- type FileDiffTextSide
- type FilesystemObservation
- type Hunk
- type Options
- type OutputClaimDiagnostic
- type Recorder
- func (r *Recorder) HasAttributedPath(ctx context.Context, sessionID, path string) bool
- func (r *Recorder) MaxFileBytes() int
- func (r *Recorder) RecordAttributedChange(ctx context.Context, rec ChangeRecord) (*llm.FileChange, error)
- func (r *Recorder) RecordChange(ctx context.Context, rec ChangeRecord) *llm.FileChange
- func (r *Recorder) RecordFileTrackingRunComplete(ctx context.Context, sessionID, runID string) error
- func (r *Recorder) RecordFileTrackingRunStart(ctx context.Context, sessionID, runID string) error
- func (r *Recorder) RecordFilesystemObservation(ctx context.Context, obs FilesystemObservation) (*llm.FilesystemObservationSummary, error)
- func (r *Recorder) RecordRunComplete(ctx context.Context, run RunRecord) error
- func (r *Recorder) RecordRunStart(ctx context.Context, run RunRecord) error
- func (r *Recorder) SessionPaths(ctx context.Context, sessionID string) []string
- type RunRecord
- type SnapshotToken
- type Store
- func (s *Store) Close() error
- func (s *Store) CurrentSnapshotToken(ctx context.Context, sessionID string) string
- func (s *Store) GC(ctx context.Context, sessionsDBPath string, maxAgeDays int) error
- func (s *Store) GetFileDiffContent(ctx context.Context, sessionID, path string) (*FileDiffContent, error)
- func (s *Store) GetFileDiffSide(ctx context.Context, sessionID, path, side string) (*FileDiffSide, error)
- func (s *Store) GetFileDiffTextSide(ctx context.Context, sessionID, path, side string) (*FileDiffTextSide, error)
- func (s *Store) GetRecentRunFileDiffContent(ctx context.Context, sessionID, path string, runs int, snapshotSeq int64) (*FileDiffContent, error)
- func (s *Store) GetRecentRunFileDiffSide(ctx context.Context, sessionID, path, side string, runs int, snapshotSeq int64) (*FileDiffSide, error)
- func (s *Store) GetRecentRunFileDiffTextSide(ctx context.Context, sessionID, path, side string, runs int, snapshotSeq int64) (*FileDiffTextSide, error)
- func (s *Store) HasAttributedPath(ctx context.Context, sessionID, path string) (bool, error)
- func (s *Store) ListRecentRunChanges(ctx context.Context, sessionID string, runs int) ([]CumulativeChange, error)
- func (s *Store) ListRunObservations(ctx context.Context, sessionID string, runIDs []string) ([]FilesystemObservation, error)
- func (s *Store) ListSessionChanges(ctx context.Context, sessionID string) ([]CumulativeChange, error)
- func (s *Store) MaxFileBytes() int
- func (s *Store) RecentRunIDs(ctx context.Context, sessionID string, limit int) ([]string, error)
- func (s *Store) RecordAttributedChange(ctx context.Context, rec ChangeRecord) (*Change, error)
- func (s *Store) RecordChange(ctx context.Context, rec ChangeRecord) (*Change, error)
- func (s *Store) RecordFilesystemObservation(ctx context.Context, obs FilesystemObservation) (*FilesystemObservation, error)
- func (s *Store) RecordRunComplete(ctx context.Context, run RunRecord) error
- func (s *Store) RecordRunStart(ctx context.Context, run RunRecord) error
- func (s *Store) SessionPaths(ctx context.Context, sessionID string) ([]string, error)
Constants ¶
const ( ObservationUnclaimed = "unclaimed_transition" ObservationMaterialized = "materialized_output" ObservationUnconfirmedClaim = "unconfirmed_claim" ObservationClaimMismatch = "claim_mismatch" ObservationClaimConflict = "claim_conflict" ObservationIncomplete = "observation_incomplete" )
const ( DefaultMaxFileBytes = config.DefaultFileTrackingMaxFileBytes // per-file content cap DefaultMaxSessionBytes = config.DefaultFileTrackingMaxSessionBytes // retained-content budget per session DefaultMaxTotalBytes = config.DefaultFileTrackingMaxTotalBytes // whole-database size cap (across sessions) )
Default caps, overridable via config.
const ( KindCreate = "create" KindModify = "modify" KindDelete = "delete" )
Change kinds.
const ( ProvenanceDirect = "direct" ProvenanceDeclaredTransform = "declared_transform" ProvenanceDeclaredGenerate = "declared_generate" ProvenanceLegacyUnverified = "legacy_unverified" ClaimTransform = "transform" ClaimGenerate = "generate" ClaimMaterialize = "materialize" CoverageComplete = "complete" CoverageTruncated = "truncated" BaselineNormal = "normal" BaselinePreexistingDirty = "preexisting_dirty" BaselineUnknown = "unknown" ContentRetained = "retained" ContentRetainedImage = "retained_image" ContentBinaryUnrenderable = "binary_unrenderable" ContentOversized = "oversized" ContentSessionBudget = "session_budget" ContentStoreBudget = "store_budget" ContentBeforeUnknown = "before_unknown" ContentAfterUnknown = "after_unknown" ContentBothUnknown = "both_unknown" )
Closed attribution and evidence values persisted by the tracker.
Variables ¶
var ErrInvalidDiffSide = errors.New("invalid file diff side")
ErrInvalidDiffSide means the requested side does not exist for the resolved change kind, such as the baseline side of a newly created file.
Functions ¶
func CountAddsDels ¶
CountAddsDels counts added and removed lines between two contents. Empty/nil sides are treated as a missing file (pure create/delete).
func IsRenderableText ¶ added in v0.9.11
IsRenderableText reports whether data is valid UTF-8 text and not a browser-renderable image or other binary content.
Types ¶
type Change ¶
type Change struct {
Seq int64
EventSeq int64
RunID string
Path string
Kind string
ToolName string
ToolCallID string
BeforeHash string // empty when absent/unknown/not retained
AfterHash string
BeforeSize int64
AfterSize int64
Adds int
Dels int
Truncated bool
IsBinary bool
Provenance string
Provenances []string
ClaimKind string
ClaimPattern string
ClaimLiteral bool
ClaimCoverage string
BaselineState string
ContentStatus string
ContentAvailable bool
}
Change is one recorded change row.
type ChangeRecord ¶
type ChangeRecord struct {
SessionID string
RunID string
ToolName string
ToolCallID string
Path string // absolute path
// Provenance is mandatory for new callers of RecordAttributedChange.
Provenance string
ClaimKind string
ClaimPattern string
ClaimLiteral bool
ClaimCoverage string
BaselineState string
Before []byte // content before the change (ignored when BeforeMissing/BeforeUnknown)
After []byte // content after the change (ignored when AfterMissing/AfterUnknown)
BeforeMissing bool // file did not exist before the change
AfterMissing bool // file does not exist after the change (deletion)
BeforeUnknown bool // file existed before but its content was not captured
AfterUnknown bool // file exists after but its content was not captured (e.g. oversized)
// Size hints for unknown-content sides (from stat); ignored when the
// corresponding content is provided.
BeforeSizeHint int64
AfterSizeHint int64
}
ChangeRecord describes one before→after attributed file transition to record.
type CumulativeChange ¶
type CumulativeChange struct {
Path string `json:"path"`
Kind string `json:"kind"`
Adds int `json:"adds"`
Dels int `json:"dels"`
Truncated bool `json:"truncated"`
Seq int64 `json:"seq"` // latest change sequence for this path in the session
SnapshotSeq int64 `json:"snapshot_seq,omitempty"` // compatibility identity for a multi-run window
Provenance string `json:"provenance,omitempty"`
Provenances []string `json:"provenances,omitempty"`
BaselineState string `json:"baseline_state,omitempty"`
ContentStatus string `json:"content_status,omitempty"`
ContentAvailable bool `json:"content_available"`
ClaimCoverage string `json:"claim_coverage,omitempty"`
}
CumulativeChange summarizes a file's net attributed change relative to the selected baseline.
type DiffLine ¶
type DiffLine struct {
T string `json:"t"` // "ctx" | "add" | "del"
S string `json:"s"` // line text without the diff prefix
}
DiffLine is one row of a structured diff hunk.
type FileDiffContent ¶
type FileDiffContent struct {
Path string
Kind string
Before []byte
After []byte
Truncated bool
IsImage bool
ContentStatus string
ContentAvailable bool
Provenance string
BaselineState string
ClaimCoverage string
}
FileDiffContent holds the baseline and current contents for one file.
type FileDiffSide ¶ added in v0.0.333
FileDiffSide contains one retained side of a browser-renderable image diff.
type FileDiffTextSide ¶ added in v0.9.11
FileDiffTextSide contains one retained textual side of a file diff.
type FilesystemObservation ¶ added in v0.9.0
type FilesystemObservation struct {
ID int64 `json:"id"`
SessionID string `json:"-"`
RunID string `json:"-"`
EventSeq int64 `json:"event_seq"`
ToolName string `json:"-"`
ToolCallID string `json:"-"`
Classification string `json:"classification"`
Root string `json:"root,omitempty"`
CreatedCount int `json:"created_count"`
ModifiedCount int `json:"modified_count"`
DeletedCount int `json:"deleted_count"`
SampledPaths []string `json:"sampled_paths,omitempty"`
SamplesTruncated bool `json:"samples_truncated,omitempty"`
CoverageStatus string `json:"coverage_status"`
Details map[string]any `json:"details,omitempty"`
}
type Hunk ¶
type Hunk struct {
OldStart int `json:"old_start"`
NewStart int `json:"new_start"`
Lines []DiffLine `json:"lines"`
}
Hunk is one contiguous block of a structured diff.
func BuildHunks ¶
BuildHunks computes a structured diff between two file contents. Returns nil when the contents are identical.
func BuildHunksWithContext ¶ added in v0.0.407
BuildHunksWithContext computes a structured diff with at least contextLines unchanged lines around each change. The underlying diff library emits three lines of context; larger requests extend and merge those hunks using the original retained contents.
type Options ¶
type Options struct {
MaxFileBytes int // 0 = DefaultMaxFileBytes
MaxSessionBytes int // 0 = DefaultMaxSessionBytes
MaxTotalBytes int64 // 0 = DefaultMaxTotalBytes; whole-database size cap enforced live and by GC
MaxObservationRows int // 0 = 10,000; independent sidecar row cap
MaxObservationSessionRows int // 0 = 1,000; independent per-session sidecar row cap
MaxObservationBytes int64 // 0 = 16 MiB metadata cap
MaxObservationSessionBytes int64 // 0 = 2 MiB per-session metadata cap
MaxObservationAgeDays int // 0 = 30
}
Options configures a Store.
type OutputClaimDiagnostic ¶ added in v0.9.0
type Recorder ¶
type Recorder struct {
// contains filtered or unexported fields
}
Recorder adapts a Store to the tools-facing FileChangeRecorder interface. Recording is best-effort: failures are reported once on stderr and never surface to the calling tool — tracking must not break editing.
func NewRecorder ¶
NewRecorder wraps a store in a Recorder.
func (*Recorder) HasAttributedPath ¶ added in v0.9.0
func (*Recorder) MaxFileBytes ¶
MaxFileBytes returns the per-file content cap.
func (*Recorder) RecordAttributedChange ¶ added in v0.9.0
func (r *Recorder) RecordAttributedChange(ctx context.Context, rec ChangeRecord) (*llm.FileChange, error)
RecordAttributedChange persists one explicitly classified attributed transition.
func (*Recorder) RecordChange ¶
func (r *Recorder) RecordChange(ctx context.Context, rec ChangeRecord) *llm.FileChange
RecordChange is the compatibility adapter for older direct integrations.
func (*Recorder) RecordFileTrackingRunComplete ¶ added in v0.9.0
func (*Recorder) RecordFileTrackingRunStart ¶ added in v0.9.0
func (*Recorder) RecordFilesystemObservation ¶ added in v0.9.0
func (r *Recorder) RecordFilesystemObservation(ctx context.Context, obs FilesystemObservation) (*llm.FilesystemObservationSummary, error)
RecordFilesystemObservation persists metadata in the independent sidecar.
func (*Recorder) RecordRunComplete ¶ added in v0.9.0
func (*Recorder) RecordRunStart ¶ added in v0.9.0
type SnapshotToken ¶ added in v0.9.0
type SnapshotToken struct {
AttributedEventSeq int64 `json:"a"`
ObservationEventSeq int64 `json:"o"`
RunGeneration int64 `json:"r"`
}
func DecodeSnapshotToken ¶ added in v0.9.0
func DecodeSnapshotToken(value string) (SnapshotToken, error)
func (SnapshotToken) Encode ¶ added in v0.9.0
func (t SnapshotToken) Encode() string
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store persists file-change history in a dedicated SQLite database.
func (*Store) CurrentSnapshotToken ¶ added in v0.9.0
func (*Store) GC ¶
GC removes change rows for sessions that no longer exist in the sessions DB (and rows older than maxAgeDays when > 0), then sweeps unreferenced blobs.
func (*Store) GetFileDiffContent ¶
func (s *Store) GetFileDiffContent(ctx context.Context, sessionID, path string) (*FileDiffContent, error)
GetFileDiffContent returns the baseline and current contents for one path in a session, or nil when the path has no net change recorded.
func (*Store) GetFileDiffSide ¶ added in v0.0.333
func (s *Store) GetFileDiffSide(ctx context.Context, sessionID, path, side string) (*FileDiffSide, error)
GetFileDiffSide returns one retained side of an image diff without loading the other side. It returns nil for unknown paths, truncated content, and non-image diffs.
func (*Store) GetFileDiffTextSide ¶ added in v0.9.11
func (s *Store) GetFileDiffTextSide(ctx context.Context, sessionID, path, side string) (*FileDiffTextSide, error)
GetFileDiffTextSide returns one retained UTF-8 text side without loading the other side. It returns nil for unknown, truncated, binary, and image content.
func (*Store) GetRecentRunFileDiffContent ¶ added in v0.0.404
func (s *Store) GetRecentRunFileDiffContent(ctx context.Context, sessionID, path string, runs int, snapshotSeq int64) (*FileDiffContent, error)
GetRecentRunFileDiffContent returns one file diff across the latest runs that recorded file changes. A positive snapshotSeq pins the rolling window.
func (*Store) GetRecentRunFileDiffSide ¶ added in v0.0.404
func (s *Store) GetRecentRunFileDiffSide(ctx context.Context, sessionID, path, side string, runs int, snapshotSeq int64) (*FileDiffSide, error)
GetRecentRunFileDiffSide returns one retained image side across the latest runs that recorded file changes. A positive snapshotSeq pins the window.
func (*Store) GetRecentRunFileDiffTextSide ¶ added in v0.9.11
func (s *Store) GetRecentRunFileDiffTextSide(ctx context.Context, sessionID, path, side string, runs int, snapshotSeq int64) (*FileDiffTextSide, error)
GetRecentRunFileDiffTextSide returns one retained UTF-8 text side across the latest runs that recorded file changes. A positive snapshotSeq pins the window.
func (*Store) HasAttributedPath ¶ added in v0.9.0
func (*Store) ListRecentRunChanges ¶ added in v0.0.404
func (s *Store) ListRecentRunChanges(ctx context.Context, sessionID string, runs int) ([]CumulativeChange, error)
ListRecentRunChanges returns the cumulative changes across the latest file tracking runs, including an in-progress run. Rows without run identities are excluded.
func (*Store) ListRunObservations ¶ added in v0.9.0
func (*Store) ListSessionChanges ¶
func (s *Store) ListSessionChanges(ctx context.Context, sessionID string) ([]CumulativeChange, error)
ListSessionChanges returns the cumulative per-file changes for a session, sorted by path. Net no-ops are omitted.
func (*Store) MaxFileBytes ¶
MaxFileBytes returns the per-file content cap.
func (*Store) RecentRunIDs ¶ added in v0.9.0
func (*Store) RecordAttributedChange ¶ added in v0.9.0
RecordAttributedChange records a classified, witnessed/claim-verified file transition. Missing or incompatible attribution metadata is rejected.
func (*Store) RecordChange ¶
RecordChange is retained for source compatibility with older direct callers. New code must use RecordAttributedChange and provide explicit provenance. The compatibility path never upgrades shell detections: shell rows remain legacy unverified and are excluded from attributed views.
func (*Store) RecordFilesystemObservation ¶ added in v0.9.0
func (s *Store) RecordFilesystemObservation(ctx context.Context, obs FilesystemObservation) (*FilesystemObservation, error)