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.
- package/README.md +14 -1
- package/dist/assets/.agents/skills/spell-address-review/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-adopt-docs/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-arcane-version/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-architect/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-brainstorm/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-bug/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-bump/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-check-drift/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-close-session/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-commit-work/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-compliance/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-create-pull-request/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-document/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-dotnet-expert/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-eas-store-deploy/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-enchant/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-explain-concept/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-feedback/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-full-cycle/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-generate-bot-icons/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-implement/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-make-discoverable/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-manifest/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-open-session/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-plan/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-present-arcane/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-product-review/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-review/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-review-batch/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-save-idea/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-scope/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-scry/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-security-review/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-ship/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-status/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-suggest-feature/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-summon-venture/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-sync-pull-request/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-test/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-todo/SKILL.md +1 -1
- package/dist/assets/.agents/skills/spell-verification-ledger/SKILL.md +1 -1
- package/dist/assets/.arcane/governance/development-methodology.md +6 -6
- package/dist/assets/.arcane/governance/git-conventions.md +2 -2
- package/dist/assets/.arcane/governance/portable-bootstrap.md +1 -0
- package/dist/assets/.arcane/governance/product-excellence-standards.md +1 -1
- package/dist/assets/.arcane/governance/spell-authoring-standards.md +9 -1
- package/dist/assets/.arcane/governance/universal-agent-rules.md +5 -3
- package/dist/assets/.arcane/spells/spell-address-review.md +115 -0
- package/dist/assets/.arcane/spells/spell-adopt-docs.md +158 -0
- package/dist/assets/.arcane/spells/spell-arcane-version.md +87 -0
- package/dist/assets/.arcane/spells/spell-architect.md +117 -0
- package/dist/assets/.arcane/spells/spell-brainstorm.md +125 -0
- package/dist/assets/.arcane/spells/spell-bug.md +123 -0
- package/dist/assets/.arcane/spells/spell-bump.md +82 -0
- package/dist/assets/.arcane/spells/spell-check-drift.md +118 -0
- package/dist/assets/.arcane/spells/spell-close-session.md +266 -0
- package/dist/assets/.arcane/spells/spell-commit-work.md +279 -0
- package/dist/assets/.arcane/spells/spell-compliance.md +130 -0
- package/dist/assets/.arcane/spells/spell-create-pull-request.md +224 -0
- package/dist/assets/.arcane/spells/spell-document.md +84 -0
- package/dist/assets/.arcane/spells/spell-dotnet-expert.md +118 -0
- package/dist/assets/.arcane/spells/spell-eas-store-deploy.md +254 -0
- package/dist/assets/.arcane/spells/spell-enchant.md +386 -0
- package/dist/assets/.arcane/spells/spell-explain-concept.md +70 -0
- package/dist/assets/.arcane/spells/spell-feedback.md +138 -0
- package/dist/assets/.arcane/spells/spell-full-cycle.md +253 -0
- package/dist/assets/.arcane/spells/spell-generate-bot-icons.md +85 -0
- package/dist/assets/.arcane/spells/spell-implement.md +109 -0
- package/dist/assets/.arcane/spells/spell-make-discoverable.md +293 -0
- package/dist/assets/.arcane/spells/spell-manifest.md +148 -0
- package/dist/assets/.arcane/spells/spell-open-session.md +154 -0
- package/dist/assets/.arcane/spells/spell-plan.md +160 -0
- package/dist/assets/.arcane/spells/spell-present-arcane.md +189 -0
- package/dist/assets/.arcane/spells/spell-product-review.md +98 -0
- package/dist/assets/.arcane/spells/spell-review-batch.md +113 -0
- package/dist/assets/.arcane/spells/spell-review.md +142 -0
- package/dist/assets/.arcane/spells/spell-save-idea.md +117 -0
- package/dist/assets/.arcane/spells/spell-scope.md +266 -0
- package/dist/assets/.arcane/spells/spell-scry.md +124 -0
- package/dist/assets/.arcane/spells/spell-security-review.md +152 -0
- package/dist/assets/.arcane/spells/spell-ship.md +106 -0
- package/dist/assets/.arcane/spells/spell-status.md +86 -0
- package/dist/assets/.arcane/spells/spell-suggest-feature.md +122 -0
- package/dist/assets/.arcane/spells/spell-summon-venture.md +110 -0
- package/dist/assets/.arcane/spells/spell-sync-pull-request.md +161 -0
- package/dist/assets/.arcane/spells/spell-test.md +88 -0
- package/dist/assets/.arcane/spells/spell-todo.md +166 -0
- package/dist/assets/.arcane/spells/spell-verification-ledger.md +102 -0
- package/dist/assets/.claude/commands/spell-address-review.md +2 -2
- package/dist/assets/.claude/commands/spell-adopt-docs.md +2 -2
- package/dist/assets/.claude/commands/spell-arcane-version.md +2 -2
- package/dist/assets/.claude/commands/spell-architect.md +2 -2
- package/dist/assets/.claude/commands/spell-brainstorm.md +2 -2
- package/dist/assets/.claude/commands/spell-bug.md +2 -2
- package/dist/assets/.claude/commands/spell-bump.md +2 -2
- package/dist/assets/.claude/commands/spell-check-drift.md +2 -2
- package/dist/assets/.claude/commands/spell-close-session.md +2 -2
- package/dist/assets/.claude/commands/spell-commit-work.md +2 -2
- package/dist/assets/.claude/commands/spell-compliance.md +2 -2
- package/dist/assets/.claude/commands/spell-create-pull-request.md +2 -2
- package/dist/assets/.claude/commands/spell-document.md +2 -2
- package/dist/assets/.claude/commands/spell-dotnet-expert.md +2 -2
- package/dist/assets/.claude/commands/spell-eas-store-deploy.md +2 -2
- package/dist/assets/.claude/commands/spell-enchant.md +2 -2
- package/dist/assets/.claude/commands/spell-explain-concept.md +2 -2
- package/dist/assets/.claude/commands/spell-feedback.md +2 -2
- package/dist/assets/.claude/commands/spell-full-cycle.md +2 -2
- package/dist/assets/.claude/commands/spell-generate-bot-icons.md +2 -2
- package/dist/assets/.claude/commands/spell-implement.md +2 -2
- package/dist/assets/.claude/commands/spell-make-discoverable.md +2 -2
- package/dist/assets/.claude/commands/spell-manifest.md +2 -2
- package/dist/assets/.claude/commands/spell-open-session.md +2 -2
- package/dist/assets/.claude/commands/spell-plan.md +2 -2
- package/dist/assets/.claude/commands/spell-present-arcane.md +2 -2
- package/dist/assets/.claude/commands/spell-product-review.md +2 -2
- package/dist/assets/.claude/commands/spell-review-batch.md +2 -2
- package/dist/assets/.claude/commands/spell-review.md +2 -2
- package/dist/assets/.claude/commands/spell-save-idea.md +2 -2
- package/dist/assets/.claude/commands/spell-scope.md +2 -2
- package/dist/assets/.claude/commands/spell-scry.md +2 -2
- package/dist/assets/.claude/commands/spell-security-review.md +2 -2
- package/dist/assets/.claude/commands/spell-ship.md +2 -2
- package/dist/assets/.claude/commands/spell-status.md +2 -2
- package/dist/assets/.claude/commands/spell-suggest-feature.md +2 -2
- package/dist/assets/.claude/commands/spell-summon-venture.md +2 -2
- package/dist/assets/.claude/commands/spell-sync-pull-request.md +2 -2
- package/dist/assets/.claude/commands/spell-test.md +2 -2
- package/dist/assets/.claude/commands/spell-todo.md +2 -2
- package/dist/assets/.claude/commands/spell-verification-ledger.md +2 -2
- package/dist/assets/.github/instructions/agent-output.instructions.md +14 -13
- package/dist/assets/.github/prompts/spell-address-review.prompt.md +1 -107
- package/dist/assets/.github/prompts/spell-adopt-docs.prompt.md +1 -150
- package/dist/assets/.github/prompts/spell-arcane-version.prompt.md +1 -79
- package/dist/assets/.github/prompts/spell-architect.prompt.md +1 -109
- package/dist/assets/.github/prompts/spell-brainstorm.prompt.md +1 -117
- package/dist/assets/.github/prompts/spell-bug.prompt.md +1 -115
- package/dist/assets/.github/prompts/spell-bump.prompt.md +1 -74
- package/dist/assets/.github/prompts/spell-check-drift.prompt.md +1 -110
- package/dist/assets/.github/prompts/spell-close-session.prompt.md +1 -258
- package/dist/assets/.github/prompts/spell-commit-work.prompt.md +1 -270
- package/dist/assets/.github/prompts/spell-compliance.prompt.md +1 -122
- package/dist/assets/.github/prompts/spell-create-pull-request.prompt.md +1 -215
- package/dist/assets/.github/prompts/spell-document.prompt.md +1 -76
- package/dist/assets/.github/prompts/spell-dotnet-expert.prompt.md +1 -110
- package/dist/assets/.github/prompts/spell-eas-store-deploy.prompt.md +1 -246
- package/dist/assets/.github/prompts/spell-enchant.prompt.md +1 -378
- package/dist/assets/.github/prompts/spell-explain-concept.prompt.md +1 -62
- package/dist/assets/.github/prompts/spell-feedback.prompt.md +1 -130
- package/dist/assets/.github/prompts/spell-full-cycle.prompt.md +1 -245
- package/dist/assets/.github/prompts/spell-generate-bot-icons.prompt.md +1 -77
- package/dist/assets/.github/prompts/spell-implement.prompt.md +1 -101
- package/dist/assets/.github/prompts/spell-make-discoverable.prompt.md +1 -285
- package/dist/assets/.github/prompts/spell-manifest.prompt.md +1 -140
- package/dist/assets/.github/prompts/spell-open-session.prompt.md +1 -146
- package/dist/assets/.github/prompts/spell-plan.prompt.md +1 -152
- package/dist/assets/.github/prompts/spell-present-arcane.prompt.md +1 -181
- package/dist/assets/.github/prompts/spell-product-review.prompt.md +1 -90
- package/dist/assets/.github/prompts/spell-review-batch.prompt.md +1 -105
- package/dist/assets/.github/prompts/spell-review.prompt.md +1 -134
- package/dist/assets/.github/prompts/spell-save-idea.prompt.md +1 -109
- package/dist/assets/.github/prompts/spell-scope.prompt.md +1 -258
- package/dist/assets/.github/prompts/spell-scry.prompt.md +1 -116
- package/dist/assets/.github/prompts/spell-security-review.prompt.md +1 -144
- package/dist/assets/.github/prompts/spell-ship.prompt.md +1 -98
- package/dist/assets/.github/prompts/spell-status.prompt.md +1 -78
- package/dist/assets/.github/prompts/spell-suggest-feature.prompt.md +1 -114
- package/dist/assets/.github/prompts/spell-summon-venture.prompt.md +1 -102
- package/dist/assets/.github/prompts/spell-sync-pull-request.prompt.md +1 -152
- package/dist/assets/.github/prompts/spell-test.prompt.md +1 -80
- package/dist/assets/.github/prompts/spell-todo.prompt.md +1 -158
- package/dist/assets/.github/prompts/spell-verification-ledger.prompt.md +1 -94
- package/dist/index.js +1073 -246
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- /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
|
-
|
|
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}`/<a specific deep route, not the homepage> 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
|
-
|
|
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
|
-
|
|
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.
|