From platinum-seo-engine
Use when: kullanıcı "blog revize et", "içerik güncelle", "decay düzelt", "section revise et", "blog tazele", "post güncelle", "article refresh" der ya da `/pseo-revise` çağırır. master.xlsx [content_decay] satırından action="revise" alındığında, R-87 section-targeted diff workflow uygulanır, R-88 freshness theater preempt edilir, R-89 canonical preserve edilir. Also use when: GSC clicks delta drop > threshold detect edildiğinde (R-85 multi-signal: clicks_delta < -20%, delta_pct < -15%, trend "down" 3-month rolling); manuel revise request var ve mevcut blog outputs/blog/{slug}/article.html olarak diskten okunabiliyor; project-config[profile] enum 5-değer (e-commerce | ymyl | local-service | b2b-saas | portfolio) içinden biri sabit ve revize sırasında profile-aware tone preserve edilecek (Principle 2). Do not use when: yeni blog için (new-blog skill kullan); FAQ block re-render için (faq-optimization Wave 2 kullan); decay action "prune"/"redirect"/"delete" için (content-remediation Wave 2 domain); image generation için (generate-images kullan); existing HTML diskte yok (DURUR #1, R-89 canonical preserve enforce edilemez); R-85 multi-signal threshold satisfied değil (DURUR #3, revize gereksiz); R-87 section-targeted yasak ve scope=full manuel approve olmadan (DURUR #5).
How this skill is triggered — by the user, by Claude, or both
Slash command
/platinum-seo-engine:revise-contentThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Section-targeted revise skill. master.xlsx[content_decay] satırından
Section-targeted revise skill. master.xlsx[content_decay] satırından action="revise" alır, R-87 section-targeted diff uygular, R-88 freshness theater preempt eder, R-89 canonical preserve eder, R-103 content version increment eder. READ-ONLY contract: master.xlsx [content_decay] + master_task sheet'lerine YAZMAZ (allowed_writers null + master_task protected_columns 7 alan); sadece outputs/ + _state yazar.
Tüm content/source/link/data %100 doğru ve kanıtlanabilir; uydurma yasak. Revise context'inde:
truth_verifiable: true
field zorunlu.Skill behavior project.config.json[profile] enum'una göre değişir.
Enum 5-value: e-commerce | ymyl | local-service | b2b-saas |
portfolio.
profile == "ymyl" → counter-argument (R-50) korunur, revize
sırasında counter-argument silinemez; byline (R-28) preserve
edilmeli, author değişmez (R-89 canonical adjacent).profile == "e-commerce" → conversational tone preserve, CTA
freshness güncelle.profile == "local-service" → location signal preserve (NAP
consistency).profile == "b2b-saas" → formal tone + diagram/screenshot
preserve.profile == "portfolio" → showcase entity preserve (project
list).AI'ın doğal cheap content padding davranışını preempt et. Revise context'inde:
delta == 0 AND claim_delta == 0 AND structure_hash unchanged → RED (sahte tarih güncelleme).Bank entry (R-105 expert quote / R-114 original research / R-119 first-hand experience) selection passes a 3-step filter, with one revise-specific addition: the existing article's already-cited bank entries count toward the density cap. R-121 is per content, not per skill invocation — replacing a stale fact with a new bank entry adds, removing one subtracts, holding one steady leaves the cap unchanged.
Step 4 (Existing Blog Parse) addition: during the BeautifulSoup parse, also extract pre-revise bank citations. Two detection paths:
<blockquote data-bank-entry-id="exp-..." /> or
<aside data-bank-entry-id="res-..." /> — explicit attribution
attribute (preferred; new-blog runtime will emit this once Phase 11
Wave 2 lands).data-bank-entry-id: regex against entry.claim_core + phrasings
of every bank entry in project.config[content_settings. experience_database] ∪ original_research_database.The detected entries form bank_entries_pre[]; the revise pass then
runs the 3-step filter against bank_entries_pre[] ∪ candidates_new[]:
entry.applicable_topics ∩ (decay_row.url_slug ∪ decay_row.matched_keywords ∪ topical_map[matching_row].cluster) ≠ ∅
→ entry remains a candidate; empty intersection → entry skipped
(and if it was a pre-revise entry, the removal is logged in
change_summary.md as "bank entry pruned: topic no longer matches
revised content").|bank_entries_pre| already meets or exceeds the cap, no new
entries are introduced during revise — the skill rotates phrasings
on existing entries instead.master.xlsx[completed_work] rows where
bank_entry_id == entry.id AND timestamp >= now - 30d. Skip if
count >= entry.max_usage_per_month. Pre-revise entries are
exempted from rotation (they are already on the page; removing them
only to satisfy the rotation cap would be churn).If a pre-revise entry fails topic match (filter 1), the revise drops
it from the article; this counts as a claim_delta -= 1 for the R-88
freshness-theater check (Step 6) — a genuine content delta, not a
fake bump.
R-89 canonical interplay. Bank entry attribution (the
data-bank-entry-id attribute on <blockquote> / <aside>) is part
of the article's content signal, not its canonical URL. Changing
which entries are cited does not trigger R-89 canonical change —
only URL slug changes do (R-91 redirect path).
Post-publish state mutation (Step 8 events.jsonl append):
last_used_in_content_id is set; the master.xlsx[completed_work]
row records the bank_entry_id(s) added.completed_work row when the article originally
shipped).completed_work row —
historical attribution preserved (append-only state, R-rule
events-writer discipline).Schema enablement (v1.4, commit 8e07e1c): R-121 reads
applicable_topics, phrasings, last_used_in_content_id,
max_usage_per_month on each bank entry. Stage C of brand-onboarding
(commit cb8df43) populates these via R-44 evidence-gated atomic
write.
Runtime integration deferred to Phase 11 Wave 2. This SKILL.md
section is the spec lock; scripts/production/revise_content.py does
not yet exist. When Wave 2 lands the runtime, the pre-revise
extraction lives in Step 4; the 3-step filter runs between Step 5
(section-targeted detect) and Step 6 (revise generate).
YMYL profillerinde (profile == "ymyl"), R-124 gereği yazar künyesi
(R-28) yalnızca kayıtlı bir insan incelemesi ile geçerlidir. Revize
edilmiş YMYL içeriği yayınlanmadan (Step 7 dateModified bump'tan) ÖNCE
zorunlu bir inceleme-imzası adımı çalışır:
scripts/state/events_writer.append_audit(...) ile bir
event_kind=audit satırına yazar:
audit_action="modified" (events.schema 6-değer canonical enum
{created, modified, deleted, accessed, permission_changed, config_changed}).audit_target="content:{project_slug}:{post-slug}" (post-slug
input.url'den türetilir).actor="skill:revise-content".notes payload üç zorunlu alan taşır (R-124): reviewer
(inceleyen adı) + review_date (ISO 8601) + content_version
(R-103 revision id veya content hash).READ-ONLY contract korunur: bu audit satırı _state/events.jsonl
append'idir (master.xlsx WRITE değil). Non-YMYL profillerde adım atlanır.
master.xlsx[content_decay].action schema'da type/enum/
description null. Bu skill action enum'unu R-86/R-87/R-90/R-91
rules'tan rule-derived consume eder (string compare):
revise / prune / redirect / delete.master.xlsx[content_decay].allowed_writers null →
READ-ONLY consume; transaction.append/update/delete YASAK.event_type=content_revise (events.schema
12-value enum).master.xlsx[content_decay] satırı url == {input.url} filtresiyle
okunur. Action string compare (schema'da enum null, R-86/R-87/R-90/
R-91 rules'tan derive):
action == "revise" → bu skill trigger devam.action == "prune" → DURUR #2 (content-remediation Wave 2 domain).action == "redirect" → DURUR #2 (content-remediation Wave 2).action == "delete" → DURUR #2 (content-remediation Wave 2).DURUR #1 trigger: existing blog yok (outputs/blog/{slug}/article. html filesystem'de bulunamıyor).
mcp__gsc__search_analytics çağrı: siteUrl={project_slug domain}, dimensions=[query, page], page filtresi {input.url}.
GSC clicks delta hesaplama: clicks_recent - clicks_previous
(content_decay.clicks_delta cross-check).
R-85 multi-signal threshold:
clicks_delta < -20% (significant drop)delta_pct < -15%trend == "down" (3-month rolling)DURUR #3 trigger: multi-signal threshold satisfied değil → revize gereksiz, master_task sync close request emit (READ-ONLY contract — bu skill kendisi master_task'a yazmaz).
projects/{slug}/project.config.json parse → profile field read
(W-F1 schema 1.2 enum 5-value varsayımı). content_settings 14
field consume (toc_strategy, ai_training_optin, byline_policy, vs.).
Profile-aware revise switch:
profile == "ymyl" → R-28 byline preserve + R-50 counter-argument
intact.profile == "e-commerce" → conversational tone preserve.profile == "local-service" → NAP signal preserve.profile == "b2b-saas" → formal tone + diagram preserve.profile == "portfolio" → showcase entity preserve.outputs/blog/{slug}/article.html BeautifulSoup parse:
<link rel="canonical"> extract → canonical_original.DURUR #6 trigger: revise içinde canonical URL change attempt → RED (R-89 immutable; URL slug change R-91 redirect path).
input.scope switch:
scope == "section" (default) → section-targeted diff zorunlu,
Step 6 devam.scope == "full" → DURUR #5 trigger (manuel approve gate; R-87
full-rewrite yasak default).Section identify (target_sections[] internal state):
Pre-revise snapshot:
word_count_pre = total visible text word count.claim_count_pre = stat/quote/fact reference count.structure_hash_pre = hash(H1+H2+H3 outline tuple).Revise generate (revision.template.md render, profile-aware tone):
target_sections[] içinde content delta compose.Post-revise snapshot:
word_count_post, claim_count_post, structure_hash_post.R-88 freshness theater check (CRITICAL):
word_delta = word_count_post - word_count_preclaim_delta = claim_count_post - claim_count_prestructure_changed = structure_hash_pre != structure_hash_postDURUR #4 trigger: word_delta == 0 AND claim_delta == 0 AND NOT structure_changed → RED (sahte tarih güncelleme; dateModified bump
YOK, çıktı discard).
AMBER warning: word_delta > 0 AND claim_delta == 0 AND NOT structure_changed → manuel review öner (style-only change).
Major revise detect:
claim_delta > 5 ORstructure_changed ORprofile_switch detected (project-config profile değişmiş eski
vs yeni snapshot).Major revise → version increment: v1 → v2 (R-103 content-
version meta increment, semver minor bump on output schema).
Minor revise (claim_delta <= 5 AND NOT structure_changed AND NOT profile_switch) → version unchanged.
dateModified update: UTC ISO 8601 now() (Article schema +
visible HTML).
canonical UNCHANGED (R-89 immutable enforce).
Output write: outputs/blog/{slug}/article.html (atomic temp+
rename).
change_summary.md format:
# Change Summary — {url}
**Revised:** 2026-XX-XXTHH:MM:SSZ
**Scope:** section
**Sections Modified:** N
**Word Delta:** +147 (1832 → 1979)
**Claim Delta:** +2 (12 → 14)
**Structure Delta:** unchanged (R-87 section-targeted)
**Version:** v1 → v2 (major revise; claim_delta=7 > 5)
**dateModified:** 2026-XX-XXTHH:MM:SSZ
**Canonical:** UNCHANGED (https://example.com/blog/post-slug)
**Profile (P2):** ymyl
## Sections Modified
1. H2 "Subheading 1" — outdated stat replaced (2024 → 2026)
2. H2 "Subheading 3" — broken link replaced
3. H2 "Subheading 5" — counter-argument added (profile=ymyl R-50)
## R-88 Freshness Theater Check
- Pre snapshot: 1832 word, 12 claim, structure_hash=abc123
- Post snapshot: 1979 word, 14 claim, structure_hash=abc123
- Result: PASS (claim_delta=2 > 0; word_delta=+147 orantılı)
## Principle 1 Truth-Verifiable Audit
- New claims: 2
- Source verified: 2/2 (R-44)
- Citations attached: 2/2 (R-105)
events.jsonl append (events.schema event_type enum):
event_type = content_reviseevent_kind = workschema_version = 1.0actor = skill:revise-contenttarget = {url}timestamp = UTC ISO 8601scope = {input.scope}version_increment = true|falseword_delta, claim_delta, structure_changed (R-88 audit
trail)canonical_preserved = true (R-89 invariant)outputs/blog/{slug}/article. html filesystem'de bulunamıyor → R-89 canonical preserve enforce
edilemez (revize için kaynak yok); kullanıcıyı new-blog skill'e
yönlendir.content_decay.action != "revise"
(prune/redirect/delete) → wrong skill; content-remediation Wave 2
domain.word_delta == 0 AND claim_delta == 0 AND NOT structure_changed → RED, sahte
tarih güncelleme; çıktı discard, dateModified bump YAPMA.input.scope == "full" →
R-87 section-targeted yasak default; manuel approve gate (skill
tek başına full-rewrite yapamaz).profile == "ymyl" ve reviewer adı verilmemiş → RED (yayın + dateModified
bump bloklu). Operatör inceleyeni adlandırmalı; skill
append_audit ile reviewer + review_date + content_version kaydını
yazar (Principle 1 Truth-Verifiable; uydurulmuş yazarlık yasak).Bu skill master.xlsx hiçbir sheet'e YAZMAZ:
master.xlsx[content_decay] allowed_writers null (F-6) → READ-
ONLY.master.xlsx[master_task] protected_columns 7 alan (task,
category, priority, impact, duration_est_min, assignee, note) →
READ-ONLY consume; revize tracking için master_task row reference
okur, yazmaz. master_task sync skill (allowed_writers içinde)
yazma sorumluluğunu taşır.Sadece şu artifact'lere yazılır (outputs § + produces §):
outputs/blog/{slug}/article.html (updated)outputs/blog/{slug}/change_summary.md (new)_state/events.jsonl (append, events.schema event_type enum)Skill content'inde proje slug hardcode YASAK. Tüm proje referansları
runtime input ({input.project_slug}, {input.url}) üzerinden
çözümlenir. URL örnekleri SKILL.md'de generic placeholder
(https://example.com/blog/post-slug) kullanır.
version: "1.0" (Phase 11 Wave 1 ilk shipping).status: wip (Phase 11 Wave 2 stabilizasyon sonrası active
promote).1.0 (events.jsonl payload + change_summary
format kontratı).npx claudepluginhub popiliadam/platinum-seo-engine --plugin platinum-seo-engineUse when: kullanıcı "yeni blog yaz", "blog üret", "content gen", "blog draft", "makale yaz", "yeni içerik üret", "new blog post", "pillar yaz", "cluster yaz" der ya da /pseo-new-blog çağırır; master.xlsx[new_content_plan] satırından plan al, SERP analiz yap, 5 template render et, JSON-LD @graph 5 entity üret, Foundational Principles 3-katman (truth-verifiable + profile-aware + anti-cheap-content) enforce et. Also use when: master.xlsx[topical_map] içinde assigned_url=null olan pillar/cluster/supporting satırı için ilk içerik üretilecek; new_content_plan satırının lifecycle_status=GREEN ya da PLANNED durumda; mode='draft' (review) veya 'publish' (immediate) seçildi; profile-aware switch tetik (project-config[profile] ya da project-config[profiles] priority merge). Do not use when: mevcut blog revize için (revise-content kullan); FAQ block re-render için (faq-optimization kullan); decay/sunset/prune için (content-remediation kullan); image generation için (generate-images kullan); manuel WordPress upload için (Section A upload-instructions template render edilir, skill upload yapmaz); master.xlsx eksikse (init-project önce çalışmalı, DURUR #1).
Rewrites blog posts for Google rankings (E-E-A-T, Dec 2025 Core Update) and AI citations (GEO/AEO). Replaces fabricated stats, adds charts/images/FAQ schema, and detects AI content.
Analyzes blog quality then rewrites with data updates, YouTube embeds, and anti-AI humanization. Invoke via /rewrite.