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
v0.3.0
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
v0.2.0
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