oh-my-second-brain 0.20.4 → 0.20.6

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.
Files changed (42) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/CHANGELOG-assets.md +8 -0
  5. package/CHANGELOG-cli.md +6 -0
  6. package/CHANGELOG-kernel.md +4 -0
  7. package/CHANGELOG-mcp.md +6 -0
  8. package/CHANGELOG-vendors.md +6 -0
  9. package/CHANGELOG.md +4 -0
  10. package/README.ko.md +10 -12
  11. package/README.md +9 -11
  12. package/assets/claude/CLAUDE.md +19 -11
  13. package/assets/codex/AGENTS.md +15 -8
  14. package/assets/codex/rules/oms.md +6 -4
  15. package/assets/hermes/README.md +4 -2
  16. package/assets/hermes/SOUL.md +15 -8
  17. package/assets/hermes-manifest.json +1 -1
  18. package/assets/skills/distill/SKILL.md +1 -1
  19. package/assets/skills/doctor/SKILL.md +1 -1
  20. package/assets/skills/setup/SKILL.md +2 -2
  21. package/assets/skills/write/SKILL.md +5 -5
  22. package/dist/cli/contract-command.js +5 -3
  23. package/dist/cli/contract-command.js.map +1 -1
  24. package/dist/cli/doctor-command.js +2 -1
  25. package/dist/cli/doctor-command.js.map +1 -1
  26. package/dist/kernel/contract/status.d.ts +1 -1
  27. package/dist/mcp/server.js +1 -1
  28. package/dist/mcp/server.js.map +1 -1
  29. package/dist/vendors/claude/claude-marketplace.js +1 -1
  30. package/dist/vendors/claude/claude-marketplace.js.map +1 -1
  31. package/docs/adapters.md +5 -5
  32. package/docs/architecture.md +2 -2
  33. package/docs/cli-map.md +2 -2
  34. package/docs/conventions.md +5 -5
  35. package/docs/install.md +4 -2
  36. package/docs/migration-0.19.md +1 -1
  37. package/docs/verified-target.md +2 -2
  38. package/package.json +1 -1
  39. package/skills/distill/SKILL.md +1 -1
  40. package/skills/doctor/SKILL.md +1 -1
  41. package/skills/setup/SKILL.md +2 -2
  42. package/skills/write/SKILL.md +5 -5
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
3
- "name": "oms",
3
+ "name": "oh-my-second-brain",
4
4
  "description": "Oh My Second Brain: a host-agnostic, user-owned convention layer for Obsidian and plain-markdown knowledge vaults.",
5
5
  "owner": {
6
6
  "name": "gobeumsu",
@@ -10,7 +10,7 @@
10
10
  {
11
11
  "name": "oms",
12
12
  "description": "Oh My Second Brain convention layer for Obsidian vaults — capture, retrieve, and validate knowledge under a declared semantic convention.",
13
- "version": "0.20.4",
13
+ "version": "0.20.6",
14
14
  "author": {
15
15
  "name": "gobeumsu",
16
16
  "email": "gobeumsu@gmail.com"
@@ -37,5 +37,5 @@
37
37
  ]
38
38
  }
39
39
  ],
40
- "version": "0.20.4"
40
+ "version": "0.20.6"
41
41
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oms",
3
- "version": "0.20.4",
3
+ "version": "0.20.6",
4
4
  "description": "Oh My Second Brain convention layer for Obsidian vaults — six shared skills and four MCP tools under a user-owned contract.",
5
5
  "author": {
6
6
  "name": "gobeumsu"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oms",
3
- "version": "0.20.4",
3
+ "version": "0.20.6",
4
4
  "description": "Oh My Second Brain convention layer for Obsidian vaults — Codex native rules, skills, and MCP adapter.",
5
5
  "_note": "oms setup host install writes Codex MCP config and provenance, installs ~/.codex/rules/oms.md, and installs the six shared skills under ~/.codex/skills/oms-*.",
6
6
  "skills": "./assets/skills/",
@@ -4,6 +4,14 @@ Skills, agents, templates, and host guidance changes belong here.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.20.6] - 2026-10-01
8
+
9
+ - **Skills and host guidance now say that contract findings warn instead of deny.** The `write`, `distill`, and `setup` skills, the Claude, Codex, and Hermes host guidance, and the README and docs had kept saying that a note breaking the contract is denied. Since the contract became warn-first, such a note is saved with each finding as a `{field, kind}` warning and one guidance command; only a safety refusal (a path outside the vault, a control or unsafe path, unsupported input, a tampered contract) denies, and in a sealed vault a note written through MCP or `oms write` whose frontmatter does not parse may be kept as a draft. Agents reading the old wording stopped and asked after a write that had already succeeded. The README also no longer says MCP cannot seal: `interview` `op: seal` seals a proposal the owner confirmed. Run `oms setup host sync` to refresh installed host guidance.
10
+
11
+ - **Docs and skills say what `--fix` and `ifMatch` do.** The README, the docs, and the `doctor` skill now say that `oms doctor contract --fix` also rebuilds an unreadable index. The architecture page no longer counts a stale `ifMatch` among the safety refusals; it is a revision precondition that writes nothing. The `write` skill says that among contract states only a tampered contract denies, the 0.19 migration guide notes that a contract finding has warned since 0.20, and the harness architecture page cites the current `status.ts` lines.
12
+
13
+ ## [0.20.5] - 2026-09-30
14
+
7
15
  ## [0.20.4] - 2026-09-30
8
16
 
9
17
  ## [0.20.3] - 2026-09-30
package/CHANGELOG-cli.md CHANGED
@@ -4,6 +4,12 @@ Changes to the `oms` command surface belong here.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.20.6] - 2026-10-01
8
+
9
+ - **`oms doctor contract --fix` usage says what it repairs.** The `doctor` and contract usage text said `--fix` only re-indexes a moved or unindexed vault; it also rebuilds an unreadable index, and the usage now says so. The contract usage also names `oms interview` as the command that reseals a broken seal, matching the diagnosis's `recovery` field.
10
+
11
+ ## [0.20.5] - 2026-09-30
12
+
7
13
  ## [0.20.4] - 2026-09-30
8
14
 
9
15
  ## [0.20.3] - 2026-09-30
@@ -4,6 +4,10 @@ Domain logic changes belong here.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.20.6] - 2026-10-01
8
+
9
+ ## [0.20.5] - 2026-09-30
10
+
7
11
  ## [0.20.4] - 2026-09-30
8
12
 
9
13
  - **`oms doctor contract` names `oms interview` as the recovery command.** The `recovery` field of a contract diagnosis now reads `oms interview` instead of `oms setup`, so the diagnosis, the write warnings, the interview refusal and the doctor skill all name the same reseal command. Both commands run the same terminal interview, so recovery itself is unchanged; an agent that matched on the literal `oms setup` value should match `oms interview`.
package/CHANGELOG-mcp.md CHANGED
@@ -4,6 +4,12 @@ MCP server tools and resources belong here.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.20.6] - 2026-10-01
8
+
9
+ - **The server instructions no longer call a stale `ifMatch` a safety refusal.** They listed it beside the vault boundary and a tampered contract as something that denies `write`. A missing or stale `ifMatch` is a revision precondition: it returns `WRITE_IF_MATCH_REQUIRED` or the retryable `WRITE_TARGET_CHANGED` and writes nothing, and the safety list now also names unsupported input.
10
+
11
+ ## [0.20.5] - 2026-09-30
12
+
7
13
  ## [0.20.4] - 2026-09-30
8
14
 
9
15
  ## [0.20.3] - 2026-09-30
@@ -4,6 +4,12 @@ Per-host adapter and installer changes belong here.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.20.6] - 2026-10-01
8
+
9
+ ## [0.20.5] - 2026-09-30
10
+
11
+ - **The Claude marketplace is named after the repository.** `.claude-plugin/marketplace.json` is now `oh-my-second-brain`, so the plugin id is `oms@oh-my-second-brain` for Claude Code and Gajae-Code instead of the doubled `oms@oms`; the plugin and its skills stay `oms` and `/oms:*`. To pick up the new name, run `claude plugin uninstall oms@oms` and `claude plugin marketplace remove oms`, then install again. The README now credits Gajae Code through the acknowledgements, and the Gajae-Code install command lives in the host asset guide.
12
+
7
13
  ## [0.20.4] - 2026-09-30
8
14
 
9
15
  ## [0.20.3] - 2026-09-30
package/CHANGELOG.md CHANGED
@@ -10,6 +10,10 @@ This aggregate changelog contains changes that span multiple layers.
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [0.20.6] - 2026-10-01
14
+
15
+ ## [0.20.5] - 2026-09-30
16
+
13
17
  ## [0.20.4] - 2026-09-30
14
18
 
15
19
  ## [0.20.3] - 2026-09-30
package/README.ko.md CHANGED
@@ -93,7 +93,7 @@ oms setup status --vault /path/to/vault
93
93
  oms setup host install --runtime claude --vault /path/to/vault --yes
94
94
  ```
95
95
 
96
- `claude` 대신 `codex` 또는 `hermes`를 쓸 수 있다. 세 호스트를 모두 설치하려면 `all`을 쓴다. CLI만 사용한다면 호스트 설치는 선택 사항이다. Hermes 프로필, 모델 설정, 제거 방법은 [설치 가이드](./docs/install.md)를 참고한다.
96
+ `claude` 대신 `codex` 또는 `hermes`를 쓸 수 있다. 세 호스트를 모두 설치하려면 `all`을 쓴다. Claude Code에서 `--execute`를 붙이면 OMS가 plugin marketplace를 추가하고 `claude plugin install oms@oh-my-second-brain` 명령을 실행해 `/oms:*` 스킬을 설치한다. 붙이지 않으면 직접 실행할 명령을 그대로 보여준다. CLI만 사용한다면 호스트 설치는 선택 사항이다. Hermes 프로필, 모델 설정, 제거 방법은 [설치 가이드](./docs/install.md)를 참고한다.
97
97
 
98
98
  ### 4. 지식 꺼내 쓰기
99
99
 
@@ -127,17 +127,17 @@ oms search "프로젝트 결정" --vault /path/to/vault
127
127
  | **에이전트** | 맥락을 읽고 노트를 작성하며 호스트에 맞는 워크플로를 쓴다. 보존할 가치는 사용자와 에이전트가 판단한다. |
128
128
 
129
129
  > [!IMPORTANT]
130
- > **쓰기 검사를 신뢰하기 전에 계약부터 설정한다.** 이 기기에 봉인이 없는 볼트는 계약 판정을 하지 않는다. 일반적인 경로·입력 보호는 그대로 적용된다. 계약을 위반하는 쓰기는 파일을 바꾸지 않는다. 쓰기 허용은 구조 준수를 뜻하며, 사실의 정확성이나 품질 승인이 아니다.
130
+ > **쓰기 검사를 신뢰하기 전에 계약부터 설정한다.** 이 기기에 봉인이 없는 볼트는 계약 판정을 하지 않는다. 그 쓰기에는 `oms interview`를 안내하는 `contract-open` 경고가 붙고, 일반적인 경로·입력 보호는 그대로 적용된다. 계약을 어긴 쓰기는 경고와 함께 저장되고, 안전 거부, 없거나 오래된 `ifMatch`, 검증되지 않은 대상은 파일을 바꾸지 않는다. 경고 없이 허용된 쓰기는 구조 준수를 뜻하며, 사실의 정확성이나 품질 승인이 아니다.
131
131
 
132
132
  <details>
133
133
  <summary><strong>볼트 계약 자세히 보기</strong></summary>
134
134
 
135
135
  - **의미는 사용자 소유다.** 폴더와 속성 pool을 함께 인터뷰한다. 속성 이름·폴더·페르소나를 하드코딩하지 않고 Inbox fallback도 없다.
136
136
  - **볼트 안의 제어 파일은 하나다.** `.oms/settings.json`에 `version`, `vaultId`, `templateFolder`, `embedding`, `agentRepair`를 둔다. 다른 `.oms/` 항목은 무시하고 `oms doctor contract`가 예상하지 않은 제어 파일로 보고한다. `.obsidian/types.json`은 읽기 전용 관측값이며 봉인을 덮어쓰지 않는다.
137
- - **템플릿은 원본으로 남는다.** 템플릿은 `templateFolder`에 있으며 봉인하거나 판정하지 않는다. 새 노트는 살아 있는 템플릿으로 뼈대를 채운다. 쓰기가 이름을 준 템플릿, 없으면 basename이나 `folder:` 키가 대상 폴더와 맞는 유일한 템플릿이다. 템플릿 파일을 다시 쓰거나 복사하지 않으며, Templater·JavaScript·전용 token 언어를 해석하거나 실행하지 않는다. 쓰기는 작성 중인 노트의 기계적인 부분만 채운다. `{{title}}`·`{{date}}`·`{{time}}` 변수, 새 노트의 date·datetime 기본값, 선택한 템플릿의 frontmatter 기본값과 빠진 heading이다. 노트에 이미 있는 값이 우선한다. 필수 값을 대신 채우지는 않는다.
137
+ - **템플릿은 원본으로 남는다.** 템플릿은 `templateFolder`에 있으며 봉인하거나 판정하지 않는다. 새 노트는 살아 있는 템플릿으로 뼈대를 채운다. 쓰기가 이름을 준 템플릿, 없으면 basename이나 `folder:` 키가 대상 폴더와 맞는 유일한 템플릿이다. 템플릿 파일을 다시 쓰거나 복사하지 않으며, Templater·JavaScript·전용 token 언어를 해석하거나 실행하지 않는다. 쓰기는 작성 중인 노트의 기계적인 부분만 채운다. `{{title}}`·`{{date}}`·`{{time}}` 변수, 새 노트의 date·datetime 기본값, 선택한 템플릿의 frontmatter 기본값과 빠진 heading이다. 노트에 이미 있는 값이 우선한다. 필수 값을 지어내지 않으며, 계약이 값을 하나로 정한 경우에만 무손실 수정으로 채우고 영수증의 `fixes`에 남긴다.
138
138
  - **이전 봉인도 읽힌다.** 새 봉인은 폴더와 속성만 저장한다. 이전 릴리스가 만든 봉인도 그대로 읽히며, `oms setup status`는 그 템플릿 제약을 `legacyTemplates` 개수로 보고할 뿐 강제하지 않는다.
139
- - **판정자는 하나다.** 거부 시 `{field, kind}` 위반과 안내 명령 하나만 반환한다. 규칙 값, 저장소 경로, 계약 본문은 반환하지 않는다.
140
- - **봉인 증거가 맞지 않으면 쓰기를 거부한다.** 이 기기의 증거가 볼트와 어긋나면 `contract-unreadable`로 거부하고 소유자가 `oms setup`을 다시 실행해야 한다. 봉인이 아예 없는 기기에서는 판정하지 않는 것과 구별한다.
139
+ - **판정자는 하나다.** 저장된 쓰기는 계약 위반을 `{field, kind}` 경고로, 거부된 쓰기는 그 이유를 같은 형태로 반환하며, 각각 안내 명령 하나가 붙는다. 규칙 값, 저장소 경로, 계약 본문은 반환하지 않는다.
140
+ - **변조된 봉인은 쓰기를 거부한다.** `.oms/settings.json`의 vault id가 이 기기의 봉인과 어긋나면 `contract-tampered`로 거부하고, `oms doctor contract`가 원인을 알려준다. 봉인 증거가 없거나 깨졌으면 `contract-unreadable` 경고와 함께 저장하며, 소유자가 `oms interview`로 다시 봉인할 때까지 이어진다. `oms doctor contract`가 볼트 이동이나 색인 항목의 누락·손상을 찾으면, 다시 봉인하지 않고 색인만 고치는 `oms doctor contract --fix`를 안내한다. 봉인이 아예 없는 기기에서는 판정하지 않는 것과 구별한다.
141
141
 
142
142
  [아키텍처](./docs/architecture.md), [컨벤션](./docs/conventions.md), [ADR-007](https://github.com/GoBeromsu/oh-my-second-brain/blob/main/docs/decisions/ADR-007-vault-contract-ontology.md)을 참고한다.
143
143
 
@@ -152,7 +152,7 @@ oms search "프로젝트 결정" --vault /path/to/vault
152
152
 
153
153
  setup과 인터뷰는 폴더와 속성만 묻는다. `oms setup extract --template <name>`은 `templateFolder`의 템플릿이 채울 뼈대(원본 경로, `folder:` 선택자, 속성 이름, heading)를 미리 보여 준다. 템플릿을 고치면 재봉인 없이 다음 쓰기부터 반영된다.
154
154
 
155
- `oms doctor contract`는 봉인, 오래된 lock, 고아 generation, 예상하지 않은 제어 파일, hook 전송 실패를 진단한다. `--fix`는 이동했거나 색인되지 않은 볼트를 다시 색인할 뿐이다. 다른 봉인 문제는 `oms setup`으로 복구한다.
155
+ `oms doctor contract`는 봉인, 오래된 lock, 고아 generation, 예상하지 않은 제어 파일, hook 전송 실패를 진단한다. `--fix`는 이동했거나 색인되지 않은 볼트를 다시 색인하거나, 읽을 수 없는 색인을 다시 만들 뿐이다. 다른 봉인 문제는 `oms interview`로 다시 봉인한다.
156
156
 
157
157
  모델 수명주기는 별도다: `oms setup model install|select|waive|status`.
158
158
 
@@ -168,12 +168,12 @@ setup과 인터뷰는 폴더와 속성만 묻는다. `oms setup extract --templa
168
168
  | :--- | :--- |
169
169
  | `write` | 노트 전체를 봉인된 계약으로 판정하고 허용된 쓰기를 저장한다. |
170
170
  | `search` | 볼트를 바꾸지 않고 노트, 구조화된 맥락, wikilink 제안을 찾는다. |
171
- | `interview` | 볼트 인터뷰 질문과 봉인 상태를 보여 준다. 아무것도 봉인하지 않는다. |
171
+ | `interview` | 볼트 인터뷰를 이어 간다. 열린 질문을 보여 주고 답을 기록하며, 소유자가 확인한 제안만 봉인한다. |
172
172
  | `doctor` | 읽기 전용 `status`, 계약 진단, 노트 감사, 링크 검사, 명시적인 색인 유지보수를 수행한다. |
173
173
 
174
174
  6개 스킬은 `distill`, `doctor`, `interview`, `search`, `setup`, `write`다.
175
175
 
176
- `distill`과 `setup`은 대응 MCP 도구가 없는 워크플로다. 봉인에는 MCP 작업이 없고, 세부 기능은 네 도구 아래의 `op` 값으로 제공한다. 도구 annotation은 도구별로 정한다. `write`와 `doctor` 복구는 변경을 일으키고 `interview`는 보수적으로 두므로 읽기 전용으로 표시한 도구는 `search`뿐이다.
176
+ `distill`과 `setup`은 대응 MCP 도구가 없는 워크플로다. MCP는 소유자가 확인한 제안만 `interview` `op: seal`로 봉인하고, 세부 기능은 네 도구 아래의 `op` 값으로 제공한다. 도구 annotation은 도구별로 정한다. `write`와 `doctor` 복구는 변경을 일으키고 `interview`는 보수적으로 두므로 읽기 전용으로 표시한 도구는 `search`뿐이다.
177
177
 
178
178
  | 호스트 | 통합 방식 | 쓰기 검사 |
179
179
  | :--- | :--- | :--- |
@@ -182,9 +182,7 @@ setup과 인터뷰는 폴더와 속성만 묻는다. `oms setup extract --templa
182
182
  | **Hermes** | 프로필별 스킬, 가이드, MCP | MCP `write`만 검사. 기본 쓰기 hook은 없다. |
183
183
 
184
184
  > [!NOTE]
185
- > Claude hook은 판정된 계약 위반을 거부하지만, hook 자체를 실행할 수 없으면 경고와 함께 쓰기를 허용한다. Codex와 Hermes의 기본 파일 쓰기는 OMS 판정자를 거치지 않는다. 파일시스템 전체를 통제하는 sandbox가 아니다.
186
-
187
- Gajae-Code에서는 `gjc plugin install oms@oms`로 marketplace plugin을 설치한다. 패키지 루트 `skills/` 경로에서 스킬 6개를 발견한다. 자세한 내용은 [호스트 asset](./docs/adapters.md)을 참고한다.
185
+ > Claude hook은 안전 거부(제어 경로나 안전하지 않은 경로, `~/.oms/` 접근, 지원하지 않는 입력, 변조된 계약)만 막는다. 계약 위반은 경고와 함께 쓰기를 허용하고, hook 자체를 실행할 수 없으면 쓰기를 허용하고 경고를 기록한다. Codex와 Hermes의 기본 파일 쓰기는 OMS 판정자를 거치지 않는다. 파일시스템 전체를 통제하는 sandbox가 아니다.
188
186
 
189
187
  <details>
190
188
  <summary><strong>호스트 유지보수와 볼트 선택</strong></summary>
@@ -261,7 +259,7 @@ oms hook pre Claude 쓰기를 계약으로
261
259
 
262
260
  [기여 가이드](https://github.com/GoBeromsu/oh-my-second-brain/blob/main/CONTRIBUTING.md)를 읽거나, 재현 가능한 문제와 구체적인 제안을 [이슈](https://github.com/GoBeromsu/oh-my-second-brain/issues)로 남길 수 있다.
263
261
 
264
- [ACKNOWLEDGMENTS](./ACKNOWLEDGMENTS.md)는 Ouroboros, Gajae Code의 deep-interview 등 설계에 영향을 준 아이디어를 기록한다. runtime 복제나 연구 결과를 뜻하지 않는다. 별자리 배너는 [beomsukoh.com](https://beomsukoh.com/)의 연결된 노트 풍경에서 착안한 자체 제작 일러스트다. 이미지는 개념을 설명하는 도식이며 제품 화면, host smoke 증거, 제품 gate 통과 결과가 아니다.
262
+ [ACKNOWLEDGMENTS](./ACKNOWLEDGMENTS.md)는 [Ouroboros](./ACKNOWLEDGMENTS.md#ouroboros), [Gajae Code](./ACKNOWLEDGMENTS.md#gajae-code)의 deep-interview 등 설계에 영향을 준 아이디어를 기록한다. runtime 복제나 연구 결과를 뜻하지 않는다. 별자리 배너는 [beomsukoh.com](https://beomsukoh.com/)의 연결된 노트 풍경에서 착안한 자체 제작 일러스트다. 이미지는 개념을 설명하는 도식이며 제품 화면, host smoke 증거, 제품 gate 통과 결과가 아니다.
265
263
 
266
264
  ---
267
265
 
package/README.md CHANGED
@@ -93,7 +93,7 @@ Install the integration for the host you use:
93
93
  oms setup host install --runtime claude --vault /path/to/vault --yes
94
94
  ```
95
95
 
96
- Replace `claude` with `codex` or `hermes`; use `all` to install all three. Host integration is optional if you only need the CLI. See the [installation guide](./docs/install.md) for Hermes profiles, model setup, and removal.
96
+ Replace `claude` with `codex` or `hermes`; use `all` to install all three. For Claude Code, add `--execute` to let OMS add the plugin marketplace and run `claude plugin install oms@oh-my-second-brain`, which brings the `/oms:*` skills; without it, OMS prints the exact commands for you to run. Host integration is optional if you only need the CLI. See the [installation guide](./docs/install.md) for Hermes profiles, model setup, and removal.
97
97
 
98
98
  ### 4. Put your knowledge to work
99
99
 
@@ -127,17 +127,17 @@ These are example requests, not captured run results. Available workflows and wr
127
127
  | **Your agent** | Reads context, composes notes, and uses the appropriate host workflow. You and the agent decide what is worth keeping. |
128
128
 
129
129
  > [!IMPORTANT]
130
- > **Set up the contract before relying on write checks.** A vault with no seal on this machine is not contract-judged; general path and input safeguards still apply. A contract violation leaves the file unchanged. An allowed write means structural compliance, not factual accuracy or quality approval.
130
+ > **Set up the contract before relying on write checks.** A vault with no seal on this machine is not contract-judged: its writes carry a `contract-open` warning naming `oms interview`, and general path and input safeguards still apply. A write that breaks the contract is saved with warnings; a safety refusal, a missing or stale `ifMatch`, or an unverified target leaves the file unchanged. An allowed write with no warnings means structural compliance, not factual accuracy or quality approval.
131
131
 
132
132
  <details>
133
133
  <summary><strong>The vault contract, in detail</strong></summary>
134
134
 
135
135
  - **Meaning is user-owned.** The interview covers folders and the property pool together. OMS hardcodes no property names, folders, or personas and has no Inbox fallback.
136
136
  - **One control file inside the vault.** `.oms/settings.json` holds `version`, `vaultId`, `templateFolder`, `embedding`, and `agentRepair`. Other `.oms/` entries are ignored and reported as unexpected control files by `oms doctor contract`. `.obsidian/types.json` is a read-only observation, not an override of the seal.
137
- - **Templates stay yours.** Templates live in your `templateFolder` and are never sealed or judged. A new note is scaffolded from the live template: the one the write names, or else the one template whose basename or `folder:` key matches the target folder. OMS never rewrites or copies a template file, and does not parse or execute Templater, JavaScript, or a private token language. A write only fills what is mechanical in the note being written: `{{title}}`, `{{date}}` and `{{time}}` variables, date and datetime defaults on a new note, and the chosen template's frontmatter defaults and missing headings. The note's own values win. It never supplies a required value.
137
+ - **Templates stay yours.** Templates live in your `templateFolder` and are never sealed or judged. A new note is scaffolded from the live template: the one the write names, or else the one template whose basename or `folder:` key matches the target folder. OMS never rewrites or copies a template file, and does not parse or execute Templater, JavaScript, or a private token language. A write only fills what is mechanical in the note being written: `{{title}}`, `{{date}}` and `{{time}}` variables, date and datetime defaults on a new note, and the chosen template's frontmatter defaults and missing headings. The note's own values win. It never invents a required value; only a value the contract fixes is filled, as a lossless fix listed in the receipt's `fixes`.
138
138
  - **Old seals stay readable.** A new seal stores folders and properties only. A seal made by an older release still loads; `oms setup status` counts its template constraints as `legacyTemplates`, and they are reported, never enforced.
139
- - **One judge, bounded feedback.** Denied writes return `{field, kind}` violations and one guidance command, not rule values, store paths, or the contract body.
140
- - **Mismatched seal evidence blocks writes.** When this machine's evidence no longer matches the vault, writes fail with `contract-unreadable` until the owner runs `oms setup` again. A machine with no seal is a different case: its vault is not contract-judged.
139
+ - **One judge, bounded feedback.** A saved write returns its contract findings as `{field, kind}` warnings, and a refused write returns its reason the same way. Each of these comes with one guidance command, never rule values, store paths, or the contract body.
140
+ - **A tampered seal blocks writes.** When the vault id in `.oms/settings.json` no longer matches this machine's seal, writes are refused as `contract-tampered`; `oms doctor contract` explains it. Missing or broken seal evidence is `contract-unreadable`: the write is saved with that warning until the owner reseals with `oms interview`. When `oms doctor contract` finds a moved vault or a missing or unreadable index entry, it names `oms doctor contract --fix`, which reindexes without resealing. A machine with no seal is a different case: its vault is not contract-judged.
141
141
 
142
142
  See [architecture](./docs/architecture.md), [conventions](./docs/conventions.md), and [ADR-007](https://github.com/GoBeromsu/oh-my-second-brain/blob/main/docs/decisions/ADR-007-vault-contract-ontology.md).
143
143
 
@@ -152,7 +152,7 @@ The `setup` skill asks the owner each question via `oms setup --questions` and s
152
152
 
153
153
  Setup and the interview ask about folders and properties only. `oms setup extract --template <name>` previews what a template in `templateFolder` would scaffold: its source, `folder:` selector, property names, and headings. Editing a template takes effect on the next write without a reseal.
154
154
 
155
- `oms doctor contract` diagnoses seal problems, stale locks, orphaned generations, unexpected control files, and hook transport failures. Its `--fix` only re-indexes a moved or unindexed vault. Other broken seals are recovered through `oms setup`.
155
+ `oms doctor contract` diagnoses seal problems, stale locks, orphaned generations, unexpected control files, and hook transport failures. Its `--fix` only re-indexes a moved or unindexed vault, or rebuilds an unreadable index. Other broken seals are resealed with `oms interview`.
156
156
 
157
157
  Model lifecycle is separate: `oms setup model install|select|waive|status`.
158
158
 
@@ -173,7 +173,7 @@ Model lifecycle is separate: `oms setup model install|select|waive|status`.
173
173
 
174
174
  The six skills are `distill`, `doctor`, `interview`, `search`, `setup`, and `write`.
175
175
 
176
- `distill` and `setup` are tool-less workflows; sealing has no MCP operation. Detail capabilities use `op` values under the four tools. Tool annotations are per tool: only `search` is marked read-only, because `write` and the `doctor` repairs mutate and `interview` is kept conservative.
176
+ `distill` and `setup` are tool-less workflows; MCP seals only through `interview` `op: seal` on a proposal the owner confirmed. Detail capabilities use `op` values under the four tools. Tool annotations are per tool: only `search` is marked read-only, because `write` and the `doctor` repairs mutate and `interview` is kept conservative.
177
177
 
178
178
  | Host | Integration | Write checks |
179
179
  | :--- | :--- | :--- |
@@ -182,9 +182,7 @@ The six skills are `distill`, `doctor`, `interview`, `search`, `setup`, and `wri
182
182
  | **Hermes** | Profile-scoped skills, guidance, and MCP | MCP `write`; no native write hook. |
183
183
 
184
184
  > [!NOTE]
185
- > Claude's hook rejects a judged contract violation, but allows the write with a warning if the hook itself cannot run. Native file writes in Codex and Hermes do not pass through the OMS judge. This is not a filesystem-wide sandbox.
186
-
187
- For Gajae-Code, install the marketplace plugin with `gjc plugin install oms@oms`; it discovers the six skills at the package-root `skills/` path. See [host assets](./docs/adapters.md) for integration details.
185
+ > Claude's hook denies a write only on a safety refusal: a control or unsafe path (including access under `~/.oms/`), unsupported input, or a tampered contract. A contract finding allows the write with a warning; a hook that cannot run allows the write and logs a warning. Native file writes in Codex and Hermes do not pass through the OMS judge. This is not a filesystem-wide sandbox.
188
186
 
189
187
  <details>
190
188
  <summary><strong>Host maintenance and vault targeting</strong></summary>
@@ -261,7 +259,7 @@ Note `create`, `append`, `update`, and `backfill` are retired operations. There
261
259
 
262
260
  Contributions are welcome. Start with the [contributing guide](https://github.com/GoBeromsu/oh-my-second-brain/blob/main/CONTRIBUTING.md), or [open an issue](https://github.com/GoBeromsu/oh-my-second-brain/issues) with a reproducible problem or a focused proposal.
263
261
 
264
- [ACKNOWLEDGMENTS](./ACKNOWLEDGMENTS.md) records design influences, including Ouroboros and Gajae Code's deep-interview. Those credits describe ideas, not a copied runtime or a research result. The original constellation illustration is inspired by the connected-note landscape at [beomsukoh.com](https://beomsukoh.com/). Illustrations explain concepts; they are not product screenshots, host-smoke evidence, or product-gate results.
262
+ [ACKNOWLEDGMENTS](./ACKNOWLEDGMENTS.md) records design influences, including [Ouroboros](./ACKNOWLEDGMENTS.md#ouroboros) and [Gajae Code](./ACKNOWLEDGMENTS.md#gajae-code)'s deep-interview. Those credits describe ideas, not a copied runtime or a research result. The original constellation illustration is inspired by the connected-note landscape at [beomsukoh.com](https://beomsukoh.com/). Illustrations explain concepts; they are not product screenshots, host-smoke evidence, or product-gate results.
265
263
 
266
264
  ---
267
265
 
@@ -10,23 +10,31 @@ outside the vault, and it is not yours to read.
10
10
  ## Writing
11
11
 
12
12
  Write vault notes with MCP `write {path, content, template?, ifMatch?, check?}` (the `/write`
13
- skill). A denial gives only `{field, kind}` and a guidance command. Never ask
14
- about or guess the contract's location or values.
13
+ skill). A note that breaks the contract is saved, with each finding as a
14
+ `{field, kind}` warning; only a safety refusal denies a write. A saved note
15
+ with warnings, or a denial, comes with one guidance command. Never ask about or
16
+ guess the contract's location or values.
15
17
 
16
18
  - `template` is optional. Pass it only when the user names the template a note
17
19
  follows.
18
- - An allowed note is saved whole. A denied write leaves the file unchanged. Read
19
- each `{field, kind}`, fix the content from what the user gave you, and write
20
- again. When you cannot fix it, ask the user. Never invent a value.
20
+ - A note is saved whole, even with warnings. A safety refusal (a path outside
21
+ the vault, a control or unsafe path, unsupported input, a tampered contract),
22
+ a missing or stale `ifMatch`, or an unverified target leaves the file
23
+ unchanged. In a sealed vault, frontmatter that does not parse may be kept as
24
+ a draft (through MCP or `oms write`) instead of saved; otherwise it is saved
25
+ with a `yaml-syntax` warning. Read each `{field, kind}`, fix the content from
26
+ what the user gave you, and write again. When you cannot fix it, ask the
27
+ user. Never invent a value.
21
28
  - Native Write, Edit, MultiEdit, and NotebookEdit inside the vault reach the
22
- same judge through the Claude write hook. The hook denies a write that breaks
23
- the contract. When the hook itself cannot run, it allows the write and prints
24
- a warning.
29
+ same judge through the Claude write hook. The hook denies only a safety
30
+ refusal; it allows a write with contract findings and returns them as a
31
+ warning. When the hook itself cannot run, it allows the write and prints a
32
+ warning.
25
33
  - `~/.oms` is off-limits. The hook denies reads, searches, and writes there as
26
34
  `control-path`. Inside the vault, `.oms/settings.json` is the only OMS file.
27
- - OMS is not the author or repair engine. An allowed write means the note fits
28
- the sealed structure, not that it is worth keeping. That judgement is yours
29
- and the user's.
35
+ - OMS is not the author or repair engine. An allowed write with no warnings
36
+ means the note fits the sealed structure, not that it is worth keeping. That
37
+ judgement is yours and the user's.
30
38
 
31
39
  ## Retrieval and health
32
40
 
@@ -15,19 +15,26 @@ the only OMS file.
15
15
  ## Writing
16
16
 
17
17
  Write vault notes with MCP `write {path, content, template?, ifMatch?, check?}` (`$oms-write`). A
18
- denial gives only `{field, kind}` and a guidance command. Never ask about or
19
- guess the contract's location or values.
18
+ note that breaks the contract is saved, with each finding as a `{field, kind}`
19
+ warning; only a safety refusal denies a write. A saved note with warnings, or a
20
+ denial, comes with one guidance command. Never ask about or guess the
21
+ contract's location or values.
20
22
 
21
23
  - `template` is optional. Pass it only when the user names the template a note
22
24
  follows.
23
- - An allowed note is saved whole. A denied write leaves the file unchanged. Read
24
- each `{field, kind}`, fix the content from what the user gave you, and write
25
- again. When you cannot fix it, ask the user. Never invent a value.
25
+ - A note is saved whole, even with warnings. A safety refusal (a path outside
26
+ the vault, a control or unsafe path, unsupported input, a tampered contract),
27
+ a missing or stale `ifMatch`, or an unverified target leaves the file
28
+ unchanged. In a sealed vault, frontmatter that does not parse may be kept as
29
+ a draft instead of saved; otherwise it is saved with a `yaml-syntax`
30
+ warning. Read each `{field, kind}`, fix the content from
31
+ what the user gave you, and write again. When you cannot fix it, ask the
32
+ user. Never invent a value.
26
33
  - Codex declares no write hook. A note written with host file tools is not
27
34
  judged, so use MCP `write` for vault notes.
28
- - OMS is not the author or repair engine. An allowed write means the note fits
29
- the sealed structure, not that it is worth keeping. That judgement is yours
30
- and the user's.
35
+ - OMS is not the author or repair engine. An allowed write with no warnings
36
+ means the note fits the sealed structure, not that it is worth keeping. That
37
+ judgement is yours and the user's.
31
38
 
32
39
  ## Read-only work and health
33
40
 
@@ -17,11 +17,13 @@ sealed contract is not yours to read.
17
17
 
18
18
  ## Boundaries
19
19
 
20
- - Write vault notes with MCP `write {path, content, template?, ifMatch?, check?}`. A denial gives
21
- only `{field, kind}` and a guidance command. Never ask about or guess the
20
+ - Write vault notes with MCP `write {path, content, template?, ifMatch?, check?}`. A note that
21
+ breaks the contract is saved, with each finding as a `{field, kind}` warning;
22
+ only a safety refusal denies a write. Never ask about or guess the
22
23
  contract's location or values.
23
- - A denied write leaves the file unchanged. Fix the content from what the user
24
- gave you and write again, or ask the user. Never invent a missing value.
24
+ - A denied write, a missing or stale `ifMatch`, or an unverified target leaves
25
+ the file unchanged. For a warning or a denial, fix the content from what the
26
+ user gave you and write again, or ask the user. Never invent a missing value.
25
27
  - Codex has no write hook. Notes written with host file tools are not judged.
26
28
  - `~/.oms` is off-limits. Inside the vault, `.oms/settings.json` is the only
27
29
  OMS file.
@@ -20,8 +20,10 @@ skills are listed under `knowledge-management`. Filter with
20
20
  `knowledge-management/oms` matches nothing.
21
21
 
22
22
  Agents write notes with MCP `write {path, content, template?, ifMatch?, check?}`. OMS judges each
23
- note against the contract the user sealed with `oms setup`. A denial returns
24
- only `{field, kind}` and a guidance command. There is no completion operation
23
+ note against the contract the user sealed with `oms setup`. A note that
24
+ breaks the contract is saved, and each finding comes back as a `{field, kind}`
25
+ warning in the receipt; only a safety refusal denies a write. A saved note with
26
+ warnings, or a denial, carries one guidance command. There is no completion operation
25
27
  and no reviewer protocol, so deciding whether a note is worth keeping and
26
28
  repairing it belong to the user and the agent. See the [Hermes role guidance](./SOUL.md).
27
29
 
@@ -11,19 +11,26 @@ the only OMS file.
11
11
  ## Writing
12
12
 
13
13
  Write vault notes with MCP `write {path, content, template?, ifMatch?, check?}` (the `write`
14
- skill). A denial gives only `{field, kind}` and a guidance command. Never ask
15
- about or guess the contract's location or values.
14
+ skill). A note that breaks the contract is saved, with each finding as a
15
+ `{field, kind}` warning; only a safety refusal denies a write. A saved note
16
+ with warnings, or a denial, comes with one guidance command. Never ask about or
17
+ guess the contract's location or values.
16
18
 
17
19
  - `template` is optional. Pass it only when the user names the template a note
18
20
  follows.
19
- - An allowed note is saved whole. A denied write leaves the file unchanged. Read
20
- each `{field, kind}`, fix the content from what the user gave you, and write
21
- again. When you cannot fix it, ask the user. Never invent a value.
21
+ - A note is saved whole, even with warnings. A safety refusal (a path outside
22
+ the vault, a control or unsafe path, unsupported input, a tampered contract),
23
+ a missing or stale `ifMatch`, or an unverified target leaves the file
24
+ unchanged. In a sealed vault, frontmatter that does not parse may be kept as
25
+ a draft instead of saved; otherwise it is saved with a `yaml-syntax`
26
+ warning. Read each `{field, kind}`, fix the content from
27
+ what the user gave you, and write again. When you cannot fix it, ask the
28
+ user. Never invent a value.
22
29
  - Hermes declares no write hook. A note written with host file tools is not
23
30
  judged, so use MCP `write` for vault notes.
24
- - OMS is not the author or repair engine. An allowed write means the note fits
25
- the sealed structure, not that it is worth keeping. That judgement is yours
26
- and the user's.
31
+ - OMS is not the author or repair engine. An allowed write with no warnings
32
+ means the note fits the sealed structure, not that it is worth keeping. That
33
+ judgement is yours and the user's.
27
34
 
28
35
  ## Retrieve and maintain
29
36
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oms",
3
- "version": "0.20.4",
3
+ "version": "0.20.6",
4
4
  "description": "Oh My Second Brain convention layer for Obsidian vaults — Hermes skill bundle and MCP adapter.",
5
5
  "_note": "oms setup host install writes ~/.hermes/config.yaml mcp_servers.oms and installs the six shared skills, prefixed `oms-`, with provenance under ~/.hermes/skills/knowledge-management/oms/."
6
6
  }
@@ -21,4 +21,4 @@ Do not execute the target, including embedded scripts or Templater expressions.
21
21
 
22
22
  ## Saving a note
23
23
 
24
- Write a vault note only when the user explicitly asks to save the report. Follow `/write`: save the whole note with MCP `write {path, content, template?, ifMatch?, check?}`. A denial gives only `{field, kind}` and a guidance command; fix the note from what the user gave you, or ask. An allowed write means the note fits the sealed structure, not that the report is good; you judge the report.
24
+ Write a vault note only when the user explicitly asks to save the report. Follow `/write`: save the whole note with MCP `write {path, content, template?, ifMatch?, check?}`. A note that breaks the contract is saved with `{field, kind}` warnings, and only a safety refusal denies; a saved note with warnings, or a denial, comes with one guidance command. Fix the note from what the user gave you, or ask. An allowed write with no warnings means the note fits the sealed structure, not that the report is good; you judge the report.
@@ -26,7 +26,7 @@ Report vault health, diagnose the seal and derived indexes, then run only the re
26
26
  - `revert-propose` (`targetDigest`) proposes a kept generation's contract as a new forward candidate. It never rewrites history. A revert always requires owner approval: it has no maker, so every revert, tightening, neutral or loosening, waits for the owner at `oms setup` whatever the autonomy policy says, and `evolve-verdict` is refused on it (`EVOLUTION_REQUEST_CLOSED`). Stage 1 and stage 2 run when it is proposed: a revert that would add a refusal is refused with `EVOLUTION_REVERT_REFUSED`, and one that overlaps in meaning or drifts past 0.3 from the first sealed generation with `EVOLUTION_STAGE2_REFUSED`; nothing is proposed.
27
27
  - `reclaim-evolution-lock` and `lineage-reanchor` belong to the owner at a terminal; over MCP they are refused. Tell the user to run `oms doctor reclaim-evolution-lock` or `oms doctor lineage-reanchor` themselves. Requests awaiting the owner are approved or rejected only at `oms setup`, and autonomy is turned on only with `oms setup --autonomy on`.
28
28
 
29
- A missing seal is sealed by the user running `oms interview` at a terminal, the command the `contract-open` write warning names. A broken seal (a tampered or unreadable contract store) is diagnosed with `oms doctor contract`, then resealed by the user running `oms interview` at a terminal; the `contract-unreadable` write warning names that reseal, and the `contract-tampered` warning names the diagnosis; recovery is never done through the `setup` skill. The only automatic seal repair is `oms doctor contract --fix`, which re-indexes a moved or unindexed vault and nothing else. `oms doctor contract` also names the unexpected `.oms` entries for the person at the CLI.
29
+ A missing seal is sealed by the user running `oms interview` at a terminal, the command the `contract-open` write warning names. A broken seal (a tampered or unreadable contract store) is diagnosed with `oms doctor contract`, then resealed by the user running `oms interview` at a terminal; the `contract-unreadable` write warning names that reseal, and the `contract-tampered` warning names the diagnosis; recovery is never done through the `setup` skill. The only automatic seal repair is `oms doctor contract --fix`, which re-indexes a moved or unindexed vault, or rebuilds an unreadable index, and nothing else. `oms doctor contract` also names the unexpected `.oms` entries for the person at the CLI.
30
30
 
31
31
  Index repairs run only when explicitly requested and do not edit notes. There is no default-value backfill: OMS never rewrites a note.
32
32
 
@@ -35,8 +35,8 @@ Always pass the vault with `--vault <path>`. A vault inferred from the current d
35
35
  - The values the owner gives (allowed values, patterns, ranges) are part of the hidden contract. Do not repeat them into notes, messages to others, or memory.
36
36
  - `--answers` seals a first contract, or a reseal that only adds or tightens. Removing a folder or property, dropping a requirement, or widening a rule is loosening, and it belongs to the owner's own terminal.
37
37
  - The reseal may add new folders and properties, and tighten folder and property rules. Editing a template needs no reseal: it takes effect on the next write.
38
- - Adding is allowed but is not neutral: registering a new folder or property widens that closed axis, so notes the sealed contract refused there can be written afterwards. Ask the owner about every addition; never add one they did not answer for.
39
- - A write denied as `unregistered-folder` or `unknown-property` is not yours to clear. Do not create the folder, add the type to `.obsidian/types.json`, or answer the registration question yourself so that the write passes. Ask the owner, and register the folder or property only when they answer. Nothing but that answer enforces this.
38
+ - Adding is allowed but is not neutral: registering a new folder or property widens that closed axis, so notes the sealed contract flagged there are saved without that warning afterwards. Ask the owner about every addition; never add one they did not answer for.
39
+ - An `unregistered-folder` or `unknown-property` warning on a write is not yours to clear. Do not create the folder, add the type to `.obsidian/types.json`, or answer the registration question yourself so that the warning goes away. Ask the owner, and register the folder or property only when they answer. Nothing but that answer enforces this.
40
40
  - Never run `oms setup` without `--questions` or `--answers`. The interactive interview is the owner's, in their own terminal.
41
41
  - Never run setup under a pseudo-terminal wrapper such as `script`, `expect`, or `unbuffer`, and never set up a terminal for it. The interactive gate only checks for a TTY, so a wrapper would take the owner's full authority, including loosening.
42
42
  - Never move or rename the vault with Bash, and never delete, edit, or re-ID `.oms/settings.json`. Either makes the vault look never sealed, so `--answers` would take a fresh first seal in place of the owner's contract.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: write
3
- description: Write a vault note through the contract judge; a denied write names each violation.
3
+ description: Write a vault note through the contract judge; contract findings come back as warnings, and only a safety refusal denies.
4
4
  mcp_tool: write
5
5
  mcp_args:
6
6
  path: "$1"
@@ -15,7 +15,7 @@ The user owns meaning. The agent writes the note. OMS judges the bytes against t
15
15
  /write <note-path> [template]
16
16
  ```
17
17
 
18
- Write vault notes with MCP `write {path, content, template?, ifMatch?, check?}`. A denial gives only `{field, kind}` and a guidance command. Never ask about or guess the contract's location or values.
18
+ Write vault notes with MCP `write {path, content, template?, ifMatch?, check?}`. A note that breaks the contract is saved, with each finding as a `{field, kind}` warning; only a safety refusal denies a write. A saved note with warnings, or a denial, comes with one guidance command. Never ask about or guess the contract's location or values.
19
19
 
20
20
  Document reads stay on `search { op: "get-document" }`.
21
21
 
@@ -27,15 +27,15 @@ write { path, content, template?, ifMatch?, check? }
27
27
 
28
28
  `path` is vault-relative. `content` is the whole note. `template` names a template in the vault's template folder to scaffold a new note from; omit it to use the one template matching the target folder, if any. A named template that does not exist scaffolds nothing and is reported as `template-missing`. `ifMatch` is the `sha256:` revision of the note you are replacing. `check: true` judges without writing. There are no other fields.
29
29
 
30
- OMS fills only what is mechanical before it judges: template variables such as `{{title}}` and `{{date}}`, date and datetime defaults on a new note, and the chosen template's missing headings. It never supplies a required value or changes one the judge would refuse.
30
+ OMS fills only what is mechanical before it judges: template variables such as `{{title}}` and `{{date}}`, date and datetime defaults on a new note, and the chosen template's missing headings. It never invents a value; a flagged value is changed only by a lossless fix, listed in `fixes`.
31
31
 
32
- The judge answers allow or deny. Allow writes the note atomically and returns the receipt `{ ok: true, path, revision, contractRevision, index: { keyword, vector }, conformed, missingDefaults, warnings, fixes, next? }`; the note is searchable by keyword in the next call when the vault has an index. When `next` is present, the note was saved but has warnings, and `next` names the one command to run next; with `contract-open` it is `oms interview`, which the user runs once to seal the vault's folders and properties, so tell the user to run it. Deny writes nothing and returns `{ ok: false, status: "denied", refusals, violations: [{ field, kind }], reason }`. A violation names a field and a kind only; it never quotes a rule. Read the kinds, fix the note, and write again. Do not guess missing values and do not weaken the contract so the note passes; when you cannot fix a violation from what the user gave you, ask.
32
+ The judge answers allow or deny, and only a safety refusal denies. Allow writes the note atomically and returns the receipt `{ ok: true, path, revision, contractRevision, index: { keyword, vector }, conformed, missingDefaults, warnings, fixes, next? }`; the note is searchable by keyword in the next call when the vault has an index. A note that breaks the contract is still allowed: each finding is a `warnings` entry, and `next` names the one command to run next; with `contract-open` it is `oms interview`, which the user runs once to seal the vault's folders and properties, so tell the user to run it. To clear a warning, fix the note and write it again with the receipt's revision as `ifMatch`. Deny is for a safety refusal only (a path outside the vault, a control or unsafe path, unsupported input, a tampered contract): it writes nothing and returns `{ ok: false, status: "denied", refusals, violations: [{ field, kind }], reason }`, and `reason` ends with the guidance command. In a sealed vault, when the frontmatter does not parse, the note may be kept as a draft outside the vault instead of saved, and the answer is `{ ok: false, status: "drafted", draftRef, warnings }` (when no draft can be kept, the note is saved with its warnings instead); fix the frontmatter and write again. A finding names a field and a kind only; it never quotes a rule. Do not guess missing values and do not weaken the contract so the note passes; when you cannot fix a finding from what the user gave you, ask.
33
33
 
34
34
  To replace an existing note, pass its current revision as `ifMatch`: a previous receipt or `write { path, content, check: true }` reports it. Without `ifMatch` the overwrite is refused with `WRITE_IF_MATCH_REQUIRED` and nothing is written; `WRITE_TARGET_CHANGED` means the note moved on, so read it again before retrying; `WRITE_TARGET_ABSENT` means there is no note to replace, so retry without `ifMatch` to create it. `check` also returns the frame for the target (folder meaning, the property and template fields to satisfy, and which may stay absent) and touches nothing on disk.
35
35
 
36
36
  Placement is explicit: an explicit path, otherwise the folder meaning the user approved, otherwise ask. There is no Inbox fallback.
37
37
 
38
- A vault with no sealed contract accepts any note inside it, with a `contract-open` warning whose `next` is `oms interview`. A contract that cannot be read also accepts the note, with a `contract-unreadable` warning that names `oms interview`. Only a tampered contract denies writes, until the user runs `oms doctor contract` at a terminal; the `setup` skill does not recover a broken seal. Paths outside the vault and the vault's control paths are always denied.
38
+ A vault with no sealed contract accepts any note inside it, with a `contract-open` warning whose `next` is `oms interview`. A contract that cannot be read also accepts the note, with a `contract-unreadable` warning that names `oms interview`. Among contract states, only a tampered contract denies writes, until the user runs `oms doctor contract` at a terminal; the `setup` skill does not recover a broken seal. Paths outside the vault and the vault's control paths are always denied.
39
39
 
40
40
  ## Host file tools
41
41
 
@@ -35,12 +35,14 @@ export function contractUsage() {
35
35
  oms setup status [--vault <path>]
36
36
  Show the contract posture. Hidden values are never printed.
37
37
  oms doctor contract [--fix] [--vault <path>]
38
- Diagnose the seal. --fix only re-indexes a moved or unindexed vault.
38
+ Diagnose the seal. --fix only re-indexes a moved or unindexed vault,
39
+ or rebuilds an unreadable index.
39
40
 
40
41
  setup in a terminal has full authority, including loosening a sealed contract.
41
42
  --questions and --answers let an agent ask the owner each question (the setup skill):
42
- they seal a first contract or a stricter one, never a looser one. Loosening, and any
43
- seal that needs recovery first, is left to \`oms setup\` run by the owner in a terminal.`;
43
+ they seal a first contract or a stricter one, never a looser one. Loosening is left to
44
+ \`oms setup\` run by the owner in a terminal, and a broken seal is resealed there with
45
+ \`oms interview\`.`;
44
46
  }
45
47
  const VERBS = ["setup", "extract", "status", "doctor", "gaps"];
46
48
  function parse(argv) {