arcane-cli 0.39.0 → 1.1.0

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 (176) hide show
  1. package/README.md +14 -1
  2. package/dist/assets/.agents/skills/spell-address-review/SKILL.md +1 -1
  3. package/dist/assets/.agents/skills/spell-adopt-docs/SKILL.md +1 -1
  4. package/dist/assets/.agents/skills/spell-arcane-version/SKILL.md +1 -1
  5. package/dist/assets/.agents/skills/spell-architect/SKILL.md +1 -1
  6. package/dist/assets/.agents/skills/spell-brainstorm/SKILL.md +1 -1
  7. package/dist/assets/.agents/skills/spell-bug/SKILL.md +1 -1
  8. package/dist/assets/.agents/skills/spell-bump/SKILL.md +1 -1
  9. package/dist/assets/.agents/skills/spell-check-drift/SKILL.md +1 -1
  10. package/dist/assets/.agents/skills/spell-close-session/SKILL.md +1 -1
  11. package/dist/assets/.agents/skills/spell-commit-work/SKILL.md +1 -1
  12. package/dist/assets/.agents/skills/spell-compliance/SKILL.md +1 -1
  13. package/dist/assets/.agents/skills/spell-create-pull-request/SKILL.md +1 -1
  14. package/dist/assets/.agents/skills/spell-document/SKILL.md +1 -1
  15. package/dist/assets/.agents/skills/spell-dotnet-expert/SKILL.md +1 -1
  16. package/dist/assets/.agents/skills/spell-eas-store-deploy/SKILL.md +1 -1
  17. package/dist/assets/.agents/skills/spell-enchant/SKILL.md +1 -1
  18. package/dist/assets/.agents/skills/spell-explain-concept/SKILL.md +1 -1
  19. package/dist/assets/.agents/skills/spell-feedback/SKILL.md +1 -1
  20. package/dist/assets/.agents/skills/spell-full-cycle/SKILL.md +1 -1
  21. package/dist/assets/.agents/skills/spell-generate-bot-icons/SKILL.md +1 -1
  22. package/dist/assets/.agents/skills/spell-implement/SKILL.md +1 -1
  23. package/dist/assets/.agents/skills/spell-make-discoverable/SKILL.md +1 -1
  24. package/dist/assets/.agents/skills/spell-manifest/SKILL.md +1 -1
  25. package/dist/assets/.agents/skills/spell-open-session/SKILL.md +1 -1
  26. package/dist/assets/.agents/skills/spell-plan/SKILL.md +1 -1
  27. package/dist/assets/.agents/skills/spell-present-arcane/SKILL.md +1 -1
  28. package/dist/assets/.agents/skills/spell-product-review/SKILL.md +1 -1
  29. package/dist/assets/.agents/skills/spell-review/SKILL.md +1 -1
  30. package/dist/assets/.agents/skills/spell-review-batch/SKILL.md +1 -1
  31. package/dist/assets/.agents/skills/spell-save-idea/SKILL.md +1 -1
  32. package/dist/assets/.agents/skills/spell-scope/SKILL.md +1 -1
  33. package/dist/assets/.agents/skills/spell-scry/SKILL.md +1 -1
  34. package/dist/assets/.agents/skills/spell-security-review/SKILL.md +1 -1
  35. package/dist/assets/.agents/skills/spell-ship/SKILL.md +1 -1
  36. package/dist/assets/.agents/skills/spell-status/SKILL.md +1 -1
  37. package/dist/assets/.agents/skills/spell-suggest-feature/SKILL.md +1 -1
  38. package/dist/assets/.agents/skills/spell-summon-venture/SKILL.md +1 -1
  39. package/dist/assets/.agents/skills/spell-sync-pull-request/SKILL.md +1 -1
  40. package/dist/assets/.agents/skills/spell-test/SKILL.md +1 -1
  41. package/dist/assets/.agents/skills/spell-todo/SKILL.md +1 -1
  42. package/dist/assets/.agents/skills/spell-verification-ledger/SKILL.md +1 -1
  43. package/dist/assets/.arcane/governance/development-methodology.md +6 -6
  44. package/dist/assets/.arcane/governance/git-conventions.md +2 -2
  45. package/dist/assets/.arcane/governance/portable-bootstrap.md +1 -0
  46. package/dist/assets/.arcane/governance/product-excellence-standards.md +1 -1
  47. package/dist/assets/.arcane/governance/spell-authoring-standards.md +9 -1
  48. package/dist/assets/.arcane/governance/universal-agent-rules.md +5 -3
  49. package/dist/assets/.arcane/spells/spell-address-review.md +115 -0
  50. package/dist/assets/.arcane/spells/spell-adopt-docs.md +158 -0
  51. package/dist/assets/.arcane/spells/spell-arcane-version.md +87 -0
  52. package/dist/assets/.arcane/spells/spell-architect.md +117 -0
  53. package/dist/assets/.arcane/spells/spell-brainstorm.md +125 -0
  54. package/dist/assets/.arcane/spells/spell-bug.md +123 -0
  55. package/dist/assets/.arcane/spells/spell-bump.md +82 -0
  56. package/dist/assets/.arcane/spells/spell-check-drift.md +118 -0
  57. package/dist/assets/.arcane/spells/spell-close-session.md +266 -0
  58. package/dist/assets/.arcane/spells/spell-commit-work.md +279 -0
  59. package/dist/assets/.arcane/spells/spell-compliance.md +130 -0
  60. package/dist/assets/.arcane/spells/spell-create-pull-request.md +224 -0
  61. package/dist/assets/.arcane/spells/spell-document.md +84 -0
  62. package/dist/assets/.arcane/spells/spell-dotnet-expert.md +118 -0
  63. package/dist/assets/.arcane/spells/spell-eas-store-deploy.md +254 -0
  64. package/dist/assets/.arcane/spells/spell-enchant.md +386 -0
  65. package/dist/assets/.arcane/spells/spell-explain-concept.md +70 -0
  66. package/dist/assets/.arcane/spells/spell-feedback.md +138 -0
  67. package/dist/assets/.arcane/spells/spell-full-cycle.md +253 -0
  68. package/dist/assets/.arcane/spells/spell-generate-bot-icons.md +85 -0
  69. package/dist/assets/.arcane/spells/spell-implement.md +109 -0
  70. package/dist/assets/.arcane/spells/spell-make-discoverable.md +293 -0
  71. package/dist/assets/.arcane/spells/spell-manifest.md +148 -0
  72. package/dist/assets/.arcane/spells/spell-open-session.md +154 -0
  73. package/dist/assets/.arcane/spells/spell-plan.md +160 -0
  74. package/dist/assets/.arcane/spells/spell-present-arcane.md +189 -0
  75. package/dist/assets/.arcane/spells/spell-product-review.md +98 -0
  76. package/dist/assets/.arcane/spells/spell-review-batch.md +113 -0
  77. package/dist/assets/.arcane/spells/spell-review.md +142 -0
  78. package/dist/assets/.arcane/spells/spell-save-idea.md +117 -0
  79. package/dist/assets/.arcane/spells/spell-scope.md +266 -0
  80. package/dist/assets/.arcane/spells/spell-scry.md +124 -0
  81. package/dist/assets/.arcane/spells/spell-security-review.md +152 -0
  82. package/dist/assets/.arcane/spells/spell-ship.md +106 -0
  83. package/dist/assets/.arcane/spells/spell-status.md +86 -0
  84. package/dist/assets/.arcane/spells/spell-suggest-feature.md +122 -0
  85. package/dist/assets/.arcane/spells/spell-summon-venture.md +110 -0
  86. package/dist/assets/.arcane/spells/spell-sync-pull-request.md +161 -0
  87. package/dist/assets/.arcane/spells/spell-test.md +88 -0
  88. package/dist/assets/.arcane/spells/spell-todo.md +166 -0
  89. package/dist/assets/.arcane/spells/spell-verification-ledger.md +102 -0
  90. package/dist/assets/.claude/commands/spell-address-review.md +2 -2
  91. package/dist/assets/.claude/commands/spell-adopt-docs.md +2 -2
  92. package/dist/assets/.claude/commands/spell-arcane-version.md +2 -2
  93. package/dist/assets/.claude/commands/spell-architect.md +2 -2
  94. package/dist/assets/.claude/commands/spell-brainstorm.md +2 -2
  95. package/dist/assets/.claude/commands/spell-bug.md +2 -2
  96. package/dist/assets/.claude/commands/spell-bump.md +2 -2
  97. package/dist/assets/.claude/commands/spell-check-drift.md +2 -2
  98. package/dist/assets/.claude/commands/spell-close-session.md +2 -2
  99. package/dist/assets/.claude/commands/spell-commit-work.md +2 -2
  100. package/dist/assets/.claude/commands/spell-compliance.md +2 -2
  101. package/dist/assets/.claude/commands/spell-create-pull-request.md +2 -2
  102. package/dist/assets/.claude/commands/spell-document.md +2 -2
  103. package/dist/assets/.claude/commands/spell-dotnet-expert.md +2 -2
  104. package/dist/assets/.claude/commands/spell-eas-store-deploy.md +2 -2
  105. package/dist/assets/.claude/commands/spell-enchant.md +2 -2
  106. package/dist/assets/.claude/commands/spell-explain-concept.md +2 -2
  107. package/dist/assets/.claude/commands/spell-feedback.md +2 -2
  108. package/dist/assets/.claude/commands/spell-full-cycle.md +2 -2
  109. package/dist/assets/.claude/commands/spell-generate-bot-icons.md +2 -2
  110. package/dist/assets/.claude/commands/spell-implement.md +2 -2
  111. package/dist/assets/.claude/commands/spell-make-discoverable.md +2 -2
  112. package/dist/assets/.claude/commands/spell-manifest.md +2 -2
  113. package/dist/assets/.claude/commands/spell-open-session.md +2 -2
  114. package/dist/assets/.claude/commands/spell-plan.md +2 -2
  115. package/dist/assets/.claude/commands/spell-present-arcane.md +2 -2
  116. package/dist/assets/.claude/commands/spell-product-review.md +2 -2
  117. package/dist/assets/.claude/commands/spell-review-batch.md +2 -2
  118. package/dist/assets/.claude/commands/spell-review.md +2 -2
  119. package/dist/assets/.claude/commands/spell-save-idea.md +2 -2
  120. package/dist/assets/.claude/commands/spell-scope.md +2 -2
  121. package/dist/assets/.claude/commands/spell-scry.md +2 -2
  122. package/dist/assets/.claude/commands/spell-security-review.md +2 -2
  123. package/dist/assets/.claude/commands/spell-ship.md +2 -2
  124. package/dist/assets/.claude/commands/spell-status.md +2 -2
  125. package/dist/assets/.claude/commands/spell-suggest-feature.md +2 -2
  126. package/dist/assets/.claude/commands/spell-summon-venture.md +2 -2
  127. package/dist/assets/.claude/commands/spell-sync-pull-request.md +2 -2
  128. package/dist/assets/.claude/commands/spell-test.md +2 -2
  129. package/dist/assets/.claude/commands/spell-todo.md +2 -2
  130. package/dist/assets/.claude/commands/spell-verification-ledger.md +2 -2
  131. package/dist/assets/.github/instructions/agent-output.instructions.md +14 -13
  132. package/dist/assets/.github/prompts/spell-address-review.prompt.md +1 -107
  133. package/dist/assets/.github/prompts/spell-adopt-docs.prompt.md +1 -150
  134. package/dist/assets/.github/prompts/spell-arcane-version.prompt.md +1 -79
  135. package/dist/assets/.github/prompts/spell-architect.prompt.md +1 -109
  136. package/dist/assets/.github/prompts/spell-brainstorm.prompt.md +1 -117
  137. package/dist/assets/.github/prompts/spell-bug.prompt.md +1 -115
  138. package/dist/assets/.github/prompts/spell-bump.prompt.md +1 -74
  139. package/dist/assets/.github/prompts/spell-check-drift.prompt.md +1 -110
  140. package/dist/assets/.github/prompts/spell-close-session.prompt.md +1 -258
  141. package/dist/assets/.github/prompts/spell-commit-work.prompt.md +1 -270
  142. package/dist/assets/.github/prompts/spell-compliance.prompt.md +1 -122
  143. package/dist/assets/.github/prompts/spell-create-pull-request.prompt.md +1 -215
  144. package/dist/assets/.github/prompts/spell-document.prompt.md +1 -76
  145. package/dist/assets/.github/prompts/spell-dotnet-expert.prompt.md +1 -110
  146. package/dist/assets/.github/prompts/spell-eas-store-deploy.prompt.md +1 -246
  147. package/dist/assets/.github/prompts/spell-enchant.prompt.md +1 -378
  148. package/dist/assets/.github/prompts/spell-explain-concept.prompt.md +1 -62
  149. package/dist/assets/.github/prompts/spell-feedback.prompt.md +1 -130
  150. package/dist/assets/.github/prompts/spell-full-cycle.prompt.md +1 -245
  151. package/dist/assets/.github/prompts/spell-generate-bot-icons.prompt.md +1 -77
  152. package/dist/assets/.github/prompts/spell-implement.prompt.md +1 -101
  153. package/dist/assets/.github/prompts/spell-make-discoverable.prompt.md +1 -285
  154. package/dist/assets/.github/prompts/spell-manifest.prompt.md +1 -140
  155. package/dist/assets/.github/prompts/spell-open-session.prompt.md +1 -146
  156. package/dist/assets/.github/prompts/spell-plan.prompt.md +1 -152
  157. package/dist/assets/.github/prompts/spell-present-arcane.prompt.md +1 -181
  158. package/dist/assets/.github/prompts/spell-product-review.prompt.md +1 -90
  159. package/dist/assets/.github/prompts/spell-review-batch.prompt.md +1 -105
  160. package/dist/assets/.github/prompts/spell-review.prompt.md +1 -134
  161. package/dist/assets/.github/prompts/spell-save-idea.prompt.md +1 -109
  162. package/dist/assets/.github/prompts/spell-scope.prompt.md +1 -258
  163. package/dist/assets/.github/prompts/spell-scry.prompt.md +1 -116
  164. package/dist/assets/.github/prompts/spell-security-review.prompt.md +1 -144
  165. package/dist/assets/.github/prompts/spell-ship.prompt.md +1 -98
  166. package/dist/assets/.github/prompts/spell-status.prompt.md +1 -78
  167. package/dist/assets/.github/prompts/spell-suggest-feature.prompt.md +1 -114
  168. package/dist/assets/.github/prompts/spell-summon-venture.prompt.md +1 -102
  169. package/dist/assets/.github/prompts/spell-sync-pull-request.prompt.md +1 -152
  170. package/dist/assets/.github/prompts/spell-test.prompt.md +1 -80
  171. package/dist/assets/.github/prompts/spell-todo.prompt.md +1 -158
  172. package/dist/assets/.github/prompts/spell-verification-ledger.prompt.md +1 -94
  173. package/dist/index.js +1073 -246
  174. package/dist/index.js.map +1 -1
  175. package/package.json +4 -4
  176. /package/dist/assets/{.github/prompts → .arcane/spells}/_fragments/tracking-mode-declaration.md +0 -0
@@ -6,288 +6,4 @@ argument-hint: Optional path or origin of the property to audit (defaults to the
6
6
  agent: agent
7
7
  ---
8
8
 
9
- ## Executive Summary
10
-
11
- - This spell audits a web property's discoverability to search engines and, by
12
- extension, to the AI assistants that retrieve from those engines' indexes —
13
- per-route share metadata, robots/sitemap policy, non-production noindexing,
14
- and search-engine registration — then proposes fixes.
15
- - **The default run changes nothing.** It produces an audit and a proposed
16
- change set, and stops at an explicit approval gate. Nothing is written
17
- without `--apply` *and* that approval.
18
- - **It never performs an outward-facing action on its own** — a DNS write, a
19
- console submission, a crawl-notification ping. Every such action is
20
- confirmed individually, with the current live state printed first, never
21
- batched and never assumed from a prior run.
22
- - **It verifies by content, never by confirmation.** Every claimed fix is
23
- checked by re-fetching the actual served response or re-reading the actual
24
- external state, per `EV-01`/`EV-02`.
25
- - **This spell audits a property that is already live.** It does not deploy
26
- one — run it after your team's own deploy/ship workflow has put something
27
- live at `{SITE_ORIGIN}`, not instead of it.
28
-
29
- ---
30
-
31
- ## Placeholders
32
-
33
- Every placeholder below follows the same resolution rule: pull it from
34
- `.arcane.json`, the invoking frontmatter, or the repository's own existing
35
- config; if it is not resolvable from any of those, **ask** — never assume.
36
- A wrong guess in this spell is not a local mistake, it is published to the
37
- public internet.
38
-
39
- | Placeholder | What it is | Resolution rule |
40
- | --- | --- | --- |
41
- | `{SITE_ORIGIN}` | The production origin (scheme + host) of the property being audited. | Resolve from `.arcane.json` / frontmatter / the repo's own deploy config; if unset, ask — never assume, a wrong guess here is published to the public internet. |
42
- | `{SERVING_LAYER}` | The component that already serves the built app's HTML responses (a static host, an edge/SSR function, a CDN in front of the origin). | Resolve from `.arcane.json` / frontmatter / the repo's own build-and-deploy config; if unset, ask rather than assuming a serving layer that isn't actually there. |
43
- | `{ENV_SIGNAL}` | The repo's own existing signal for which environment a given request is running in (an env var, a build-time flag, a hostname pattern) — used to gate non-production noindexing. | Resolve from `.arcane.json` / frontmatter / the repo's own config; if unset, ask — guessing wrong here either noindexes production or leaves staging indexable. |
44
- | `{PUBLIC_ASSET_PREFIX}` | The path prefix or origin that serves publicly-fetchable static/share assets (e.g. share-card images) without authentication. | Resolve from `.arcane.json` / frontmatter / the repo's own asset/storage config; if unset, ask. |
45
- | `{RESTRICTED_PREFIX}` | The path prefix for admin, internal, or otherwise non-public routes that must never be indexable or listed in a sitemap. | Resolve from `.arcane.json` / frontmatter / the repo's own routing config; if unset, ask. |
46
- | `{NONPROD_ORIGINS}` | The staging, preview, and development origins for this property that must never be indexed. | Resolve from `.arcane.json` / frontmatter / the repo's own deploy config; if unset, ask — never assume a short list you found is exhaustive. |
47
- | `{DNS_ZONE}` | The DNS zone that holds, or will hold, this property's domain-ownership verification record for search-engine registration. | Resolve from `.arcane.json` / frontmatter / the repo's own infrastructure config; if unset, ask — never assume (see `EV-05`). |
48
- | `{PUBLIC_VISIBILITY_PREDICATE}` | The app's own existing rule for what counts as publicly listed/indexable content, as distinct from private, draft, or restricted content. | Resolve from `.arcane.json` / frontmatter / the app's own existing authorization or visibility logic; if unset, ask — never invent a visibility rule the app doesn't already enforce. |
49
-
50
- ## Context files
51
-
52
- - [governance/web-discoverability-standards.md](../../.arcane/governance/web-discoverability-standards.md) —
53
- every `WD-nn` rule this spell checks against. Rules are **cited by ID
54
- only** in this spell, never restated. **If the file is not installed**,
55
- this spell still runs in full — findings just cite each check as
56
- `WD-nn (rationale unavailable — install the standards doc)` instead of
57
- linking to it.
58
- - [governance/external-verification-standards.md](../../.arcane/governance/external-verification-standards.md) —
59
- every `EV-nn` rule the Verify phase (and the outward-facing-action gating
60
- in Phase 4b) checks against, cited by ID only. **If the file is not
61
- installed**, this spell still runs, and Phase 5 still re-fetches and
62
- re-reads rather than trusting a write's own success signal — it just
63
- cites those checks as `EV-nn (rationale unavailable — install the
64
- standards doc)` instead of linking to it.
65
- - An existing decisions or architecture doc, if one is present (e.g.
66
- `DECISIONS.md` or an equivalent) — check it for any prior decision that
67
- already governs this property's discoverability approach before proposing
68
- something that would conflict with it. **If none is present**, proceed
69
- without it and note in Phase 6 that no prior decision was found.
70
-
71
- ## Preconditions
72
-
73
- Stop and report, without changing anything, if any of these fail:
74
-
75
- 1. **`{SITE_ORIGIN}` resolves**, per the Placeholders rule above, or the
76
- operator supplies it when asked. If it cannot be resolved and the
77
- operator does not answer, stop before Phase 1.
78
- 2. **At least one HTTP(S) response is actually reachable at
79
- `{SITE_ORIGIN}`.** This spell audits a property that is already live; if
80
- nothing responds, stop and report that a deploy needs to happen first
81
- (see Related) rather than auditing an empty origin.
82
- 3. **`--apply` never substitutes for approval.** If `--apply` is passed up
83
- front, the explicit approval gate in Phase 3 still applies in full before
84
- Phase 4 runs anything.
85
-
86
- ## Phase 1 — Inventory (always read-only)
87
-
88
- Enumerate the current state before proposing anything to change. Do not
89
- judge it yet — just record what is actually there, for `{SITE_ORIGIN}` and
90
- for each of `{NONPROD_ORIGINS}`:
91
-
92
- - **Per-route metadata**, sampled across a small set of distinct route
93
- types (not just the homepage): `<title>`, meta description, canonical
94
- link, Open Graph / social-card tags, and any structured-data block —
95
- fetched with a plain HTTP client that does not execute JavaScript.
96
- - **`robots.txt`** — full raw contents, and whether it exists at all.
97
- - **AI user-agent policy in `robots.txt`** — every `User-agent:` group
98
- present, and which vendor-published *retrieval* agents (the ones an AI
99
- assistant or answer engine fetches with at answer time or indexes with)
100
- versus *training* crawlers each group's rules match — checked against each
101
- vendor's current crawler documentation, not memory, because the names
102
- change.
103
- - **AI-readable convention files** — whether `/llms.txt` exists, its raw
104
- contents, and whether documentation routes also serve a Markdown
105
- representation.
106
- - **Non-canonical production hostnames** — every hostname the platform
107
- serves the production artifact on besides `{SITE_ORIGIN}` (a
108
- platform-assigned default hostname, a `www` alias), with the canonical tag
109
- and robots meta of one sampled route on each. These are not
110
- `{NONPROD_ORIGINS}` — they serve the real artifact — so record them
111
- separately.
112
- - **`sitemap.xml`** (or wherever `robots.txt` points) — full raw contents,
113
- whether it parses as well-formed, and the set of distinct `lastmod` values
114
- it carries.
115
- - **Non-production noindex signals** — for each `{NONPROD_ORIGINS}` host,
116
- the response headers and parsed `<head>` of one sampled route.
117
- - **DNS state at `{DNS_ZONE}`** relevant to search-engine registration —
118
- the full current record set for the relevant name, queried directly
119
- rather than read from a console (per `EV-01`).
120
- - **Anything unreachable** — a route, origin, or DNS name that doesn't
121
- resolve at all. Report it; never silently skip it.
122
-
123
- ## Phase 2 — Audit
124
-
125
- For each check below, capture the stated evidence and mark it
126
- `PASS`/`FAIL`. **Do not restate any rule's justification here — cite the ID
127
- only**; the reasoning lives in `web-discoverability-standards.md`. A row
128
- marked *(supplementary)* is a useful check that doesn't correspond to any
129
- single `WD-nn` rule — capture its evidence the same way, but don't cite a
130
- rule ID for it.
131
-
132
- **Per-route share metadata**
133
-
134
- | Rule ID | Check | Evidence to capture |
135
- | --- | --- | --- |
136
- | `WD-01` | Fetch `{SITE_ORIGIN}`/&lt;a specific deep route, not the homepage&gt; with a plain HTTP client that does not execute JavaScript. Does the raw response body carry a `<title>` and meta description distinct from the homepage's? | The two raw response bodies, with the extracted `<title>`/description values highlighted. |
137
- | *(supplementary)* | In that same response, do the Open Graph / social-card tags (`og:title`, `og:description`, `og:image`) reflect the route's own content, not the homepage's or a hard-coded default? | Extracted `og:*` tag values per sampled route. |
138
- | `WD-03` | Fetch a route representing content that no longer exists, or that was never public. Does the response return a genuine `404` or `410` status — not a `200` that merely renders a not-found-looking page? | The response status code, and the rendered body (to confirm it's the application's own not-found UI, not a generic host error page). |
139
- | *(supplementary)* | Does each fetched route carry exactly one `<link rel="canonical">`, self-referential or pointing at the one intended canonical URL, with no second conflicting canonical tag? | Canonical URL(s) found per route; flag any route with more than one. |
140
- | *(supplementary)* | Where the route type is expected to carry structured data, is an `application/ld+json` block present and does it parse as valid JSON? | The raw JSON-LD block per route, and the parse result. |
141
- | `WD-13` | Where a share-metadata or structured-data value is built from user- or content-supplied text (e.g. a title containing a quote or ampersand), is it correctly escaped for both contexts it appears in — JSON-escaped inside the JSON-LD payload, and separately HTML-escaped in surrounding markup — with no raw pass-through? | One sampled route whose content contains a quote, ampersand, or angle bracket, with the rendered JSON-LD and HTML attribute shown side by side. |
142
- | *(supplementary)* | Fetch a sampled `{PUBLIC_ASSET_PREFIX}` share-image URL with a plain, unauthenticated HTTP client. Does it return `200` with an image content-type and no auth redirect? | Response status, `Content-Type` header, and byte size for the sampled asset. |
143
-
144
- **Robots and sitemap policy**
145
-
146
- | Rule ID | Check | Evidence to capture |
147
- | --- | --- | --- |
148
- | *(supplementary)* | Fetch `{SITE_ORIGIN}/robots.txt` directly. Does it exist, return `200`, parse as valid, and avoid disallowing any route intended to be indexed? | Raw `robots.txt` body, and any `Disallow` line matching an intended-public route. |
149
- | *(supplementary)* | Does `robots.txt` contain a `Sitemap:` directive, and does fetching that URL return a well-formed sitemap? | The `Sitemap:` line and the fetched sitemap's parse result. |
150
- | `WD-07` | Does every URL listed in the sitemap satisfy `{PUBLIC_VISIBILITY_PREDICATE}`? | Any sitemap entries that fail the predicate. |
151
- | `WD-08` | Where `{PUBLIC_ASSET_PREFIX}` (or another specific public path referenced by page metadata) falls under a broader disallowed prefix in `robots.txt`, is an explicit `Allow:` rule declared for that specific path? | The relevant `Allow:`/`Disallow:` lines from `robots.txt`, and confirmation the specific path is fetchable by a crawler despite the broader disallow. |
152
- | `WD-16` | Parse `{SITE_ORIGIN}/robots.txt` group by group. Is any *retrieval*-class AI user-agent (per each vendor's current crawler documentation) matched by a `Disallow:` that covers an intended-public route? A training-crawler `Disallow:` is not a failure — record it as the operator's declared policy. | Every `User-agent:` group with its rules, each agent name classified as retrieval or training with the vendor page that says so, and the resolved allow/disallow verdict per retrieval agent for one sampled public route. |
153
- | `WD-18` | Parse the sitemap's `lastmod` values. Do they differ across URLs and track each URL's actual content change date — or does every entry carry one shared constant? | The distinct `lastmod` values with their counts, and for one sampled URL, the content's own change date (file date, changelog entry, or commit) next to its `lastmod`. |
154
- | *(supplementary)* | For a sampled route under `{RESTRICTED_PREFIX}`: is it absent from the sitemap, does it carry a noindex signal, and is it unreachable via any link from a route that satisfies `{PUBLIC_VISIBILITY_PREDICATE}`? | Sitemap membership (should be none), noindex signal, and an inbound-link check from the public route set. |
155
-
156
- **Non-production noindexing**
157
-
158
- | Rule ID | Check | Evidence to capture |
159
- | --- | --- | --- |
160
- | *(supplementary)* | For each `{NONPROD_ORIGINS}` host: is a site-wide `Disallow: /` in `robots.txt` the *only* suppression signal present — no accompanying noindex header or meta tag? Closely related to `WD-09` below. | The host's `robots.txt` plus presence/absence of a noindex header and meta tag on a sampled route. |
161
- | `WD-09` | For each `{NONPROD_ORIGINS}` host: does a sampled route serve **both** an `X-Robots-Tag: noindex` response header **and** an HTML `<meta name="robots" content="noindex">` tag, gated by `{ENV_SIGNAL}`? | Response headers and parsed `<head>` for one sampled route per non-prod host. |
162
-
163
- **Search-engine registration**
164
-
165
- | Rule ID | Check | Evidence to capture |
166
- | --- | --- | --- |
167
- | `WD-10` | Query `{DNS_ZONE}` directly (independent of any console) for the domain-ownership verification record this property's registration depends on. Is it present, and does it match the value the registration actually expects? | Raw DNS query result — record type, name, and full current value — captured before any write, per `EV-05`. |
168
- | `WD-11` | Is a crawl/recrawl notification path (e.g. IndexNow) wired for URLs that change, and has `{SITE_ORIGIN}` been submitted through the webmaster console for each target search engine? | Notification endpoint configuration (if any), and the submission status shown in each webmaster console. |
169
- | `WD-12` | In the webmaster console of the search engine with the largest share of query volume in the target market, **and** in the console of each engine whose index an AI answer engine draws on (these are frequently different engines), does `{SITE_ORIGIN}` show confirmed index coverage with no outstanding manual-action or coverage blocker? | Each console's own coverage/status readout, copied verbatim, plus its AI-visibility report (citations, grounding queries, or generative-AI impressions) where the console offers one — this is what downstream AI-assistant retrieval actually depends on, not the site's own claim of being indexable. |
170
-
171
- ## Phase 3 — Propose
172
-
173
- Render every `FAIL` from Phase 2 as one line:
174
-
175
- ```text
176
- WD-08 FAIL — <what was actually observed, in one sentence>
177
- → see web-discoverability-standards.md § non-production noindexing
178
- ```
179
-
180
- Group the findings under the same four headings used in Phase 2. For each,
181
- give the exact remediation: what changes in-repo (Phase 4a) versus what
182
- requires an outward-facing action (Phase 4b).
183
-
184
- End with the full proposed change set and one explicit question:
185
-
186
- **"Approve this change set? (yes / edit / cancel)"**
187
-
188
- Stop here. Nothing before this point writes anything, with or without
189
- `--apply`.
190
-
191
- ## Phase 4a — Apply: in-repo changes
192
-
193
- Only with `--apply` **and** after Phase 3 approval. Typical fixes:
194
-
195
- - Inject the missing per-route title/description/`og:*`/canonical tags at
196
- `{SERVING_LAYER}` (server-rendered or edge-injected — never
197
- client-side-only, per `WD-01`).
198
- - Add or correct `robots.txt` and `sitemap.xml`, and exclude
199
- `{RESTRICTED_PREFIX}` from the sitemap.
200
- - Add the missing noindex header and meta tag for `{NONPROD_ORIGINS}`,
201
- gated by `{ENV_SIGNAL}` so production never picks it up by accident.
202
- - Declare named per-agent `robots.txt` groups so retrieval and training
203
- agents are visibly separate and a later edit cannot silently block both
204
- (`WD-16`); derive sitemap `lastmod` from content dates (`WD-18`); publish
205
- `/llms.txt` and, for documentation routes, a Markdown representation
206
- (`WD-12`).
207
- - Fix the escaping gap found under `WD-13`.
208
-
209
- Each fix lands as its own commit, so any one of them can be reverted on its
210
- own (`git revert`, by commit) without touching the others.
211
-
212
- ## Phase 4b — Apply: outward-facing actions
213
-
214
- Only with `--apply` **and** after Phase 3 approval. Every item here is
215
- confirmed **individually**, one at a time, with current state printed
216
- first — never batched:
217
-
218
- - **DNS TXT write at `{DNS_ZONE}`.** Print the CURRENT full record
219
- verbatim (re-queried live, not from Phase 1's cached inventory). State
220
- explicitly that the operation is an ADD/APPEND, never a create-or-replace
221
- (`EV-05`). Require the operator to confirm the resulting full record
222
- before writing. If the underlying tool only offers a replace operation,
223
- refuse and require the operator to make the change manually instead.
224
- - **Search-engine registration and verification-value entry.** This spell
225
- *prepares* the exact value(s) the webmaster console needs and hands them
226
- to the operator to enter — it does not attempt to drive the console's UI
227
- itself.
228
- - **Crawl/recrawl instant-notification pings (`WD-11`).** Confirmed once
229
- per batch of changed URLs. Never auto-re-fired on a later re-run without
230
- a fresh, explicit confirmation for that run.
231
-
232
- ## Phase 5 — Verify
233
-
234
- Cite `EV-01` and `EV-02` explicitly for every check below.
235
-
236
- - For every in-repo fix from Phase 4a: re-fetch the actual served response
237
- at `{SITE_ORIGIN}` (a fresh request, independent of the deploy that
238
- shipped the fix) and compare it against the Phase 3 proposal, allowing a
239
- short, bounded propagation window before treating a fresh mismatch as
240
- failure (`EV-02`).
241
- - For the DNS write from Phase 4b: re-query `{DNS_ZONE}` independently
242
- (a different resolver path than whatever console performed the write) and
243
- compare the full record against what was confirmed.
244
- - For any console value entered by the operator: re-read it back from the
245
- console rather than trusting the entry UI's own confirmation (`EV-01`).
246
-
247
- Report each item as `PASS` / `FAIL` / `UNVERIFIED`. An item that could not
248
- actually be re-checked is `UNVERIFIED` — never silently reported as `PASS`
249
- just because nothing threw an error.
250
-
251
- ## Phase 6 — Report
252
-
253
- Summarize what changed, what's still open, and close with a plain-language,
254
- user-verifiable acceptance checklist:
255
-
256
- - [ ] A plain fetch (no JavaScript) of three distinct deep routes returns
257
- three distinct `<title>` values.
258
- - [ ] `{SITE_ORIGIN}/robots.txt` and its sitemap both return `200`, and the
259
- sitemap contains no `{RESTRICTED_PREFIX}` or `{NONPROD_ORIGINS}` URLs.
260
- - [ ] Each `{NONPROD_ORIGINS}` host serves both a noindex header and a
261
- noindex meta tag on a sampled route.
262
- - [ ] `{SITE_ORIGIN}/robots.txt` disallows no retrieval-class AI user-agent
263
- (`WD-16`), and the sitemap's `lastmod` values are not one shared
264
- constant (`WD-18`).
265
- - [ ] The property's analytics has a dedicated AI-referrer channel and its
266
- access log is watched for retrieval-class user-agents (`WD-17`) — so
267
- the effect of everything above is measurable rather than assumed.
268
- - [ ] The DNS verification record at `{DNS_ZONE}`, re-queried
269
- independently, matches what the registration expects.
270
- - [ ] The webmaster console for each target search engine shows the
271
- property verified with no outstanding coverage blocker.
272
-
273
- ## Rules
274
-
275
- This spell defers entirely to
276
- [governance/web-discoverability-standards.md](../../.arcane/governance/web-discoverability-standards.md)
277
- for what "discoverable" means and why, and to
278
- [governance/external-verification-standards.md](../../.arcane/governance/external-verification-standards.md)
279
- for how any claimed fix is verified. Findings and gates in this spell cite
280
- rule IDs from both; they do not re-explain them. Where the two disagree with
281
- what this spell says to do, the governance docs win.
282
-
283
- ## Related
284
-
285
- - **Consumes from:** the spell your team uses to ship/deploy a build (in
286
- this repository, `spell-ship`). Run `spell-make-discoverable` only after a
287
- deploy has put something live at `{SITE_ORIGIN}` — it audits an
288
- already-deployed property, it does not deploy one.
289
- - **Feeds into:** `spell-product-review` — once discoverability fixes are
290
- applied and verified, carry the before/after state into the next
291
- product-review cycle as one more measured signal.
292
- - [Web Discoverability Standards](../../.arcane/governance/web-discoverability-standards.md)
293
- - [External Verification Standards](../../.arcane/governance/external-verification-standards.md)
9
+ This prompt is the Arcane `spell-make-discoverable` spell. Read [`.arcane/spells/spell-make-discoverable.md`](../../.arcane/spells/spell-make-discoverable.md) and follow it as the complete workflow.
@@ -6,143 +6,4 @@ argument-hint: Optional --venture <slug> to restrict triage to one venture's boo
6
6
  agent: agent
7
7
  ---
8
8
 
9
- ## Executive Summary
10
-
11
- - This prompt is the promotion step of the idea lifecycle: it takes `status: new` entries out of hub-side `IDEAS.md`/`TODO.md` books and lands them where they actually get built — a consumer repo, a tracker, a PRD, or (deliberately, never by accident) a public disclosure.
12
- - **Hub-gated:** requires `role: "hub"` in `.arcane.json`. Refuses cleanly in a consumer repo.
13
- - Batch-capable: list entries once, select by number/range, route each (or all identically), execute with one final confirmation — except disclosure, which is never covered by a batch confirmation and always requires its own literal answer.
14
- - Every downstream write is leak-scanned first: no sibling venture names, no hub paths, no machine names ever land in a consumer artifact.
15
- - Idempotent: promoted entries are marked in place, so re-running never double-lands the same idea.
16
-
17
- ---
18
-
19
- ## Step 0 — Hub Gate
20
-
21
- Read `.arcane.json`. If `role` is not `"hub"`, stop and report:
22
-
23
- > `spell-manifest` runs only in a hub repo (`role: "hub"` in `.arcane.json`). This repo is a consumer — triage its own `IDEAS.md`/`TODO.md` with `spell-todo` (task), `spell-suggest-feature` (tracked story), or `spell-plan` (PRD) instead.
24
-
25
- Do not read or list anything further. If `role` is `"hub"`, resolve `{BUSINESS_ROOT}` from `.arcane.json` (default `ventures/`) and load `{BUSINESS_ROOT}/registry.json`. If the registry is missing or fails to parse, stop and report the exact error — never triage blind without knowing the venture list (sibling names come from here, and the leak scan in Step 5 depends on it).
26
-
27
- ## Step 1 — Collect
28
-
29
- Parse `status: new` entries from the hub root `IDEAS.md` and every `{BUSINESS_ROOT}/<slug>/IDEAS.md` / `TODO.md` that exists. If `--venture <slug>` was given, resolve it through the registry's aliases first (exact slug → alias → closest match offered — never guessed; unknown slug lists the closest matches and stops) and restrict collection to that venture's two books plus the hub root.
30
-
31
- Tolerate operator YAML frontmatter above a book's header — entries always live below the `---` divider. Malformed entries (missing timestamp, unparseable status comment) are listed under a `Skipped` heading with `file:line`, never silently dropped.
32
-
33
- ## Step 2 — List
34
-
35
- Print one numbered list, grouped by book, oldest entry first within each group. Numbering is session-scoped — it does not persist across runs.
36
-
37
- ```
38
- Idea triage — hub books (N books, M new entries)
39
-
40
- hub IDEAS.md
41
- 1. [2026-08-02] [#dx] Portfolio-wide spell usage stats dashboard
42
- ventures/ordovica/IDEAS.md
43
- 2. [2026-07-30] [#ui] Dark-mode toggle for event pages
44
- ventures/ordovica/TODO.md
45
- 3. [ ] Confirm cart snapshot order (open item, no status comment — todo-book entries are listed as-is)
46
- ```
47
-
48
- ## Step 3 — Select
49
-
50
- Ask: `Promote which? (numbers/ranges, e.g. 1,3,5-8, or "all")`. Accept a single answer covering the whole batch. `all` selects every listed entry, including ones in books outside `--venture` if no filter was given.
51
-
52
- ## Step 4 — Route (per entry)
53
-
54
- For each selected entry, in list order, resolve the venture it belongs to (`hub` for root-book entries) and offer destinations. The menu depends on that venture's registry entry:
55
-
56
- | # | Destination | Requires | What lands |
57
- | --- | --- | --- | --- |
58
- | a | Consumer repo-root `IDEAS.md` | a registered clone on this machine | New entry, `status: new`, fresh timestamp |
59
- | b | PRD scaffold in consumer `features/<slug>/PRD.md` | a registered clone | spell-plan-style stub: Problem Statement = idea text; tracking frontmatter from that repo's own `.arcane.json`; open question noting no work-item ID exists yet |
60
- | c | Tracker item | venture `tracking != "none"` | ADO: resolve process template + work item type, `az boards work-item create`. GitHub: `gh issue create --repo <owner>/<repo>`. Works without a local clone. |
61
- | d | Public disclosure to that repo's `IDEAS.md` | a registered clone, destination `visibility: "public"` | Same as (a) — but gated by Step 5's disclosure confirm, always |
62
- | e | Demote to a TODO book | — | Venture's own `TODO.md` (or hub root `TODO.md` for hub-book entries), as a `- [ ]` line |
63
- | f | Drop | — | Nothing lands |
64
- | g | Cross-copy to another venture's book | target venture exists in registry | Fresh `status: new` entry appended to that venture's book |
65
-
66
- If the venture has no registered repo (`repos: []`, e.g. an idea-stage venture), only (e), (f), (g) are offered. Typing `same` for any entry after the first repeats the previous entry's destination.
67
-
68
- Once every selected entry has a destination, print one consolidated plan — per the generated state
69
- diagrams convention (rule 8, ARC-036), built only from the routing already decided in this step; skip
70
- entirely (the applicability guard) for a single selected entry going to a single destination — routing
71
- a lone entry has no topology to visualize:
72
-
73
- ```mermaid
74
- flowchart LR
75
- E1["#1 dark-mode toggle"] --> A["(a) repo IDEAS.md"]
76
- E2["#2 cart snapshot"] --> Eroute["(e) demote to TODO"]
77
- A --> Ordovica[ordovica]
78
- ```
79
-
80
- One node per selected entry (its list number + a short title fragment), pointing to its chosen
81
- destination letter; where the destination names a specific venture or repo, a further node names it,
82
- matching the batch's actual routing rather than a fixed shape. Then ask `Proceed? (go / edit / cancel)`.
83
- This confirmation covers ordinary destinations only — it never authorizes a disclosure; see Step 5.
84
-
85
- ## Step 5 — Disclosure Gate
86
-
87
- Any destination whose repo has `visibility: "public"` — (a) or (d) landing in a public repo, or (c) filing a tracker item in a public tracker (a GitHub issue on a public repo is exactly as much a disclosure as its `IDEAS.md`) — is a disclosure, never covered by `all`, `go`, or any other batch confirmation. Per entry, print the **exact text** that will become public and ask for the literal word `disclose`. Anything else skips that one entry (it stays `status: new`) without aborting the rest of the batch.
88
-
89
- On a repo's first-ever disclosure (its `IDEAS.md` has no existing entries with a `promoted → public:` marker), offer to add this boundary statement to that file's header in the same staged change:
90
-
91
- > Build-in-public covers source, decisions, and the accepted roadmap; idea incubation is curated and lands here when committed.
92
-
93
- ## Step 6 — Execute
94
-
95
- Per entry, in list order: **land downstream first, mark the hub entry after.** Before writing anything to a consumer repo, run the leak scan (Step 7) on the outbound text; a hit blocks that entry and asks for an operator rewrite rather than writing leaked content. After a successful downstream write, mark the hub entry:
96
-
97
- ```
98
- <!-- status: promoted → <dest> YYYY-MM-DD -->
99
- ```
100
-
101
- where `<dest>` is one of:
102
-
103
- ```
104
- repo:<slug>/IDEAS.md
105
- prd:<slug>/features/<feature-slug>
106
- ado:<slug>#<id>
107
- github:<slug>#<id> (append " (disclosed)" if the repo is public)
108
- public:<slug>/IDEAS.md (disclosed)
109
- hub:TODO.md
110
- book:<other-slug>/IDEAS.md
111
- ```
112
-
113
- Dropped entries get `<!-- status: dropped YYYY-MM-DD -->`, optionally with a trailing `(reason)`.
114
-
115
- Before any downstream write, grep the target file for the entry's normalized first ~40 characters — if already present, treat this entry as already-landed, mark the hub entry promoted, and skip the write. This is what makes an interrupted or re-run batch safe.
116
-
117
- ## Step 7 — Leak Scan
118
-
119
- Before writing outbound text to any consumer or public destination, scan it for:
120
-
121
- - Every other venture's slug and aliases from the registry (never the destination's own)
122
- - Hub path fragments (`{BUSINESS_ROOT}` paths, this repo's own root-relative paths)
123
- - Machine names (the `clones` keys across the registry)
124
- - This repo's org-token denylist, if `.arcane.json`/config defines one
125
-
126
- A hit blocks the write and reports exactly what matched; offer the operator a rewrite or `keep in book` (leave the entry `status: new`, untouched). This scan is only possible hub-side, because only the hub holds the full sibling list — that asymmetry is deliberate, not a gap: a consumer repo could never run this check on itself without first being handed the very list it must never see.
127
-
128
- ## Step 8 — Report
129
-
130
- Stage (never commit) the touched files in each repo that received a write, including this hub repo. Print one proposed commit message per repo:
131
-
132
- ```
133
- Staged (not committed):
134
- hub: ventures/ordovica/IDEAS.md
135
- proposed: docs(ideas): promote 1 entry to ordovica
136
- ordovica: IDEAS.md
137
- proposed: docs(ideas): capture dark-mode toggle candidate
138
- Run spell-commit-work in each repo. N entries remain new.
139
- ```
140
-
141
- ## Rules
142
-
143
- - Never run outside a hub repo. Never infer hub status.
144
- - Never let `all` or the plan-confirm authorize a disclosure — that confirmation is always separate, always per-entry, always the literal word `disclose`.
145
- - Never write a sibling venture's slug, a hub path, or a machine name into a consumer or public artifact — the leak scan is mandatory, not advisory.
146
- - Never commit. Stage and report; hand off to `spell-commit-work`.
147
- - Never guess a venture from partial input — resolve through the registry's aliases or ask.
148
- - Land downstream before marking the hub entry promoted, so an interrupted batch never loses track of what actually shipped.
9
+ This prompt is the Arcane `spell-manifest` spell. Read [`.arcane/spells/spell-manifest.md`](../../.arcane/spells/spell-manifest.md) and follow it as the complete workflow.
@@ -6,149 +6,4 @@ argument-hint: Optional focus area (e.g., security hardening, a specific feature
6
6
  agent: agent
7
7
  ---
8
8
 
9
- ## Executive Summary
10
-
11
- - This prompt opens a new session after chat reset by reading core docs and identifying unfinished work.
12
- - It produces a state snapshot, top priorities, and concrete next actions to minimize startup friction.
13
- - Use this when opening work in a new chat session to avoid re-reading full context manually.
14
- - Optional focus argument narrows scope to a specific domain (security, business, infrastructure).
15
-
16
- ---
17
-
18
- Open work in this repository after context reset. Treat repository documents as source of truth. See [[README]] and [[CLAUDE]] for repo orientation.
19
-
20
- If the user provided a focus area in the prompt argument, prioritize that area. Otherwise perform a general session-opening pass.
21
-
22
- Use these files first:
23
-
24
- - [README.md](../../README.md)
25
- - [project.md](../../project.md)
26
- - [TODO.md](../../TODO.md)
27
- - [DECISIONS.md](../../DECISIONS.md)
28
- - [naming-conventions.md](../../.arcane/governance/naming-conventions.md)
29
- - [ai-context/system-prompt-context.md](../../ai-context/system-prompt-context.md)
30
- - [agents/agent-policies.md](../../.arcane/governance/agent-policies.md)
31
- - Most recent journal file(s) in [journal/](../../journal/)
32
- - Relevant business overview(s) under `{BUSINESS_ROOT}/` (resolve from `.arcane.json`'s `business_root` field, default `ventures/` if unset)
33
-
34
- **Handoff Detection (run before anything else):**
35
-
36
- Check `ai-context/system-prompt-context.md` for a `## Next Session Handoff` section.
37
-
38
- - If present and **not yet marked consumed** (no `> ✓ Consumed:` line): surface it immediately as `## Picking Up From Last Session` at the very top of your output, before all other sections — include `Last completed step`, `Blockers`, and `Notes` verbatim alongside the rest (session handoff durability: these three are written by close-session but were previously never read back). Use the `Next concrete action` field as the first item in `## Next Session Plan`. Use the `Active task`, `Active files`, and `Branch` fields to pre-populate the State Snapshot.
39
- - **If the handoff's `Pending Verification` field lists anything other than "None" (EF-21):** surface each listed item explicitly, then actively re-check its current status (per the item's stated verification action) rather than treating the state recorded at close-session time as still current — a `dispatched`/`pending` item may have since succeeded, failed, or still be running, and carrying it forward as inert text would repeat the exact failure mode this field exists to prevent. Report what you found (resolved succeeded / resolved failed / still pending / still unverifiable) before relying on anything downstream that depended on it.
40
- - After surfacing it, apply the Mutation Guard below, then run the **Durability check** (session handoff durability, ARC-040): confirm that an incomplete `Active task`, the `Next concrete action`, and any task-bearing `Notes` content each name a durable location that genuinely exists (the cited `TODO.md` item — by stable locator, not a line number that may have already drifted — or tracker work item). If a named location is missing, or close-session's own step 4b was skipped when it shouldn't have been, register the missing content now — on this session's own branch — before proceeding. Only then append `> ✓ Consumed: YYYY-MM-DD` (today's date); the marker write is a repository mutation. If the Durability check cannot complete, leave the handoff unconsumed so the next open-session retries the same check idempotently, rather than silently losing the gap.
41
- - If the section is absent or already marked consumed: skip this step and proceed with the normal workspace scan.
42
-
43
- ## Mutation Guard (run lazily before the first repository write)
44
-
45
- Do not create a branch during a read-only session. Immediately before the first file edit, generated file, staging action, or other repository mutation, classify the current Git/remote state and apply exactly one path:
46
-
47
- | Observed state | Required action before mutation |
48
- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
49
- | Supported, authenticated GitHub/ADO remote + trunk checked out | Create and switch the **current worktree only** to `sessions/YYYY-MM-DD-<topic-slug>`, derived deterministically from the focus, handoff active task, or top next action. |
50
- | Already on a compliant `sessions/YYYY-MM-DD-<topic-slug>` branch | Stay on it; do not create or switch branches. |
51
- | Noncompliant unpushed branch with no active PR | Rename it to the deterministic session name before mutation. |
52
- | Branch has an active PR | Stay on the PR branch and report it; never rename a branch backing an active PR. |
53
- | Current path is a linked worktree | Mutate/switch only the current worktree. Never switch or delete a branch attached to another worktree. |
54
- | No remote, unsupported remote, or provider authentication unavailable | Stay on the repository trunk. Print `Local-only session: no usable remote merge path; mutations remain on <trunk> and close-session must use its local-only path.` |
55
-
56
- A usable merge path requires a configured remote on a supported provider (`github.com`, `dev.azure.com`, or `visualstudio.com`) and authenticated provider tooling. A remote URL alone is insufficient. Re-evaluate immediately before the first mutation so a remote added or removed during the read-only portion is handled from observed state.
57
-
58
- If branch creation/rename is required, complete it before writing the handoff consumed marker or any other file. If the guard cannot determine the current worktree, active-PR state, or merge capability, fail closed without mutation and ask for operator direction.
59
-
60
- **Drift Check (run before deep context gathering):**
61
-
62
- Run the `spell-check-drift` spell first, before building the state snapshot or gathering deep context. Drift compounds the longer a session runs, so catch it early.
63
-
64
- - If **HIGH** drift is found: list it under the `## Risks And Gaps` output section and ask the user whether to fix it before proceeding. Do not continue deep context gathering until they decide.
65
- - If **MEDIUM** or **LOW** drift is found: note it and suggest deferring it until after the session-opening pass.
66
- - If no drift is found: note `drift check passed` and continue.
67
-
68
- Then produce output in this exact structure:
69
-
70
- ## Workspace Health Check
71
-
72
- Before anything else, check:
73
-
74
- - **Current branch:** Run `git branch --show-current` and `git worktree list`. Report the current state; do not switch during this read-only check. Branch creation/switching is owned by the lazy Mutation Guard. **Caveat (EF-33):** if this repository or its linked worktrees might be reached through more than one filesystem view (a bridged/remote mount, a container bind-mount), `git worktree list` can truthfully report a live, healthy worktree as `prunable` when read from a vantage point that can't resolve its registered path — this is a read-only report, not a reason to act; never run a destructive worktree/branch command on its output alone (see git-conventions.md's Same-Vantage-Point Check section before any such command elsewhere in this or later sessions).
75
- - **Isolation primitive (ARC-028 R1–R5):** name where this session will run *before* the Mutation Guard creates anything, and state it in the session output. Every unit of work lives in exactly one of three primitives — the **primary checkout**, a **linked worktree**, or a **full clone**. Select from what the previous bullet's `git worktree list` and `git status` already showed, in this order:
76
- - **Managing repository state** — reconciling uncommitted files, pruning branches, fast-forwarding `main`, cutting a release, or any `git worktree` lifecycle operation → **primary checkout** (R1). These are the only operations that require holding `main`, and only one working tree can.
77
- - **The primary checkout is occupied** — another session's branch is checked out there, or it holds uncommitted work that is not yours → **linked worktree** (R3). At most one actor occupies the primary checkout at a time. Create it with `git worktree add <path> -b <session-branch>`; never switch or delete a branch attached to a worktree you are not in.
78
- - **Unattended/automated git operations** (cron, daemon fleets, anything pulling or pushing without a human present) → **full clone** (R5). Linked worktrees share one physical `.git`, so concurrent unattended operations contend on the same locks.
79
- - **Otherwise** → **primary checkout on a session branch** (R2). This is the default and it is deliberately the do-nothing path: one actor, one checkout, no new tooling.
80
- - **Footprint overlap overrides the choice (R4).** If this session's work touches the same files or the same shared sequence (migration numbers, generated indexes, lockfiles) as work already running in another primitive, do **not** isolate it — serialize instead: wait, or re-scope to a disjoint footprint first. Isolation does not prevent those collisions, it hides them until merge review.
81
- - Working in a linked worktree changes two things later in the session and nothing else: `spell-close-session` must not check out `main` (see git-conventions.md's Post-Merge Cleanup section), and the worktree contains no untracked tooling state — budget for `npm install` or equivalent in a code repo. Branch naming, attribution, and the PR gate are identical from every primitive (R8).
82
- - **Session branch naming compliance:** Branch names must be human-readable and policy-compliant:
83
- - Interactive session default: `sessions/YYYY-MM-DD-<topic-slug>` (kebab-case topic from current task/session objective).
84
- - Disallow random adjective-noun generator names (example: `ideal-disco`) as session defaults.
85
- - If current branch is non-compliant and no active PR depends on it, record the required rename for the Mutation Guard. Do not rename during a read-only session.
86
- - If an active PR uses the old branch name, do not force-delete the old remote branch; flag it and continue with a follow-up rename plan.
87
- - **Stale local branches:** Run `git branch --merged main` to list branches already merged that should be deleted — this session's own read-only candidate list (`--merged` also misses every branch landed via this repo's sanctioned rebase-and-fast-forward, so treat a *clean* result as "no ancestry-visible candidates," not "nothing to check"). Open-session only lists; it does not delete. Apply the [Content-Verified Branch Deletion](../../.arcane/governance/git-conventions.md#content-verified-branch-deletion-todomd-merged-branch-cleanup-finding) procedure (git-conventions.md) to any candidate before flagging it as safe, and leave the actual idempotent prune to `spell-close-session`'s sweep.
88
- - **Tracker configuration check (early):** resolve active tracking settings before planning, in this order: root `.arcane.json` (if present) -> the committed self-hosted source manifest (`src/assets/.arcane.json`, read only when it declares `selfHosted: true` -- this is EF-14's recorded self-hosting resolution tier, distinct from treating the mere presence of a self-host marker as license to infer other, unrelated config) -> the current feature PRD frontmatter -> ask. Persisted once at `spell init`/`spell update` (EF-14); do not re-ask when any of the first three sources already sets it.
89
- <!-- fragment:tracking-mode-declaration:start -->
90
- - `tracking_mode: internal | external`
91
- - `external_provider: ado | github | jira | other`
92
- <!-- fragment:tracking-mode-declaration:end -->
93
- - If all three sources are absent, ask: "Track work in this repo (TODO.md / PRDs)" [internal] vs "Track work in an external tracker (Azure DevOps / GitHub / Jira / other)" [external]. Default to `external` + `ado` only when existing ADO context already exists (backward compatibility).
94
- - **Open PRs (external/ado mode only):** if tracking mode is `external` with provider `ado` and ADO MCP is available, list all open PRs across all repos in the configured repo list (resolve from `.arcane.json`; if unset, ask the operator which repos to scan). Flag PRs older than 3 days as stale, older than 7 days as overdue. Format each as a clickable markdown link: `[PR #{id} — {title}](https://dev.azure.com/{ADO_ORG}/{ADO_PROJECT}/_git/{repo}/pullrequest/{id})` — resolve `{ADO_ORG}` and `{ADO_PROJECT}` from `.arcane.json` / PRD frontmatter; ask if unset. Never list a bare `PR #NNN`.
95
- - **Uncommitted changes:** Run `git status` and report any uncommitted files.
96
- - **Arcane version check (two-axis):** If `.arcane.json` exists in the repo root, check both whether the repo's managed files are behind the installed CLI _and_ whether the installed CLI is behind the latest published version of `arcane-cli`:
97
- - Read the installed version from `.arcane.json` (field: `arcaneVersion` or `version`).
98
- - Determine the version of the installed `arcane-cli` CLI (for example, `npx arcane-cli --version`, or the locally installed package version).
99
- - Run `npm view arcane-cli version` to get the latest published version.
100
- - **(a) Managed files behind the installed CLI** (installed CLI version is newer than the version recorded in `.arcane.json`): surface a warning: `⚠️ Managed files out of date: files at <installed> → CLI at <cli>. Run spell update to resync files.`
101
- - **(b) Installed CLI behind the latest published version** (latest published is newer than the installed CLI): surface a warning: `⚠️ Arcane CLI update available: CLI at <cli> → latest <latest>. Upgrade the CLI, then run spell update.`
102
- - **If either axis shows drift, emit the canonical version-drift diagram beside the warning(s)** — per the generated state diagrams convention (rule 8, ARC-036). One commit per *distinct* version value among the three readings, in the order repo-files → installed-CLI → npm-latest; collapse consecutive identical values into a single shared commit rather than repeating it. Branch off immediately after the commit for each axis that drifts — `repo-files` after the repo-files-version commit if axis A drifts, `installed-cli` after the installed-CLI-version commit if axis B drifts. Tag the final commit `"latest"`. The dangling branch(es) *are* the drifting axis/axes — no legend needed:
103
- ```mermaid
104
- gitGraph
105
- commit id: "<repo-files version>"
106
- branch repo-files
107
- checkout main
108
- commit id: "<installed-CLI version>"
109
- branch installed-cli
110
- checkout main
111
- commit id: "<npm-latest version>" tag: "latest"
112
- ```
113
- (Shown here with both axes drifting — omit whichever `branch`/`checkout` pair belongs to a non-drifting axis, and collapse its commit into its neighbor's if the values are equal.) Use `:::mermaid` fencing instead of ` ```mermaid ` when the output surface is an Azure DevOps wiki — resolve `external_provider` from `.arcane.json` rather than assuming, the same as every other tracker-conditional step in this file; note for bare terminals that the fenced source is still readable without a renderer.
114
- - If both axes are current, report current and continue — no diagram (the applicability guard: a single, matching reading has nothing to visualize).
115
- - If no `.arcane.json` exists, skip silently.
116
-
117
- ## State Snapshot
118
-
119
- - Short bullets by area: security, infrastructure, `{PRIMARY_VENTURE}` readiness, business readiness, and documentation maturity. Resolve `{PRIMARY_VENTURE}` from `.arcane.json` / venture frontmatter; if unset, substitute the active focus area (or omit that bullet).
120
-
121
- ## Top Unfinished Work
122
-
123
- - Prioritized list with severity labels: Critical, High, Medium.
124
- - Every item must include a file reference.
125
-
126
- ## Next Session Plan
127
-
128
- - 3 to 5 concrete actions to execute now.
129
- - Keep actions specific and immediately executable.
130
- - If moving from one completed epic to the next, include an explicit checkpoint action to run `spell-commit-work` first.
131
-
132
- ## Suggested Session Name
133
-
134
- - **Required output field.**
135
- - Provide a 1–4 word, sentence-case, human-meaningful session name.
136
- - If a focus/task argument is provided, generate the name deterministically from that focus (never use the generic name `Open session`).
137
- - If no focus argument is provided, generate the name from the top recommended action in `## Next Session Plan`.
138
- - Optional helper line: `Branch helper: sessions/YYYY-MM-DD-<kebab-case-slug>`.
139
-
140
- ## Risks And Gaps
141
-
142
- - Contradictions, stale assumptions, missing files, or draft documents that block progress.
143
-
144
- ## Clarifications Needed
145
-
146
- - Up to 3 short questions only if they materially change priorities.
147
-
148
- Rules:
149
-
150
- - Prefer facts from docs over assumptions.
151
- - Keep output concise but actionable.
152
- - Include clickable file paths for claims.
153
- - If you find outdated statements (for example, docs that contradict the current state of the system), call them out explicitly as drift.
154
- - Never return a generic session name like `Open session` when a meaningful alternative can be derived from focus or the top next action.
9
+ This prompt is the Arcane `spell-open-session` spell. Read [`.arcane/spells/spell-open-session.md`](../../.arcane/spells/spell-open-session.md) and follow it as the complete workflow.