arcane-cli 0.29.1 → 0.29.3

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.
@@ -47,19 +47,19 @@ How a web property becomes retrievable by search-engine crawlers and by the AI a
47
47
 
48
48
  ### WD-01 — Metadata renders before JavaScript runs
49
49
 
50
- **Rule:** Per-route share/SEO metadata — title, description, canonical URL, and structured preview tags (Open Graph, a card-style social preview format, JSON-LD) — must be present in the raw HTML response *before* any client-side JavaScript executes.
50
+ **Rule: Per-route share/SEO metadata — title, description, canonical URL, and structured preview tags (Open Graph, a card-style social preview format, JSON-LD) — must be present in the raw HTML response *before* any client-side JavaScript executes. Enforcement: structured spell gate (ARC-023) — spell-make-discoverable's Phase 2 Audit table (Per-route share metadata, WD-01) fetches a live deep route with a non-executing HTTP client and requires a title/description distinct from the homepage before Phase 3's approval gate allows any fix to proceed.**
51
51
 
52
52
  **Why:** Link-unfurl scrapers used by chat apps, messaging platforms, and social platforms fetch the HTML document once over HTTP and do not execute JavaScript. A client-side head-management approach — a library that sets `document.title` and injects meta tags after the app mounts — is invisible to that entire audience, even though it looks completely correct to a human inspecting the live DOM in a browser. The browser ran the JavaScript; the scraper didn't. "Works when I look at it" and "works for the audience that matters here" are different claims, and only one of them is being tested by opening dev tools.
53
53
 
54
54
  ### WD-02 — Inject at the existing serving layer, not a new rendering pipeline
55
55
 
56
- **Rule:** The correct injection point for per-route metadata is the layer *already* serving the built application to browsers — intercept and augment the response there (template substitution, response rewriting, an edge/proxy rule) — not a separate server-side rendering pipeline built to solve this one problem.
56
+ **Rule: The correct injection point for per-route metadata is the layer *already* serving the built application to browsers — intercept and augment the response there (template substitution, response rewriting, an edge/proxy rule) — not a separate server-side rendering pipeline built to solve this one problem. Enforcement: explicitly advisory (ARC-023) — which layer performed the injection is indistinguishable from the outside, so no executable check or spell gate confirms it; spell-make-discoverable's Phase 2 table cites WD-02 only for Open Graph tag content, not injection-layer architecture.**
57
57
 
58
58
  **Why:** That layer already sees every request and already returns the HTML document; per-route string-level substitution at that point gets the metadata into the raw response without introducing a second rendering runtime, a hydration story, or a new build target. See "Why per-route injection beats both alternatives" below for the fuller comparison.
59
59
 
60
60
  ### WD-03 — Dead or non-public routes return a real not-found status
61
61
 
62
- **Rule:** A route representing content that no longer exists, or that was never public, must return a genuine "not found" HTTP status (404, or 410 if the removal is intentional and permanent) while still rendering the application's own not-found UI in the response body.
62
+ **Rule: A route representing content that no longer exists, or that was never public, must return a genuine "not found" HTTP status (404, or 410 if the removal is intentional and permanent) while still rendering the application's own not-found UI in the response body. Enforcement: explicitly advisory (ARC-023) — no executable check or spell gate in this codebase asserts response status codes for dead routes; spell-make-discoverable's Phase 2 table cites WD-03 for canonical-tag uniqueness, a different check.**
63
63
 
64
64
  **Why:** An always-200 catch-all — common with client-side routing, where every path resolves to the same shell and the app decides what to render after the fact — is invisible to a human browsing normally; they see a "not found" page and move on. A search engine reads the status code, not the rendered pixels. A 200 on a dead URL tells the crawler the page is valid and indexable — a "soft 404" — and the URL gets indexed, sometimes ranked, and eventually shown to a searcher as a dead end.
65
65
 
@@ -81,13 +81,13 @@ Between an approach that solves a narrower problem than it claims to and one tha
81
81
 
82
82
  ### WD-04 — Environment-specific values resolve at runtime
83
83
 
84
- **Rule:** Any value that legitimately differs between deployed environments — most commonly the canonical public origin or hostname embedded in canonical URLs, structured data, or preview metadata — must be resolved at runtime from the actual running environment, never baked in at build time.
84
+ **Rule: Any value that legitimately differs between deployed environments — most commonly the canonical public origin or hostname embedded in canonical URLs, structured data, or preview metadata — must be resolved at runtime from the actual running environment, never baked in at build time. Enforcement: explicitly advisory (ARC-023) — no executable check confirms build-time values are absent from the running artifact; spell-make-discoverable's Phase 2 table cites WD-04 for JSON-LD validity, a different check.**
85
85
 
86
86
  **Why:** When a single build artifact is deployed unchanged to multiple environments (build once, promote the same artifact — standard practice, and good practice for other reasons), any value fixed at build time is physically identical across every environment that artifact runs in. It cannot carry an environment-specific answer no matter how carefully it was set at build time, because build time happens once, upstream of every environment the artifact will later run in. There is no way to make a single frozen value simultaneously correct for staging and production; the fix is to stop trying and read the value from the environment that's actually running.
87
87
 
88
88
  ### WD-05 — Confirm environment flags actually vary, don't trust their default
89
89
 
90
- **Rule:** A generic "is this production" flag commonly defaults to the same value across *all* deployed environments, not only production. Branching discoverability logic on it (for example, suppressing indexing everywhere that isn't production) silently gives every environment the production answer unless that default has been checked. Before relying on any such signal, confirm it actually differs per environment by reading it back from each running environment — not by trusting how it was configured or assumed to behave.
90
+ **Rule: A generic "is this production" flag commonly defaults to the same value across *all* deployed environments, not only production. Branching discoverability logic on it (for example, suppressing indexing everywhere that isn't production) silently gives every environment the production answer unless that default has been checked. Before relying on any such signal, confirm it actually differs per environment by reading it back from each running environment — not by trusting how it was configured or assumed to behave. Enforcement: explicitly advisory (ARC-023) — confirming this requires operator judgment about which signal to trust and read back per environment; spell-make-discoverable's Phase 2 table cites WD-05 for basic robots.txt validity, a different check.**
91
91
 
92
92
  **Why:** The mistake is invisible precisely because production looks correct — it's the one environment where the flag's default happens to match reality. The bug only shows up in every *other* environment, which is exactly where it's least likely to get noticed during a review that (reasonably) focuses attention on production. Prefer a signal already confirmed to vary — a runtime-resolved hostname, an explicitly-set per-environment value — over a flag whose default was never actually read back from a non-production environment.
93
93
 
@@ -97,13 +97,13 @@ Between an approach that solves a narrower problem than it claims to and one tha
97
97
 
98
98
  ### WD-06 — Never route crawlers through user-traffic side effects
99
99
 
100
- **Rule:** Never route crawler or bot traffic through an endpoint that has view-counting, rate-limiting-by-request, or other side effects meant for real user traffic. Serve crawler-facing responses — sitemaps, crawler-visible pages, structured-data feeds — by reading the underlying data directly, bypassing those side-effecting code paths.
100
+ **Rule: Never route crawler or bot traffic through an endpoint that has view-counting, rate-limiting-by-request, or other side effects meant for real user traffic. Serve crawler-facing responses — sitemaps, crawler-visible pages, structured-data feeds — by reading the underlying data directly, bypassing those side-effecting code paths. Enforcement: explicitly advisory (ARC-023) — no executable check or spell gate in this codebase confirms crawler routes bypass side-effecting code paths; spell-make-discoverable's Phase 2 table cites WD-06 for sitemap-directive presence, a different check.**
101
101
 
102
102
  **Why:** A well-behaved crawler generates a high volume of requests across a large route set in a short window, and that volume is not representative of user behavior even when the crawler is behaving exactly as intended. Run that volume through a view counter and the counter becomes meaningless noise on top of real signal. Run it through a rate limiter designed to catch abusive human traffic and it trips the limiter, throttling or blocking the crawler — and the content behind it — for doing nothing wrong.
103
103
 
104
104
  ### WD-07 — Crawler listings reuse the application's own visibility rule
105
105
 
106
- **Rule:** Any listing of publicly discoverable content generated for a crawler — most commonly a sitemap — must be derived from the *exact same* visibility rule the application's own public listing or feed uses for that content, never a second, independently written copy of that rule.
106
+ **Rule: Any listing of publicly discoverable content generated for a crawler — most commonly a sitemap — must be derived from the *exact same* visibility rule the application's own public listing or feed uses for that content, never a second, independently written copy of that rule. Enforcement: structured spell gate (ARC-023) — spell-make-discoverable's Phase 2 Audit table (Robots and sitemap policy, WD-07) checks every sitemap URL against `{PUBLIC_VISIBILITY_PREDICATE}` before Phase 3's approval gate allows any fix to proceed.**
107
107
 
108
108
  **Why:** A hand-maintained second copy of a visibility rule is correct on the day it's written and drifts silently after that. The real rule gains a condition over time — a moderation flag, a scheduled-publish date, a soft-delete check — and the sitemap-generation copy doesn't get the same update, because nothing forces the two to change together. The result is a sitemap that lists things a visitor can't actually reach, or omits things that are genuinely public. Call or import the same predicate the listing endpoint already uses; don't restate its logic anywhere else.
109
109
 
@@ -113,7 +113,7 @@ Between an approach that solves a narrower problem than it claims to and one tha
113
113
 
114
114
  ### WD-08 — A specific allow-rule must be declared to escape a broader disallow
115
115
 
116
- **Rule:** In a robots-exclusion file, when both an explicit allow-rule for a specific path (for example, a public media/asset path that page metadata references) and a broader disallow-rule for a prefix that would otherwise contain it (for example, a general API path prefix) are both relevant, the specific allow-rule *must be declared* so that it actually takes effect.
116
+ **Rule: In a robots-exclusion file, when both an explicit allow-rule for a specific path (for example, a public media/asset path that page metadata references) and a broader disallow-rule for a prefix that would otherwise contain it (for example, a general API path prefix) are both relevant, the specific allow-rule *must be declared* so that it actually takes effect. Enforcement: explicitly advisory (ARC-023) — no executable check or spell gate in this codebase verifies allow/disallow specificity for a given path; spell-make-discoverable's Phase 2 table cites WD-08 for an unrelated non-production noindex-signal check, not this rule's actual claim.**
117
117
 
118
118
  **Why:** Crawlers that respect a robots-exclusion file resolve overlapping rules by specificity — the most specific matching path generally wins over a broader one, not "whichever rule appears first in the file" and not "disallow always wins." Get the specificity wrong, or simply omit the specific allow-rule and assume the broader disallow won't apply to it, and a media-asset path nested under a disallowed API prefix becomes entirely invisible to image crawling — even though the page's own metadata correctly points at that image. A correct metadata reference doesn't help if the crawler was never permitted to fetch what it points to.
119
119
 
@@ -127,7 +127,7 @@ The allow-rule for the more specific path has to exist in the file; it isn't inf
127
127
 
128
128
  ### WD-09 — Non-production origins need crawl control AND index control
129
129
 
130
- **Rule:** A non-production or staging origin needs *both* a crawl-blocking mechanism (a robots-exclusion rule disallowing the origin) *and* an index-suppression response header (for example, a `noindex` directive delivered via response header, or an equivalent tag) on every response.
130
+ **Rule: A non-production or staging origin needs *both* a crawl-blocking mechanism (a robots-exclusion rule disallowing the origin) *and* an index-suppression response header (for example, a `noindex` directive delivered via response header, or an equivalent tag) on every response. Enforcement: structured spell gate (ARC-023) — spell-make-discoverable's Phase 2 Audit table (Non-production noindexing, WD-09) fetches a sampled non-prod route and requires both an `X-Robots-Tag: noindex` header and a matching meta tag before Phase 3's approval gate allows any fix to proceed.**
131
131
 
132
132
  ```http
133
133
  X-Robots-Tag: noindex, nofollow
@@ -158,15 +158,15 @@ Using only the robots-exclusion rule leaves the bare-URL-listing gap open. Using
158
158
 
159
159
  ### WD-10 — Apex DNS verification records are appended, not replaced
160
160
 
161
- **Rule:** Registering a property's ownership with a search console commonly requires adding a DNS TXT record at the domain apex. Follow EV-05 (see [[.arcane/governance/external-verification-standards|External Verification Standards]]) when writing it, rather than re-deriving the append-vs-replace reasoning here — the apex TXT record set is very often already carrying other unrelated values (a mail-sender authorization policy, other verification strings), and a careless write destroys them.
161
+ **Rule: Registering a property's ownership with a search console commonly requires adding a DNS TXT record at the domain apex. Follow EV-05 (see [[.arcane/governance/external-verification-standards|External Verification Standards]]) when writing it, rather than re-deriving the append-vs-replace reasoning here — the apex TXT record set is very often already carrying other unrelated values (a mail-sender authorization policy, other verification strings), and a careless write destroys them. Enforcement: structured spell gate (ARC-023) — spell-make-discoverable's Phase 2 Audit table (Search-engine registration, WD-10) re-queries the live DNS record, and Phase 4b requires the operator to confirm the full resulting record as an append before any write is made.**
162
162
 
163
163
  ### WD-11 — Cover both instant notification and sitemap freshness
164
164
 
165
- **Rule:** Instant crawl/recrawl notification protocols exist and are adopted by some search engines and services — IndexNow is one — but not by the search engine with the largest share of global query volume, which instead relies on periodically re-fetching a submitted sitemap. Covering "notify search engines the moment content changes" therefore requires *both*: an instant-notification call where the protocol is supported, *and* ensuring the sitemap itself is submitted through the relevant search console and kept current for the engine(s) that don't support instant notification.
165
+ **Rule: Instant crawl/recrawl notification protocols exist and are adopted by some search engines and services — IndexNow is one — but not by the search engine with the largest share of global query volume, which instead relies on periodically re-fetching a submitted sitemap. Covering "notify search engines the moment content changes" therefore requires *both*: an instant-notification call where the protocol is supported, *and* ensuring the sitemap itself is submitted through the relevant search console and kept current for the engine(s) that don't support instant notification. Enforcement: structured spell gate (ARC-023) — spell-make-discoverable's Phase 2 Audit table (Search-engine registration, WD-11) checks notification-endpoint wiring and console submission status before Phase 3's approval gate allows any fix to proceed.**
166
166
 
167
167
  ### WD-12 — Search-index presence outweighs a static AI-readable file
168
168
 
169
- **Rule/observation:** For the specific goal of being retrievable *by AI assistants* — as distinct from being found by a human searching directly — being present and current in a major search engine's index is a substantially stronger lever than any single static "AI-readable" convention file placed at a well-known path (for example, a plain-text site-description file such as the emerging `llms.txt` convention). Several AI assistants answer by drawing on a search engine's index rather than crawling the web independently, so an assistant's ability to surface a page is frequently bottlenecked on that page's search-index presence, not on whether a convention file exists at all. A convention file is still worth publishing — it costs little and helps the assistants that do read it directly — but it should not be mistaken for the primary lever. The everything-else in this document (WD-01 through WD-11) is the primary lever.
169
+ **Rule/observation: For the specific goal of being retrievable *by AI assistants* — as distinct from being found by a human searching directly — being present and current in a major search engine's index is a substantially stronger lever than any single static "AI-readable" convention file placed at a well-known path (for example, a plain-text site-description file such as the emerging `llms.txt` convention). Several AI assistants answer by drawing on a search engine's index rather than crawling the web independently, so an assistant's ability to surface a page is frequently bottlenecked on that page's search-index presence, not on whether a convention file exists at all. A convention file is still worth publishing — it costs little and helps the assistants that do read it directly — but it should not be mistaken for the primary lever. The everything-else in this document (WD-01 through WD-11) is the primary lever. Enforcement: structured spell gate (ARC-023) — spell-make-discoverable's Phase 2 Audit table (Search-engine registration, WD-12) reads the webmaster console's own coverage status verbatim before Phase 3's approval gate allows any fix to proceed.**
170
170
 
171
171
  ---
172
172
 
@@ -176,8 +176,8 @@ Using only the robots-exclusion rule leaves the bare-URL-listing gap open. Using
176
176
 
177
177
  **Rule:** Any user-supplied text embedded into page metadata needs two independent escaping treatments:
178
178
 
179
- 1. Standard HTML-attribute escaping for the visible meta tags (title, description, preview-card values) — the ordinary defense against a value breaking out of an attribute or tag context.
180
- 2. Separately, for structured data embedded as inline JSON inside a `<script type="application/ld+json">` tag: escape the `<` character wherever it appears inside JSON string values (for example, to its Unicode-escape form), in addition to standard JSON string escaping.
179
+ 1. **Standard HTML-attribute escaping for the visible meta tags (title, description, preview-card values) — the ordinary defense against a value breaking out of an attribute or tag context.**
180
+ 2. **Separately, for structured data embedded as inline JSON inside a `<script type="application/ld+json">` tag: escape the `<` character wherever it appears inside JSON string values (for example, to its Unicode-escape form), in addition to standard JSON string escaping. Enforcement: structured spell gate (ARC-023) — spell-make-discoverable's Phase 2 Audit table (Per-route share metadata, WD-13) renders a sampled route's JSON-LD and surrounding HTML attribute side by side before Phase 3's approval gate allows any fix to proceed.**
181
181
 
182
182
  ```json
183
183
  {
@@ -194,13 +194,13 @@ Using only the robots-exclusion rule leaves the bare-URL-listing gap open. Using
194
194
 
195
195
  ### WD-14 — Aspect ratio, safe margin, file size
196
196
 
197
- **Rule:** Link-preview (share) images should follow the aspect ratio broadly adopted across major platforms — close to 1.91:1 — with a safe-content margin around the edges so platform-specific cropping doesn't cut off text or a focal subject, and should stay modest in file size.
197
+ **Rule: Link-preview (share) images should follow the aspect ratio broadly adopted across major platforms — close to 1.91:1 — with a safe-content margin around the edges so platform-specific cropping doesn't cut off text or a focal subject, and should stay modest in file size. Enforcement: explicitly advisory (ARC-023) — no executable check measures aspect ratio or safe-margin compliance in this codebase; spell-make-discoverable's Phase 2 table cites WD-14 for restricted-path sitemap exclusion, a different check, and checks share-image fetchability/size under the WD-15 label instead.**
198
198
 
199
199
  **Why:** Scrapers fetch preview images synchronously as part of unfurling a link, and some platforms silently refuse to fetch, or silently fail to display, an image above their own size ceiling — there is usually no visible error; the preview simply renders without an image. A safe-content margin matters because different platforms crop the same source image to slightly different final frames; content placed right at the edge survives on some platforms and gets cut on others.
200
200
 
201
201
  ### WD-15 — Composite real assets; don't ask a generator for exact type or logos
202
202
 
203
- **Rule:** Current AI image-generation tools cannot reliably reproduce an exact existing typeface or an exact existing vector logo/mark — both come out as a visible approximation, and no amount of prompt refinement reliably fixes this. It's a property of how these generators work (they produce plausible-looking glyphs and marks probabilistically rather than reproducing exact vector paths or font outlines), not a quality issue specific to any one generation attempt. When brand-exact typography or an exact logo mark matters for a share image, composite the real font files and the real vector logo asset over separately generated artwork or background — don't ask the generator to produce the whole image including the exact type and mark.
203
+ **Rule: Current AI image-generation tools cannot reliably reproduce an exact existing typeface or an exact existing vector logo/mark — both come out as a visible approximation, and no amount of prompt refinement reliably fixes this. It's a property of how these generators work (they produce plausible-looking glyphs and marks probabilistically rather than reproducing exact vector paths or font outlines), not a quality issue specific to any one generation attempt. When brand-exact typography or an exact logo mark matters for a share image, composite the real font files and the real vector logo asset over separately generated artwork or background — don't ask the generator to produce the whole image including the exact type and mark. Enforcement: explicitly advisory (ARC-023) — whether generated artwork faithfully reproduces exact type or a logo is a design judgment call no automated check can verify; spell-make-discoverable's Phase 2 table cites WD-15 for share-image fetchability, a different, mechanically-checkable concern.**
204
204
 
205
205
  ---
206
206
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arcane-cli",
3
- "version": "0.29.1",
3
+ "version": "0.29.3",
4
4
  "description": "Arcane framework CLI — scaffold and manage governance files in consuming repositories",
5
5
  "keywords": [
6
6
  "arcane",