shcizo
f25a7a7779
docs: webhook contract, auto mode and phase 3 plan ( #8 )
2026-10-12 20:43:11 +02:00
shcizo
71d66846f2
feat(web): update-mode toggle and available-version badge ( #8 )
2026-10-12 20:41:41 +02:00
shcizo
5d95a35b3b
feat(master): POST /update webhook with auto-mode updates ( #8 )
2026-10-12 20:40:38 +02:00
shcizo
cfc6ea6713
feat(store): available ref, update mode and services-by-repo for the webhook ( #8 )
2026-10-12 20:40:04 +02:00
shcizo
417ef315c2
Merge pull request 'feat: master/agent phase 2 — jobs and manual update ( #7 )' ( #20 ) from feat/master-agent-jobs-7 into main
...
Docker Build / docker (push) Successful in 40s
Reviewed-on: #20
2026-10-12 17:58:48 +00:00
shcizo
ec96d5687d
fix(agent): reset per-service warnings after a successful build check ( #7 )
2026-10-12 19:45:29 +02:00
shcizo
c5dba96cf8
fix(agent): list all compose profiles and fail closed on unknown services ( #7 )
2026-10-12 19:38:07 +02:00
shcizo
27c4200dda
feat(agent): report and refuse Compose services built from source; honour --env-file ( #7 )
2026-10-12 19:32:05 +02:00
shcizo
69ef55837e
docs: compose environment and built-from-source services ( #7 )
2026-10-12 19:30:38 +02:00
shcizo
3d3dfb47e6
feat(master): show built-from-source services but never update them ( #7 )
2026-10-12 19:30:38 +02:00
shcizo
c3bd4ca1ed
test(master): CreateJob waits for a concurrent revoke ( #7 )
2026-10-12 19:29:43 +02:00
shcizo
91cb027ef6
feat(protocol): Service.Built marks Compose services built from source ( #7 )
2026-10-12 19:29:18 +02:00
shcizo
7e23e1843f
docs: spell out the upgrade risk and the bare-image rule ( #7 )
2026-10-12 19:15:24 +02:00
shcizo
961ddd275c
test(master): wait for the replacement connection to register ( #7 )
2026-10-12 19:15:24 +02:00
shcizo
caa6c81716
fix(master): treat a bare image as :latest and handle a revoked agent in Trigger ( #7 )
2026-10-12 19:14:59 +02:00
shcizo
c09e774d74
fix(master): refuse jobs for revoked agents, signal revoked jobs, agent start time wins ( #7 )
2026-10-12 19:14:32 +02:00
shcizo
93ba6915b9
fix(agent): minimal env and explicit project dir for compose, resolve every config file's symlinks ( #7 )
2026-10-12 19:13:25 +02:00
shcizo
8b2c10cc05
fix(web): job log polls while active, one service history limit ( #7 )
2026-10-12 19:13:01 +02:00
shcizo
88d5507217
docs: describe Swarm registry auth ( #7 )
2026-10-12 18:50:12 +02:00
shcizo
b7e25bb1fb
docs: master/agent phase 2 — jobs and manual update ( #7 )
2026-10-12 18:48:53 +02:00
shcizo
b392e11b37
test: jobs end to end over pinned TLS ( #7 )
2026-10-12 18:48:06 +02:00
shcizo
55f8021b0a
build: agent is the image's default entrypoint; drop the old server examples ( #7 )
2026-10-12 18:45:47 +02:00
shcizo
601c6da0d4
feat(agent): run jobs from the master and resend results until acked ( #7 )
2026-10-12 18:45:44 +02:00
shcizo
e313365686
feat(agent): job runner, compose override executor and swarm executor ( #7 )
2026-10-12 18:45:44 +02:00
shcizo
32c30194c4
feat(master): wire jobs into the master ( #7 )
2026-10-12 18:43:20 +02:00
shcizo
02de0b8cf3
feat(master): start manual update jobs with self-protection ( #7 )
2026-10-12 18:43:11 +02:00
shcizo
68e5c33722
feat(master): route jobs to agents and reconcile them on reconnect ( #7 )
2026-10-12 18:42:30 +02:00
shcizo
574f425267
feat(web): service page, manual update, jobs list and live job log ( #7 )
...
Also publishes the jobs topic on agent revoke and updates the agent
snippet to mount stacks read-write at the same path.
2026-10-12 18:41:46 +02:00
shcizo
9d3a6f808c
feat(master): store update jobs ( #7 )
2026-10-12 18:40:48 +02:00
shcizo
e2b73dfd81
feat(agent): UPDATE_TIMEOUT and DOCKER_CONFIG settings ( #7 )
2026-10-12 18:40:15 +02:00
shcizo
c9c4e0cadb
refactor(web): web.New takes the jobs service ( #7 )
2026-10-12 18:39:57 +02:00
shcizo
9e09de0a16
feat(protocol): job messages, protocol version and job model ( #7 )
2026-10-12 18:38:39 +02:00
shcizo
eb41967cd1
docs: plan revisions after review ( #7 )
2026-10-12 18:37:28 +02:00
shcizo
7e55ec3b33
docs: implementation plan for master/agent phase 2 (jobs) ( #7 )
2026-10-12 17:13:15 +02:00
shcizo
3090b6d4f0
Merge pull request 'feat: master/agent phase 1 — live inventory ( #6 )' ( #19 ) from feat/master-agent-inventory-6 into main
Docker Build / docker (push) Successful in 58s
2026-10-12 13:50:09 +00:00
shcizo
2fe9b5ba0d
fix(master): block inventory writes from revoked agents ( #6 )
...
ApplySnapshot and UpsertService now take a FOR SHARE lock on the agent's
row and refuse with model.ErrRevoked when it is revoked. RevokeAgent's
UPDATE waits on that lock, so an in-flight snapshot or upsert can no
longer bring a revoked agent's services back after the revoke cleanup.
2026-10-12 15:18:51 +02:00
shcizo
0e9e34db06
fix: address final review findings for master/agent phase 1 ( #6 )
...
- inventory: resolve the image reference via ContainerInspect when a moved
tag makes ContainerList report the image ID
- store: allow reusing a revoked agent's name (partial unique index) and
mark the revoked agent's compose/container services removed
- web: publish a services event on revoke; no-store on the one-time token page
- webauth: reject empty OIDC state; accept the CSRF form token from the body only
- agent conn: bound the WebSocket handshake to 30s
- hub: log agent_replaced when a connection replaces an older one
2026-10-12 15:16:29 +02:00
shcizo
4f092eaf79
docs: document master/agent phase 1 and add master stack example
2026-10-12 15:04:43 +02:00
shcizo
05610391e3
test: agent to master inventory over pinned TLS end to end
2026-10-12 15:02:50 +02:00
shcizo
e8f7cb3378
feat(master): add updater-master binary wiring store, hub, auth and UI
2026-10-12 15:01:11 +02:00
shcizo
a596d67728
feat(master): htmx UI with live service overview and agent management
...
Vendored static assets (sha256):
e209dda5c8235479f3166defc7750e1dbcd5a5c1808b7792fc2e6733768fb447 htmx.min.js (htmx.org@2.0.4)
83eca6fa0611fe2b0bf1700b424b88b5eced38ef448ef9760a2ea08fbc875611 htmx-ext-sse.js (htmx-ext-sse@2.2.2)
2026-10-12 14:57:23 +02:00
shcizo
b4894db6d7
feat(master): OIDC login with group check, sessions and CSRF protection
2026-10-12 14:54:11 +02:00
shcizo
049324b2f4
fix(master): recheck revocation after register, reject duplicate hello
2026-10-12 14:52:24 +02:00
shcizo
75e28262f8
feat(master): agent hub that authenticates agents and stores their inventory
2026-10-12 14:50:22 +02:00
shcizo
5d75f9a7da
feat(master): in-process broker for live UI change signals
2026-10-12 14:48:03 +02:00
shcizo
8a1fb45971
feat(master): store service inventory snapshots and web sessions
2026-10-12 14:45:46 +02:00
shcizo
99c553b7c6
feat(master): postgres store with migrations, master identity and agents
2026-10-12 14:43:34 +02:00
shcizo
9b74286c9b
feat(agent): add updater-agent binary and ship it in the image
2026-10-12 14:41:05 +02:00
shcizo
ad6ff1e066
feat(agent): connect to master over pinned TLS and stream inventory
2026-10-12 14:38:14 +02:00
shcizo
3edaf4e602
feat(agent): diff inventories and debounce docker events
2026-10-12 14:36:11 +02:00
shcizo
abee9abb1b
feat(agent): collect compose, swarm and container inventory from docker
2026-10-12 14:34:13 +02:00
shcizo
61e738e39d
feat: pinned master key TLS and per-agent tokens
2026-10-12 14:32:40 +02:00
shcizo
b482c2e29c
feat(protocol): define agent-to-master wire messages
2026-10-12 14:31:18 +02:00
shcizo
adeddf0254
feat(imageref): parse image references into repo, tag and digest
2026-10-12 14:29:52 +02:00
shcizo
a57df51532
Merge pull request 'docs: master/agent design spec and phase 1 plan' ( #16 ) from feat/master-agent into main
2026-10-12 12:15:16 +00:00
shcizo
d2a8b548c9
docs: implementation plan for master/agent phase 1 (inventory)
2026-10-12 13:42:27 +02:00
shcizo
1c833f9fbe
docs: design for master/agent architecture with live inventory, update modes and polling
2026-10-12 13:20:50 +02:00
shcizo
9ea082de82
Merge branch 'worktree-docker-swarm-support'
...
Adds MODE=compose|swarm. Each instance owns one Docker daemon and runs
one paradigm; see docs/superpowers/specs/2026-08-04-multi-server-fanout-design.md
for why this exclusivity is the intended design.
2026-08-04 19:25:08 +02:00
shcizo
50ef1a9a07
Merge pull request 'feat: add Docker Swarm support (MODE=swarm)' ( #4 ) from worktree-docker-swarm-support into main
...
Docker Build / docker (push) Successful in 1m7s
Reviewed-on: #4
2026-07-04 18:54:14 +00:00
shcizo
db84a2f6ba
fix(api): plumb request tag into discovery so swarm mode deploys the requested version
...
req.Tag was only echoed in the HTTP response, never used to match jobs.
Compose mode didn't care (ComposeExecutor re-pulls the compose file's own
pinned tag), but SwarmExecutor sets the service image directly from
Job.Image, which was built from the untagged req.Image alone -- so a
Swarm deploy silently rewrote the service to :latest instead of the
requested tag. Build the full image:tag reference once in the handler
and pass it into FindJobs; NormaliseImage/ImagesMatch already strip
tags before matching, so this doesn't change which jobs match in either
mode.
2026-07-04 20:41:59 +02:00
shcizo
9881812eca
docs: document MODE=swarm support and its opt-in label / manager-node requirements
2026-07-04 20:32:22 +02:00
shcizo
ac3912367f
merge: bring in CLAUDE.md and CI workflow from main
2026-07-04 20:31:25 +02:00
shcizo
9a3a200873
feat: wire MODE config to select compose or swarm discovery/executor
2026-07-04 20:28:28 +02:00
shcizo
f92f8ac6b1
feat(api): surface ServiceID in update results for swarm jobs
2026-07-04 20:22:30 +02:00
shcizo
34865c9fd0
feat(updater): add SwarmExecutor to run docker service update via the Docker API
...
Adds the Swarm-mode counterpart to ComposeExecutor: updates a Swarm
service's image directly through the Docker SDK (ServiceInspectWithRaw +
ServiceUpdate with QueryRegistry=true so floating tags resolve to a fresh
digest), gated by the same Refused guard used in Compose mode. Satisfies
the existing Executor interface unchanged, so Queue needs no changes.
2026-07-04 20:19:00 +02:00
shcizo
a8524e5ff4
feat(discovery): add SwarmDiscovery to find opted-in Swarm services by image
...
Verified the Docker SDK v28.5.2+incompatible ServiceList signature via go doc
before implementing: the options type is swarm.ServiceListOptions, not
types.ServiceListOptions as the brief assumed. Everything else (Service.ID,
Service.Spec via embedded Annotations for Name/Labels, TaskTemplate.ContainerSpec.Image)
matched the brief exactly.
Reuses discovery.ImagesMatch and discovery.HasOptIn rather than duplicating
matching/opt-in logic. Opt-in label is read from the service spec's own
labels since Swarm services have no local compose file to anchor a
STACKS_ROOT path check against (unlike Compose mode).
2026-07-04 20:12:44 +02:00
shcizo
9cf484e164
feat(discovery): add Image and ServiceID fields to Job for swarm support
2026-07-04 20:09:39 +02:00
shcizo
1002bb7b96
feat(config): add MODE env var to select compose or swarm operation
2026-07-04 20:06:50 +02:00
shcizo
8f999c69bd
docs: add docker swarm support implementation plan
2026-07-04 20:05:02 +02:00
shcizo
df54bbaacf
docs: add CLAUDE.md with project context for Claude Code
...
Captures design intent, gotchas, and references that aren't obvious
from code alone — single-worker queue rationale, defense-in-depth
security model, the not-yet-wired selfupdate package, and pointers
to the design spec and implementation plan in docs/superpowers/.
2026-05-22 14:27:28 +02:00
shcizo
476945722b
Merge pull request 'ci: docker build + push workflow on v* tags' ( #2 ) from feat/ci-docker-build into main
Docker Build / docker (push) Successful in 51s
2026-05-22 14:09:02 +02:00
shcizo
2494e71969
ci: docker build + push on v* tags
2026-05-22 14:02:45 +02:00
shcizo
46ef00c742
Merge pull request 'Initial implementation: package-updater v1' ( #1 ) from feat/initial-implementation into main
2026-05-22 13:59:37 +02:00
shcizo
e43868bf41
build: bump Dockerfile to golang:1.26-alpine to match go.mod
2026-05-22 13:56:23 +02:00
shcizo
9a8b171198
feat: docker-compose.local.yml for local build/smoke-test
2026-05-22 13:53:49 +02:00
shcizo
3abd1bf9af
feat(metrics): wire instrumentation through queue, handlers, middleware
2026-05-22 13:17:09 +02:00
shcizo
ef9c0f1313
chore: gitignore stray ./server binary from go build
2026-05-22 13:05:43 +02:00
shcizo
b866f6d47c
feat(cmd): wire config, discovery, queue, http server, metrics
2026-05-22 13:04:44 +02:00
shcizo
952189eb09
feat(metrics): Prometheus collectors and /metrics handler
2026-05-22 12:59:53 +02:00
shcizo
2be2fdf325
docs: real README with quick start, endpoints, observability
2026-05-22 12:09:37 +02:00
shcizo
33a8b8689f
feat(action): reusable Gitea composite action for /update
2026-05-22 12:08:12 +02:00
shcizo
804b69b67c
docs: docker-compose.example.yml for end-user deploy
2026-05-22 12:07:47 +02:00
shcizo
00bada890b
build: multi-stage Dockerfile with build info ldflags
2026-05-22 12:07:36 +02:00
shcizo
e88f105490
feat(selfupdate): defer self-replacement until response flushed
2026-05-22 12:06:07 +02:00
shcizo
857f504d36
feat(api): /update, /healthz, /version handlers
2026-05-22 12:03:56 +02:00
shcizo
df2dc30cea
feat(api): auth, request_id, and request-logging middleware
2026-05-22 11:59:34 +02:00
shcizo
c9b1af42e5
feat(updater): FIFO queue with single worker and per-job results
2026-05-22 11:57:09 +02:00
shcizo
a275f208c4
feat(updater): ComposeExecutor shells out to docker compose
2026-05-22 11:54:03 +02:00
shcizo
058b9d8c07
feat(updater): Executor interface
2026-05-22 11:53:42 +02:00
shcizo
db784ad303
feat(discovery): orchestrate match, opt-in filter, dedup, path-check
2026-05-22 11:51:07 +02:00
shcizo
897093ed1c
feat(discovery): STACKS_ROOT path safety check
2026-05-22 11:45:56 +02:00
shcizo
13ccb79ef5
feat(discovery): parse Compose-managed labels
2026-05-22 11:44:10 +02:00
shcizo
cff6c1baff
feat(discovery): tag-agnostic image name normalisation
2026-05-22 11:41:33 +02:00
shcizo
e665b6cd7e
feat(logging): structured JSON logger with request_id context
2026-05-22 11:38:07 +02:00
shcizo
883f3cfecf
chore: tidy go.sum for testify transitive deps
2026-05-22 11:35:33 +02:00
shcizo
9832b2b190
docs: complete se.enocsson to se.shcizo rename in spec
2026-05-22 11:35:33 +02:00
shcizo
4f2a19c663
chore: gitignore Serena MCP workspace
2026-05-22 11:35:33 +02:00
shcizo
2b7f7d863a
feat(config): load and validate env-var config
2026-05-22 11:24:29 +02:00
shcizo
1ca9f5296a
chore: scaffold Go project layout
2026-05-22 11:16:23 +02:00
shcizo
ef14465314
docs: remove dead strconv import from main.go in plan
2026-05-22 11:13:40 +02:00