@ericrisco/rsc 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/manifest.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.13",
2
+ "version": "0.1.15",
3
3
  "counts": {
4
4
  "skills": 231
5
5
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ericrisco/rsc",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Eric Risco's agent-skills catalog as a granular, self-recommending CLI installer.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,7 +11,7 @@ profiles: [minimal, core, full]
11
11
  The **harness** is the control plane of a workspace. A workspace need not be code: it can be a company, an ops desk, a legal archive, a personal knowledge vault. Whatever it is, the harness is the durable apparatus that keeps it operable and legible, made of three parts:
12
12
 
13
13
  - **`01-TOOLS/<PROVIDER>/`** — the operational tooling layer. One folder per external provider, co-locating credentials (`.env`) with the scripts that consume them. Each tool ships a working `test_connection` against the real API.
14
- - **`02-DOCS/`** — the **Karpathy chaos→knowledge engine**: a domain-agnostic LLM wiki (`inbox/` + `raw/` + `wiki/` + `wiki/index.md` + `wiki/log.md` + `wiki/gaps.md` + `wiki/scores.json`), fully embedded in this skill. The user drops **any raw file in any format** (PDF, image, CSV, JSON, txt, html…) into `inbox/`; an **Inbox Sweep** ("the agent goes for a walk") extracts, classifies by content, cross-links, and compiles it into the wiki — see `references/ingest-formats.md` for the multiformat Fetch and `references/wiki-protocol.md` for the protocol. Topics are inferred from content (`finanzas/`, `legal/`, `crm/`…), never hardcoded to software docs. The wiki **self-improves continuously**: every Ingest, Sweep and Query triggers a Maintenance Pass (deterministic lint, score recomputation, gap detection, See Also sweep), and every N interactions a Micro-Improve runs (rewrite 1 low-scoring article, fill 1 gap, preserving old versions in `_archive/`). Deep Improve runs on explicit request or via scheduled cron. No external skill needed.
14
+ - **`02-DOCS/`** — the **Karpathy chaos→knowledge engine**: a domain-agnostic LLM wiki (`inbox/` + `raw/` + `raw/worklog/` + `wiki/` + `wiki/index.md` + `wiki/log.md` + `wiki/gaps.md` + `wiki/scores.json` + the `.base` views), fully embedded in this skill. It feeds from **two on-ramps**: (1) the user drops **any raw file in any format** (PDF, image, CSV, JSON, txt, html…) into `inbox/`, and an **Auto-Ingest Sweep** ("the agent goes for a walk") extracts, classifies, cross-links, and compiles it — and goes further, **discovering un-ingested documents anywhere in the workspace** (a stray `/transcripts`, `/facturas`…), bounded by `.rscignore` and de-duplicated by the `wiki/.ingested.json` ledger, fired automatically at SessionStart (when the inbox has material) and by the daily cron. Ingest is non-destructive (originals are copied, never moved); removing an emptied folder needs explicit consent; (2) a **Worklog Sweep** captures **what we do** — every meaningful session of work is itself a `raw` source (`raw/worklog/`) compiled into the wiki, fired by a `PreCompact`/`SessionEnd` hook, by an explicit milestone (a commit), or by the daily curation automation (`references/daily-curation-automation.md`). The wiki is **Obsidian-native**: wikilinks, YAML frontmatter (Properties), readable filenames, and `.base` views give a real graph + live tables structure, **not vector DB / embeddings / RAG**. The agent writes it; the human reads it in Obsidian. See `references/wiki-protocol.md` for the protocol, `references/ingest-formats.md` for the multiformat Fetch, `references/wiki-worklog-template.md` for the work capture, and `references/obsidian-scaffolding.md` for the vault scaffolding. Topics are inferred from content (`finanzas/`, `legal/`, `crm/`…), never hardcoded. The wiki **self-improves continuously**: every Ingest, Sweep and Query triggers a Maintenance Pass (deterministic lint, score recomputation, gap detection, Related/See-Also sweep), and every N interactions a Micro-Improve runs. Deep Improve runs on explicit request or via the scheduled daily curation. No external skill needed.
15
15
  - **The Knowledge map** — the `## Knowledge map` section of the root `CLAUDE.md` that indexes the wiki (including the `harness/` topic) and is read by every other skill before it works in its area.
16
16
 
17
17
  `harness` is the **protagonist concept**. `init` is the bootstrap front door — it gauges the user, drafts the profile, and hands off the first scaffold. THIS skill (`harness`) is the **ongoing control**: it audits, migrates, scaffolds, sweeps the inbox, and keeps the wiki, the tooling and the Knowledge map honest over the life of the workspace. It also generates root `CLAUDE.md` and `AGENTS.md`, and migrates legacy `XX-*` numbered folders into the canonical layout.
@@ -55,6 +55,8 @@ phase, last verdict, next steps, risks, commands and skill_resolution. This is
55
55
  not a replacement for the wiki; it is the recovery note that lets the next
56
56
  agent resume without trusting chat history.
57
57
 
58
+ **Opt-out marker.** When a workspace has no profile yet, a freshly-installed session auto-starts `init` (via the `suggest` Onboarding gate and claude's SessionStart hook). A `.rsc/.no-harness` file is the explicit opt-out: present → never auto-start onboarding in this repo, even without a profile. `harness` treats it as canonical and never overwrites or deletes it.
59
+
58
60
  ### 4. Decision pattern — "siempre 3 opciones"
59
61
 
60
62
  For **any significant decision** (deploy target, database, framework, hosting, tooling…):
@@ -98,12 +100,15 @@ harness/
98
100
  │ ├── agents-md-template.md ← root AGENTS.md template
99
101
  │ ├── tools-readme-template.md ← 01-TOOLS/README.md catalog template
100
102
  │ ├── audit-report-template.md ← exact format of the audit report shown to user
101
- │ ├── wiki-protocol.md ← embedded wiki protocol + Inbox Sweep + Continuous Improvement
103
+ │ ├── wiki-protocol.md ← embedded wiki protocol + Inbox/Worklog Sweep + Continuous Improvement
102
104
  │ ├── ingest-formats.md ← multiformat Fetch (PDF, image, CSV, JSON, html…)
103
105
  │ ├── inbox-readme-template.md ← the inbox/README.md drop-zone contract
104
106
  │ ├── wiki-raw-template.md ← format for raw/<topic>/*.md
105
- │ ├── wiki-article-template.md ← format for wiki/<topic>/*.md
106
- │ ├── wiki-index-template.md ← format for wiki/index.md (with Score column)
107
+ │ ├── wiki-worklog-template.md ← format for raw/worklog/*.md (work-driven capture)
108
+ │ ├── wiki-article-template.md ← format for wiki/<topic>/*.md (Obsidian frontmatter + wikilinks)
109
+ │ ├── wiki-index-template.md ← format for wiki/index.md (machine catalog; .base = human nav)
110
+ │ ├── obsidian-scaffolding.md ← .base views, .gitignore, attachments, .obsidian config
111
+ │ ├── daily-curation-automation.md ← portable scheduled compounding pass (the third trigger)
107
112
  │ ├── wiki-archive-template.md ← format for archived query answers
108
113
  │ └── wiki-gaps-template.md ← format for wiki/gaps.md (Knowledge Gaps log)
109
114
  ├── assets/
@@ -321,12 +326,15 @@ If any of these occur, stop and report:
321
326
  - `references/tools-readme-template.md` — `01-TOOLS/README.md` catalog template.
322
327
  - `references/audit-report-template.md` — text summary format for the in-conversation audit summary.
323
328
  - `references/audit-report-template.html` — HTML format for the full per-run audit artifact written to `02-DOCS/audits/`.
324
- - `references/wiki-protocol.md` — embedded protocol for the `02-DOCS/` chaos→knowledge layer (initialization, **Inbox Sweep**, ingest, query, lint, **Continuous Improvement**: Maintenance Pass, Micro-Improve, Deep Improve).
329
+ - `references/wiki-protocol.md` — embedded protocol for the `02-DOCS/` chaos→knowledge layer (initialization, **Inbox Sweep**, **Worklog Sweep**, ingest, query, lint, **Continuous Improvement**: Maintenance Pass, Micro-Improve, Deep Improve; Obsidian-native conventions).
325
330
  - `references/ingest-formats.md` — multiformat Fetch: how any input (PDF, image, CSV/Excel, JSON/API, html, docx, email, unknown binary) becomes `raw/` markdown with the original preserved in `_originals/`.
326
331
  - `references/inbox-readme-template.md` — the `inbox/README.md` drop-zone contract shown to the user.
327
332
  - `references/wiki-raw-template.md` — format for `02-DOCS/raw/<topic>/*.md`.
328
- - `references/wiki-article-template.md` — format for `02-DOCS/wiki/<topic>/*.md`.
329
- - `references/wiki-index-template.md` — format for `02-DOCS/wiki/index.md` (with Score column).
333
+ - `references/wiki-worklog-template.md` — format for `02-DOCS/raw/worklog/*.md` (the work-driven capture; the session as a raw source).
334
+ - `references/wiki-article-template.md` — format for `02-DOCS/wiki/<topic>/*.md` (Obsidian frontmatter + wikilinks + `## Related`).
335
+ - `references/wiki-index-template.md` — format for `02-DOCS/wiki/index.md` (machine catalog; the `.base` views are the human navigation).
336
+ - `references/obsidian-scaffolding.md` — the vault scaffolding: `.base` views, `.gitignore`, `attachments/`, `.obsidian` config (no vector DB / RAG).
337
+ - `references/daily-curation-automation.md` — portable scheduled compounding pass; on Claude Code wired via the `schedule` skill.
330
338
  - `references/wiki-archive-template.html` — HTML format for archived query answers (point-in-time, never edited).
331
339
  - `references/wiki-dashboard-template.html` — HTML format for the live wiki dashboard, regenerated by Maintenance Pass.
332
340
  - `references/wiki-deep-improve-report-template.html` — HTML format for Deep Improve run reports.
@@ -0,0 +1,66 @@
1
+ # Daily curation automation — the compounding pass on a timer
2
+
3
+ The third trigger of the work-driven path (the other two: the PreCompact/SessionEnd
4
+ hook and explicit milestones). This is the harness's existing **Continuous
5
+ Improvement** (Maintenance Pass / Micro-Improve / Deep Improve) promoted to a
6
+ **first-class, portable, scheduled** automation — "the agent goes for a walk" on a
7
+ timer, not only when asked.
8
+
9
+ **Portable definition + Claude-Code reliability** (same pattern as the hooks): the
10
+ spec below works on any assistant as a protocol; on Claude Code, wire a real daily
11
+ cron via the `schedule` skill pointed at this prompt.
12
+
13
+ ## Purpose
14
+
15
+ Run once per day, at a quiet hour, to keep the second brain alive:
16
+
17
+ - run the **Auto-Ingest Sweep**: process `inbox/`, then scan the workspace (minus
18
+ `.rscignore`) for un-ingested documents, ingest the clearly-documentary folders,
19
+ record them in `wiki/.ingested.json`, and propose the ambiguous ones
20
+ - process pending `raw/worklog/` material into `wiki/`
21
+ - strengthen weak / low-score pages; fill one open gap
22
+ - repair links and the graph (resolve broken wikilinks, add `## Related` where proper nouns recur)
23
+ - mark `stale` pages whose sources moved on
24
+ - record what changed in `wiki/log.md`
25
+
26
+ ## Suggested schedule
27
+
28
+ Daily, at a quiet hour when the user is unlikely to be editing the vault.
29
+
30
+ ## Scope (paths)
31
+
32
+ The **workspace root** (for Auto-Ingest discovery, bounded by `.rscignore`),
33
+ `raw/worklog/`, `inbox/`, `raw/`, `wiki/`, `wiki/.ingested.json`, `wiki/harness/`.
34
+
35
+ ## Prompt
36
+
37
+ ```text
38
+ Run the daily curation pass for this 02-DOCS second brain.
39
+
40
+ Use the harness wiki-protocol.md as the contract. First run the Auto-Ingest Sweep:
41
+ process inbox/, then scan the workspace (minus .rscignore) for un-ingested documents,
42
+ ingest the clearly-documentary folders (copy originals, never move), record them in
43
+ wiki/.ingested.json, and list ambiguous folders as proposals (do not grab them).
44
+ Then compile pending raw/worklog/ material into wiki/ pages (update existing before
45
+ creating new), keep frontmatter + wikilinks consistent, append significant decisions
46
+ to wiki/harness/decisions.md, refresh the .base-backed navigation, recompute
47
+ scores.json + the score: property, and append a dated entry to wiki/log.md.
48
+
49
+ Be conservative. If the topic map no longer fits, record a recommendation in
50
+ wiki/gaps.md or a page's Open Questions instead of moving large parts of the
51
+ vault without explicit approval.
52
+ ```
53
+
54
+ ## Expected outcome (one of)
55
+
56
+ - worklog/inbox material distilled; `status` flipped to processed
57
+ - maintenance improvements to links, scores, `.base` views, or stale flags
58
+ - a `wiki/log.md` entry explaining what was checked and what remains open
59
+ - no file changes when there is genuinely nothing useful to do
60
+
61
+ ## Safety
62
+
63
+ - Do not rewrite or delete raw sources.
64
+ - Do not perform large taxonomy reorganizations without explicit approval.
65
+ - Do not create pages from weak connections just to look busy.
66
+ - Prefer small, compounding improvements over big sweeps.
@@ -0,0 +1,48 @@
1
+ # Ignore defaults — what the Auto-Ingest Sweep must never scan
2
+
3
+ The Auto-Ingest Sweep discovers un-ingested documents across the whole workspace.
4
+ `02-DOCS/.rscignore` scopes that scan so it never grabs code, build output, tooling,
5
+ the wiki's own internals, or non-document files. This is the single guardrail that
6
+ keeps "automatic, workspace-wide" from turning into "tragar lo que no toca".
7
+
8
+ `02-DOCS/.rscignore` is **tracked** (not gitignored): the team shares the same scan
9
+ boundary. Users append their own patterns freely.
10
+
11
+ ## Default `02-DOCS/.rscignore`
12
+
13
+ ```gitignore
14
+ # 02-DOCS/.rscignore — paths the Auto-Ingest Sweep must NEVER scan as a knowledge source.
15
+ # Tracked (the team shares it). Append your own patterns below.
16
+ node_modules/
17
+ .git/
18
+ .next/
19
+ dist/
20
+ build/
21
+ .venv/
22
+ __pycache__/
23
+ .dart_tool/
24
+ .pytest_cache/
25
+ .ruff_cache/
26
+ 01-TOOLS/
27
+ 02-DOCS/inbox/_processed/
28
+ 02-DOCS/raw/
29
+ 02-DOCS/wiki/
30
+ .DS_Store
31
+ # Only document-like files are candidates anyway — pdf, docx, doc, md, txt, csv,
32
+ # tsv, json, html, rtf, and doc-like images (png/jpg of scans). Everything else
33
+ # (code, archives, binaries, lockfiles) is ignored even outside these paths.
34
+ ```
35
+
36
+ ## App source dirs are ignored at scan time
37
+
38
+ Beyond the file above, the sweep adds every detected **app source directory** to the
39
+ effective ignore set: any directory carrying a manifest (`package.json`,
40
+ `pyproject.toml`, `pubspec.yaml`, `go.mod`, `Cargo.toml`) and its tree. Source code is
41
+ never a knowledge source — `02-DOCS/wiki/` is where understanding about the code lives,
42
+ written deliberately, not scraped from the repo.
43
+
44
+ ## Why `02-DOCS/raw/` and `02-DOCS/wiki/` are ignored
45
+
46
+ They are *outputs* of ingestion, not inputs. Scanning them would re-ingest the wiki
47
+ into itself. `inbox/` is the only `02-DOCS/` subtree the sweep reads as a source
48
+ (plus discovered external folders).
@@ -0,0 +1,96 @@
1
+ # Obsidian scaffolding — make `02-DOCS/` open as a vault
2
+
3
+ Materialized during **Initialization** (see `wiki-protocol.md`). Turns the wiki
4
+ into a native Obsidian vault: graph, backlinks, Properties, and Bases — with **no
5
+ vector DB, no embeddings, no RAG**. Navigation is structure (links + frontmatter),
6
+ not semantic search. Do NOT add embedding/semantic-search plugins; that breaks the
7
+ thesis. Obsidian core only.
8
+
9
+ The point a human opens the vault at (the "base folder") is `02-DOCS/` itself —
10
+ not the repo root. Obsidian writes its config into `02-DOCS/.obsidian/`.
11
+
12
+ ## `02-DOCS/.gitignore` (additions)
13
+
14
+ ```gitignore
15
+ # Obsidian per-machine state (the rest of .obsidian/ — themes, bases, config — is tracked)
16
+ .obsidian/workspace*.json
17
+ .obsidian/cache
18
+ # regenerated / per-run surfaces
19
+ wiki/dashboard.html
20
+ audits/*.html
21
+ inbox/_processed/
22
+ ```
23
+
24
+ ## `02-DOCS/attachments/README.md`
25
+
26
+ ```markdown
27
+ # attachments
28
+
29
+ Shared binaries referenced from wiki pages (images, PDFs, diagrams) when they are
30
+ not bundled with a specific raw source. Link them from the page that depends on
31
+ them. Source-bundled originals stay in `raw/<topic>/_originals/`.
32
+ ```
33
+
34
+ ## `02-DOCS/.obsidian/app.json` (attachment folder)
35
+
36
+ ```json
37
+ {
38
+ "attachmentFolderPath": "attachments",
39
+ "newLinkFormat": "shortest",
40
+ "useMarkdownLinks": false
41
+ }
42
+ ```
43
+
44
+ `useMarkdownLinks: false` makes new internal links wikilinks. `userIgnoreFilters`
45
+ (Settings → Files & Links → Excluded files) should hide noise from search/graph:
46
+ `raw/_originals/`, `inbox/_processed/`, `audits/`.
47
+
48
+ ## `.base` views — the human navigation (replace hand-maintained nav)
49
+
50
+ These supersede manual upkeep of `index.md`/`dashboard.html` for humans;
51
+ `index.md` and `scores.json` remain as the machine layer + fallback.
52
+
53
+ ### `02-DOCS/wiki/Articles.base`
54
+
55
+ ```yaml
56
+ filters:
57
+ and:
58
+ - type == "article"
59
+ views:
60
+ - type: table
61
+ name: All Articles
62
+ order: [file.name, topic, status, score, updated]
63
+ sort:
64
+ - property: score
65
+ direction: DESC
66
+ ```
67
+
68
+ ### `02-DOCS/wiki/Worklog.base`
69
+
70
+ ```yaml
71
+ filters:
72
+ and:
73
+ - type == "worklog"
74
+ views:
75
+ - type: table
76
+ name: Worklog
77
+ order: [file.name, topic, date, status]
78
+ sort:
79
+ - property: date
80
+ direction: DESC
81
+ ```
82
+
83
+ ### `02-DOCS/wiki/Decisions.base`
84
+
85
+ ```yaml
86
+ filters:
87
+ and:
88
+ - type == "decision"
89
+ views:
90
+ - type: table
91
+ name: Decisions
92
+ order: [file.name, topic, status, updated]
93
+ sort:
94
+ - property: updated
95
+ direction: DESC
96
+ ```
@@ -1,7 +1,19 @@
1
+ ---
2
+ title: {Title}
3
+ aliases: [{old-slug}]
4
+ tags: []
5
+ type: article
6
+ topic: {topic}
7
+ status: draft
8
+ sources: []
9
+ updated: {YYYY-MM-DD}
10
+ score: 0.0
11
+ ---
12
+
1
13
  # {Title}
2
14
 
3
15
  > Sources: {Author1, YYYY-MM-DD; Author2, YYYY-MM-DD}
4
- > Raw: [{source1}](../../raw/{topic1}/{filename1}.md); [{source2}](../../raw/{topic2}/{filename2}.md)
16
+ > Raw: [[{raw-source-1}]]; [[{raw-source-2}]]
5
17
 
6
18
  ## Overview
7
19
 
@@ -11,10 +23,21 @@
11
23
 
12
24
  {Synthesize a coherent structure from the source material. Do not copy source text verbatim; distill and reorganize. Use blockquotes sparingly for particularly important original phrasing.}
13
25
 
14
- {OPTIONAL — include this section only when cross-references exist:}
15
-
16
- ## See Also
17
-
18
- {Cross-references to related wiki articles. Maintained during lint. Use relative links:
19
- - Same topic: [Other Article](other-article.md)
20
- - Different topic: [Other Article](../other-topic/other-article.md)}
26
+ ## Related
27
+
28
+ {OPTIONAL include only when cross-references exist. Maintained during lint. Use wikilinks so the link survives renames and shows in the Obsidian graph + backlinks:
29
+ - Same or different topic: `- [[Other Article]] — why it connects.`
30
+ - With display text: `- [[Other Article|how we say it here]] — why it connects.`}
31
+
32
+ <!--
33
+ FRONTMATTER CONTRACT (this is what powers Obsidian Properties + Bases + graph):
34
+ - title human-readable; the H1 matches it.
35
+ - aliases keep the old kebab slug here so pre-migration links/wikilinks still resolve.
36
+ - tags cross-cutting qualities ONLY — never the main category (that is `topic`).
37
+ - type article | decision | worklog | brief | spec | profile
38
+ - topic the wiki/<topic>/ folder, one level. Inferred from content, never hardcoded.
39
+ - status draft | stable | stale (lifecycle; filterable in a Base).
40
+ - sources wikilinks to raw/ pages this was distilled from (cite your evidence).
41
+ - updated YYYY-MM-DD of the last meaningful edit.
42
+ - score mirror of scores.json, written by the Maintenance Pass (single writer → no drift).
43
+ -->
@@ -1,13 +1,18 @@
1
1
  # Knowledge Base Index
2
2
 
3
+ > **Human navigation lives in the `.base` views** (`Articles.base`, `Worklog.base`,
4
+ > `Decisions.base`) — live tables over frontmatter, sorted by score/status/date.
5
+ > This index is the **machine-readable catalog + fallback** the agent maintains;
6
+ > it is not the primary surface a human browses in Obsidian.
7
+
3
8
  ## {topic-name}
4
9
 
5
10
  {One-line description of this topic.}
6
11
 
7
12
  | Article | Summary | Updated | Score |
8
13
  |---------|---------|---------|-------|
9
- | [{Article Title}]({topic-name}/{article}.md) | {One-line summary} | {YYYY-MM-DD} | {N.N} |
10
- | [{Archived Article}]({topic-name}/{archived}.md) | [Archived] {One-line summary} | {YYYY-MM-DD} | {N.N} |
14
+ | [[{Article Title}]] | {One-line summary} | {YYYY-MM-DD} | {N.N} |
15
+ | [[{Archived Article}]] | [Archived] {One-line summary} | {YYYY-MM-DD} | {N.N} |
11
16
 
12
17
  ## {another-topic}
13
18
 
@@ -15,7 +20,7 @@
15
20
 
16
21
  | Article | Summary | Updated | Score |
17
22
  |---------|---------|---------|-------|
18
- | [{Article Title}]({another-topic}/{article}.md) | {One-line summary} | {YYYY-MM-DD} | {N.N} |
23
+ | [[{Article Title}]] | {One-line summary} | {YYYY-MM-DD} | {N.N} |
19
24
 
20
25
  > **Score**: composite quality score (inbound links, source count, cited count,
21
26
  > freshness; minus conflicts and orphan penalty). Regenerated on every
@@ -12,9 +12,12 @@ skill required. When the parent skill (`SKILL.md`) reaches Phase 4 step 8
12
12
 
13
13
  - [The paradigm — chaos in, knowledge out](#the-paradigm--chaos-in-knowledge-out)
14
14
  - [Architecture](#architecture) · [Format split: markdown for state, HTML for surfaces](#format-split-markdown-for-state-html-for-surfaces)
15
+ - [The vault is Obsidian-native](#the-vault-is-obsidian-native)
15
16
  - [Initialization](#initialization)
16
17
  - [Ingest](#ingest) · [Fetch](#fetch-raw) · [Compile](#compile-wiki) · [Cascade Updates](#cascade-updates) · [Post-Ingest](#post-ingest)
17
18
  - [Inbox Sweep — "el agente sale a pasear"](#inbox-sweep--el-agente-sale-a-pasear)
19
+ - [Worklog Sweep — work-driven capture](#worklog-sweep--work-driven-capture)
20
+ - [Auto-Ingest Sweep — automatic, workspace-wide](#auto-ingest-sweep--automatic-workspace-wide)
18
21
  - [Query](#query)
19
22
  - [Lint](#lint) · [Deterministic Checks](#deterministic-checks-auto-fix) · [Heuristic Checks](#heuristic-checks-report-only)
20
23
  - [Continuous Improvement](#continuous-improvement) — Maintenance Pass / Micro-Improve / Deep Improve
@@ -144,6 +147,18 @@ Templates live alongside this file in `references/`:
144
147
 
145
148
  ---
146
149
 
150
+ ## The vault is Obsidian-native
151
+
152
+ `02-DOCS/` opens directly as an Obsidian vault (the human's "base folder" is
153
+ `02-DOCS/` itself, not the repo root). The agent writes the wiki; the human
154
+ **reads** it in Obsidian — graph, backlinks, Properties, and `.base` views — which
155
+ is exactly the Karpathy split. Navigation is **structure** (wikilinks + frontmatter
156
+ + Bases), not semantic similarity: **no vector DB, no embeddings, no RAG**, and no
157
+ embedding/search plugins. The `.base` views become the human navigation; `index.md`
158
+ + `scores.json` remain the machine layer + fallback. The exact scaffolding (the
159
+ `.base` files, `.obsidian/app.json`, attachments, `.gitignore`, excluded files) is
160
+ materialized from `obsidian-scaffolding.md` during Initialization.
161
+
147
162
  ## Initialization
148
163
 
149
164
  Triggers on the first Ingest. Check whether `02-DOCS/raw/` and `02-DOCS/wiki/`
@@ -158,15 +173,28 @@ exist. Create only what is missing; never overwrite existing files:
158
173
  - `02-DOCS/wiki/log.md` — heading `# Wiki Log`, empty body
159
174
  - `02-DOCS/wiki/gaps.md` — heading `# Knowledge Gaps`, empty body
160
175
  - `02-DOCS/wiki/scores.json` — `{}` (populated by the first Maintenance Pass)
176
+ - `02-DOCS/wiki/.ingested.json` — `{}` (the Auto-Ingest Sweep's seen-ledger)
177
+ - `02-DOCS/.rscignore` — the scan boundary for the Auto-Ingest Sweep, from
178
+ `ingest-ignore-defaults.md` (tracked, not gitignored)
161
179
  - `02-DOCS/wiki/reports/` directory (with `.gitkeep`) — will hold Deep Improve reports
162
180
  - `02-DOCS/audits/` directory (with `.gitkeep`) — holds per-run audit reports
163
181
  from the parent skill (`audit-YYYY-MM-DD-HHMM.html`). May already exist if
164
182
  Phase 2 of the parent skill created it eagerly to write the first audit.
183
+ - `02-DOCS/raw/worklog/` directory (with `.gitkeep`) — the **work-driven on-ramp**
184
+ (see "Worklog Sweep"); holds `YYYY-MM-DD-<slug>.md` captures of what we did.
185
+ - `02-DOCS/attachments/` directory + `README.md` — shared binaries (Obsidian's
186
+ default attachment folder), from `obsidian-scaffolding.md`.
187
+ - `02-DOCS/wiki/Articles.base`, `Worklog.base`, `Decisions.base` — the human
188
+ navigation views, from `obsidian-scaffolding.md`.
189
+ - `02-DOCS/.obsidian/app.json` — sets the attachment folder and wikilink defaults,
190
+ from `obsidian-scaffolding.md`.
165
191
  - `02-DOCS/.gitignore` — at minimum:
166
192
  - `wiki/dashboard.html` (regenerated by Maintenance Pass)
167
193
  - `audits/*.html` (per-run audit artifacts from the parent skill)
168
194
  - `inbox/_processed/` (sweep archive — bulky, derivable; the durable copy
169
195
  of every binary lives in `raw/<topic>/_originals/`)
196
+ - `.obsidian/workspace*.json` and `.obsidian/cache` (Obsidian per-machine state;
197
+ the rest of `.obsidian/` — themes, bases, config — is tracked)
170
198
  - `wiki/reports/*.html` is **not** gitignored — Deep Improve reports are
171
199
  durable historical records, unlike the per-run audit snapshots.
172
200
 
@@ -341,6 +369,123 @@ Append to `02-DOCS/wiki/log.md`:
341
369
 
342
370
  ---
343
371
 
372
+ ## Worklog Sweep — work-driven capture
373
+
374
+ The Inbox Sweep turns files the user *dropped* into knowledge. The **Worklog
375
+ Sweep** turns what we *did* into knowledge — the second on-ramp. A work session is
376
+ just another source of chaos: it lands in `raw/worklog/` and is Compiled into
377
+ `wiki/` through the exact same pipeline. No parallel system.
378
+
379
+ ### What it captures
380
+
381
+ One `raw/worklog/YYYY-MM-DD-<slug>.md` per meaningful unit of work, in the format
382
+ of `wiki-worklog-template.md` (frontmatter `type: worklog`, `topic`, `date`,
383
+ `status: unprocessed`): what we did, why (intent + decisions), files touched
384
+ (`path:line`), outcome with evidence, open questions/next, commands. This
385
+ generalizes the SDD session-summary convention to *any* work.
386
+
387
+ ### Triggers
388
+
389
+ - **Hook — `PreCompact` / `SessionEnd`** (Claude Code): fires right before context
390
+ is lost or the session ends. The hook only *reminds*; the agent writes the
391
+ worklog (Karpathy: the LLM writes). Wired by `targets/` → `.rsc/worklog-checkpoint.sh`.
392
+ - **Explicit milestone**: after a commit or a shipped feature, capture a worklog.
393
+ - **Daily curation automation**: distills any pending worklog raw on a timer (see
394
+ Continuous Improvement and `daily-curation-automation.md`).
395
+
396
+ ### Throttle — capture signal, not noise
397
+
398
+ Write a worklog **only** when there is durable signal: files changed, a decision
399
+ was made, or a milestone was hit. **Skip** pure read/answer turns and questions
400
+ with no change. Never manufacture a worklog "to look busy" — that is the same
401
+ safety rule the curation pass honors.
402
+
403
+ ### Steps
404
+
405
+ 1. **Capture.** Write the worklog to `raw/worklog/YYYY-MM-DD-<slug>.md`
406
+ (`status: unprocessed`). Infer `topic` from content.
407
+ 2. **Compile.** Run the normal Compile (Fetch is a no-op — the worklog is already
408
+ `raw`): distill durable points into `wiki/<topic>/` articles (update existing
409
+ before creating new), add wikilink cross-refs + `## Related`, cascade.
410
+ 3. **Route decisions.** Every significant decision is appended to
411
+ `wiki/harness/decisions.md` (append-only, the "siempre 3 opciones" shape).
412
+ 4. **Close.** Flip the worklog's `status` to `processed` (the raw stays as
413
+ evidence — never deleted or rewritten) and append to `wiki/log.md`.
414
+
415
+ ### Post-Sweep log
416
+
417
+ Append to `02-DOCS/wiki/log.md`:
418
+
419
+ ```markdown
420
+ ## [YYYY-MM-DD] worklog | <slug> → <A> articles touched
421
+ ```
422
+
423
+ ### Worklog Sweep safety rails
424
+
425
+ - **Evidence is immutable.** The worklog raw is never edited for style after the
426
+ fact; only its `status` flips. Distillation happens in `wiki/`, not in the raw.
427
+ - **No invention.** Capture what actually happened (cite commands/outputs); do not
428
+ embellish outcomes. "Done" requires evidence.
429
+ - **Throttled.** No worklog for trivial turns (see Throttle above).
430
+
431
+ ---
432
+
433
+ ## Auto-Ingest Sweep — automatic, workspace-wide
434
+
435
+ The Inbox Sweep processes what the user *dropped* in `inbox/`. The **Auto-Ingest
436
+ Sweep** extends it: it also **discovers** un-ingested documents anywhere in the
437
+ workspace and ingests them on its own — so the user never has to remember to file
438
+ sources. It runs automatically (SessionStart nudge + daily cron; see Triggers) and
439
+ on request.
440
+
441
+ The hard rule that keeps "automatic, workspace-wide" safe: **ingesting is
442
+ non-destructive** (read + create wiki pages + copy the original into
443
+ `raw/<topic>/_originals/`), so it is safe to do unattended. **Moving or deleting
444
+ anything is destructive** and always requires explicit, quoted consent.
445
+
446
+ ### Steps
447
+
448
+ 1. **inbox/** — run the Inbox Sweep on `inbox/` (unchanged).
449
+ 2. **Scan** — walk the workspace minus `.rscignore` (and minus detected app source
450
+ dirs). Consider only document-like files. A file is **un-ingested** when its
451
+ `path` is absent from `wiki/.ingested.json` OR its content hash differs.
452
+ 3. **Classify** each candidate folder:
453
+ - **Clearly documentary** (a folder of docs/transcripts/pdfs, no code) →
454
+ **auto-ingest**: Compile to `wiki/`, copy the original into
455
+ `raw/<topic>/_originals/` (**copy, never move** — the source stays put).
456
+ - **Ambiguous** (mixed, or possibly app data) → **list it and propose**; do not
457
+ touch it. Log it to `gaps.md` so the next pass remembers.
458
+ 4. **Record** every ingested source in `wiki/.ingested.json`.
459
+ 5. **Offer cleanup** — for a folder the sweep fully ingested, **offer** to remove it
460
+ once empty, with the consent quoted back from the user. **Never auto-delete**, and
461
+ never a folder the sweep did not itself empty.
462
+
463
+ ### Ledger — `wiki/.ingested.json`
464
+
465
+ The seen-ledger; the single source of truth for "what we've already ingested",
466
+ which makes the workspace scan idempotent (the Inbox Sweep alone tracks
467
+ processed-ness only by moving files to `inbox/_processed/`).
468
+
469
+ ```json
470
+ {
471
+ "<relpath-from-workspace-root>": { "hash": "sha256:…", "ingested": "YYYY-MM-DD", "topic": "…" }
472
+ }
473
+ ```
474
+
475
+ Un-ingested = path absent OR hash changed. `inbox/` files still move to
476
+ `inbox/_processed/` **and** get a ledger entry. Initialized as `{}`.
477
+
478
+ ### Auto-Ingest safety rails
479
+
480
+ - **Ledger-idempotent.** Never reprocess a source whose path+hash is recorded.
481
+ - **Scoped by `.rscignore`.** Never scan code, build output, `01-TOOLS/`, the
482
+ wiki's own `raw/`+`wiki/`, or non-document files (see `ingest-ignore-defaults.md`).
483
+ - **Copy, don't move.** Discovered originals are copied; the source is left in place.
484
+ - **Consent for destruction.** Removing an emptied folder is quoted-consent only.
485
+ - **Ambiguity is proposed, not grabbed.**
486
+
487
+ ---
488
+
344
489
  ## Query
345
490
 
346
491
  Search the wiki and answer questions. Examples of triggers:
@@ -635,15 +780,25 @@ These apply to all Layers:
635
780
 
636
781
  ## Conventions
637
782
 
638
- - Standard markdown with relative links throughout.
783
+ - **Obsidian-friendly markdown.** Internal cross-references use **wikilinks**
784
+ (`[[Page]]` / `[[Page|alias]]`) — resolved by filename, no path needed — so the
785
+ Obsidian graph + backlinks come for free and survive moves. (Legacy relative
786
+ markdown links still resolve in Obsidian; the migration pass converts them.)
787
+ - **Frontmatter on curated articles.** Every `wiki/<topic>/` article carries the
788
+ YAML frontmatter from `wiki-article-template.md` (`title, aliases, tags, type,
789
+ topic, status, sources, updated, score`). This is what powers Obsidian
790
+ Properties + the `.base` views. Operational files (`index.md`, `log.md`,
791
+ `gaps.md`) may use simpler formats.
792
+ - **Human-readable wiki filenames** (`Month-End Close.md`) for clean graph nodes;
793
+ the old kebab slug goes in `aliases` so prior links/wikilinks still resolve.
794
+ `raw/` and `raw/worklog/` filenames stay kebab + date (chaos, not display).
639
795
  - `wiki/` supports one level of topic subdirectories only. No deeper
640
796
  nesting.
641
797
  - Today's date for log entries, Collected dates, and Archived dates.
642
798
  Updated dates reflect when the article's knowledge content last changed.
643
799
  Published dates come from the source (use `Unknown` when unavailable).
644
- - Inside `wiki/` files, all markdown links use paths relative to the
645
- current file. In conversation output, use project-root-relative paths
646
- (e.g., `02-DOCS/wiki/topic/article.md`).
800
+ - Inside `wiki/` files, internal references use wikilinks. In conversation
801
+ output, use project-root-relative paths (e.g., `02-DOCS/wiki/topic/Article.md`).
647
802
  - Ingest updates both `02-DOCS/wiki/index.md` and `02-DOCS/wiki/log.md`.
648
803
  Archive (from Query) updates both. Lint updates `02-DOCS/wiki/log.md`
649
804
  (and `02-DOCS/wiki/index.md` only when auto-fixing index entries). Plain
@@ -0,0 +1,56 @@
1
+ # Worklog raw template — `raw/worklog/<YYYY-MM-DD>-<slug>.md`
2
+
3
+ The **work-driven on-ramp**. A Worklog Sweep writes one of these per meaningful
4
+ unit of work — what we *did*, not what someone dropped in `inbox/`. It is `raw`
5
+ (evidence: preserved, never edited after the fact) and is Compiled into `wiki/`
6
+ like any other source. The session is just another source of chaos.
7
+
8
+ **Throttle — do NOT write a worklog for:** pure read/answer turns, questions with
9
+ no file change, no decision, and no commit. Capture only durable signal. Never
10
+ manufacture a worklog "to look busy."
11
+
12
+ ```yaml
13
+ ---
14
+ type: worklog
15
+ topic: {inferred-topic}
16
+ date: {YYYY-MM-DD}
17
+ status: unprocessed
18
+ sources: []
19
+ ---
20
+ ```
21
+
22
+ ## What we did
23
+
24
+ {Concrete changes / features / fixes — one bullet each. Plain, factual.}
25
+
26
+ ## Why
27
+
28
+ {Intent and the decisions taken. Every *significant* decision is ALSO appended to
29
+ `wiki/harness/decisions.md` (append-only, with the 3-options shape) during Compile.}
30
+
31
+ ## Files touched
32
+
33
+ - `{path}:{line}` — {what changed}
34
+
35
+ ## Outcome
36
+
37
+ {Verdict: shipped & verified / partial / blocked. Include the evidence — test
38
+ output, command result, screenshot path. No "done" without proof.}
39
+
40
+ ## Open questions / next
41
+
42
+ - {What remains, what to pick up next session.}
43
+
44
+ ## Commands
45
+
46
+ - `{command}` — {result}
47
+
48
+ <!--
49
+ LIFECYCLE: written by the Worklog Sweep → status: unprocessed. The Compile step
50
+ distills durable points into wiki/<topic>/ articles (update existing before
51
+ creating new), cross-links, cascades, appends decisions to decisions.md, then
52
+ flips this file's status to processed (the raw stays as evidence; it is not
53
+ deleted or rewritten). Triggers that fire a Worklog Sweep: a PreCompact/SessionEnd
54
+ hook (Claude Code), an explicit milestone (a commit / a shipped feature), and the
55
+ daily curation automation. See `wiki-protocol.md` → "Worklog Sweep".
56
+ -->
@@ -55,6 +55,10 @@ Before discovery, before any recommendation, write the profile to `02-DOCS` and
55
55
 
56
56
  If `02-DOCS/` does not yet exist (greenfield), create `02-DOCS/wiki/harness/` now — just enough to hold these two files. That, plus the `CLAUDE.md` Knowledge-map link, is everything `init` writes; ALL other `01-TOOLS/` + `02-DOCS/` scaffolding is the `harness` skill's job.
57
57
 
58
+ ### Opt-out marker — `.rsc/.no-harness`
59
+
60
+ A freshly-installed session auto-starts `init` while `02-DOCS/wiki/harness/user-profile.md` is absent (the `suggest` Onboarding gate + claude's SessionStart hook). If the user does not want a harness in this repo (e.g. they installed only code skills), write an empty `.rsc/.no-harness` — this permanently silences the auto-start here even before a profile exists. Completing first contact (which writes `user-profile.md`) also silences it. The marker is project-local; commit it so the "no harness here" decision is shared by the team.
61
+
58
62
  ### How every skill adapts to the dial
59
63
 
60
64
  Every rsc skill MUST read `user-profile.md` at the start of a session and adapt:
@@ -24,6 +24,16 @@ Rules:
24
24
  - Never recommend something already installed (`npx @ericrisco/rsc list`).
25
25
  - One suggestion at a time. Don't interrupt the flow for nice-to-haves.
26
26
 
27
+ ## Onboarding gate (first contact)
28
+
29
+ Before handling the first request of the session, check the workspace state:
30
+
31
+ - If `02-DOCS/wiki/harness/user-profile.md` is **missing** AND `.rsc/.no-harness` is **missing**, the harness has never been set up here — your FIRST action is to invoke `init` (auto-onboarding), which opens with the two gauging questions (technical level + accompaniment dial). Don't wait to be asked; don't start the user's task until first contact is done.
32
+ - If the user declines or says they don't want a harness here ("sin harness", "solo código", "no quiero esto") — create an empty `.rsc/.no-harness` and never auto-start `init` in this repo again. Confirm in one line.
33
+ - Once `02-DOCS/wiki/harness/user-profile.md` exists, this gate is inert — never re-onboard.
34
+
35
+ This is the universal layer every assistant reads. On Claude Code a SessionStart hook also prints this reminder deterministically, but the rule above is what makes it fire everywhere.
36
+
27
37
  ## Orientación (siempre)
28
38
 
29
39
  Cierra cada turno con el **bloque-brújula** (📍 dónde estás · ✅ qué hiciste · 🧭 por qué · ➡️ siguiente, terminando en pregunta), calibrado al dial de `02-DOCS/wiki/harness/user-profile.md`. **Nunca termines en seco.** Protocolo completo: skill `orient` → `skills/orient/references/orientation-contract.md`. (Defiere a `suggest` el "¿instalo la skill que falta?".)
package/targets/claude.js CHANGED
@@ -1,22 +1,56 @@
1
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
2
- import { dirname } from 'node:path';
1
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, copyFileSync, chmodSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
3
4
  import { linkOrCopy } from './index.js';
4
5
 
5
6
  export function writeSkill(id, fromDir, toPath) {
6
7
  return linkOrCopy(fromDir, toPath);
7
8
  }
8
9
 
10
+ // SessionStart runs a project-local session-start.sh: it cats suggest's always-on
11
+ // body (preserving prior behavior) and appends an onboarding banner when the
12
+ // workspace has no harness profile yet. We materialize the script next to the
13
+ // shared base and point the hook at it. Any prior rsc SessionStart entry (the old
14
+ // `cat …/suggest/SKILL.md` form or a previous script form) is dropped before we
15
+ // add the current one — idempotent, and it migrates legacy hooks in place. Other
16
+ // (non-rsc) SessionStart hooks are preserved.
9
17
  export function wireHook(paths) {
18
+ const scriptDest = join(paths.projectRoot, '.rsc', 'session-start.sh');
19
+ mkdirSync(dirname(scriptDest), { recursive: true });
20
+ copyFileSync(join(dirname(fileURLToPath(import.meta.url)), 'session-start.sh'), scriptDest);
21
+ chmodSync(scriptDest, 0o755);
22
+
23
+ const suggestMd = `${paths.skillDir('suggest')}/SKILL.md`;
24
+ const cmd = `bash "${scriptDest}" "${suggestMd}" "${paths.projectRoot}"`;
25
+
10
26
  const file = paths.hookTarget;
11
27
  const settings = existsSync(file) ? JSON.parse(readFileSync(file, 'utf8')) : {};
12
28
  settings.hooks ||= {};
13
29
  settings.hooks.SessionStart ||= [];
14
- const cmd = `cat "${paths.skillDir('suggest')}/SKILL.md"`;
15
- const already = JSON.stringify(settings.hooks.SessionStart).includes('skills/rsc/suggest');
16
- if (!already) {
17
- settings.hooks.SessionStart.push({ hooks: [{ type: 'command', command: cmd }] });
30
+ settings.hooks.SessionStart = settings.hooks.SessionStart.filter((e) => {
31
+ const s = JSON.stringify(e);
32
+ return !s.includes('skills/rsc/suggest') && !s.includes('.rsc/session-start.sh');
33
+ });
34
+ settings.hooks.SessionStart.push({ hooks: [{ type: 'command', command: cmd }] });
35
+
36
+ // Worklog checkpoint: PreCompact + SessionEnd run a project-local
37
+ // worklog-checkpoint.sh that reminds the agent to capture what we did this
38
+ // session into 02-DOCS/raw/worklog/ (the work-driven on-ramp). Silent when the
39
+ // workspace has no harness wiki. Registered idempotently on both events, with
40
+ // any prior rsc worklog-checkpoint entry dropped first.
41
+ const wlDest = join(paths.projectRoot, '.rsc', 'worklog-checkpoint.sh');
42
+ copyFileSync(join(dirname(fileURLToPath(import.meta.url)), 'worklog-checkpoint.sh'), wlDest);
43
+ chmodSync(wlDest, 0o755);
44
+ const wlCmd = `bash "${wlDest}" "${paths.projectRoot}"`;
45
+ for (const event of ['PreCompact', 'SessionEnd']) {
46
+ settings.hooks[event] ||= [];
47
+ settings.hooks[event] = settings.hooks[event].filter(
48
+ (e) => !JSON.stringify(e).includes('.rsc/worklog-checkpoint.sh'),
49
+ );
50
+ settings.hooks[event].push({ hooks: [{ type: 'command', command: wlCmd }] });
18
51
  }
52
+
19
53
  mkdirSync(dirname(file), { recursive: true });
20
54
  writeFileSync(file, JSON.stringify(settings, null, 2) + '\n');
21
- return [file];
55
+ return [file, scriptDest, wlDest];
22
56
  }
package/targets/index.js CHANGED
@@ -105,6 +105,7 @@ export function targetPaths(target, home = homedir(), cwd = process.cwd()) {
105
105
  const rootAbs = join(cwd, ...s.root.split('/'));
106
106
  return {
107
107
  root: rootAbs,
108
+ projectRoot: cwd,
108
109
  skillDir: (id) => (s.skillExt ? join(rootAbs, `${id}${s.skillExt}`) : join(rootAbs, id)),
109
110
  stateFile: join(rootAbs, '.rsc-state.json'),
110
111
  hookTarget: join(cwd, ...s.hook.split('/')),
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env bash
2
+ # rsc SessionStart payload (claude). Wired by targets/claude.js.
3
+ # $1 = absolute path to suggest's SKILL.md $2 = absolute project root
4
+ # Always emits suggest's always-on body; appends an onboarding banner when the
5
+ # workspace has no harness profile yet, and an auto-ingest nudge when there is
6
+ # un-ingested material waiting in the inbox.
7
+ set -u
8
+
9
+ cat "$1" 2>/dev/null
10
+
11
+ profile="$2/02-DOCS/wiki/harness/user-profile.md"
12
+ optout="$2/.rsc/.no-harness"
13
+
14
+ if [ ! -f "$profile" ] && [ ! -f "$optout" ]; then
15
+ cat <<'BANNER'
16
+
17
+ ===== rsc onboarding =====
18
+ Fresh setup: 02-DOCS/wiki/harness/user-profile.md is missing.
19
+ ACTION: invoke `init` now (first contact: technical level + accompaniment dial) before the task.
20
+ If the user does not want a harness here: create .rsc/.no-harness
21
+ ==========================
22
+ BANNER
23
+ fi
24
+
25
+ # Auto-Ingest nudge: when a harness wiki exists and the inbox holds a real file
26
+ # (anything other than README.md / dotfiles / the _processed archive), tell the
27
+ # agent to run the Auto-Ingest Sweep. The hook only reminds; the agent does the
28
+ # scan + ingest. Cheap signal here; the thorough workspace scan lives in the sweep.
29
+ inbox="$2/02-DOCS/inbox"
30
+ if [ -d "$2/02-DOCS/wiki" ] && [ -d "$inbox" ]; then
31
+ pending=$(find "$inbox" -maxdepth 1 -type f ! -name 'README.md' ! -name '.*' 2>/dev/null | head -1)
32
+ if [ -n "$pending" ]; then
33
+ cat <<'BANNER'
34
+
35
+ ===== rsc auto-ingest =====
36
+ Un-ingested material is waiting in 02-DOCS/inbox/.
37
+ ACTION: run the Auto-Ingest Sweep now — ingest inbox/, then scan the workspace
38
+ (minus .rscignore) for un-ingested documents, recording them in wiki/.ingested.json.
39
+ Originals are copied, never moved; deleting an emptied folder needs explicit consent.
40
+ ===========================
41
+ BANNER
42
+ fi
43
+ fi
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env bash
2
+ # rsc Worklog checkpoint payload (claude). Wired by targets/claude.js onto the
3
+ # PreCompact and SessionEnd hooks.
4
+ # $1 = absolute project root
5
+ # Reminds the agent to run a Worklog Sweep (capture what we did this session into
6
+ # 02-DOCS/raw/worklog/ so the harness can compile it into the wiki). The hook only
7
+ # REMINDS — the agent writes the worklog (Karpathy: the LLM writes the wiki).
8
+ # Silent when this workspace has no harness wiki yet (nothing to document into).
9
+ set -u
10
+
11
+ root="${1:-$PWD}"
12
+
13
+ # No harness wiki here → nothing to do. Stay silent.
14
+ [ -d "$root/02-DOCS/wiki" ] || exit 0
15
+
16
+ cat <<'BANNER'
17
+
18
+ ===== rsc worklog checkpoint =====
19
+ If this session did meaningful work (files changed, a decision made, a commit),
20
+ run a WORKLOG SWEEP before context is lost:
21
+ 1. Write 02-DOCS/raw/worklog/<YYYY-MM-DD>-<slug>.md using the harness
22
+ wiki-worklog-template.md (what we did · why · files touched · outcome · next).
23
+ 2. Compile it into wiki/ (update existing articles first; wikilinks + Related);
24
+ append significant decisions to 02-DOCS/wiki/harness/decisions.md.
25
+ Skip entirely if this was a pure read/answer turn with no changes.
26
+ ==================================
27
+ BANNER