Sweep addressed callouts older than a threshold (default 180 days) into the target note's
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Rebuild the vault dependency graph (_graph.md) via the deterministic generator script. /graph forces a full rebuild; /graph last (run after every /sync) rebuilds only if the vault changed; /graph [N] is treated as last. The generator reads the vault and writes _graph.md directly, so the file never streams through a model response.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
Rebuild _graph.md from vault state. Structural metadata only — no content files modified, no snapshots, no _hot.md changes.
Engine: .claude/skills/graph/generate_graph.py (deterministic). It reads every Thesis / Sector / Macro / Research file, validates wikilinks, and writes _graph.md directly. This replaced the legacy LLM-extraction + incremental-Edit procedure on 2026-06-04, after that approach hit a max-output-token wall: the full file is ~90 KB ≈ ~21 K output tokens, too large to emit in one model response — and both /graph (always full Write) and /graph last (escalation Write) funneled into that single oversized write. Generating the file from a script removes model output tokens from the path entirely, so the failure class (token ceiling, escalation traps, watermark edge cases, surgical-Edit anchor failures) cannot recur.
.last_sync is owned exclusively by /sync. /graph never touches it.
Design rationale for the (now-superseded) incremental design: .claude/skills/graph/RATIONALE.md. Legacy manual procedure: git history prior to 2026-06-04 + the Fallback section below.
vault-wide scope per .claude/skills/_shared/preflight.md Procedure 1 (§1.3a) — /graph reads every thesis file, so a concurrent writer could produce inconsistent extraction. Capture the token; release in the final Bash block (ownership-checked).
Use the standard §1.3a block verbatim (with skill: /graph) — do NOT hand-roll a lock. The prior inline form omitted timeout_at:, the .vault-lock.* collision scan, and set -C noclobber, so (a) any preflight-conformant skill's collision loop read graph's lock as timeout_at:-empty → [[ "" > "$NOW" ]] false → classified a LIVE graph run STALE and invited a force-unlock, and (b) graph did not detect concurrent ticker locks at all.
LOCK_FILE=".vault-lock"
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
TOKEN="$(printf '%08x' $RANDOM$RANDOM)-$(date -u +%s)"
TIMEOUT_AT=$(date -u -v+10M +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d '+10 minutes' +%Y-%m-%dT%H:%M:%SZ)
setopt NULL_GLOB 2>/dev/null || shopt -s nullglob 2>/dev/null || true
for existing in .vault-lock .vault-lock.* ; do
[ -f "$existing" ] || continue
EX_TIMEOUT=$(grep '^timeout_at:' "$existing" | sed 's/timeout_at: //')
EX_SKILL=$(grep '^skill:' "$existing" | sed 's/skill: //')
EX_TOKEN=$(grep '^token:' "$existing" | sed 's/token: //')
if [[ "$EX_TIMEOUT" > "$NOW" ]]; then
echo "LOCK_HELD|$existing|$EX_SKILL|$EX_TOKEN|$EX_TIMEOUT"; exit 1
else
echo "STALE_LOCK|$existing|$EX_SKILL|$EX_TOKEN|timeout_exceeded_at|$EX_TIMEOUT"; exit 2
fi
done
set -C
if ! cat > "$LOCK_FILE" <<EOF
---
token: $TOKEN
skill: /graph
scope: vault-wide
started_at: $NOW
timeout_at: $TIMEOUT_AT
session_id: ${CLAUDE_SESSION_ID:-unknown}
---
# Vault lock
Held by /graph (token $TOKEN) since $NOW.
EOF
then
set +C; echo "LOCK_RACE|$LOCK_FILE|created by a concurrent run between check and write — re-run"; exit 1
fi
set +C
trap "rm -f '$LOCK_FILE'" INT TERM
echo "ACQUIRED|$LOCK_FILE|$TOKEN"
Reclaim a stale lock (STALE_LOCK) only per §1.6 — never auto-steal. Release in the final Bash block with the ownership-verified form (grep '^token:' .vault-lock == $TOKEN before rm -f).
/graph is read-only for theses; the graph faithfully reflects current filenames + wikilinks. /lint #37 surfaces pending rename markers separately.
Map the argument to a mode and invoke once:
| Invocation | Arg | Behavior |
|---|---|---|
/graph | full | Always (re)writes _graph.md (disaster-recovery semantics). |
/graph last | last | Writes only if the body changed OR a force-marker is present; else leaves the file untouched and reports up-to-date. |
/graph [N] | last | Same as last (N accepted for back-compat, treated as last). |
python3 .claude/skills/graph/generate_graph.py full # or: last
What the generator does (so the report is faithful):
Macro/ prefix, typo'd thesis names) and the intentional-unresolved [[pinned]] / [[preserve]] markers (never flagged as broken).status: + log_tail: — last 3 Log entries, truncated at 100 chars + …) that /sync Pass 1 triage depends on.### / status / log_tail counts all equal the thesis count). Exit 0 = written or up-to-date, 2 = validation failed, 1 = runtime error..sync_all_fresh and .graph_invalidations force-markers (their presence forces a write even when the body is unchanged, so closures/sync-all always reconcile).If the generator exits non-zero: do NOT leave a half-written graph. Surface its stdout/stderr verbatim and use the Fallback section. Exit 2 means the file was written but failed structural checks — re-run full; if it persists, the schema contract or the vault is the problem.
The generator already self-validated. Confirm structure and release the lock in one Bash block:
echo "=== frontmatter ==="; head -13 _graph.md
echo "=== sections (expect 5) ==="; grep -cE '^## ' _graph.md
echo "=== entries vs cache (three numbers must be equal) ==="
printf '### %s | status %s | log_tail %s\n' \
"$(grep -cE '^### ' _graph.md)" "$(grep -c '\*\*status:\*\*' _graph.md)" "$(grep -c '\*\*log_tail:\*\*' _graph.md)"
# lock release — ownership-checked (substitute LOCK_TOKEN captured at Step 0.1)
EXPECTED="<LOCK_TOKEN>"
if [ -f .vault-lock ] && grep -q "token: $EXPECTED" .vault-lock; then rm -f .vault-lock && echo "LOCK RELEASED";
else echo "⚠️ lock token mismatch — not removing"; fi
Report to the user:
written / up-to-date) + reason (from generator stdout)./lint pass or manual cleanup fixes the source, the graph just reflects current truth.Frozen interface — consumers depend on it: /sync Pass 1 triage (reads status: + log_tail: prefixes) and the graph-primer in /ingest, /compare, /thesis, /stress-test, /brief, /deepen. Any change to generate_graph.py must preserve:
type: vault-graph, date, last_graph_write (ISO-8601 …Z), graph_mode, theses, sectors, macro, research, edges, orphans.## Thesis Adjacency Index, ## Reverse Index: Macro → Theses, ## Reverse Index: Sector → Theses, ## Cross-Thesis Clusters, ## Orphan Research Notes.### TICKER - Name then 2-space bullets sectors / macros / cross-thesis / research / status / log_tail (— for empty); log_tail sub-bullets 4-space indent, ≤3, each truncated at 100 chars + … (horizontal ellipsis — /lint #42 safe, never ...)./lint #38 ages the graph state-markers (.sync_all_fresh / .graph_invalidations), NOT graph_mode:; /lint #43 enforces the lock contract. Validation false-positive note: unbalanced [[ ]] inside log_tail sub-bullets is EXPECTED (truncation can sever a quoted link) — only structural fields and table rows must balance.
Reproduce the schema above without ever single-Write-ing the whole file (that is the failure this skill exists to avoid — at vault scale one Write is ~21 K output tokens and aborts):
[[pinned]], legacy Macro/).Write frontmatter + ## Thesis Adjacency Index + the first ≤20 entries; then cat >> _graph.md <<'GRAPHEOF' … GRAPHEOF (quoted delimiter, so [[, backticks, $, | are literal) for each remaining ≤20-entry batch and each later section. Keep every call ≤ ~6 KB..sync_all_fresh + .graph_invalidations only after success.아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
Sweep addressed callouts older than a threshold (default 180 days) into the target note's
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Extract a thesis's load-bearing assumptions and scan for internal contradictions — the falsifiable claims the bull case requires, what would falsify each, and where the thesis's own Risks / Bear Case / research already argue against it. Use when user says "assumptions", "what must be true", "load-bearing assumptions", or "does [TICKER] contradict itself".
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Generate a concise 1-page investment brief from a thesis — the elevator pitch version. Use when user says "brief", "summarise thesis", "pitch me [TICKER]", "one-pager", or "investment memo".
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Extract and maintain a cross-portfolio catalyst calendar from all thesis notes. Use when user says "catalyst", "calendar", "what's coming up", "upcoming events", or "what could move the portfolio".
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Delete old snapshots from _Archive/Snapshots/. Accepts a day threshold (default 180). Also `daily-intel [days]` mode — prune auto-generated n8n scanning surfaces (news briefs, X dashboards) from Daily Intel/ older than 90 days. Use when user says "clean", "clean snapshots", "delete old snapshots", "clean daily intel", or when /lint flags stale snapshots.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Delete old snapshots from _Archive/Snapshots/. Accepts a day threshold (default 180). Also `daily-intel [days]` mode — prune auto-generated n8n scanning surfaces (news briefs, X dashboards) from Daily Intel/ older than 90 days. Use when user says "clean", "clean snapshots", "delete old snapshots", "clean daily intel", or when $lint flags stale snapshots.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.