Skip to content

feat(sessions): session-level identity + cross-machine attribution - #1

Merged
constant-itis merged 3 commits into
mainfrom
sessions
Jul 27, 2026
Merged

feat(sessions): session-level identity + cross-machine attribution#1
constant-itis merged 3 commits into
mainfrom
sessions

Conversation

@constant-itis

Copy link
Copy Markdown
Owner

Adds a session dimension to slinkd so agent runs are attributable to a specific window/machine, not just the durable agent id.

Core (server/sessions.go)

  • sessions registry table: session_id (PK), agent_id (soft reference, no FK), host, os, client, started_at, last_seen, ended_at.
  • Endpoints: POST /sessions (register/upsert — re-register resumes the same row, preserving started_at), POST /sessions/{id}/heartbeat, POST /sessions/{id}/end, GET /sessions/{id}, GET /sessions?live=1&agent=.

Attribution (events, tasks)

  • Nullable session_id/host columns; direct event publishes and task creation stamp them, surfaced on reads. Empty → SQL NULL; a stale id never fails a write.

Migration is additive and idempotent. Preserves the per-call identity model. Smoke-tested full lifecycle against Postgres 16.

officialbubies added 3 commits July 26, 2026 22:41
Add a sessions registry so cross-machine agent runs are attributable to a
specific window, not just the durable agent id. A session is a sub-dimension
of agent identity (agent_id stays the durable id; session_id/host/os pin the
run). Per-call identity model is preserved (#874).

- sessions table: session_id (PK), agent_id (soft ref, no FK), host, os,
  client, started_at, last_seen, ended_at. Register upserts; re-register
  reopens the same row (ended_at->null) and preserves started_at (resume).
- endpoints: POST /sessions (register), POST /sessions/{id}/heartbeat,
  POST /sessions/{id}/end, GET /sessions/{id}, GET /sessions?live=1&agent=.
- events/tasks gain nullable session_id/host columns for stream attribution
  (best-effort, no FK — a stale id never fails a write).

Migration is additive and idempotent. Smoke-tested full lifecycle against
Postgres 16: register/heartbeat/live-filter/end/resume/agent-filter/auth/404.
Populate the attribution columns added in the previous commit. Direct event
publishes (POST /channels/{id}/events) and task creation (POST
/projects/{id}/tasks) now accept optional session_id/host and store them;
both are surfaced on reads so board/tail can show which session/host produced
a row. Empty -> SQL NULL via strPtrOrNil, so unattributed writes (and internal
task_update events) stay null rather than blank. Task rows carry creation
origin; transitions don't overwrite it.

Smoke-tested: attributed + unattributed events and tasks round-trip correctly.
Add a Sessions API subsection (register/resume, heartbeat, end, live view),
a 'What It Does' entry, the sessions table + nullable events/tasks columns in
the schema, and sessions.go in the project structure.
@constant-itis
constant-itis merged commit cac1b10 into main Jul 27, 2026
@constant-itis
constant-itis deleted the sessions branch July 27, 2026 02:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant