Skip to main content

Navigating Project Context

Plugin: TSH Product Management
Invoke: /tsh-product-management:navigating-project-context [question] [context repository URL] (also model-invocable: it routes on questions about a project's scope, decisions, terms and owners)
Used by: the tsh:project-context block that Initializing Project Context writes into a connected repository's CLAUDE.md (or CLAUDE.local.md). The block directs sessions to this skill for work that touches decisions, scope, glossary terms, the data model or new dependencies. No other skill or agent loads it.

Reads a project's knowledge base, the <project>-context repository, before work that depends on it. It never answers a project question from memory: it reads the corpus and cites the document.

When it applies​

  • Questions about the project's scope, requirements, decisions or terminology in a repository whose CLAUDE.md carries a tsh:project-context block, or whose settings declare a *-context marketplace.
  • Starting a feature, review or plan in such a repository.
  • "What did we decide about", "who owns", "what does a term mean here".
  • Code and documentation disagreeing.
  • A context-repository URL given to read from anywhere, with no code repository.

What it covers​

AreaCoverage
LocateFinds the knowledge base (KB) wherever the clone sits: beside the code, in a project folder, or in ~/.tsh/context/<slug>/. With a git URL in the arguments it resolves by URL
SyncBrings the clone up to date before reading. The only change it can make is a fast-forward of a clean clone on the default branch
Reading orderKB/CLAUDE.md, then KB/docs/README.md (the area map), then KB/docs/decisions/README.md, then the owning workspace's README.md and CLAUDE.md, then KB/docs/glossary.md when a term is in question
DecisionsFilters the index to Accepted first, then narrows by the Scope column. Only Accepted records are constraints; a Superseded record is read with its successor. This is the only archive: no records are looked up or written in a code repository
CitationsEvery project fact is followed by its source: file, last-change date and owner, for example (docs/decisions/0004-payments.md · changed 2026-09-12 · owner: Jane Doe). A file with no output from git log is reported as "uncommitted"
WarningsEvery sync warning goes at the top of the answer, one line each, before anything else
ConflictsA source older than the code it describes, or than a later document on the same topic, is a finding. When knowledge and code disagree, both sources are reported and the workspace owner who decides is named
DeprecationA DEPRECATED banner under a title is checked before citing the document; such a document is history, not current state
VocabularyUses the glossary's canonical terms in identifiers, tickets and documents it writes

How it works​

  1. Locate and sync. Follow the shared locating guide: run locate_project_context.py (with --url when the arguments carry a git URL), then sync_project_context.py. Stop if nothing resolves; keep the sync's warnings for the answer.
  2. Read only what the task needs, in the order above. The corpus is large by design and the area map exists so the skill does not read all of it.
  3. Date every source it will cite, one git log -1 --format='%cs %an' per file. The owner is the one named in the owning workspace's CLAUDE.md.
  4. Answer. Warnings first, then the answer, each project fact followed by its source.

Locator outcomes​

ExitMeansWhat the skill does
0FoundContinues, then checks BLOCK and READ_ACCESS
1Not wired, nothing foundStops and says the repository is not connected; points to Initializing Project Context (Attach repository) or to --url
2Several knowledge bases in one folder (old layout)Asks which project the task belongs to; never picks one
3Wired, but this person has not chosen a clone yetAsks once where the knowledge base should live on this machine, offering existing clones, a default clone location or another folder; the choice is remembered for every repository of the project
4--use or --clone refusedShows the message; another project's clone is never used
5The name is taken: <slug>-context already names another project on this machineStops; one of the two projects must be renamed by its lead. Neither clone is read and the registry is never edited
  • BLOCK=missing or BLOCK=drift: the pointer block is gone or points at another URL. The skill says so in one line and offers to restore it through Attach repository; it never restores or edits it itself.
  • READ_ACCESS=missing: reads outside the session's folder will prompt each time. The skill offers once to add one line to the repository's .claude/settings.local.json, which git never sees (--grant-read).

Sync behaviour​

sync_project_context.py prints JSON and always exits 0 when the knowledge base exists: a stale read with a warning beats no read. It fetches at most once per TTL (default 600 s, TSH_CONTEXT_TTL), caps the fetch (default 5 s, TSH_CONTEXT_FETCH_TIMEOUT; the fast-forward pull that may follow is capped at no less than 30 s) and can never prompt for a password. It never merges, rebases, stashes, resets, checks out or pushes.

Warning codeMeans
not-gitThe knowledge base is plain files, not a git clone
local-onlyNo remote yet: the knowledge exists only on this machine
index-lockAnother git process holds the index; nothing was done
busyAnother sync of this knowledge base is running; read as is
offlineFetch failed or timed out (network, VPN, credentials)
blockedA local file the update would overwrite stopped the pull
not-default-branchThe clone is on another branch; that branch is what is read
dirtyUncommitted changes in the clone; they are what is read
behindThe clone is behind the remote and was not updated
unknown-defaultThe approved branch could not be determined; nothing was pulled
divergedLocal and remote history differ (for example after a force-push); nothing was changed and a fresh clone is the fix

On diverged the skill offers to clone the remote again into <KB>-fresh; the old copy stays and is never deleted. On no, it keeps reading the old copy with the warning.

Boundaries​

  • It never edits anything under KB as a side effect of work in a code repository. Changes go through Writing Project Knowledge, which writes on its own branch and routes the change to the owner.
  • Git in KB is limited to the two scripts and git log. The side effects allowed are a fast-forward of a clean default branch, a clone and a registry entry after the person chose a folder, and a settings.local.json entry after they said yes.

Source​