Commit Graph

224 Commits

Author SHA1 Message Date
q792602257 de73ad4935 feat(acp): relay skeleton (subscribe/unsubscribe/fanout/close) + supervisor.GetRelay 2026-05-07 12:16:06 +08:00
q792602257 839e5c9e95 feat(acp/handlers): handlers subpackage with shared types + placeholder handlers 2026-05-07 12:16:03 +08:00
q792602257 bd95fd33d6 feat(acp): supervisor skeleton + AcpConfig wiring 2026-05-07 12:12:05 +08:00
q792602257 dee20bb618 feat(acp): ResolveSafePath helper (3-fold check: abs/prefix/symlink) 2026-05-07 12:06:37 +08:00
q792602257 cf314021e7 feat(acp): JSON-RPC 2.0 codec (number/string id, LF-delimited, concurrent-safe encoder) 2026-05-07 12:04:27 +08:00
q792602257 2696a03055 feat(web): register /admin/acp/agent-kinds routes 2026-05-07 12:00:26 +08:00
q792602257 e5a921c26f feat(web): AgentKindEditView (create + edit) 2026-05-07 12:00:23 +08:00
q792602257 996c3c8c9b feat(web): AgentKindAdminListView (admin list) 2026-05-07 12:00:19 +08:00
q792602257 6e8a9ee8d6 feat(web): AgentKindForm component (Naive UI form with env editor) 2026-05-07 12:00:16 +08:00
q792602257 b044c86728 feat(web): acp pinia store (agent_kinds) 2026-05-07 11:45:41 +08:00
q792602257 7307ad0054 feat(web): acp api client (agent_kinds) 2026-05-07 11:45:33 +08:00
q792602257 e97541030a feat(app): wire ACP AgentKindService + handler 2026-05-07 11:41:14 +08:00
q792602257 8202a7a679 test(acp): handler unit tests (admin / user / field redaction / PATCH semantics) 2026-05-07 11:37:33 +08:00
q792602257 e096b1a671 feat(acp): HTTP handler for agent kinds (admin write / user read with field redaction) 2026-05-07 11:34:11 +08:00
q792602257 79480b32f8 feat(acp): AgentKindService + unit tests (fake repo + real encryptor) 2026-05-07 11:28:15 +08:00
q792602257 1ef2e93b72 test(acp): pgRepo integration tests (CRUD + lifecycle + event order) 2026-05-07 11:21:40 +08:00
q792602257 a9a9e6d8ab feat(acp): repository interface + pgRepo full implementation (agent_kind + session + event) 2026-05-07 10:42:58 +08:00
q792602257 631f957cd9 feat(acp): sqlc queries (agent_kinds + sessions + events) + generated code 2026-05-07 10:37:16 +08:00
q792602257 cb845f2374 feat(acp): domain types + service interfaces (skeleton) 2026-05-07 10:34:31 +08:00
q792602257 c4ddfde0ff feat(errs): add 11 ACP error codes + HTTP mapping 2026-05-07 10:32:36 +08:00
q792602257 4d939ddc05 feat(acp): wire internal/acp/queries into sqlc 2026-05-07 10:29:17 +08:00
q792602257 8055d9f294 feat(acp): add migration 0006 down 2026-05-07 10:26:16 +08:00
q792602257 3457c2e8c4 feat(acp): add migration 0006 up — agent_kinds + sessions + events + workspaces ALTER 2026-05-07 10:21:33 +08:00
q792602257 e38ada6674 chore(gitignore): exclude /.worktrees/ and /worktrees/ 2026-05-07 10:15:41 +08:00
q792602257 a2b6d5382e feat(workspace,jobs): emit sync_aborted_on_restart audit + enrich worktree.pruned metadata
- workspace.ResetStuckSyncStatuses now returns affected IDs so app.New can record one workspace.sync_aborted_on_restart audit per reset row
- worktree_prune audit metadata gains workspace_id and path alongside existing branch
- updated fakeRepo + integration test for new ResetStuckSyncStatuses signature
- add TestWorktreePrune_AuditMetadataContainsWorkspaceIDAndPath
2026-05-07 10:14:46 +08:00
q792602257 b1ccce567e feat(jobs): emit job.enqueue + worktree.pruned audit rows
Deferred audit retrofits from Plan #5 self-review:
- WebhookNotifier now records a job.enqueue audit row after each
  successful repo.Enqueue (best-effort: failures are warn-logged, not
  propagated). Added optional audit.Recorder + *slog.Logger params to
  NewWebhookNotifier.
- WorktreePrune.executionPhase now records a worktree.pruned audit row
  after each successful FinishPruneSuccess. Added optional audit.Recorder
  param to NewWorktreePrune.
- app.go wires the existing auditRec into both constructors.
- integration_test.go: drop the _ = auditRec suppression and pass
  auditRec into the webhook notifier so the closed-loop test exercises
  the audit emit path.
2026-05-06 13:35:45 +08:00
q792602257 f6089ac5fb chore(jobs): align log keys + add prune no-op test + down-migration comment
Cross-cutting review polish:
- worker.go: id/type → job_id/job_type; one stray attempts → attempt for
  consistency with the other 4 sites in the same file.
- runners/workspace_fetch.go: ws_id → workspace_id (matches the dispatched
  notify.Message metadata key).
- runners/worktree_prune.go: id → worktree_id (same reason).
- runners/worktree_prune_test.go: add TestWorktreePrune_NoRowsIsNoOp for
  symmetry with the no-op tests in the other 4 runner test files.
- migrations/0005_jobs.down.sql: comment that DROP TABLE jobs cascades to
  drop the three idx_jobs_* indexes automatically.
2026-05-06 11:52:17 +08:00
q792602257 cf1ec7b1c6 fix(app): give dispatcher.Shutdown its own ctx in ctx.Done branch
Final cross-cutting review finding: shutCtx was shared between
server.Shutdown and dispatcher.Shutdown, with jobs.Stop's wall-clock
time burning the budget in between. Under load, dispatcher.Shutdown
could receive an already-dead ctx and skip draining in-flight async
notify dispatches (including webhook enqueues). Mirror the errCh
branch by creating a fresh 10s drainCtx for dispatcher.Shutdown.
2026-05-06 11:40:34 +08:00
q792602257 187991378b docs(jobs): operator guide + acceptance checklist 2026-05-06 11:15:03 +08:00
q792602257 69c5831783 fix(app): respect cfg.Jobs.ShutdownGrace and skip jobs.Stop when disabled
Code review fixes for T16:
- Pass cfg.Jobs.ShutdownGrace+5s to jobs.Stop call-site context (was
  hard-coded 30s, would mask configured longer grace).
- Guard jobs.Stop block on cfg.Jobs.Enabled so disabled jobs don't
  spin up the no-op shutdown goroutine + timer.
- Use clock.Real().Now() in deadLetterFn for consistency with the rest
  of the jobs wiring.
2026-05-06 11:10:29 +08:00
q792602257 c7db7a9604 feat(app): wire jobs.Module + WebhookNotifier + integration test for webhook closed loop 2026-05-06 09:25:19 +08:00
q792602257 7b3892c42e feat(config,workspace,user): jobs/notify config + workspace fetch repo + user ListAdmins 2026-05-06 09:10:43 +08:00
q792602257 895799a6c9 fix(jobs): timer leak in Module.Stop and warn on unknown runner names
Module.Stop used time.After which leaks the timer if the done channel
wins first; switch to time.NewTimer + defer Stop() to align with the
codebase convention.

scheduleEntry silently returned {0, false} for unknown runner names —
typos in production wiring were invisible. Return (entry, known) and
log Warn at NewModule registration time so misconfiguration surfaces.
2026-05-06 08:37:09 +08:00
q792602257 895a816221 feat(jobs): Module wiring + WorkerOptions.OnDeadLetter hook 2026-05-06 08:31:24 +08:00
q792602257 2d0c45a52b feat(jobs/runners): job_reaper (lease timeout) + job_purge (retention) 2026-05-06 08:20:29 +08:00
q792602257 f6add1598e test(jobs/runners): cover partial-storage-success, list-error isolation, DB-delete-error branches 2026-05-06 08:14:47 +08:00
q792602257 f56fe449fd feat(jobs/runners): attachment cleanup + chat DeleteAttachments query/method 2026-05-06 08:07:49 +08:00
q792602257 c50621eeca feat(jobs/runners): worktree prune two-phase + workspace prune queries/repo methods 2026-05-06 07:55:56 +08:00
q792602257 0111135e78 test(jobs/runners): cover CAS-lost, MarkSyncing-error, MarkFetchResult-error branches 2026-05-06 07:33:40 +08:00
q792602257 af1855b753 feat(jobs/runners): workspace fetch runner with notify dispatch on failure 2026-05-05 23:35:58 +08:00
q792602257 e361670539 feat(jobs): WebhookNotifier enqueues webhook.deliver jobs (topic whitelist + disabled short-circuit) 2026-05-05 23:26:47 +08:00
q792602257 9f290335b2 feat(jobs/handlers): webhook handler with HMAC sign + 4xx permanent / 5xx retry 2026-05-05 23:17:47 +08:00
q792602257 3aa19c8f7e fix(jobs): log repo write errors in worker.execute
Previously, write-back errors from Complete/DeadLetter/FailWithRetry
were silently dropped via underscore assignment. A transient DB
failure here would leave a job stuck (still 'running' with active
lease) until the reaper resets it, with zero observability into why.

Log each write-back error at Error level so operators can correlate
stuck jobs with DB symptoms. Code quality review of T8.
2026-05-05 23:12:43 +08:00
q792602257 1a83a5b1cf feat(jobs): worker pool with retry/dead-letter/panic-recovery 2026-05-05 19:57:23 +08:00
q792602257 f235b1be63 feat(jobs): periodic scheduler with panic-recovery and per-entry enable flag 2026-05-05 19:47:51 +08:00
q792602257 2e8135bcdf feat(jobs): postgres repository with SKIP LOCKED lease + retry/dead-letter/purge 2026-05-05 19:40:39 +08:00
q792602257 ff3f27c1dc feat(jobs): sqlc queries for jobs table 2026-05-05 16:59:03 +08:00
q792602257 215c1bb821 feat(jobs): domain types + Handler interface + Config 2026-05-05 16:52:17 +08:00
q792602257 ba1d657973 feat(workspace): clear prune_warning_at on SetWorktreeActive/Idle 2026-05-05 16:45:25 +08:00
q792602257 e768adb3ff chore(sqlc): regenerate per-module models for migration 0005 schema
T1 added jobs table and workspace_worktrees.prune_warning_at column but
sqlc generate was not re-run for all modules. This catches the audit,
notify, project, and user models up; chat partially regenerated already.
Workspace's regen is part of T3 (next commit).
2026-05-05 14:28:09 +08:00