Ingest a project directory into the Obsidian vault as a linked context sub-graph — Architecture, Conventions, Invariants, Hotspots, Tests, Glossary, plus per-bounded-context module notes. Tracks refresh deltas over time, flags stale context, and feeds prompt generation via backlinks. Use when the user says "load context", "refresh context", "ingest project", "update context for X", or provides a directory path to analyze.
Ingest a project directory into the Obsidian vault as a linked context sub-graph — Architecture, Conventions, Invariants, Hotspots, Tests, Glossary, plus per-bounded-context module notes. Tracks refresh deltas over time, flags stale context, and feeds prompt generation via backlinks. Use when the user says "load context", "refresh context", "ingest project", "update context for X", or provides a directory path to analyze.
Conducty Context — Project Ingestion as a Sub-Graph
A single big Context My App.md is a brittle context engine. Re-reading 250 lines on every plan misses what changed and what's stale. Instead, decomposes a project into a linked sub-graph in the Obsidian vault. Each note has one purpose, a stable filename, and explicit cross-links. Plans pull only the slices they need; refreshes record deltas instead of overwriting.
conducty-context
[!important] Read [[conducty-obsidian]] first
All output goes to the vault. Per-instance notes follow Title Case; this skill writes a hub note plus several sub-notes per project.
When to Use
First time loading a project: conducty-context /path/to/project
The user says "refresh context" or "the project has changed since last load"
Plan execution surfaces stale architecture info — a refresh fires
A new bounded context emerges that wasn't captured before
The Project Sub-Graph
For each project, the vault holds one hub note plus a set of slice notes. All slice names are deterministic so wikilinks resolve from any plan or design.
Slice
Filename
Holds
Hub
Context {Project}.md
One-paragraph project identity, links to every slice, last-refreshed timestamp
Context Refresh {Project} YYYY-MM-DD HHmm.md — what changed since last load: new files, removed files, new bounded contexts, broken invariants, new convention violations. Older refresh notes accumulate as a temporal record.
Workflow
Step 1: Identify the Target
Resolve the directory path to absolute. Extract project name from the basename, convert to Title Case for vault filenames (my-app → My App).
Check the vault for an existing hub note:
test -f "$VAULT/Context/$PROJECT/Context $PROJECT.md" && echo"refresh" || echo"first load"
If this is a first load, create the project sub-graph directories before writing any slice:
First load: generate every slice + the hub. Move on.
Refresh: read the existing hub's last_refreshed frontmatter. Compute deltas (Step 7) and either edit each slice in place (preserving frontmatter, prepending changes) or write a refresh-delta note describing the diff and updating the hub's last_refreshed.
Use Glob (src/**, lib/**, pkg/**, app/**) two levels deep to enumerate modules. For each module:
What is its responsibility?
What does it import from other modules?
What imports it?
What's its public surface (exports)?
Render a Mermaid dependency diagram in the Architecture slice — Obsidian renders Mermaid natively:
flowchart LR
auth --> session
api --> auth
api --> billing
billing --> session
session --> db
For modules with non-trivial internal complexity (>500 lines, multiple sub-responsibilities, or a public API surface other code depends on), generate a bounded-context deep note at Context/{Project}/Modules/Context {Project} {Module}.md and link it from Architecture.
Step 5: Capture Conventions
From style configs and observed code:
Naming: file, type, function, variable
File organization: where do new features go? where do tests live?
If a command can't be run safely (long-running, external deps required), record it but don't execute. If you can run it, do — record last_test_count, last_pass_count, last_run timestamp.
Step 9: Build the Glossary
Pull domain terms from:
README headings + first occurrence prose
Public type names, route names, table names
Comments that define terms
For each: term + 1-sentence definition + a backlink to the most relevant code path. The glossary makes plans precise — when a prompt says "publish a SessionTrace", everyone reading the plan knows what that means without re-deriving it.
Step 10: Write the Sub-Graph
Write each slice with frontmatter and a ## Related section that links the hub and peers. All paths below are relative to $VAULT. The hub and the six standard slices live directly under Context/{Project}/. Module deep notes live under Context/{Project}/Modules/. Refresh deltas live under Context/{Project}/Refreshes/.
Wikilinks remain unchanged across the move — Obsidian resolves them by basename. Use [[Context {Project} Architecture]] etc, never path-prefixed wikilinks.
Hub note
---
type: context
project: {project-name}
path: /absolute/path
last_refreshed: YYYY-MM-DD HH:MM
language: {primary language}
tags: [conducty, conducty/context, conducty/context-hub]
---
# Context: {Project Title Case}
{One-paragraph project identity: what it does, who uses it, primary language/framework.}
## Slices
- [[Context {Project} Architecture]]
- [[Context {Project} Conventions]]
- [[Context {Project} Invariants]]
- [[Context {Project} Hotspots]]
- [[Context {Project} Tests]]
- [[Context {Project} Glossary]]
## Bounded-context deep notes
- [[Context {Project} {Module1}]]
- [[Context {Project} {Module2}]]
## Refresh history
- [[Context Refresh {Project} 2026-04-27 1830]]
- [[Context Refresh {Project} 2026-04-20 0915]]
## Related
- Index: [[Context Index]]
- Used by plans: (backlinks fill in)
Slice notes
Each slice carries type: context-{slice} (e.g. context-architecture), the project frontmatter, and ## Related linking the hub and any peer slice that's relevant (e.g. Architecture links Tests because deep modules need their own test commands).
When refreshing an existing project, write Context/{Project}/Refreshes/Context Refresh {Project} YYYY-MM-DD HHmm.md:
---
type: context-refresh
project: {project-name}
date: YYYY-MM-DD
time: HHmm
prior_refresh: YYYY-MM-DD HHmm
tags: [conducty, conducty/context, conducty/refresh]
---
# Context Refresh — {Project} — YYYY-MM-DD HHmm
Compared against the prior refresh ({prior date}).
## Files
- **New** ({n}): {list with one-line purpose where obvious}
- **Removed** ({n}): {list}
- **Major churn** ({n}): {list with delta line counts}
## Bounded contexts
- **New**: {module names + responsibility}
- **Removed**: {names}
- **Boundary changes**: {module X now depends on Y where it didn't before}
## Invariants
- **Broken / deviated**: {public API change, schema change, etc. — flag prominently}
- **New**: {newly declared contracts}
## Conventions
- **Drift**: {new patterns appearing inconsistent with declared conventions}
- **New rules**: {explicit additions to lint config or AGENTS.md}
## Tests
- Test count: {old → new}
- Pass count: {old → new}
- New failing tests: {list}
## Notes
{anything surprising worth flagging for the next plan}
## Related
- Hub: [[Context {Project}]]
- Architecture: [[Context {Project} Architecture]]
- Prior refresh: [[Context Refresh {Project} YYYY-MM-DD HHmm]]
Apply changes to slice notes (Edit, not full overwrite). Update the hub's last_refreshed frontmatter. Prepend the new refresh-delta note to the hub's ## Refresh history list.
Step 12: Stale Detection
After writing, check all other project hub notes in the vault (Glob Context/*/Context *.md, then filter to depth-2 to skip slices). For any hub with last_refreshed older than {stale threshold — default 14 days, configurable per project via frontmatter stale_after_days}, flag it in your report:
"Stale context: [[Context Other Project]] last refreshed 2026-04-10 (17 days ago). Consider refresh before next plan touching it."
This catches drift before it bites a plan.
Step 13: Confirm
Tell the user:
Path written/refreshed
Bounded contexts identified (count + names)
Key seams for prompt decomposition
Any characterization concerns (failing tests, no tests, command not found)
For refresh: a one-line summary of the most important delta
Any stale hubs flagged (Step 12)
Reading Context During Planning
[[conducty-plan]] and [[conducty-shape]] do not read the entire sub-graph by default. They read the hub plus the slice(s) the plan needs:
A new feature touching auth → read [[Context {Project}]], [[Context {Project} Architecture]], [[Context {Project} Conventions]], [[Context {Project} {Auth Module}]] if present.
A refactor → also read [[Context {Project} Tests]] (for characterization) and [[Context {Project} Invariants]].
A ship gate → [[conducty-ship]] reads [[Context {Project} Tests]] only.
Slice loading keeps prompt context budgets sane and makes "what do you know about X?" answerable by Glob + Read on a known filename, not freeform search.
Backlink-Driven Planning
When [[conducty-plan]] starts a project plan, it can ask Obsidian-style: "find every plan / design / failure-pattern that ever referenced this project." That's a vault grep for [[Context {Project} (matches the hub and all slices). The result is the project's full historical context — every prior decision, failure, design choice — surfaced for the new plan.
# Find every note referencing this project's context
grep -rl "\\[\\[Context {Project}""$CONDUCTY_VAULT"
This is the payoff for splitting context into a sub-graph: history compounds.
Guidelines
Slice over single-doc — easier to refresh deltas, easier to prompt with only what's needed
Determinism in filenames — every slice is Context {Project} {Slice}.md, no improvising
Mermaid in Architecture — Obsidian renders it; don't waste lines on ASCII art
Refresh deltas, not overwrites — preserve the temporal record
Stale flag on every load — drift kills plans; surface it proactively
Bounded-context deep notes are optional — only for modules large enough to merit one. Don't generate one per file.
Glossary feeds prompt precision — terms used in plans should resolve to glossary entries
Tests slice is [[conducty-ship]]'s contract — keep its commands current and runnable