feat(ai-workspace): support SEO codex provider bridge
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"updatedAt": "2026-07-02",
|
||||
"aliases": [
|
||||
{ "alias": "SEO mod", "canonicalId": "seo.project" },
|
||||
{ "alias": "NDC SEO mod", "canonicalId": "seo.project" },
|
||||
{ "alias": "seo project", "canonicalId": "seo.project" },
|
||||
{ "alias": "site", "canonicalId": "seo.site" },
|
||||
{ "alias": "сайт", "canonicalId": "seo.site" },
|
||||
{ "alias": "source", "canonicalId": "seo.source" },
|
||||
{ "alias": "scan", "canonicalId": "seo.scan_version" },
|
||||
{ "alias": "scope", "canonicalId": "seo.scope_contract" },
|
||||
{ "alias": "scope contract", "canonicalId": "seo.scope_contract" },
|
||||
{ "alias": "page", "canonicalId": "seo.page" },
|
||||
{ "alias": "страница", "canonicalId": "seo.page" },
|
||||
{ "alias": "section", "canonicalId": "seo.section" },
|
||||
{ "alias": "block", "canonicalId": "seo.section" },
|
||||
{ "alias": "секция", "canonicalId": "seo.section" },
|
||||
{ "alias": "блок", "canonicalId": "seo.section" },
|
||||
{ "alias": "ProjectOntology", "canonicalId": "seo.project_ontology" },
|
||||
{ "alias": "project ontology", "canonicalId": "seo.project_ontology" },
|
||||
{ "alias": "semantic profile", "canonicalId": "seo.semantic_profile" },
|
||||
{ "alias": "intent cluster", "canonicalId": "seo.intent_cluster" },
|
||||
{ "alias": "demand universe", "canonicalId": "seo.demand_universe" },
|
||||
{ "alias": "semantic anchor", "canonicalId": "seo.semantic_anchor" },
|
||||
{ "alias": "смысловой якорь", "canonicalId": "seo.semantic_anchor" },
|
||||
{ "alias": "anchor review", "canonicalId": "seo.anchor_review" },
|
||||
{ "alias": "фиксация ключей", "canonicalId": "seo.anchor_review" },
|
||||
{ "alias": "wordstat queue", "canonicalId": "seo.wordstat_queue" },
|
||||
{ "alias": "очередь Wordstat", "canonicalId": "seo.wordstat_queue" },
|
||||
{ "alias": "seed", "canonicalId": "seo.seed_query" },
|
||||
{ "alias": "seed query", "canonicalId": "seo.seed_query" },
|
||||
{ "alias": "keyword", "canonicalId": "seo.keyword" },
|
||||
{ "alias": "ключ", "canonicalId": "seo.keyword" },
|
||||
{ "alias": "ключевик", "canonicalId": "seo.keyword" },
|
||||
{ "alias": "Wordstat signal", "canonicalId": "seo.market_signal" },
|
||||
{ "alias": "market evidence", "canonicalId": "seo.market_signal" },
|
||||
{ "alias": "keyword curation board", "canonicalId": "seo.keyword_curation_board" },
|
||||
{ "alias": "карта распределения ключей", "canonicalId": "seo.keyword_curation_board" },
|
||||
{ "alias": "keyword role", "canonicalId": "seo.keyword_role_decision" },
|
||||
{ "alias": "роль ключа", "canonicalId": "seo.keyword_role_decision" },
|
||||
{ "alias": "keyword map", "canonicalId": "seo.keyword_map" },
|
||||
{ "alias": "landing section mapping", "canonicalId": "seo.landing_section_mapping" },
|
||||
{ "alias": "маппинг посадочных", "canonicalId": "seo.landing_section_mapping" },
|
||||
{ "alias": "future landing gap", "canonicalId": "seo.future_landing_gap" },
|
||||
{ "alias": "будущая посадочная", "canonicalId": "seo.future_landing_gap" },
|
||||
{ "alias": "optimization plan", "canonicalId": "seo.optimization_plan" },
|
||||
{ "alias": "rewrite eligibility", "canonicalId": "seo.rewrite_eligibility" },
|
||||
{ "alias": "semantic block", "canonicalId": "seo.semantic_block" },
|
||||
{ "alias": "семантический блок", "canonicalId": "seo.semantic_block" },
|
||||
{ "alias": "rewrite variant", "canonicalId": "seo.rewrite_variant" },
|
||||
{ "alias": "validation result", "canonicalId": "seo.validation_result" },
|
||||
{ "alias": "change set", "canonicalId": "seo.change_set" },
|
||||
{ "alias": "changeset", "canonicalId": "seo.change_set" },
|
||||
{ "alias": "apply result", "canonicalId": "seo.apply_result" },
|
||||
{ "alias": "coverage expansion", "canonicalId": "seo.expansion_opportunity" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"updatedAt": "2026-07-02",
|
||||
"capabilities": [
|
||||
{ "id": "assistant.seo_read", "entityId": "assistant.capability", "level": "member", "summary": "Assistant can read SEO project context visible to the actor." },
|
||||
{ "id": "assistant.seo_run_analysis", "entityId": "assistant.capability", "level": "member", "summary": "Assistant can request non-destructive SEO scan, ontology extraction, semantic analysis, and evidence collection in an authorized project." },
|
||||
{ "id": "assistant.seo_plan_changes", "entityId": "assistant.capability", "level": "member", "summary": "Assistant can request anchor review, keyword curation, keyword map, optimization plan, rewrite variants, and validation previews." },
|
||||
{ "id": "assistant.seo_apply_changes", "entityId": "assistant.capability", "level": "member", "summary": "Assistant can request an SEO changeset apply only through the SEO-owned adapter, confirmation, validation, and Gateway/app scopes." }
|
||||
],
|
||||
"roleMatrix": [
|
||||
{
|
||||
"roleId": "assistant_member",
|
||||
"allowedCapabilities": [
|
||||
"assistant.seo_read",
|
||||
"assistant.seo_run_analysis",
|
||||
"assistant.seo_plan_changes",
|
||||
"assistant.seo_apply_changes"
|
||||
],
|
||||
"summary": "SEO actions are app-owned and remain bounded by SEO project permissions and Gateway scopes."
|
||||
},
|
||||
{
|
||||
"roleId": "assistant_admin",
|
||||
"allowedCapabilities": [
|
||||
"assistant.seo_read",
|
||||
"assistant.seo_run_analysis",
|
||||
"assistant.seo_plan_changes",
|
||||
"assistant.seo_apply_changes"
|
||||
],
|
||||
"summary": "Assistant admin does not bypass SEO project permissions; it only has the same SEO capabilities plus existing admin capabilities."
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"id": "assistant.op.seo_read_project",
|
||||
"capabilityId": "assistant.seo_read",
|
||||
"sourceEndpoints": ["GET /seo/projects/:projectId"],
|
||||
"requiredGuards": ["requireSeoProjectRead"],
|
||||
"summary": "Read SEO project context through SEO-owned API."
|
||||
},
|
||||
{
|
||||
"id": "assistant.op.seo_run_analysis",
|
||||
"capabilityId": "assistant.seo_run_analysis",
|
||||
"sourceEndpoints": ["POST /seo/projects/:projectId/scan", "POST /seo/projects/:projectId/analysis/semantic", "POST /seo/projects/:projectId/market/collect"],
|
||||
"requiredGuards": ["requireSeoProjectWrite"],
|
||||
"summary": "Run SEO scan and analysis through SEO-owned API."
|
||||
},
|
||||
{
|
||||
"id": "assistant.op.seo_plan_changes",
|
||||
"capabilityId": "assistant.seo_plan_changes",
|
||||
"sourceEndpoints": ["POST /seo/projects/:projectId/anchor-review", "POST /seo/projects/:projectId/keyword-map", "POST /seo/projects/:projectId/optimization-plan", "POST /seo/projects/:projectId/rewrite-variants"],
|
||||
"requiredGuards": ["requireSeoProjectWrite"],
|
||||
"summary": "Prepare anchor review, curated keyword map, SEO plan and rewrite variants without mutating target source."
|
||||
},
|
||||
{
|
||||
"id": "assistant.op.seo_apply_changes",
|
||||
"capabilityId": "assistant.seo_apply_changes",
|
||||
"sourceEndpoints": ["POST /seo/projects/:projectId/changesets/:changesetId/apply"],
|
||||
"requiredGuards": ["requireSeoProjectApply", "requireSeoFinalValidation", "requireConfirmationToken", "requireIdempotencyKey"],
|
||||
"summary": "Apply approved SEO changeset through SEO-owned adapter and safety gates."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"updatedAt": "2026-07-02",
|
||||
"apps": [
|
||||
{
|
||||
"id": "seo",
|
||||
"name": "NDC SEO mod",
|
||||
"authorityEntityIds": ["seo.project", "seo.site", "seo.scope_contract", "seo.change_set"],
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"summary": "Owns SEO project source/crawl, project ontology extraction, semantic analysis, market evidence, planning, validation, changesets, and apply/export."
|
||||
}
|
||||
],
|
||||
"actions": [
|
||||
{
|
||||
"id": "seo.project.read_context",
|
||||
"app": "seo",
|
||||
"domain": "projects",
|
||||
"intentAliases": ["show seo project", "show site seo context", "покажи seo проект", "покажи сео проект", "покажи контекст сайта"],
|
||||
"entityIds": ["seo.project", "seo.site", "seo.scope_contract", "seo.project_ontology"],
|
||||
"capabilityIds": ["assistant.seo_read"],
|
||||
"riskLevel": "read",
|
||||
"confirmationMode": "none",
|
||||
"selfActionPolicy": "allowed",
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"adapterStatus": "future",
|
||||
"summary": "Read SEO project context visible to the actor."
|
||||
},
|
||||
{
|
||||
"id": "seo.project.scan",
|
||||
"app": "seo",
|
||||
"domain": "scan",
|
||||
"intentAliases": ["scan seo project", "scan site", "run seo scan", "просканируй сайт", "запусти seo scan", "запусти скан сайта"],
|
||||
"entityIds": ["seo.project", "seo.source", "seo.scan_version"],
|
||||
"capabilityIds": ["assistant.seo_run_analysis"],
|
||||
"riskLevel": "write",
|
||||
"confirmationMode": "explicit",
|
||||
"selfActionPolicy": "allowed",
|
||||
"requiredScopes": ["seo.project.can_run_scan"],
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"adapterStatus": "future",
|
||||
"summary": "Run SEO project scan and create a new scan_version artifact."
|
||||
},
|
||||
{
|
||||
"id": "seo.ontology.extract",
|
||||
"app": "seo",
|
||||
"domain": "ontology",
|
||||
"intentAliases": ["extract project ontology", "build site ontology", "определи онтологию сайта", "собери онтологию проекта"],
|
||||
"entityIds": ["seo.project", "seo.project_ontology", "seo.semantic_profile"],
|
||||
"capabilityIds": ["assistant.seo_run_analysis"],
|
||||
"riskLevel": "write",
|
||||
"confirmationMode": "explicit",
|
||||
"selfActionPolicy": "allowed",
|
||||
"requiredScopes": ["seo.project.can_run_analysis"],
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"adapterStatus": "future",
|
||||
"summary": "Extract per-project site ontology from approved source/scope evidence."
|
||||
},
|
||||
{
|
||||
"id": "seo.semantic.analyze",
|
||||
"app": "seo",
|
||||
"domain": "semantic",
|
||||
"intentAliases": ["run semantic analysis", "analyze seo semantics", "проанализируй семантику", "запусти semantic analysis"],
|
||||
"entityIds": ["seo.semantic_profile", "seo.intent_cluster", "seo.demand_universe", "seo.semantic_anchor"],
|
||||
"capabilityIds": ["assistant.seo_run_analysis"],
|
||||
"riskLevel": "write",
|
||||
"confirmationMode": "explicit",
|
||||
"selfActionPolicy": "allowed",
|
||||
"requiredScopes": ["seo.project.can_run_analysis"],
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"adapterStatus": "future",
|
||||
"summary": "Run semantic analysis bounded by ProjectOntologyInstance and scope contract."
|
||||
},
|
||||
{
|
||||
"id": "seo.anchor_review.approve",
|
||||
"app": "seo",
|
||||
"domain": "market",
|
||||
"intentAliases": ["approve seo anchors", "approve wordstat anchors", "зафиксируй ключи", "подтверди якоря", "зафиксируй смысловые якоря"],
|
||||
"entityIds": ["seo.semantic_anchor", "seo.anchor_review", "seo.wordstat_queue"],
|
||||
"capabilityIds": ["assistant.seo_plan_changes"],
|
||||
"riskLevel": "write",
|
||||
"confirmationMode": "explicit",
|
||||
"selfActionPolicy": "allowed",
|
||||
"requiredScopes": ["seo.project.can_collect_market_evidence"],
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"adapterStatus": "future",
|
||||
"summary": "Create or update the human-approved anchor review and Wordstat queue before provider collection."
|
||||
},
|
||||
{
|
||||
"id": "seo.market.collect_wordstat",
|
||||
"app": "seo",
|
||||
"domain": "market",
|
||||
"intentAliases": ["collect wordstat", "run wordstat", "собери wordstat", "собери частотности", "запусти вордстат"],
|
||||
"entityIds": ["seo.anchor_review", "seo.wordstat_queue", "seo.seed_query", "seo.market_signal", "seo.keyword"],
|
||||
"capabilityIds": ["assistant.seo_run_analysis"],
|
||||
"riskLevel": "write",
|
||||
"confirmationMode": "explicit",
|
||||
"selfActionPolicy": "allowed",
|
||||
"requiredScopes": ["seo.project.can_collect_market_evidence"],
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"adapterStatus": "future",
|
||||
"summary": "Collect Wordstat market evidence only for the human-approved Wordstat queue."
|
||||
},
|
||||
{
|
||||
"id": "seo.keyword.curate",
|
||||
"app": "seo",
|
||||
"domain": "keywords",
|
||||
"intentAliases": ["curate keywords", "sort keyword board", "распредели вес ключей", "разложи ключи", "отсортируй ключи"],
|
||||
"entityIds": ["seo.keyword", "seo.keyword_curation_board", "seo.keyword_role_decision"],
|
||||
"capabilityIds": ["assistant.seo_plan_changes"],
|
||||
"riskLevel": "write",
|
||||
"confirmationMode": "explicit",
|
||||
"selfActionPolicy": "allowed",
|
||||
"requiredScopes": ["seo.project.can_plan_changes"],
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"adapterStatus": "future",
|
||||
"summary": "Pre-sort external keyword candidates into unresolved, landing core, supporting core, differentiators, or long tail lanes for human review."
|
||||
},
|
||||
{
|
||||
"id": "seo.keyword.map",
|
||||
"app": "seo",
|
||||
"domain": "keywords",
|
||||
"intentAliases": ["build keyword map", "map keywords", "собери keyword map", "распредели ключи", "составь карту ключей"],
|
||||
"entityIds": ["seo.keyword", "seo.keyword_curation_board", "seo.keyword_role_decision", "seo.keyword_map", "seo.scope_item"],
|
||||
"capabilityIds": ["assistant.seo_plan_changes"],
|
||||
"riskLevel": "write",
|
||||
"confirmationMode": "explicit",
|
||||
"selfActionPolicy": "allowed",
|
||||
"requiredScopes": ["seo.project.can_plan_changes"],
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"adapterStatus": "future",
|
||||
"summary": "Build keyword map from curated keyword role decisions and approved scope items."
|
||||
},
|
||||
{
|
||||
"id": "seo.mapping.approve",
|
||||
"app": "seo",
|
||||
"domain": "plan",
|
||||
"intentAliases": ["approve landing mapping", "approve section mapping", "утверди посадочные", "утверди маппинг секций"],
|
||||
"entityIds": ["seo.keyword_map", "seo.landing_section_mapping", "seo.future_landing_gap", "seo.scope_item"],
|
||||
"capabilityIds": ["assistant.seo_plan_changes"],
|
||||
"riskLevel": "write",
|
||||
"confirmationMode": "explicit",
|
||||
"selfActionPolicy": "allowed",
|
||||
"requiredScopes": ["seo.project.can_plan_changes"],
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"adapterStatus": "future",
|
||||
"summary": "Approve keyword landing/section mapping and keep future landing gaps non-blocking until explicit promotion."
|
||||
},
|
||||
{
|
||||
"id": "seo.plan.build",
|
||||
"app": "seo",
|
||||
"domain": "plan",
|
||||
"intentAliases": ["build optimization plan", "prepare seo plan", "собери план оптимизации", "подготовь seo план"],
|
||||
"entityIds": ["seo.keyword_map", "seo.landing_section_mapping", "seo.future_landing_gap", "seo.optimization_plan", "seo.scope_contract"],
|
||||
"capabilityIds": ["assistant.seo_plan_changes"],
|
||||
"riskLevel": "write",
|
||||
"confirmationMode": "explicit",
|
||||
"selfActionPolicy": "allowed",
|
||||
"requiredScopes": ["seo.project.can_plan_changes"],
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"adapterStatus": "future",
|
||||
"summary": "Build SEO optimization plan before rewrite."
|
||||
},
|
||||
{
|
||||
"id": "seo.rewrite.propose",
|
||||
"app": "seo",
|
||||
"domain": "rewrite",
|
||||
"intentAliases": ["propose rewrite variants", "generate seo variants", "предложи варианты текста", "сгенерируй rewrite variants"],
|
||||
"entityIds": ["seo.optimization_plan", "seo.rewrite_eligibility", "seo.semantic_block", "seo.rewrite_variant"],
|
||||
"capabilityIds": ["assistant.seo_plan_changes"],
|
||||
"riskLevel": "write",
|
||||
"confirmationMode": "explicit",
|
||||
"selfActionPolicy": "allowed",
|
||||
"requiredScopes": ["seo.project.can_plan_changes"],
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"adapterStatus": "future",
|
||||
"summary": "Generate rewrite variants into working draft only."
|
||||
},
|
||||
{
|
||||
"id": "seo.validation.run",
|
||||
"app": "seo",
|
||||
"domain": "validation",
|
||||
"intentAliases": ["run seo validation", "validate seo changes", "проверь seo изменения", "запусти финальную проверку"],
|
||||
"entityIds": ["seo.validation_result", "seo.change_set", "seo.rewrite_variant"],
|
||||
"capabilityIds": ["assistant.seo_plan_changes"],
|
||||
"riskLevel": "write",
|
||||
"confirmationMode": "explicit",
|
||||
"selfActionPolicy": "allowed",
|
||||
"requiredScopes": ["seo.project.can_validate_changes"],
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"adapterStatus": "future",
|
||||
"summary": "Run final SEO validation before changeset apply/export."
|
||||
},
|
||||
{
|
||||
"id": "seo.change_set.preview",
|
||||
"app": "seo",
|
||||
"domain": "changesets",
|
||||
"intentAliases": ["preview seo changeset", "show seo diff", "покажи seo diff", "покажи changeset"],
|
||||
"entityIds": ["seo.change_set", "seo.validation_result"],
|
||||
"capabilityIds": ["assistant.seo_read"],
|
||||
"riskLevel": "read",
|
||||
"confirmationMode": "none",
|
||||
"selfActionPolicy": "allowed",
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"adapterStatus": "future",
|
||||
"summary": "Preview SEO changeset and validation state without applying changes."
|
||||
},
|
||||
{
|
||||
"id": "seo.change_set.apply",
|
||||
"app": "seo",
|
||||
"domain": "changesets",
|
||||
"intentAliases": ["apply seo changes", "apply seo changeset", "примени seo изменения", "примени changeset"],
|
||||
"entityIds": ["seo.change_set", "seo.validation_result", "seo.apply_result"],
|
||||
"capabilityIds": ["assistant.seo_apply_changes"],
|
||||
"riskLevel": "write",
|
||||
"confirmationMode": "explicit",
|
||||
"selfActionPolicy": "allowed",
|
||||
"requiredScopes": ["seo.project.can_apply_change_set"],
|
||||
"adapterId": "adapter.seo.module_api",
|
||||
"adapterStatus": "future",
|
||||
"summary": "Apply an approved SEO changeset through SEO-owned adapter after validation, backup, idempotency, and explicit confirmation."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"updatedAt": "2026-06-28",
|
||||
"contexts": [],
|
||||
"bindingTypes": [
|
||||
{
|
||||
"id": "binding_type.seo_project_to_ops_context",
|
||||
"relationId": "ontology.resolves_seo_project_to_ops_context",
|
||||
"fromEntityIds": ["seo.project"],
|
||||
"toEntityIds": ["ops.project", "ops.card"],
|
||||
"requiredFromRefs": ["seo_project_id"],
|
||||
"requiredToRefs": ["workspace_slug", "project_id"],
|
||||
"summary": "Binds an SEO project to its OPS Product project/card context."
|
||||
},
|
||||
{
|
||||
"id": "binding_type.ops_context_to_seo_project",
|
||||
"relationId": "ontology.resolves_ops_context_to_seo_project",
|
||||
"fromEntityIds": ["ops.project", "ops.card"],
|
||||
"toEntityIds": ["seo.project"],
|
||||
"requiredFromRefs": ["workspace_slug", "project_id"],
|
||||
"requiredToRefs": ["seo_project_id"],
|
||||
"summary": "Binds OPS Product context to an SEO project."
|
||||
},
|
||||
{
|
||||
"id": "binding_type.hub_app_to_seo_project",
|
||||
"relationId": "ontology.resolves_hub_app_to_seo_project",
|
||||
"fromEntityIds": ["hub.application"],
|
||||
"toEntityIds": ["seo.project"],
|
||||
"requiredFromRefs": ["application_id"],
|
||||
"requiredToRefs": ["seo_project_id"],
|
||||
"summary": "Binds a HUB/Launcher app entry to SEO module project context."
|
||||
}
|
||||
],
|
||||
"bindings": []
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"updatedAt": "2026-07-02",
|
||||
"entities": [
|
||||
{ "id": "seo.project", "name": "SEO Project", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "SEO module project boundary for one connected site/source and its analysis history." },
|
||||
{ "id": "seo.site", "name": "SEO Site", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Analyzed website as seen through source import and/or live crawl." },
|
||||
{ "id": "seo.source", "name": "SEO Source", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Input source: local folder, uploaded package, browser-folder import, repository, or live URL crawl." },
|
||||
{ "id": "seo.scan_version", "name": "SEO Scan Version", "surface": "seo", "status": ["source-evidenced"], "authority": "NDC SEO mod", "summary": "Immutable scan boundary for project index, pages, media, and derived scope." },
|
||||
{ "id": "seo.scope_contract", "name": "SEO Scope Contract", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "User-approved working scope consumed consistently by analysis, planning, rewrite, validation, and apply." },
|
||||
{ "id": "seo.scope_item", "name": "SEO Scope Item", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "One selectable work zone: URL page, generated section, template block, admin page, technical page, content source, or hidden section." },
|
||||
{ "id": "seo.page", "name": "SEO Page", "surface": "seo", "status": ["source-evidenced"], "authority": "NDC SEO mod", "summary": "Logical page or route-level SEO target." },
|
||||
{ "id": "seo.section", "name": "SEO Section", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Stable section/block identity under a page or template, not a fragile DOM selector." },
|
||||
{ "id": "seo.media_asset", "name": "SEO Media Asset", "surface": "seo", "status": ["source-evidenced"], "authority": "NDC SEO mod", "summary": "Image, video, poster, picture/srcset source, CSS background, or other media target with SEO metadata." },
|
||||
{ "id": "seo.project_ontology", "name": "SEO Project Ontology Instance", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod + Ontology Core", "summary": "Versioned per-project site ontology extracted from evidence and aligned with Ontology Core." },
|
||||
{ "id": "seo.semantic_profile", "name": "SEO Semantic Profile", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Structured meaning, tone, entities, intents, gaps, and constraints extracted from selected scope." },
|
||||
{ "id": "seo.intent_cluster", "name": "SEO Intent Cluster", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Search/user intent cluster grounded in project ontology and site evidence." },
|
||||
{ "id": "seo.demand_universe", "name": "SEO Demand Universe", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod + model provider", "summary": "Broad pre-Wordstat meaning and query hypothesis set derived from project context before external evidence collection." },
|
||||
{ "id": "seo.semantic_anchor", "name": "SEO Semantic Anchor", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod + model provider", "summary": "Human-reviewable meaning anchor extracted from project context and used as the only allowed route into Wordstat/SERP queues." },
|
||||
{ "id": "seo.anchor_review", "name": "SEO Anchor Review", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Human approval gate that decides which semantic anchors may be sent to external market evidence providers." },
|
||||
{ "id": "seo.wordstat_queue", "name": "SEO Wordstat Queue", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Explicit queue of human-approved anchor phrases sent to Wordstat evidence collection." },
|
||||
{ "id": "seo.seed_query", "name": "SEO Seed Query", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Candidate phrase sent to market evidence providers after user/model review." },
|
||||
{ "id": "seo.keyword", "name": "SEO Keyword", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Cleaned and classified search phrase with project-level decision state." },
|
||||
{ "id": "seo.market_signal", "name": "SEO Market Signal", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod + external providers", "summary": "Wordstat, SERP, Webmaster, Metrica, or model evidence attached to project-level decisions." },
|
||||
{ "id": "seo.keyword_curation_board", "name": "SEO Keyword Curation Board", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Human-in-the-loop board where external keyword candidates are sorted into SEO roles before strategy." },
|
||||
{ "id": "seo.keyword_role_decision", "name": "SEO Keyword Role Decision", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "User/model-assisted role assignment for a keyword: unresolved, landing core, supporting core, differentiator, or long tail." },
|
||||
{ "id": "seo.keyword_map", "name": "SEO Keyword Map", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Approved mapping from keywords to pages/sections with roles and limits." },
|
||||
{ "id": "seo.landing_section_mapping", "name": "SEO Landing Section Mapping", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Human-approved mapping from curated keyword groups to existing pages, sections, or future landing gaps." },
|
||||
{ "id": "seo.future_landing_gap", "name": "SEO Future Landing Gap", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Non-blocking strategy gap for a potential future landing that must not be materialized or rewritten without explicit promotion." },
|
||||
{ "id": "seo.optimization_plan", "name": "SEO Optimization Plan", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Approved plan of text/meta/media/schema tasks before rewrite." },
|
||||
{ "id": "seo.rewrite_eligibility", "name": "SEO Rewrite Eligibility", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Gate proving that a rewrite target is an approved existing page/section/content-field binding rather than a future gap." },
|
||||
{ "id": "seo.semantic_block", "name": "SEO Semantic Block", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Persisted semantic grouping of page content targets used for block-level rewrite proposals." },
|
||||
{ "id": "seo.rewrite_variant", "name": "SEO Rewrite Variant", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod + model provider", "summary": "Generated optimization variant over working text, not a direct source mutation." },
|
||||
{ "id": "seo.validation_result", "name": "SEO Validation Result", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Final validation output: deterministic checks, over-SEO, language quality, media checks, and hard/soft issues." },
|
||||
{ "id": "seo.change_set", "name": "SEO Change Set", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Explicit diff/apply unit with dry-run, backup, rollback, and export boundaries." },
|
||||
{ "id": "seo.apply_result", "name": "SEO Apply Result", "surface": "seo", "status": ["product-required"], "authority": "NDC SEO mod", "summary": "Result of app-owned apply/export action after confirmation and validation." },
|
||||
{ "id": "seo.expansion_opportunity", "name": "SEO Expansion Opportunity", "surface": "seo", "status": ["future-concept"], "authority": "NDC SEO mod", "summary": "Optional future coverage/growth suggestion after core analysis and market evidence, not part of the current ontology slice." }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"updatedAt": "2026-07-02",
|
||||
"sourceRoots": [
|
||||
{
|
||||
"surface": "seo",
|
||||
"path": "/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_SEO/seo_mode/seo_mode",
|
||||
"mode": "read-only architecture/source inspection"
|
||||
}
|
||||
],
|
||||
"ledgers": [
|
||||
{
|
||||
"id": "ledger.seo_domain_v0",
|
||||
"path": "docs/SEO_DOMAIN_ONTOLOGY.md",
|
||||
"entityIds": [
|
||||
"seo.project",
|
||||
"seo.scope_contract",
|
||||
"seo.project_ontology",
|
||||
"seo.semantic_profile",
|
||||
"seo.semantic_anchor",
|
||||
"seo.anchor_review",
|
||||
"seo.wordstat_queue",
|
||||
"seo.market_signal",
|
||||
"seo.keyword_curation_board",
|
||||
"seo.landing_section_mapping",
|
||||
"seo.future_landing_gap",
|
||||
"seo.change_set"
|
||||
]
|
||||
}
|
||||
],
|
||||
"baselineDocs": [
|
||||
"docs/SEO_DOMAIN_ONTOLOGY.md"
|
||||
],
|
||||
"restrictions": [
|
||||
"Do not promote per-project SEO keywords or market rows into global ontology truth.",
|
||||
"Do not let Ontology Core execute SEO source mutations.",
|
||||
"Do not implement optional business expansion before core SEO pipeline evidence is proven."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"updatedAt": "2026-07-02",
|
||||
"rules": [
|
||||
{
|
||||
"id": "guardrail.seo.project_ontology_not_global_truth",
|
||||
"severity": "error",
|
||||
"summary": "Per-project SEO ontology is versioned project evidence; it must not be silently promoted into global Ontology Core truth.",
|
||||
"entityIds": ["seo.project_ontology", "future.domain_package"]
|
||||
},
|
||||
{
|
||||
"id": "guardrail.seo.keywords_are_project_evidence",
|
||||
"severity": "error",
|
||||
"summary": "Keywords, Wordstat rows, SERP rows, and forecasts are project evidence, not reusable ontology roots.",
|
||||
"entityIds": ["seo.keyword", "seo.market_signal", "seo.project_ontology"]
|
||||
},
|
||||
{
|
||||
"id": "guardrail.seo.scope_contract_required",
|
||||
"severity": "error",
|
||||
"summary": "Semantic analysis, keyword map, rewrite, validation, and changeset must be bounded by an approved scope contract.",
|
||||
"entityIds": ["seo.scope_contract", "seo.scope_item", "seo.semantic_profile", "seo.change_set"]
|
||||
},
|
||||
{
|
||||
"id": "guardrail.seo.wordstat_requires_anchor_review",
|
||||
"severity": "error",
|
||||
"summary": "Wordstat/SERP collection must use only human-approved semantic anchors from anchor review, never raw site text or model auto proposals.",
|
||||
"entityIds": ["seo.semantic_anchor", "seo.anchor_review", "seo.wordstat_queue", "seo.market_signal"]
|
||||
},
|
||||
{
|
||||
"id": "guardrail.seo.strategy_requires_curated_keywords",
|
||||
"severity": "error",
|
||||
"summary": "Strategy and optimization plan must consume curated keyword role decisions, not raw provider rows or unreviewed normalization output.",
|
||||
"entityIds": ["seo.keyword_curation_board", "seo.keyword_role_decision", "seo.keyword_map", "seo.optimization_plan"]
|
||||
},
|
||||
{
|
||||
"id": "guardrail.seo.future_landing_gap_non_blocking",
|
||||
"severity": "error",
|
||||
"summary": "Future landing gaps are strategy context only; they must not force materialization, rewrite, or random existing page selection without explicit promotion.",
|
||||
"entityIds": ["seo.future_landing_gap", "seo.landing_section_mapping", "seo.rewrite_eligibility", "seo.rewrite_variant"]
|
||||
},
|
||||
{
|
||||
"id": "guardrail.seo.rewrite_requires_existing_binding",
|
||||
"severity": "error",
|
||||
"summary": "Rewrite variants require approved existing page/section/content-field bindings and must not be generated for unresolved future gaps.",
|
||||
"entityIds": ["seo.rewrite_eligibility", "seo.semantic_block", "seo.section", "seo.rewrite_variant"]
|
||||
},
|
||||
{
|
||||
"id": "guardrail.seo.apply_requires_validation",
|
||||
"severity": "error",
|
||||
"summary": "SEO apply/export requires explicit changeset, final validation, dry-run/backup boundary, and app-owned adapter execution.",
|
||||
"entityIds": ["seo.change_set", "seo.validation_result", "seo.apply_result", "assistant.action"]
|
||||
},
|
||||
{
|
||||
"id": "guardrail.seo.ontology_core_does_not_apply",
|
||||
"severity": "error",
|
||||
"summary": "Ontology Core may resolve SEO action context but must not mutate site sources or execute SEO apply.",
|
||||
"entityIds": ["seo.change_set", "assistant.action", "agent.scope", "agent.audit_event"]
|
||||
},
|
||||
{
|
||||
"id": "guardrail.seo.expansion_is_future_optional_branch",
|
||||
"severity": "warning",
|
||||
"summary": "Expansion opportunities are a future optional branch after core analysis and market evidence; they must not replace current site context by default.",
|
||||
"entityIds": ["seo.expansion_opportunity", "seo.market_signal", "seo.optimization_plan"]
|
||||
}
|
||||
],
|
||||
"blockedConflations": [
|
||||
["seo.project_ontology", "future.domain_package"],
|
||||
["seo.keyword", "future.domain_package"],
|
||||
["seo.semantic_anchor", "seo.market_signal"],
|
||||
["seo.anchor_review", "seo.market_signal"],
|
||||
["seo.market_signal", "seo.intent_cluster"],
|
||||
["seo.keyword_curation_board", "seo.keyword_map"],
|
||||
["seo.future_landing_gap", "seo.page"],
|
||||
["seo.expansion_opportunity", "seo.optimization_plan"],
|
||||
["seo.change_set", "assistant.action"]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"id": "seo",
|
||||
"version": "0.1.0",
|
||||
"updatedAt": "2026-06-28",
|
||||
"status": "product-required/pending-source-pass",
|
||||
"summary": "SEO module domain ontology package for site scans, project ontology, scope contracts, semantic analysis, market evidence, optimization plans, validation, and changesets."
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://nodedc.local/ontology/seo/project-ontology.schema.json",
|
||||
"title": "SEO Project Ontology Instance",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"schemaVersion",
|
||||
"projectId",
|
||||
"siteId",
|
||||
"coreOntologyVersion",
|
||||
"seoDomainPackageVersion",
|
||||
"source",
|
||||
"scope",
|
||||
"brand",
|
||||
"pages",
|
||||
"sections",
|
||||
"intentClusters",
|
||||
"tone",
|
||||
"constraints",
|
||||
"evidence",
|
||||
"approvals"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"schemaVersion": { "const": "seo-project-ontology.v1" },
|
||||
"projectId": { "type": "string", "minLength": 1 },
|
||||
"siteId": { "type": "string", "minLength": 1 },
|
||||
"coreOntologyVersion": { "type": "string", "minLength": 1 },
|
||||
"seoDomainPackageVersion": { "type": "string", "minLength": 1 },
|
||||
"source": {
|
||||
"type": "object",
|
||||
"required": ["sourceType", "scanVersionId"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"sourceType": {
|
||||
"type": "string",
|
||||
"enum": ["local_folder", "browser_folder", "uploaded_package", "repository", "live_crawl"]
|
||||
},
|
||||
"scanVersionId": { "type": "string", "minLength": 1 },
|
||||
"rootUrl": { "type": ["string", "null"] },
|
||||
"sourcePath": { "type": ["string", "null"] }
|
||||
}
|
||||
},
|
||||
"scope": {
|
||||
"type": "object",
|
||||
"required": ["scopeContractId", "scopeItemIds"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"scopeContractId": { "type": "string", "minLength": 1 },
|
||||
"scopeItemIds": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "minLength": 1 },
|
||||
"uniqueItems": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"brand": {
|
||||
"type": "object",
|
||||
"required": ["name", "aliases", "description"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": { "type": "string", "minLength": 1 },
|
||||
"aliases": { "type": "array", "items": { "type": "string" } },
|
||||
"description": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"offers": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/$defs/namedEvidenceItem" }
|
||||
},
|
||||
"audiences": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/$defs/namedEvidenceItem" }
|
||||
},
|
||||
"pages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["id", "url", "title", "evidenceIds"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"id": { "type": "string", "minLength": 1 },
|
||||
"url": { "type": "string" },
|
||||
"title": { "type": "string" },
|
||||
"evidenceIds": { "$ref": "#/$defs/evidenceIds" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"sections": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["id", "pageId", "title", "meaning", "evidenceIds"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"id": { "type": "string", "minLength": 1 },
|
||||
"pageId": { "type": "string", "minLength": 1 },
|
||||
"title": { "type": "string" },
|
||||
"meaning": { "type": "string" },
|
||||
"evidenceIds": { "$ref": "#/$defs/evidenceIds" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"intentClusters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["id", "title", "priority", "targetIntent", "seedQueries", "evidenceIds"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"id": { "type": "string", "minLength": 1 },
|
||||
"title": { "type": "string", "minLength": 1 },
|
||||
"priority": { "type": "string", "enum": ["high", "medium", "low"] },
|
||||
"targetIntent": { "type": "string" },
|
||||
"seedQueries": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "minLength": 1 }
|
||||
},
|
||||
"evidenceIds": { "$ref": "#/$defs/evidenceIds" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"tone": {
|
||||
"type": "object",
|
||||
"required": ["language", "signals", "forbiddenShifts"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"language": { "type": "string" },
|
||||
"signals": { "type": "array", "items": { "type": "string" } },
|
||||
"forbiddenShifts": { "type": "array", "items": { "type": "string" } }
|
||||
}
|
||||
},
|
||||
"constraints": {
|
||||
"type": "object",
|
||||
"required": ["forbiddenTopics", "forbiddenClaims", "mustKeep"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"forbiddenTopics": { "type": "array", "items": { "type": "string" } },
|
||||
"forbiddenClaims": { "type": "array", "items": { "type": "string" } },
|
||||
"mustKeep": { "type": "array", "items": { "type": "string" } }
|
||||
}
|
||||
},
|
||||
"evidence": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["id", "sourceType", "ref", "summary"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"id": { "type": "string", "minLength": 1 },
|
||||
"sourceType": { "type": "string" },
|
||||
"ref": { "type": "string" },
|
||||
"summary": { "type": "string" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"approvals": {
|
||||
"type": "object",
|
||||
"required": ["status", "approvedBy", "approvedAt"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["draft", "approved", "rejected", "needs_review"] },
|
||||
"approvedBy": { "type": ["string", "null"] },
|
||||
"approvedAt": { "type": ["string", "null"] }
|
||||
}
|
||||
},
|
||||
"ontologyDeltaProposals": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["id", "target", "summary", "status"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"id": { "type": "string", "minLength": 1 },
|
||||
"target": { "type": "string", "enum": ["core", "seo_domain", "project_only"] },
|
||||
"summary": { "type": "string" },
|
||||
"status": { "type": "string", "enum": ["proposed", "accepted", "rejected", "deferred"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"evidenceIds": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "minLength": 1 },
|
||||
"uniqueItems": true
|
||||
},
|
||||
"namedEvidenceItem": {
|
||||
"type": "object",
|
||||
"required": ["id", "name", "summary", "evidenceIds"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"id": { "type": "string", "minLength": 1 },
|
||||
"name": { "type": "string", "minLength": 1 },
|
||||
"summary": { "type": "string" },
|
||||
"evidenceIds": { "$ref": "#/$defs/evidenceIds" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"updatedAt": "2026-07-02",
|
||||
"relations": [
|
||||
{ "id": "seo.project.has_site", "from": ["seo.project"], "to": ["seo.site"], "status": "product-required", "summary": "SEO project analyzes one or more site contexts." },
|
||||
{ "id": "seo.project.uses_source", "from": ["seo.project"], "to": ["seo.source"], "status": "product-required", "summary": "SEO project is connected to import/crawl source." },
|
||||
{ "id": "seo.project.has_project_ontology", "from": ["seo.project"], "to": ["seo.project_ontology"], "status": "product-required", "summary": "Per-project ontology profile belongs to SEO project." },
|
||||
{ "id": "seo.source.produces_scan_version", "from": ["seo.source"], "to": ["seo.scan_version"], "status": "product-required", "summary": "Source import/crawl creates immutable scan version." },
|
||||
{ "id": "seo.scan_version.produces_scope_contract", "from": ["seo.scan_version"], "to": ["seo.scope_contract"], "status": "product-required", "summary": "Scan and user configuration produce approved scope contract." },
|
||||
{ "id": "seo.scope_contract.contains_scope_item", "from": ["seo.scope_contract"], "to": ["seo.scope_item"], "status": "product-required", "summary": "Scope contract is composed of selected work zones." },
|
||||
{ "id": "seo.scope_item.targets_page", "from": ["seo.scope_item"], "to": ["seo.page"], "status": "product-required", "summary": "Scope item can target a logical page." },
|
||||
{ "id": "seo.scope_item.targets_section", "from": ["seo.scope_item"], "to": ["seo.section"], "status": "product-required", "summary": "Scope item can target a stable section/block." },
|
||||
{ "id": "seo.site.has_page", "from": ["seo.site"], "to": ["seo.page"], "status": "product-required", "summary": "Site contains logical pages/routes." },
|
||||
{ "id": "seo.page.has_section", "from": ["seo.page"], "to": ["seo.section"], "status": "product-required", "summary": "Page can contain stable sections/blocks." },
|
||||
{ "id": "seo.section.contains_media", "from": ["seo.section"], "to": ["seo.media_asset"], "status": "product-required", "summary": "Media is attached to a section when context can be resolved." },
|
||||
{ "id": "seo.semantic_profile.uses_project_ontology", "from": ["seo.semantic_profile"], "to": ["seo.project_ontology"], "status": "product-required", "summary": "Semantic analysis is grounded in per-project ontology." },
|
||||
{ "id": "seo.semantic_profile.describes_scope_contract", "from": ["seo.semantic_profile"], "to": ["seo.scope_contract"], "status": "product-required", "summary": "Semantic profile describes selected work scope, not arbitrary site fantasy." },
|
||||
{ "id": "seo.semantic_profile.produces_demand_universe", "from": ["seo.semantic_profile"], "to": ["seo.demand_universe"], "status": "product-required", "summary": "Selected project context produces a broad demand universe before provider calls." },
|
||||
{ "id": "seo.demand_universe.contains_semantic_anchor", "from": ["seo.demand_universe"], "to": ["seo.semantic_anchor"], "status": "product-required", "summary": "Demand universe contains semantic anchors that can be reviewed for market routing." },
|
||||
{ "id": "seo.semantic_anchor.requires_anchor_review", "from": ["seo.semantic_anchor"], "to": ["seo.anchor_review"], "status": "product-required", "summary": "A semantic anchor cannot enter Wordstat/SERP routing before human anchor review." },
|
||||
{ "id": "seo.anchor_review.approves_wordstat_queue", "from": ["seo.anchor_review"], "to": ["seo.wordstat_queue"], "status": "product-required", "summary": "Anchor review creates the explicit Wordstat queue from approved anchors." },
|
||||
{ "id": "seo.intent_cluster.suggests_seed_query", "from": ["seo.intent_cluster"], "to": ["seo.seed_query"], "status": "product-required", "summary": "Intent cluster can suggest seed queries for evidence collection." },
|
||||
{ "id": "seo.wordstat_queue.contains_seed_query", "from": ["seo.wordstat_queue"], "to": ["seo.seed_query"], "status": "product-required", "summary": "Only human-approved Wordstat queue items become executable seed queries." },
|
||||
{ "id": "seo.wordstat_queue.produces_market_signal", "from": ["seo.wordstat_queue"], "to": ["seo.market_signal"], "status": "product-required", "summary": "Wordstat collection stores provider results as market signals tied to the approved queue." },
|
||||
{ "id": "seo.seed_query.expands_to_keyword", "from": ["seo.seed_query"], "to": ["seo.keyword"], "status": "product-required", "summary": "Approved seed query can produce cleaned keyword candidates." },
|
||||
{ "id": "seo.keyword.validated_by_market_signal", "from": ["seo.keyword"], "to": ["seo.market_signal"], "status": "product-required", "summary": "Keyword decisions require market evidence when available." },
|
||||
{ "id": "seo.keyword_curation_board.classifies_keyword", "from": ["seo.keyword_curation_board"], "to": ["seo.keyword_role_decision", "seo.keyword"], "status": "product-required", "summary": "Keyword curation board assigns human-reviewed roles to keyword candidates." },
|
||||
{ "id": "seo.keyword_role_decision.produces_keyword_map", "from": ["seo.keyword_role_decision"], "to": ["seo.keyword_map"], "status": "product-required", "summary": "Only curated keyword role decisions can feed the keyword map used by strategy." },
|
||||
{ "id": "seo.keyword_map.assigns_keyword", "from": ["seo.keyword_map"], "to": ["seo.keyword", "seo.scope_item"], "status": "product-required", "summary": "Keyword map assigns keywords to approved scope items." },
|
||||
{ "id": "seo.keyword_map.requires_landing_section_mapping", "from": ["seo.keyword_map"], "to": ["seo.landing_section_mapping"], "status": "product-required", "summary": "Keyword map must be resolved to approved existing pages/sections or explicit future gaps before rewrite." },
|
||||
{ "id": "seo.landing_section_mapping.maps_keyword_to_scope_item", "from": ["seo.landing_section_mapping"], "to": ["seo.keyword", "seo.scope_item"], "status": "product-required", "summary": "Landing/section mapping binds curated keywords to existing approved scope items." },
|
||||
{ "id": "seo.landing_section_mapping.identifies_future_gap", "from": ["seo.landing_section_mapping"], "to": ["seo.future_landing_gap"], "status": "product-required", "summary": "A mapping can explicitly mark a keyword group as a non-blocking future landing gap." },
|
||||
{ "id": "seo.optimization_plan.uses_keyword_map", "from": ["seo.optimization_plan"], "to": ["seo.keyword_map"], "status": "product-required", "summary": "Optimization plan is based on approved keyword map." },
|
||||
{ "id": "seo.optimization_plan.targets_scope_contract", "from": ["seo.optimization_plan"], "to": ["seo.scope_contract"], "status": "product-required", "summary": "Optimization plan targets approved scope contract." },
|
||||
{ "id": "seo.rewrite_eligibility.requires_landing_section_mapping", "from": ["seo.rewrite_eligibility"], "to": ["seo.landing_section_mapping"], "status": "product-required", "summary": "Rewrite eligibility requires an approved mapping to an existing source-backed target." },
|
||||
{ "id": "seo.semantic_block.groups_section", "from": ["seo.semantic_block"], "to": ["seo.section", "seo.scope_item"], "status": "product-required", "summary": "Semantic blocks group source-backed sections/scope items for block-level rewrite proposals." },
|
||||
{ "id": "seo.rewrite_variant.requires_rewrite_eligibility", "from": ["seo.rewrite_variant"], "to": ["seo.rewrite_eligibility", "seo.semantic_block"], "status": "product-required", "summary": "Rewrite variants can be proposed only for eligible existing bindings, optionally grouped by semantic block." },
|
||||
{ "id": "seo.rewrite_variant.generated_from_plan", "from": ["seo.rewrite_variant"], "to": ["seo.optimization_plan"], "status": "product-required", "summary": "Rewrite variant is generated from approved optimization plan." },
|
||||
{ "id": "seo.validation_result.validates_change_set", "from": ["seo.validation_result"], "to": ["seo.change_set"], "status": "product-required", "summary": "Change set must be validated before apply." },
|
||||
{ "id": "seo.change_set.applies_to_scope_contract", "from": ["seo.change_set"], "to": ["seo.scope_contract"], "status": "product-required", "summary": "Change set is bounded by approved scope contract." },
|
||||
{ "id": "seo.change_set.produces_apply_result", "from": ["seo.change_set"], "to": ["seo.apply_result"], "status": "product-required", "summary": "Apply/export produces a traceable result." },
|
||||
{ "id": "seo.expansion_opportunity.requires_market_signal", "from": ["seo.expansion_opportunity"], "to": ["seo.market_signal"], "status": "future-concept", "summary": "Future expansion proposals must be grounded in market evidence." },
|
||||
{ "id": "ontology.resolves_seo_project_to_ops_context", "from": ["seo.project"], "to": ["ops.project", "ops.card"], "status": "product-required", "summary": "Assistant can route SEO project work to the correct OPS Product context." },
|
||||
{ "id": "ontology.resolves_ops_context_to_seo_project", "from": ["ops.project", "ops.card"], "to": ["seo.project"], "status": "product-required", "summary": "Assistant can route OPS Product context into SEO module project context when bound." },
|
||||
{ "id": "ontology.resolves_hub_app_to_seo_project", "from": ["hub.application"], "to": ["seo.project"], "status": "product-required", "summary": "Launcher/HUB application context can suggest SEO module project context." }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"updatedAt": "2026-06-28",
|
||||
"rules": [
|
||||
{
|
||||
"id": "resolver.seo_to_ops.project_context",
|
||||
"relationId": "ontology.resolves_seo_project_to_ops_context",
|
||||
"fromSurface": "seo",
|
||||
"inputEntityIds": ["seo.project", "seo.site", "seo.scope_contract"],
|
||||
"intentHints": ["ops", "card", "task", "issue", "project", "report", "карточ", "задач", "отчет"],
|
||||
"outputSurface": "ops",
|
||||
"outputEntityIds": ["ops.workspace", "ops.project", "ops.card", "ops.card_type"],
|
||||
"requiredBindings": ["seo.project -> ops.project|ops.card context"],
|
||||
"status": "product-required",
|
||||
"summary": "Route SEO module project context into OPS Product work context."
|
||||
},
|
||||
{
|
||||
"id": "resolver.ops_to_seo.project_context",
|
||||
"relationId": "ontology.resolves_ops_context_to_seo_project",
|
||||
"fromSurface": "ops",
|
||||
"inputEntityIds": ["ops.project", "ops.card"],
|
||||
"intentHints": ["seo", "site", "semantic", "wordstat", "keyword", "rewrite", "validation", "сео", "сайт", "семантик"],
|
||||
"outputSurface": "seo",
|
||||
"outputEntityIds": ["seo.project", "seo.site", "seo.scope_contract", "seo.project_ontology"],
|
||||
"requiredBindings": ["ops.project|ops.card -> seo.project context"],
|
||||
"status": "product-required",
|
||||
"summary": "Route OPS Product context into SEO module project context."
|
||||
},
|
||||
{
|
||||
"id": "resolver.hub_app_to_seo.project_context",
|
||||
"relationId": "ontology.resolves_hub_app_to_seo_project",
|
||||
"fromSurface": "hub",
|
||||
"inputEntityIds": ["hub.application"],
|
||||
"intentHints": ["seo", "site", "project", "audit", "сео", "сайт", "аудит"],
|
||||
"outputSurface": "seo",
|
||||
"outputEntityIds": ["seo.project", "seo.site"],
|
||||
"requiredBindings": ["hub.application -> seo.project context"],
|
||||
"status": "product-required",
|
||||
"summary": "Route Launcher app context into SEO module project context."
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user