OpenSession is a local-first workflow for registering, sharing, and inspecting AI session traces. The public contract is a single Source URI model shared by CLI, Web, and API.
- Root quick reference:
README.md/README.ko.md - This file (
docs.md): product contract and command semantics - Development and CI parity runbook:
docs/development-validation-flow.md - Harness failure loop policy:
docs/harness-auto-improve-loop.md - Parser source/reuse boundaries:
docs/parser-source-matrix.md
Core principles:
- One concept, one name.
- One identity, one URI.
- No implicit network mutation.
- Defaults are allowed only when printed in output.
Beginner 3-step quick start:
# Print the first-user command flow
opensession docs quickstart
# 1) Install CLI
cargo install opensession
# 2) Diagnose local setup (flutter doctor style)
opensession doctor
# 3) Apply setup after explicit confirmation prompt
opensession doctor --fix --profile localdoctor --fixprints a setup plan and asks before applying hook/shim/fanout changes.- For automation or non-interactive shells, use explicit mode + approval:
opensession doctor --fix --yes --profile local --fanout-mode hidden_ref
Quick path:
# 1) Parse agent-native logs into canonical HAIL JSONL
opensession parse --profile codex ./raw-session.jsonl > ./session.hail.jsonl
# 2) Register canonical session in local object store
opensession register ./session.hail.jsonl
# -> os://src/local/<sha256>
# 3) Read local canonical bytes back
opensession cat os://src/local/<sha256>
# 4) Inspect summary metadata
opensession inspect os://src/local/<sha256>Install:
cargo install opensessionInstall profiles:
local(default): CLI-local-first path for backup/summary/handoff usersapp: desktop-linked path for app users (opensession doctor --fix --profile app --open-target app)
Auto-capture note:
opensessioncovers parse/register/share/handoff.- Automatic background capture requires the daemon process (
opensession-daemon run) to be running.
Repository development toolchain:
- Local validation hooks are executed via
mise. - Run
mise installat repo root before./.githooks/pre-commit/./.githooks/pre-push. - Desktop preflight gate:
node scripts/validate/desktop-build-preflight.mjs --mode local.
Local object storage:
- In repo:
.opensession/objects/sha256/ab/cd/<hash>.jsonl - Outside repo:
~/.local/share/opensession/objects/sha256/ab/cd/<hash>.jsonl
Hash policy:
- SHA-256 of canonical HAIL JSONL bytes.
Desktop IPC/runtime settings use the typed summary contract:
summary.provider.id|endpoint|modelsummary.prompt.templatesummary.response.style|shapesummary.storage.trigger|backendsummary.source_modevector_search.enabled|provider|model|endpoint|granularity|chunk_size_lines|chunk_overlap_lines|top_k_chunks|top_k_sessions
Desktop local constraints:
auth_enabled=falseruntime hides account/auth UI by design.summary.source_modeis locked tosession_onlyin desktop local runtime.session_or_git_changesis reserved for non-desktop runtime contexts (for example CI/CLI).- Default summary storage backend is
hidden_ref. - Even with
hidden_ref, list/search metadata and vector-index metadata are indexed in local SQLite (OPENSESSION_LOCAL_DB_PATHor default~/.local/share/opensession/local.db). - Runtime response preview UI is deterministic local sample rendering, not model output.
Desktop local extras:
/docscan be resolved from desktop IPC (desktop_get_docs_markdown) when HTTP docs route is unavailable.- Vector search uses event/line chunk indexing and local Ollama embeddings (
bge-m3default). - Vector search enablement is explicit: model install must complete first (
desktop_vector_preflight,desktop_vector_install_model). - Indexing is explicit and observable (
desktop_vector_index_rebuild,desktop_vector_index_status).
register is local-only. Remote sharing is explicit via share.
# Local source -> one-click git share URI flow
opensession share os://src/local/<sha256> --quick
# Optional network side effect
opensession share os://src/local/<sha256> --git --remote origin --pushshare --git / share --quick rules:
--quickauto-detects remote (originpreferred, single remote fallback)--gitrequires explicit--remote <name|url>- Default ref:
refs/opensession/branches/<branch_b64url> - Default path:
sessions/<sha256>.jsonl --pushomitted: no network mutation (prints runnable push command)--quickasks once before first push, then stores per-repo consent in.git/configasopensession.share.auto-push-consent=true- Legacy fixed ref
refs/heads/opensession/sessionsis no longer used for new writes.
Install-and-forget setup:
opensession doctor
opensession doctor --fix --profile local
# optional explicit mode in interactive shells
opensession doctor --fix --profile local --fanout-mode hidden_ref
# automation/non-interactive
opensession doctor --fix --yes --profile local --fanout-mode hidden_ref --open-target webdoctorcheck mode maps to internal setup checks;doctor --fixmaps to the internal setup apply flow.doctor --fixrequires explicit approval: interactive prompt by default,--yesfor automation.- Installs/updates OpenSession-managed
pre-pushhook in the current repo. - Installs/updates OpenSession shim at
~/.local/share/opensession/bin/opensession. - On first apply without a configured mode, interactive shells prompt for fanout mode (
hidden_reforgit_notes) and store it in local git config (opensession.fanout-mode). - Non-interactive apply requires explicit fanout mode (
--fanout-mode) if the repository has no storedopensession.fanout-mode. - Open target defaults by profile (
local -> web,app -> app). doctorcheck output includes daemon status from~/.config/opensession/daemon.pid.- Start daemon with
opensession-daemon run(orcargo run -p opensession-daemon -- runin a source checkout). - Does not modify
remote.<name>.push. - Hook fanout push is best-effort and warning-only.
- Set
OPENSESSION_STRICT=1to fail push when fanout helper is unavailable or fanout push fails. - PR automation currently targets same-repo non-bot PRs only.
- Merge/branch-delete cleanup removes ledger refs immediately; physical object removal follows remote GC policy.
share --web rules:
opensession config init --base-url https://opensession.io
opensession config show
opensession share os://src/git/<remote_b64>/ref/<ref_enc>/path/<path...> --webshare --webrequires explicit.opensession/config.toml- Local URI with
--webis rejected with follow-up action (share --git) - Human output prints canonical URL as first line
OpenSession can configure hidden ref cleanup for user repositories without changing server-side infrastructure.
# Initialize provider-aware cleanup templates/config
opensession cleanup init --provider auto
# Non-interactive setup
opensession cleanup init --provider auto --yes
# Inspect config + janitor dry-run summary
opensession cleanup status
# Dry-run (default)
opensession cleanup run
# Apply deletions
opensession cleanup run --apply
# Keep review snapshots permanently on a dedicated branch
opensession cleanup init --provider auto --session-archive-branch pr/sessions --yesDefaults:
- hidden ref TTL: 30 days
- artifact branch TTL: 30 days
For sensitive repositories:
opensession cleanup init --provider auto --hidden-ttl-days 0 --artifact-ttl-days 0 --yesProvider matrix:
- GitHub:
.github/workflows/opensession-cleanup.ymlplus.github/workflows/opensession-session-review.ymlare generated. By default PR updates publish ephemeralopensession/pr-<number>-sessionsbranches and delete them when the PR closes; set--session-archive-branch <branch>to keep immutable review snapshots on a dedicated archive branch such aspr/sessions. - GitLab:
.gitlab/opensession-cleanup.ymlplus.gitlab/opensession-session-review.ymlare generated;.gitlab-ci.ymlis updated only when an OpenSession managed marker block exists (or file is newly created). MR pipelines publish/refreshopensession/mr-<iid>-sessionsand post an MR note, or use the configured archive branch when--session-archive-branchis set. - Generic git:
.opensession/cleanup/cron.exampleis generated for cron/system scheduler wiring. - Session-review comments include
Reviewer Quick Digestwith mobile-friendly Q&A prose, modified file summary, and added/updated tests.
Canonical validation flow (hooks, API/worker/web/desktop E2E, CI parity, artifact policy):
docs/development-validation-flow.md
Quick local gate commands:
./.githooks/pre-commit
./.githooks/pre-pushGitHub CI split:
.github/workflows/ci.ymlkeeps fast PR/main gates only..github/workflows/ci-deep.ymlowns long-running audit/E2E/desktop validation on schedule or manual trigger.
Desktop build policy:
- Linux desktop bundle build verification is required in deep CI (
desktop-bundle-verify). - macOS desktop release target is
universal-apple-darwinonly. - Universal architecture is validated by
lipo -archsand must include bothx86_64andarm64. - A scheduled/manual
Desktop Dry Runworkflow validates no-sign desktop bundling and uploads diagnostics/metrics artifacts.
Release signing checklist (manual secret provisioning):
APPLE_CERTIFICATEAPPLE_CERTIFICATE_PASSWORDAPPLE_SIGNING_IDENTITYAPPLE_IDAPPLE_PASSWORDAPPLE_TEAM_ID
Use these commands when a common onboarding flow fails:
share --webgot a local URI:
opensession share os://src/local/<sha256> --git --remote origin
opensession share os://src/git/<remote_b64>/ref/<ref_enc>/path/<path...> --webshare --gitmissing--remote:
opensession share os://src/local/<sha256> --quickshare --gitoutside git repo:
cd <repo>
opensession share os://src/local/<sha256> --quickshare --webmissing config:
opensession config init --base-url https://opensession.io
opensession config showregisterrejected non-canonical input:
opensession parse --profile codex ./raw-session.jsonl --out ./session.hail.jsonl
opensession register ./session.hail.jsonlparseparser/input mismatch:
opensession parse --help
opensession parse --profile codex ./raw-session.jsonl --previewviewtarget resolution failed:
opensession view os://src/... --no-open
opensession view ./session.hail.jsonl --no-open
opensession view HEADcleanup runbefore initialization:
opensession cleanup init --provider auto
opensession cleanup runFive-minute first-user recovery path:
opensession doctor
opensession doctor --fix --profile local
opensession parse --profile codex ./raw-session.jsonl --out ./session.hail.jsonl
opensession register ./session.hail.jsonl
opensession share os://src/local/<sha256> --quickCanonical web routes:
/src/gh/<owner>/<repo>/ref/<ref_enc>/path/<path...>/src/gl/<project_b64>/ref/<ref_enc>/path/<path...>/src/git/<remote_b64>/ref/<ref_enc>/path/<path...>
Legacy shortcut routes are reserved and return 404:
/git/gh/*/resolve/*
Server parse-preview endpoint:
POST /api/parse/preview
opensession view is the review-first entrypoint for web view.
# Source URI -> /src/*
opensession view os://src/gl/<project_b64>/ref/<ref_enc>/path/<path...>
# Local source URI / jsonl file -> /review/local/<id>
opensession view os://src/local/<sha256>
opensession view ./session.hail.jsonl
# Commit/ref/range -> commit-linked local review bundle
opensession view HEAD
opensession view main..feature/my-branchDefault mode is web. Use --no-open to print URL only.
Local view targets do not require registered git credentials.
They use local git objects / local source bytes and generate a local review bundle.
Commit-linked local review pages expose a Reviewer Quick Digest panel that renders mobile-friendly Q&A content excerpts (not just counts), modified files, and added/updated tests.
Handoff artifacts are immutable. Build creates a new artifact URI every time.
# Build immutable artifact
opensession handoff build --from os://src/local/<sha256> --pin latest
# -> os://artifact/<sha256>
# Read payload representation
opensession handoff artifacts get os://artifact/<sha256> --format canonical --encode jsonl
# Verify deterministic hash
opensession handoff artifacts verify os://artifact/<sha256>
# Alias control
opensession handoff artifacts pin latest os://artifact/<sha256>
opensession handoff artifacts unpin latest
# Removal policy (unpinned only)
opensession handoff artifacts rm os://artifact/<sha256>No refresh/update command exists in v1. Rebuild and move pin aliases.
CLI is the canonical operator surface. Web and TUI are optional interfaces over the same URI contract.
Source and artifact identifiers:
os://src/local/<sha256>os://src/gh/<owner>/<repo>/ref/<ref_enc>/path/<path...>os://src/gl/<project_b64>/ref/<ref_enc>/path/<path...>os://src/git/<remote_b64>/ref/<ref_enc>/path/<path...>os://artifact/<sha256>
Encoding rules:
ref_enc: RFC3986 percent-encodingproject_b64,remote_b64: base64url (no padding)
API boundary:
DELETE /api/admin/sessions/{id}- Header:
X-OpenSession-Admin-Key