@lifeaitools/rdc-skills 0.13.6 → 0.13.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/rdc-skills",
3
- "version": "0.13.6",
3
+ "version": "0.13.7",
4
4
  "description": "RDC typed-agent dispatch skill suite for Claude Code - plan, build, review, overnight builds",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -56,6 +56,7 @@ rdc:deploy: <slug> → <domain>
56
56
  [ ] Gate: TLS valid (no SSL cipher mismatch)
57
57
  [ ] Gate: cache headers correct on HTML
58
58
  [ ] Gate: container running on declared port
59
+ [ ] Gate: metadata audit (see § Metadata Audit below) — warn on gaps, do not block deploy
59
60
  [ ] Cloudflare cache purged (if proxied)
60
61
  [ ] artifact_registry INSERT per PUBLISH.md surface (if PUBLISH.md present)
61
62
  [ ] deployment_registry updated (last_deploy_at, status)
@@ -163,6 +164,7 @@ rdc:deploy promote: <slug> → <prod-domain>
163
164
  [ ] Gate: HTTP 200 on prod domain
164
165
  [ ] Gate: content-level check — assert the actual changed string is live (200 alone is NOT proof; origin may serve stale)
165
166
  [ ] Gate: TLS valid
167
+ [ ] Gate: metadata audit (see § Metadata Audit below) — BLOCK promote on any missing required item
166
168
  [ ] Cloudflare cache purged (if proxied)
167
169
  [ ] deployment_registry updated (last_deploy_at, last_deploy_commit, status)
168
170
  ✅ rdc:deploy promote: <slug> live in prod — <changed-string> verified
@@ -183,6 +185,53 @@ curl -s -H "Authorization: Bearer $_COOLIFY" \
183
185
  - `develop` was 87 commits ahead of `main` (unrelated apps' WIP). Promoting must be surgical (this app's paths / one sha), never a develop→main merge.
184
186
  - HTTP 200 was returned by the stale origin the whole time — only a content-level assertion (`curl … | grep '<new string>'`) proves the promote landed.
185
187
 
188
+ ## Metadata Audit
189
+
190
+ After a successful deploy or promote, audit the live site's `<head>` metadata. Run this against the deployed URL (not a local file).
191
+
192
+ **Check list** (curl the deployed URL, parse the HTML `<head>`):
193
+
194
+ | # | Item | How to check | Required | Severity |
195
+ |---|------|-------------|----------|----------|
196
+ | 1 | `<title>` | grep `<title>` — non-empty, not default/placeholder | yes | block |
197
+ | 2 | `<meta name="description">` | content attr ≥ 50 chars, ≤ 160 chars | yes | block on promote; warn on deploy |
198
+ | 3 | `<link rel="canonical">` | href present, starts with `https://`, matches the deployed domain | yes | block on promote; warn on deploy |
199
+ | 4 | `og:title` | `<meta property="og:title">` present | yes | block on promote; warn on deploy |
200
+ | 5 | `og:description` | `<meta property="og:description">` present, ≥ 50 chars | yes | block on promote; warn on deploy |
201
+ | 6 | `og:image` | `<meta property="og:image">` present, URL returns HTTP 200 | yes | block on promote; warn on deploy |
202
+ | 7 | `og:url` | present, matches canonical | recommended | warn |
203
+ | 8 | `twitter:card` | `summary_large_image` or `summary` | recommended | warn |
204
+ | 9 | `twitter:image` | present, URL returns HTTP 200 | recommended | warn |
205
+ | 10 | Favicon | `<link rel="icon">` present, href returns HTTP 200 | yes | block on promote; warn on deploy |
206
+ | 11 | `sitemap.xml` | `<domain>/sitemap.xml` returns HTTP 200 | recommended | warn |
207
+ | 12 | `robots.txt` | `<domain>/robots.txt` returns HTTP 200 | recommended | warn |
208
+ | 13 | Version | `<meta name="version">` or visible version string in page | yes (project rule) | warn |
209
+
210
+ **Behavior by mode:**
211
+ - **Mode 1 (deploy):** run the audit after HTTP/TLS gates. Print a table of results. **Warn** on gaps but do NOT block the deploy — dev deploys are iterative.
212
+ - **Mode 5 (promote):** run the audit after content-level check. **Block the promote** if any item marked "block on promote" is missing. Print the table and require the metadata to be fixed before re-attempting.
213
+ - **Mode 4 (audit):** include the metadata sweep in the fleet scan (one row per app per missing item in the findings table).
214
+
215
+ **Implementation — one-liner per check:**
216
+ ```bash
217
+ URL="https://<domain>"
218
+ HEAD=$(curl -s "$URL" | sed -n '/<head/,/<\/head>/p')
219
+ echo "$HEAD" | grep -ioE '<title>[^<]+</title>'
220
+ echo "$HEAD" | grep -ioE 'name="description"[^>]*content="[^"]*"'
221
+ echo "$HEAD" | grep -ioE 'rel="canonical"[^>]*href="[^"]*"'
222
+ echo "$HEAD" | grep -ioE 'property="og:title"[^>]*content="[^"]*"'
223
+ echo "$HEAD" | grep -ioE 'property="og:image"[^>]*content="[^"]*"'
224
+ echo "$HEAD" | grep -ioE 'name="twitter:card"[^>]*content="[^"]*"'
225
+ echo "$HEAD" | grep -ioE 'rel="icon"[^>]*href="[^"]*"'
226
+ echo "$HEAD" | grep -ioE 'name="version"[^>]*content="[^"]*"'
227
+ curl -s -o /dev/null -w "%{http_code}" "$URL/sitemap.xml"
228
+ curl -s -o /dev/null -w "%{http_code}" "$URL/robots.txt"
229
+ OG_IMG=$(echo "$HEAD" | grep -ioE 'property="og:image"[^>]*content="([^"]*)"' | grep -ioE 'https://[^"]*')
230
+ [ -n "$OG_IMG" ] && curl -s -o /dev/null -w "%{http_code}" "$OG_IMG"
231
+ ```
232
+
233
+ **Why this exists (2026-06-05):** life.ai deployed to production with zero social/SEO metadata — no description, no OG, no favicon, no sitemap. HTTP 200 + TLS + content passed; metadata was invisible to the existing gates. This audit catches that class of defect.
234
+
186
235
  ## PUBLISH.md Integration
187
236
 
188
237
  Every deploy reads `PUBLISH.md` from the app's source root to derive `watch_paths` and to register surfaces in Studio `artifact_registry`.