cartulary 0.3.0-alpha.1

The knowledge layer of your project — decisions, issues, docs, all in one place.
Documentation
---
summary: How an entry identifies itself, where it lives, and which side of the workspace it came from.
---

# Entry identity

Every entry in a cartulary workspace — an issue or a decision
record — carries three independent pieces of identity that answer
three different questions. They overlap in shape but never in
meaning.

## The three concepts

| Concept | Question it answers | Example |
|---|---|---|
| `tracker` | Which external system follows this entry? | `local:ISSUE-0042`, `github:owner/repo#42`, `jira:PROJ-123` |
| `origin` | From which side of the workspace was it loaded? | `Local` (writable home) or `Union { name: "shared/issues" }` |
| `location` | Where is it stored right now? | `file:///workspace/docs/issues/0042-foo/index.md`, `memory://` |

A single issue can carry all three at once: a GitHub-tracked
issue, merged in from a read-only union directory, currently
stored on the filesystem. None of the three implies the others.

## Tracker — the external bug-tracking identity

`tracker` says where the issue was *authored* or *imported from*.
Format is `system:locator`:

- `system` is a short lowercase alphanumeric tag (`local`,
  `github`, `gitlab`, `jira`, …)
- `locator` is the identifier within that system

Default for issues created with `cartu issue new` is
`local:ISSUE-<id>`. Imports from external trackers carry their
upstream coordinates.

The tracker is **stable**: it survives copies, merges, and
location changes. It only changes when the upstream coordinate
itself changes.

## Origin — which workspace side it came from

A workspace may merge entries from its **writable home** with
**read-only union sides** (typically other directories declared in
`cartulary.toml`). `origin` records which side an entry was loaded
from at scan time:

- `Local` — the entry lives in the workspace's primary home and
  can be written to.
- `Union { name }` — the entry was merged in from a read-only
  side identified by `name` (the configured root path).

`origin` is **runtime metadata**, set by the adapter at load
time. It is not stored in the file's frontmatter — it is rebuilt
on every scan.

## Location — where it is stored

`location` is a URI naming the storage backend and the position
within it:

- `file://<path>` — on the local filesystem
- `memory://` — in-memory scratchpad (use-case construction,
  fixtures)
- Future: `git://`, `sql://`

`location` answers "if I want to open this entry, where do I
look?". It changes whenever the entry moves, even if `tracker`
and `origin` stay the same.

## Why three, not one?

The three are orthogonal. A change to any one of them does not
imply a change to the others:

- An issue's `tracker` can stay `github:foo#42` while it migrates
  from `union` to `local` (someone forked it locally).
- An issue's `location` can change (renamed directory) without
  affecting `tracker` or `origin`.
- An issue's `origin` flips from `Local` to `Union` the day a
  workspace adds the side that contains it — `tracker` and
  `location` are untouched.

Collapsing them into one would force conflating these dimensions.
The names are deliberately distinct so reading the type tells you
which question is being asked.