Skip to content

Commit f5d92c2

Browse files
Merge pull request #39 from diazMelgarejo/claude/2026-07-30-agentsview-purify-onto-fresh-upstream
2 parents c3f3d02 + 57d1557 commit f5d92c2

146 files changed

Lines changed: 16564 additions & 878 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ jobs:
176176
if: runner.os == 'Linux'
177177
run: |
178178
go test -tags "fts5" ./internal/duckdb -count=1
179-
go test -tags "fts5" -race $(go list ./... | grep -v '/internal/duckdb$') -count=1
179+
go test -tags "fts5" -race $(go list ./... | grep -v '/internal/duckdb$') -count=1 -timeout=20m
180180
env:
181181
CGO_ENABLED: "1"
182182

AGENTS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ Instructions for autonomous coding agents working in this repository.
2222

2323
## Required Git Rules
2424

25-
1. Commit every turn that changes tracked files.
25+
1. Do not commit after every turn; wait for explicit user review and approval
26+
before committing changes.
2627
1. Do not make empty commits. If a turn is read-only or only changes ignored
2728
files, state that no commit was made.
2829
1. Do not amend, squash, or rebase commits unless explicitly requested.

cmd/periscope/activity_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,5 +342,5 @@ func TestActivityReportGolden(t *testing.T) {
342342
})
343343
require.NoError(t, err, "activity report json golden command")
344344

345-
assertGoldenBytes(t, "activity_report_v3.json", []byte(stdout))
345+
assertGoldenBytes(t, "activity_report_v4.json", []byte(stdout))
346346
}

cmd/periscope/archive_write_backend.go

Lines changed: 101 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,11 @@ type archivePushWatchHooks struct {
7474
pgStartupSync func(
7575
context.Context, *syncpkg.Engine, bool,
7676
) (bool, error)
77-
newPGPusher func(*syncpkg.Engine) *pgPusher
78-
newDuckDBPusher func(*syncpkg.Engine) *duckDBPusher
79-
duckDBStartupSync func(
77+
duckDBStartupSync func(
8078
context.Context, *syncpkg.Engine, bool,
8179
) (bool, error)
80+
newPGPusher func(*syncpkg.Engine) *pgPusher
81+
newDuckDBPusher func(*syncpkg.Engine) *duckDBPusher
8282
newUnwatchedPoller func(context.Context, unwatchedPollSyncer) unwatchedRootPoller
8383
}
8484

@@ -138,6 +138,49 @@ func newArchivePushLoop(
138138
return loop, ticker.Stop
139139
}
140140

141+
func archivePushWatchWatcherOptions(
142+
loop *pushLoop, poller unwatchedRootPoller,
143+
) syncpkg.WatcherOptions {
144+
return syncpkg.WatcherOptions{
145+
OnCoverageDegraded: func(roots []string) error {
146+
// Degraded coverage needs both owners: the poller reconciles
147+
// the affected roots authoritatively (including tombstoning
148+
// missed deletions) and the loop re-pushes the refreshed
149+
// archive on its floor.
150+
if err := poller.AddObligation(pollingObligation{
151+
Key: "watcher-fallback", Roots: roots,
152+
}); err != nil {
153+
return err
154+
}
155+
return loop.NotifyCoverageDegraded(roots)
156+
},
157+
OnPollingRequired: func(obligation syncpkg.PollingObligation) error {
158+
return poller.AddObligation(pollingObligation{
159+
Key: obligation.Key,
160+
Roots: obligation.Roots,
161+
Probe: obligation.Probe,
162+
})
163+
},
164+
OnPollingReleased: poller.RemoveObligation,
165+
}
166+
}
167+
168+
func archivePushWatchBatchCallback(
169+
appCfg config.Config,
170+
engine *syncpkg.Engine,
171+
loop *pushLoop,
172+
) syncpkg.WatchCallback {
173+
return func(callbackCtx context.Context, batch syncpkg.WatchBatch) error {
174+
scope := func() watchRecoveryScope {
175+
return probeWatchRecoveryScope(appCfg)
176+
}
177+
if err := syncWatchBatch(callbackCtx, engine, batch, scope); err != nil {
178+
return err
179+
}
180+
return notifyPushForWatchBatch(callbackCtx, loop, batch)
181+
}
182+
}
183+
141184
func completeDuckDBWatchPush(
142185
res duckdbsync.PushResult, reason pushReason,
143186
) error {
@@ -691,6 +734,22 @@ func (b *localArchiveWriteBackend) duckDBPush(
691734
forceFull := cfg.Full || didResync
692735

693736
fmt.Println("Starting DuckDB push...")
737+
return b.duckDBMirrorPush(
738+
ctx, duckCfg, cfg, projects, excludeProjects, forceFull,
739+
)
740+
}
741+
742+
func (b *localArchiveWriteBackend) duckDBMirrorPush(
743+
ctx context.Context,
744+
duckCfg config.DuckDBConfig,
745+
cfg DuckDBPushConfig,
746+
projects []string,
747+
excludeProjects []string,
748+
forceFull bool,
749+
) (duckdbsync.PushResult, error) {
750+
if err := duckdbsync.ValidatePushTarget(duckCfg); err != nil {
751+
return duckdbsync.PushResult{}, err
752+
}
694753
opts := duckdbsync.SyncOptions{
695754
Projects: projects,
696755
ExcludeProjects: excludeProjects,
@@ -712,6 +771,37 @@ func (b *localArchiveWriteBackend) duckDBPush(
712771
return result, nil
713772
}
714773

774+
func (b *localArchiveWriteBackend) newDuckDBPusher(
775+
engine *syncpkg.Engine,
776+
duckCfg config.DuckDBConfig,
777+
cfg DuckDBPushConfig,
778+
projects, exclude []string,
779+
) *duckDBPusher {
780+
pushCfg := cfg
781+
pushCfg.Automatic = true
782+
return &duckDBPusher{
783+
localSync: func(c context.Context) error {
784+
stats := engine.SyncAll(c, nil)
785+
if err := c.Err(); err != nil {
786+
return err
787+
}
788+
if !stats.AuthoritativeDiscoveryComplete() {
789+
return errors.New("local sync discovery incomplete")
790+
}
791+
engine.FlushSignals()
792+
return nil
793+
},
794+
ensurePricing: b.ensureCurrentPricing,
795+
mirrorPush: func(c context.Context, forceFull bool) (
796+
duckdbsync.PushResult, error,
797+
) {
798+
return b.duckDBMirrorPush(
799+
c, duckCfg, pushCfg, projects, exclude, forceFull,
800+
)
801+
},
802+
}
803+
}
804+
715805
func (b *localArchiveWriteBackend) DuckDBPushWatch(
716806
ctx context.Context,
717807
duckCfg config.DuckDBConfig,
@@ -747,20 +837,7 @@ func (b *localArchiveWriteBackend) DuckDBPushWatch(
747837
if b.watchHooks != nil && b.watchHooks.newDuckDBPusher != nil {
748838
pusher = b.watchHooks.newDuckDBPusher(engine)
749839
} else {
750-
pusher = b.newDuckDBPusher(
751-
func(c context.Context) error {
752-
stats := engine.SyncAll(c, nil)
753-
if err := c.Err(); err != nil {
754-
return err
755-
}
756-
if !stats.AuthoritativeDiscoveryComplete() {
757-
return errors.New("local sync discovery incomplete")
758-
}
759-
engine.FlushSignals()
760-
return nil
761-
},
762-
duckCfg, projects, exclude,
763-
)
840+
pusher = b.newDuckDBPusher(engine, duckCfg, cfg, projects, exclude)
764841
}
765842

766843
fmt.Printf(
@@ -769,20 +846,19 @@ func (b *localArchiveWriteBackend) DuckDBPushWatch(
769846
debounce, interval,
770847
)
771848

849+
772850
loop, stopLoop := newArchivePushLoop(
773851
b.watchHooks,
774852
"duckdb watch", debounce, interval,
775853
func(c context.Context, r pushReason) error {
776-
pushCfg := cfg
777-
pushCfg.Automatic = true
778854
if b.watchHooks != nil && b.watchHooks.duckDBPush != nil {
779855
res, err := b.watchHooks.duckDBPush(c, r, false)
780856
if err != nil {
781857
return err
782858
}
783859
return completeDuckDBWatchPush(res, r)
784860
}
785-
return pusher.push(c, r, false, pushCfg)
861+
return pusher.push(c, r, false)
786862
},
787863
)
788864
defer stopLoop()
@@ -792,33 +868,8 @@ func (b *localArchiveWriteBackend) DuckDBPushWatch(
792868

793869
stopWatcher, openDispatch, unwatchedDirs := startArchivePushWatcher(
794870
b.watchHooks, b.appCfg, engine,
795-
func(callbackCtx context.Context, batch syncpkg.WatchBatch) error {
796-
scope := func() watchRecoveryScope {
797-
return probeWatchRecoveryScope(b.appCfg)
798-
}
799-
if err := syncWatchBatch(callbackCtx, engine, batch, scope); err != nil {
800-
return err
801-
}
802-
return notifyPushForWatchBatch(callbackCtx, loop, batch)
803-
},
804-
syncpkg.WatcherOptions{
805-
OnCoverageDegraded: func(roots []string) error {
806-
if err := poller.AddObligation(pollingObligation{
807-
Key: "watcher-fallback", Roots: roots,
808-
}); err != nil {
809-
return err
810-
}
811-
return loop.NotifyCoverageDegraded(roots)
812-
},
813-
OnPollingRequired: func(obligation syncpkg.PollingObligation) error {
814-
return poller.AddObligation(pollingObligation{
815-
Key: obligation.Key,
816-
Roots: obligation.Roots,
817-
Probe: obligation.Probe,
818-
})
819-
},
820-
OnPollingReleased: poller.RemoveObligation,
821-
},
871+
archivePushWatchBatchCallback(b.appCfg, engine, loop),
872+
archivePushWatchWatcherOptions(loop, poller),
822873
)
823874
defer stopWatcher()
824875
if len(unwatchedDirs) > 0 {
@@ -843,8 +894,6 @@ func (b *localArchiveWriteBackend) DuckDBPushWatch(
843894
}
844895
initialErr := startupErr
845896
if initialErr == nil {
846-
pushCfg := cfg
847-
pushCfg.Automatic = true
848897
if b.watchHooks != nil && b.watchHooks.duckDBPush != nil {
849898
res, err := b.watchHooks.duckDBPush(
850899
ctx, reasonStartup, cfg.Full || didResync,
@@ -855,9 +904,7 @@ func (b *localArchiveWriteBackend) DuckDBPushWatch(
855904
initialErr = completeDuckDBWatchPush(res, reasonStartup)
856905
}
857906
} else {
858-
initialErr = pusher.push(
859-
ctx, reasonStartup, cfg.Full || didResync, pushCfg,
860-
)
907+
initialErr = pusher.push(ctx, reasonStartup, cfg.Full || didResync)
861908
}
862909
}
863910
if initialErr != nil {
@@ -994,37 +1041,8 @@ func (b *localArchiveWriteBackend) PGPushWatch(
9941041

9951042
stopWatcher, openDispatch, unwatchedDirs := startArchivePushWatcher(
9961043
b.watchHooks, b.appCfg, engine,
997-
func(callbackCtx context.Context, batch syncpkg.WatchBatch) error {
998-
scope := func() watchRecoveryScope {
999-
return probeWatchRecoveryScope(b.appCfg)
1000-
}
1001-
if err := syncWatchBatch(callbackCtx, engine, batch, scope); err != nil {
1002-
return err
1003-
}
1004-
return notifyPushForWatchBatch(callbackCtx, loop, batch)
1005-
},
1006-
syncpkg.WatcherOptions{
1007-
OnCoverageDegraded: func(roots []string) error {
1008-
// Degraded coverage needs both owners: the poller reconciles
1009-
// the affected roots authoritatively (including tombstoning
1010-
// missed deletions) and the loop re-pushes the refreshed
1011-
// archive on its floor.
1012-
if err := poller.AddObligation(pollingObligation{
1013-
Key: "watcher-fallback", Roots: roots,
1014-
}); err != nil {
1015-
return err
1016-
}
1017-
return loop.NotifyCoverageDegraded(roots)
1018-
},
1019-
OnPollingRequired: func(obligation syncpkg.PollingObligation) error {
1020-
return poller.AddObligation(pollingObligation{
1021-
Key: obligation.Key,
1022-
Roots: obligation.Roots,
1023-
Probe: obligation.Probe,
1024-
})
1025-
},
1026-
OnPollingReleased: poller.RemoveObligation,
1027-
},
1044+
archivePushWatchBatchCallback(b.appCfg, engine, loop),
1045+
archivePushWatchWatcherOptions(loop, poller),
10281046
)
10291047
defer stopWatcher()
10301048
if len(unwatchedDirs) > 0 {

0 commit comments

Comments
 (0)