Session-rooted CLI for evidence acquisition, operational memory, durable continuity, and linked peer workflows
Project description
Gotta
gotta is a session-rooted CLI for evidence acquisition, operational memory,
durable continuity, and linked actor workflows.
The point is broader than retrieving one more document. gotta is designed to
keep actor work coherent when terminal history, model context windows, or human
working memory come under pressure. It pushes enough state, provenance, and
materialized evidence into durable external form. This lets an actor rehydrate
prior work reliably and continue from grounded context.
The public surface stays small:
gotta <plugin> ...
gotta ... is the canonical operator path. It binds or discovers the right
session for the current context, hydrates the runtime environment, and
dispatches the requested plugin with that session active. You do not need to
cd into the session root first.
Why gotta
The name is a modal verb of necessity. Every subcommand reads as a natural English sentence expressing what needs to happen:
gotta read— I have to read thisgotta oops— I have to inspect or record this frictiongotta session analyze— I have to analyze the sessiongotta want— I have to express what I wantgotta todo append— I have to track this work
That composability is not accidental. Alternative names work for acquisition
commands but break down everywhere else. glean read makes sense; glean oops
does not. trace jira search reads well; trace want does not. Only a modal
verb of necessity composes across the entire surface: evidence acquisition,
friction capture, intent declaration, actor coordination, and session synthesis.
The semantics are also exact. The tool's thesis is that evidence must be externalized, context must survive compression, and friction must be recorded. "Gotta" is that necessity made literal.
Continuity Over Context Windows
Actors work in waves. They pull a few strong anchors, expand into adjacent evidence, synthesize the resulting web, and then eventually hit compression pressure. Context windows compact. Terminal history scrolls away. Thin summaries preserve headlines but lose the path that made those headlines trustworthy.
gotta is shaped around that boundary.
It externalizes the parts of the working context that should survive:
- the session itself as a durable working root
- canonical task, log, and friction state
- materialized evidence with native reopen handles
- synthesis surfaces such as manifest, timeline, graph, leads, and analyze
That is why gotta is session-rooted rather than request-rooted. A request is
ephemeral. A session can be reopened, inspected, extended, handed off, or
compacted and rehydrated without losing the shape of the work.
The choice of medium is equally deliberate: native CLI working surfaces are
one of the strongest places for serious actor work. They provide room to
inspect, correlate, transform, act on, and resume real evidence. gotta
leans into that by treating retrieval, memory, and action as part of the same
working surface.
Why It Is Shaped This Way
gotta is deliberately native-first:
- prefer provider-native retrieval and mutation surfaces over ad hoc shell fallbacks
- keep durable truth in session state, not in terminal scrollback
- make every material read reopenable through native locators
- preserve enough provenance that compression leads to rehydration, not loss of working context
The normal working loop expands and compresses repeatedly:
- retrieve one or two strong anchors through provider-native search or read
- expand outward into adjacent evidence and materialize it into the session
- compress that evidence web through
session manifest,timeline,graph,leads, andanalyze - record friction and continuity gaps in
oops - refine the next retrieval wave from durable state instead of memory
state/oops.jsonl is the canonical friction log, and gotta oops is the live
readable surface. It captures operator-visible seams: misleading contracts,
interrupted continuations, coverage gaps, and workflow friction worth fixing.
Installation
If you do not already have uv, install it first from Astral's official
installation guide.
Install with uv:
uv tool install gotta
That installs the gotta entrypoint.
If you want to try the CLI without installing it permanently:
uvx --from gotta gotta --help
gotta supports Python >=3.10.
If you are developing on the repo, sync a local uv-managed environment:
uv sync --python 3.10 --extra dev
Installed entrypoints:
gotta ...
Development And Quality Gate
The core local gate is:
uv run pytest -q
uv run ruff check src tests
uv run python -m vulture src tests --min-confidence 80
Structural pressure tools are part of the maintenance discipline:
uv run python -m radon cc src tests -s
uv run lizard src tests
uv build --python 3.10 --clear
uvx twine check dist/*
pytest, ruff, and vulture are the correctness and hygiene gate. radon
and lizard are not bug finders; they expose responsibility concentration and
complexity hotspots so cleanup removes residue instead of burying it.
Configuration And Durable State
Durable provider config lives in GOTTA_CONFIG_FILE or, by default, under
gotta's OS-native config directory:
- macOS:
~/Library/Application Support/gotta/gotta.toml - Linux:
~/.config/gotta/gotta.toml - Windows:
%AppData%\\gotta\\gotta.toml
Example:
[providers.atlassian.env]
GOTTA_ATLASSIAN_OAUTH_CLIENT_ID = "your-client-id"
GOTTA_ATLASSIAN_OAUTH_CLIENT_SECRET = "your-client-secret"
GOTTA_ATLASSIAN_OAUTH_REDIRECT_URI = "http://localhost:8080/callback"
GOTTA_ATLASSIAN_TOOLSETS = "all"
GOTTA_JIRA_BASE_URL = "https://example.atlassian.net"
GOTTA_CONFLUENCE_BASE_URL = "https://example.atlassian.net/wiki"
[providers.google.env]
GOTTA_GOOGLE_OAUTH_CLIENT_ID = "your-client-id"
GOTTA_GOOGLE_OAUTH_CLIENT_SECRET = "your-client-secret"
GOTTA_GOOGLE_OAUTH_REDIRECT_URI = "http://localhost:8091/callback"
[providers.slack.env]
GOTTA_SLACK_WORKSPACE = "your-workspace"
[providers.grafana.env]
GOTTA_GRAFANA_BASE_URL = "https://grafana.example.com"
GOTTA_GRAFANA_SERVICE_ACCOUNT_TOKEN = "glsa_your_service_account_token"
# Optional when the token must be pinned to one org explicitly.
GOTTA_GRAFANA_ORG_ID = "1"
Durable OAuth state lands under gotta's OS-native state directory:
- macOS:
~/Library/Application Support/gotta/auth/ - Linux:
~/.local/state/gotta/auth/ - Windows:
%LocalAppData%\\gotta\\auth\\
Canonical Session Model
The canonical top-level root is a shared session root under gotta's OS-native data directory:
<gotta data dir>/sessions/<session-id>/
session.json
content/
actors/<actor-id>/
Examples:
- macOS:
~/Library/Application Support/gotta/sessions/<session-id>/ - Linux:
~/.local/share/gotta/sessions/<session-id>/
Each shared session owns:
session.jsonfor shared session membership and actor metadatacontent/for the shared evidence web and append-only manifestactors/<actor-id>/for actor-local writable surfaces and state
Each actor root then owns its local working surfaces:
actors/<actor-id>/
WANT.md
GOAL.md
state/
content -> ../../content
Top-level fingerprint bindings live separately:
<gotta data dir>/bindings/<fingerprint> -> ../sessions/<session-id>/actors/<actor-id>
The default private session for an unbound fingerprint is:
sessions/<fingerprint>/actors/<fingerprint>/
Stored artifacts have two native reopen handles:
artifact:<preferred-name>@<digest12>content:<sha256>
Both resolve through gotta read ..., so emitted evidence does not require
manual manifest spelunking just to continue.
The content store is first-class:
- the filesystem under
$WS/contentis the durable evidence graph manifest.jsonlis the append-only invocation index- identical bytes land in the same content object
- repeated fetches create additional timestamped evidence links
This is the continuity boundary in concrete form: the session keeps enough of the working set externalized that later synthesis, follow-up research, or downstream actions can be rebuilt from durable state instead of a lossy memory of prior interactions.
Retrieval And Materialization
Provider-first usage without session scaffolding is a core workflow:
gotta jira status
gotta jira search "retry budget"
gotta github search "service ownership"
gotta github https://github.com/org/repo/commits/HEAD
gotta grafana status
gotta grafana datasources
gotta grafana search --type dash-db
gotta grafana search --type dash-db production-overview
gotta grafana search "production overview"
gotta grafana get demo-dashboard-uid
gotta grafana query --dashboard demo-dashboard-uid 'sum(app_up)'
gotta grafana query --dashboard 'https://grafana.example.com/d/demo-dashboard-uid/view?orgId=1&from=now-6h&to=now' 'sum(app_up)'
gotta grafana query --datasource prom-main 'rate(http_requests_total[5m])'
gotta confluence search "queue architecture"
gotta gdocs search "incident response"
gotta granola list --time-range last_30_days --limit 5
gotta granola transcript 11111111-1111-1111-1111-111111111111 --query latency
gotta granola search-transcript latency --time-range last_30_days
gotta slack workspaces
gotta slack auth
gotta slack search "handoff failure"
gotta read https://github.com/org/repo/blob/main/README.md
Stable interactive fingerprints like Codex threads and terminal sessions
automatically adopt their deterministic default session on the first
session-aware command that actually targets session state or acquires
remote/provider evidence. Provider search, provider get, remote/provider
read, and read-only session surfaces all auto-bootstrap there. Plain local
reads stay sessionless, and explicit --actor targeting still requires an
existing session because actor selection is session topology, not session
creation. Fallback synthetic fingerprints remain conservative and can still
use provider surfaces sessionlessly until a session is explicitly bound or
created.
gotta read is the canonical retrieval entrypoint. It supports:
- local files and directories
- bounded local rereads through
--head,--tail, and--section - bounded remote/provider reads whose limits only trim what is shown while the full canonical payload still lands underneath in the evidence web
- provider URLs routed to the correct plugin
- canonical provider locators emitted by session surfaces
- stored content rereads by artifact or digest
This surface is broader than search. It is the acquisition layer for the session's evidence web. Slack threads, GitHub pages, Jira issues, Google docs and Drive files, accessible shared-drive documents, Grafana dashboards, Confluence pages, and Granola notes all become reopenable session artifacts rather than transient terminal output.
Granola extends that same model to personal notes and transcripts through the local desktop session and Granola's APIs, so meeting notes and transcripts participate in the same durable evidence graph as repository, ticket, and chat artifacts.
Once that context is grounded, the same native surfaces support follow-on action. The goal is not only to recover information, but also to preserve enough working state that research, planning, and provider-native actions can happen against the same session context.
Remote Discovery
gotta search is the canonical plain-text remote discovery surface:
gotta search jira:Architecture
gotta search slack:ABC reboot --workspace demo --limit 10
gotta search github:SomeFunction --type code --repo acme/widgets
gotta search confluence:Architecture --title-only
The top-level verb already means search, so the routed target omits the
subcommand by default. Explicit routed aliases like github:search foo still
work, but the canonical form is github:foo.
Session Synthesis Surfaces
gotta session is how the raw evidence web becomes navigable:
session manifestsession timelinesession graphsession leadssession analyze
Examples:
gotta session show
gotta session manifest --plugin jira
gotta session timeline --limit 20
gotta session graph --output mermaid
gotta session leads artifact:ticket.md@0123deadbeef
gotta session analyze --mode lineage --output mermaid
gotta session analyze --output markdown
These surfaces intentionally compress the evidence web without severing it:
manifestsummarizes what has been materializedtimelinereconstructs chronologygraphrenders lineage and continuityleadsextracts explicit next reads from existing artifactsanalyzerebuilds cached session synthesis outputs from durable state
session analyze always renders the requested --output format to stdout and
still writes the durable analysis artifacts under the hood. Textual stdout is
budgeted by default; pass --full-output to disable terminal budgeting.
Successful operator surfaces emit a compact JSON receipt on stderr only when
gotta has non-obvious side effects to report, such as truncation, artifact
locators, or durable analysis outputs; pass --quiet to suppress informational
stderr output. Raw Mermaid output requires --mode lineage or --mode semantic; use --output markdown for the combined two-graph bundle.
Empty manifest, graph, leads, and analyze output means the session has
not materialized enough evidence yet.
After compaction pressure, these are the surfaces that make rehydration cheap. They preserve the shape of the work so the next pass starts from durable structure rather than a thin summary.
Session Coordination
Bind one shared session explicitly, then rewrite the operator-owned charter surfaces inside the active actor root:
gotta session bind retry-review
gotta actor bind Claude
gotta want --stdin <<'EOF'
Queue retry context review.
EOF
gotta goal --stdin <<'EOF'
Build the execution charter for the current session from live context.
EOF
That yields one shared session plus one actor-local working root:
sessions/retry-review/
session.json
content/
actors/<actor-id>/
WANT.md
GOAL.md
state/
content -> ../../content
Inside this topology:
WANT.mdandGOAL.mdare actor-local intentional rewritesstate/todo.jsonlis actor-local checklist truth andgotta todois the live readable/mutable surfacestate/logs.jsonlis actor-local procedural/system trace andgotta logsis the live readable trace surfacestate/oops.jsonlis actor-local friction truth andgotta oopsis the live readable friction surfacestate/notes.jsonlis actor-authored narration truth andgotta notesis the live readable narration surfacesessions/<session-id>/content/is shared across all actors bound into that session
Read-only session-rooted surfaces such as gotta oops, gotta logs,
gotta todo, gotta want, gotta goal, gotta actor status, and
gotta session show auto-bootstrap the deterministic default session for
stable interactive fingerprints like Codex threads and terminal sessions.
Fallback synthetic fingerprints still require either an existing bound session
or an explicit --session <session-id>.
This split is deliberate:
- narrative framing stays editable
- operational truth stays append-only and durable
- the CLI renders readable output from canonical state on demand
gotta session init scaffolds the target session and adopts it for the current
runtime context. Future commands in that same context should resolve there
ambiently. For shared-topology sessions, other contexts should reuse the shared
session id with --session <shared-session-id> or gotta session bind <shared-session-id>. Exact-root reuse with --session <session-root> or
gotta session bind '<session-root>' is the low-level path for non-shared
roots or intentionally reusing one concrete actor root.
Examples:
gotta session init
gotta want --stdin <<'EOF'
Queue retry context review.
EOF
gotta goal --stdin <<'EOF'
Trace retry handling from the first strong source anchor and keep the charter
current as evidence lands.
EOF
gotta todo append <<'EOF'
Inspect duplicate materializations in `gotta session analyze`.
EOF
gotta logs append <<'EOF'
Captured the first GitHub, Jira, and Confluence anchor set.
EOF
gotta oops append <<'EOF'
Direct fetch coverage should preserve the same continuity guarantees as search.
EOF
Shared Sessions
Each shared session owns its evidence web directly and carries nested actor-local session areas beneath it.
- shared session roots live at
sessions/<session-id>/ - actor-local session areas live at
sessions/<session-id>/actors/<actor-id>/ - the active fingerprint points at one actor-local root through
bindings/<fingerprint> - shared evidence lives under
sessions/<session-id>/content/ - actor-local planning and lifecycle state stay local to each actor root
- actor targeting is explicit actor selection inside the current session, not
path traversal under
actors/
Examples:
gotta session bind retry-review
gotta actor bind Claude
ACTOR=<bound-actor-id>
gotta want --actor "$ACTOR" --stdin <<'EOF'
Trace retry ownership from the first strong source anchor.
EOF
gotta goal --actor "$ACTOR" --stdin <<'EOF'
Materialize the actor-local evidence contract before launch.
EOF
gotta actor launch "$ACTOR"
gotta notes show --actor "$ACTOR"
gotta todo extend --actor "$ACTOR" <<'EOF'
- Compare retry behavior across the relevant design docs.
EOF
Important invariants:
gotta session bind ...switches the active fingerprint binding to one actor root, whether you name it by shared session id, exact session root, or explicit<session>/<actor>reference- binding a shared session id joins that shared session through the caller's own actor root; binding an exact actor-root path reuses that exact actor root
gotta actor bind ...binds sibling actor sessions inside that shared session but does not launch them- actor-local
WANT.mdandGOAL.mdare seeded placeholders that must be rewritten before launch withgotta want --actor <actor> ...andgotta goal --actor <actor> ... - actor-local checklist state is seeded automatically and surfaced through
gotta todo - actor notes are the canonical actor-authored narration surface
- short one-line notes are valid; polished synthesis notes are optional
- actor evidence often lands in the shared manifest, timeline, and graph before notes fully catch up
The important property is continuity under delegation. Actors can branch, gather evidence, and rejoin the shared working set without flattening everything into a single chat transcript.
oops As Canonical Alignment
gotta oops is a first-class operator surface.
Bare gotta oops shows the friction ledger. gotta oops show is the explicit
read form. gotta oops append ... and gotta oops extend ... write new
entries. Bare prose, real piped stdin, --stdin, and --from-file still imply
append when no read action is named.
Use it to record:
- incomplete or misleading contracts
- native surfaces that should have been followable but were not
- provider coverage limits that materially shaped the working path
- workflow friction that forced avoidable detours
The point is not merely bug tracking. The point is preserving operator-visible misalignment in canonical shared state so the tool can be refined from observed behavior rather than taste or memory.
Key Concepts
These terms appear throughout gotta and its documentation:
-
session — a durable working root that survives context loss. Sessions own a content store, actor roots, and synthesis surfaces. They can be reopened, extended, handed off, or compacted and rehydrated.
-
actor — a named participant in a session. Each actor has its own charter files (
WANT.md,GOAL.md), canonical state, and lifecycle.gotta notesis actor-authored narration,gotta logsis procedural/system trace,gotta oopsis friction, andgotta todois the checklist surface. Actors can be human operators, AI agents, or automated workflows. -
fingerprint — the context identity that binds the current terminal, thread, or environment to a session and actor root. Fingerprints are derived from terminal session IDs, Codex thread IDs, or explicit bindings.
-
materialization — the act of capturing command output as a durable, content-addressed artifact in the session's content store. Materialized evidence has a SHA-256 digest and can be reopened by locator.
-
canonical locator — a provider-normalized reference for a materialized artifact. Examples:
github:org/repo/blob/main/README.md,jira:PROJ-123,slack:C01234/p1234567890. Locators are emitted when evidence lands and can be followed withgotta read. -
artifact locator — a session-relative reference to stored content. Format:
artifact:<preferred-name>@<digest12>. Resolves throughgotta readwithout requiring manifest spelunking. -
content locator — a digest-based reference to stored bytes. Format:
content:<sha256>. Two identical fetches share the same content object. -
evidence web — the accumulated set of materialized artifacts, their metadata, and the relationships between them. The web grows through retrieval waves and can be navigated through synthesis surfaces.
-
synthesis surface — a compressed, navigable view over the evidence web.
manifestsummarizes what has been materialized.timelinereconstructs chronology.graphrenders lineage.leadsextracts followable references.analyzerebuilds cached session synthesis. -
friction — operator-visible misalignment captured in
oops. Not bug tracking. Friction records seams: misleading contracts, continuity gaps, workflow detours. The canonical log isstate/oops.jsonl;gotta oopsis the readable surface. -
projection — an on-demand terminal render from canonical state or a provider/content transform. Projections are no longer seeded as live root files; the CLI is the live readable surface.
-
rehydration — recovering prior working state from durable session artifacts after context has been compressed. The synthesis surfaces make rehydration cheap: they preserve the shape of the work so the next pass starts from structure rather than a thin summary.
Plugin Architecture
gotta uses two entry-point groups:
gotta.pluginsfor top-level pluginsgotta.askfor optional ask-family extensions
Core is a PEP 420 namespace package. Plugins can live in separate distributions
and still contribute modules under the shared gotta namespace.
Core ships these top-level plugins:
askconfluencegdocsgdrivegrafanagranolagithubgsheetsjiralogsnotesoopsactorreadsessionslacktodowantgoal
read is the URL-shaped dispatcher. It routes recognized targets through
installed provider plugins by asking those plugins whether they own the target.
Ask Extensions
gotta ask is a generic host for separately installed ask-family extensions.
Ask surfaces are provided by extensions that register the gotta.ask
entry-point group.
An ask extension registers the gotta.ask entry-point group and then becomes
available as:
gotta ask <surface> ...
Use gotta ask --help-all to inspect installed ask surfaces recursively.
Contributing And Release Discipline
The project is maintained with a few deliberate rules:
- remove residue instead of layering over it
- prefer tool-observable truth to conversational assumption
- keep friction canonical in
oops - treat complexity as measurable pressure, not just aesthetic discomfort
- preserve session continuity and reopenable evidence paths
If you contribute:
- run the full quality gate before proposing changes
- keep examples and fixtures generic and public
- preserve the native evidence-first workflow
- prefer behavior-level cleanup over compatibility ballast
See CONTRIBUTING.md for the repository baseline.
Release
Build and validate artifacts with uv:
./scripts/release patch
./scripts/release minor
The script is the canonical release path. It bumps the version with uv,
runs the release gate, builds the wheel and sdist, validates them with
twine check, smoke-installs the wheel on Python 3.10, commits the release
metadata, pushes main, publishes to PyPI, and waits for public propagation.
It reads the PyPI token from ~/.pypirc under [pypi].password.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gotta-0.27.0.tar.gz.
File metadata
- Download URL: gotta-0.27.0.tar.gz
- Upload date:
- Size: 393.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f6db7a69eef664dc2ecc2049e5c598b8bfd8a0ef6adf44cd254b62e408b9e83
|
|
| MD5 |
ca6f17bc9d5504fdaa9c115cfed25666
|
|
| BLAKE2b-256 |
949ca06c2c8d22cc2a34bdb753a8b06c2ec0277b8f1a3146a447e0d2789e2571
|
File details
Details for the file gotta-0.27.0-py3-none-any.whl.
File metadata
- Download URL: gotta-0.27.0-py3-none-any.whl
- Upload date:
- Size: 334.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1418785e619ead2e713bc41e07ceaa7dc232547526850a1ac100da4a0a499696
|
|
| MD5 |
f99a6401785521de08bb3168c013281d
|
|
| BLAKE2b-256 |
98ec02dd478c1db162caa99e617cd1fa96d16e229a0b05a3e09fcb12eda4b02d
|