Skip to content

session-origin

Provenance

  • Source: .spec/spexcode/spec-cli/sessions/lifecycle/session-origin/spec.md
  • Source SHA-256: 501793e79c309be3a4951d93c9e069f80d97a3f99cf02c16ac81db3f722183dc

raw source

A session today is always born the same way: cut a node/<id> branch off the trunk and worktree it. But a session is really just an agent governing a worktree — and the worktree's starting contents are a construction parameter, not the session's identity. Once you can seed that worktree from anywhere in git, an external branch or pull request (yours, or a collaborator's) becomes an ordinary SpexCode session: a dedicated agent runs it, reads it, fixes it, and delivers it ([[deliver-port]]) — the thing SpexCode never had, a way to receive outside contributions.

expanded spec

Origin is one polymorphic field, seeded once then forgotten. The session's global record (session.json) gains origin (and its source ref); the [[portable-layout]] linker reads it. Two origins to start:

  • fresh — a new node/<id> branch off the trunk. The default; today's behaviour, byte-for-byte.
  • pr — fetch the pull request's head into the worktree (GitHub refs/pull/<n>/head, GitLab refs/merge-requests/<n>/head — a driver detail, so it routes through [[spec-forge]]'s host-agnostic [[port]], never a if github in the session code).

Internally there is ONE seed-from-any-ref primitive; the CLI exposes only spex new --from-pr <url|#> because that is the real need (collaborate on a PR). --from-branch and other origins are a zero-cost future surfacing of the same primitive, held back on YAGNI until a real need names them.

A pulled-in session does NOT mint a spec node — and that is not a leak. The tidy "one session, one node" reading was wrong: session ↔ node is a contract relation, not a production one. Every session works under a governing spec (it references the nodes whose files it touches); only a delivery whose destination is the trunk requires authoring — the fused spec+code commit — because that is the trunk's own admission gate ([[main-guard]] / [[spec-lint]] sit on the gate, not on the session). So there is one kind of session with the gate at the landing place, never two species (spec-native vs foreign). A from-pr session references the governing nodes of the files its PR touches and delivers a verdict by default ([[deliver-port]]); it authors a node only if a maintainer retargets it to the trunk.

This also names an accident already in the tree: a session whose branch was a raw forge URL had to make the node id double as the origin (the URL stood in as the node name), which is why its spex ls label read as a URL. With origin a first-class session-record field, the node id goes back to being purely a [[source-of-truth|spec-tree name]] — the neighbouring scenario the fix also explains.