Skip to content

Commit 5b8b289

Browse files
committed
fix(artifact): bound authoritative publication paging
Unchanged folder exchanges must not pay archive-sized costs merely to compare transport state, and changed exchanges must remain resumable within fixed work budgets as publication history grows. Read the authoritative checkpoint head first, page its publication ledger by a durable keyset cursor, and verify each page against the recorded revision before exposing dependencies.\n\nRemote provider URIs are not local filesystem roots, so exclude recognized S3 sources from folder-overlap protection before path canonicalization.
1 parent ab1daf2 commit 5b8b289

7 files changed

Lines changed: 733 additions & 136 deletions

cmd/agentsview/artifact_sync.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ func artifactSyncForbiddenRoots(appCfg config.Config) []string {
207207
if strings.TrimSpace(root) == "" {
208208
return
209209
}
210+
if isRemoteSourceRoot(root) {
211+
return
212+
}
210213
root = filepath.Clean(root)
211214
if _, ok := seen[root]; ok {
212215
return

cmd/agentsview/artifact_sync_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,12 @@ func TestRunArtifactFolderSyncPassesOnlyDistinctProtectedRoots(t *testing.T) {
6161
appCfg := config.Config{
6262
DataDir: dataDir,
6363
AgentDirs: map[parser.AgentType][]string{
64-
parser.AgentClaude: {providerA, filepath.Join(providerA, ".")},
65-
parser.AgentCodex: {providerB},
64+
parser.AgentClaude: {
65+
providerA,
66+
filepath.Join(providerA, "."),
67+
"s3://archive-bucket/claude",
68+
},
69+
parser.AgentCodex: {providerB, "s3://archive-bucket/codex"},
6670
parser.AgentGemini: {dataDir},
6771
},
6872
}

internal/artifact/transport_folder.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,12 @@ type folderTransport struct {
5656
}
5757

5858
type folderPushCursor struct {
59-
Generation string `json:"generation,omitempty"`
60-
Origin string `json:"origin,omitempty"`
61-
KindIndex int `json:"kind_index,omitempty"`
62-
Offset int `json:"offset,omitempty"`
63-
ManifestIndex int `json:"manifest_index,omitempty"`
64-
SegmentIndex int `json:"segment_index,omitempty"`
59+
Generation string `json:"generation,omitempty"`
60+
Origin string `json:"origin,omitempty"`
61+
KindIndex int `json:"kind_index,omitempty"`
62+
Offset int `json:"offset,omitempty"`
63+
SegmentIndex int `json:"segment_index,omitempty"`
64+
PublicationSessionID string `json:"publication_session_id,omitempty"`
6565
}
6666

6767
// OpenFolderTransport opens or initializes a marked artifact exchange target.
@@ -549,7 +549,6 @@ func validateFolderTransportState(state folderTransportPersistedState) error {
549549
if state.PullSequence < 0 ||
550550
push.KindIndex < 0 ||
551551
push.Offset < 0 ||
552-
push.ManifestIndex < 0 ||
553552
push.SegmentIndex < 0 {
554553
return errors.New("decoding artifact folder continuation state: negative cursor")
555554
}

0 commit comments

Comments
 (0)