anymorph 0.2.1 → 0.2.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.
- package/README.md +5 -0
- package/dist/index.js +26 -6
- package/dist/skillpacks/geo/skills/brand-owned-diagnosis/SKILL.md +54 -0
- package/dist/skillpacks/geo/skills/brand-owned-diagnosis/agents/openai.yaml +4 -0
- package/dist/skillpacks/geo/skills/brand-owned-diagnosis/references/diagnosis-contract.md +96 -0
- package/dist/skillpacks/geo/skills/brand-owned-diagnosis/references/workflow.md +191 -0
- package/dist/skillpacks/geo/skills/geo-generating-actions/SKILL.md +43 -0
- package/dist/skillpacks/geo/skills/geo-generating-actions/agents/openai.yaml +4 -0
- package/dist/skillpacks/geo/skills/geo-generating-actions/references/orchestrator.workflow.md +274 -0
- package/dist/skillpacks/geo/skills/geo-initializing-strategy/SKILL.md +50 -0
- package/dist/skillpacks/geo/skills/geo-initializing-strategy/agents/openai.yaml +4 -0
- package/dist/skillpacks/geo/skills/geo-initializing-strategy/references/external-authority-diagnosis.md +66 -0
- package/dist/skillpacks/geo/skills/geo-initializing-strategy/references/foundation-diagnosis.md +86 -0
- package/dist/skillpacks/geo/skills/geo-initializing-strategy/references/memory-contract.md +15 -0
- package/dist/skillpacks/geo/skills/geo-initializing-strategy/references/semantic-clusters-diagnosis.md +58 -0
- package/dist/skillpacks/geo/skills/geo-initializing-strategy/references/strategy-map-contract.md +26 -0
- package/dist/skillpacks/geo/skills/geo-initializing-strategy/references/visibility-diagnosis.md +50 -0
- package/dist/skillpacks/geo/skills/geo-pages-diagnosis/SKILL.md +51 -0
- package/dist/skillpacks/geo/skills/geo-pages-diagnosis/agents/openai.yaml +4 -0
- package/dist/skillpacks/geo/skills/geo-pages-diagnosis/references/diagnosis-contract.md +106 -0
- package/dist/skillpacks/geo/skills/geo-pages-diagnosis/references/workflow.md +219 -0
- package/dist/skillpacks/geo/skills/geo-writer/SKILL.md +234 -0
- package/dist/skillpacks/geo/skills/geo-writer/agents/openai.yaml +4 -0
- package/dist/skillpacks/geo/skills/geo-writer/references/content-writer-contract.md +316 -0
- package/dist/skillpacks/geo/skills/geo-writer/references/direct-sql.md +187 -0
- package/dist/skillpacks/geo/skills/geo-writer/references/seo-geo-insights.md +269 -0
- package/dist/skillpacks/geo/skills/social-execution-planning/SKILL.md +53 -0
- package/dist/skillpacks/geo/skills/social-execution-planning/agents/openai.yaml +5 -0
- package/dist/skillpacks/geo/skills/social-execution-planning/references/execution-contract.md +68 -0
- package/dist/skillpacks/geo/skills/social-execution-planning/references/platform-playbooks.md +59 -0
- package/dist/skillpacks/geo/skills/social-execution-planning/references/reddit-rules.md +69 -0
- package/dist/skillpacks/geo/skills/third-party-diagnosis/SKILL.md +54 -0
- package/dist/skillpacks/geo/skills/third-party-diagnosis/agents/openai.yaml +4 -0
- package/dist/skillpacks/geo/skills/third-party-diagnosis/references/diagnosis-contract.md +111 -0
- package/dist/skillpacks/geo/skills/third-party-diagnosis/references/workflow.md +174 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -142,6 +142,11 @@ anymorph geo init --repo .
|
|
|
142
142
|
anymorph geo init --repo . --skills-source /path/to/anymorph-geo-skills/plugins/anymorph-geo/skills
|
|
143
143
|
```
|
|
144
144
|
|
|
145
|
+
By default, `init` uses the GEO skillpack bundled inside the installed
|
|
146
|
+
`anymorph` npm package. That means tenant users do not need access to the
|
|
147
|
+
private `anymorph-geo-skills` repo. `--skills-source` is only for internal local
|
|
148
|
+
development when testing an unreleased skillpack.
|
|
149
|
+
|
|
145
150
|
This installs managed skills under `.claude/skills` and `.agents/skills`, writes
|
|
146
151
|
`agent/contracts`, creates `agent/runs` and `agent/archive`, and creates missing
|
|
147
152
|
memory files without overwriting existing `agent/BRAND.md`, `agent/STRATEGY.md`,
|
package/dist/index.js
CHANGED
|
@@ -7430,6 +7430,7 @@ var DEFAULT_SKILLPACK_RELATIVE_PATH = join4(
|
|
|
7430
7430
|
"skills"
|
|
7431
7431
|
);
|
|
7432
7432
|
var MANAGED_PATHS = [".claude/skills", ".agents/skills", "agent/contracts"];
|
|
7433
|
+
var BUNDLED_SKILLPACK_RELATIVE_PATH = join4("skillpacks", "geo", "skills");
|
|
7433
7434
|
async function initGeoScaffold(input) {
|
|
7434
7435
|
return applyGeoScaffold(input, { createMemory: true });
|
|
7435
7436
|
}
|
|
@@ -7476,14 +7477,22 @@ async function resolveSkillSourceDir(explicit) {
|
|
|
7476
7477
|
await ensureDirectory2(resolved);
|
|
7477
7478
|
return resolved;
|
|
7478
7479
|
}
|
|
7480
|
+
const bundled = await resolveBundledSkillSourceDir();
|
|
7481
|
+
if (bundled) return bundled;
|
|
7479
7482
|
for (const root of searchRoots()) {
|
|
7480
7483
|
const candidate = join4(root, DEFAULT_SKILLPACK_RELATIVE_PATH);
|
|
7481
7484
|
if (await isDirectory(candidate)) return candidate;
|
|
7482
7485
|
}
|
|
7483
7486
|
throw new Error(
|
|
7484
|
-
`Could not find GEO skillpack.
|
|
7487
|
+
`Could not find bundled GEO skillpack. Reinstall or update the anymorph CLI, or pass --skills-source <path> pointing to ${DEFAULT_SKILLPACK_RELATIVE_PATH}.`
|
|
7485
7488
|
);
|
|
7486
7489
|
}
|
|
7490
|
+
async function resolveBundledSkillSourceDir(fromUrl = new URL(import.meta.url)) {
|
|
7491
|
+
const moduleDir = dirname(fileURLToPath2(fromUrl));
|
|
7492
|
+
const candidate = join4(moduleDir, BUNDLED_SKILLPACK_RELATIVE_PATH);
|
|
7493
|
+
if (await isDirectory(candidate)) return candidate;
|
|
7494
|
+
return null;
|
|
7495
|
+
}
|
|
7487
7496
|
async function applyGeoScaffold(input, options) {
|
|
7488
7497
|
const repoPath = resolve2(input.repoPath);
|
|
7489
7498
|
const skillsSourceDir = await resolveSkillSourceDir(input.skillsSourceDir);
|
|
@@ -7562,12 +7571,14 @@ async function ensureMemoryFiles(repoPath, changed) {
|
|
|
7562
7571
|
}
|
|
7563
7572
|
async function writeSkillpackLock(input, changed) {
|
|
7564
7573
|
const sourceCommit = await gitOutput2(input.skillsSourceDir, ["rev-parse", "HEAD"]);
|
|
7574
|
+
const cliPackageVersion = await readCliPackageVersion();
|
|
7565
7575
|
const lock = {
|
|
7566
7576
|
name: "anymorph-geo",
|
|
7567
7577
|
source: input.skillsSourceDir,
|
|
7568
7578
|
sourceRepo: "opactor-dev/anymorph-geo-skills",
|
|
7569
7579
|
requestedRef: input.ref,
|
|
7570
7580
|
resolvedCommit: sourceCommit,
|
|
7581
|
+
cliPackageVersion,
|
|
7571
7582
|
manifestHash: input.manifestHash,
|
|
7572
7583
|
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7573
7584
|
managedPaths: MANAGED_PATHS
|
|
@@ -7653,6 +7664,15 @@ async function gitOutput2(cwd, args) {
|
|
|
7653
7664
|
return null;
|
|
7654
7665
|
}
|
|
7655
7666
|
}
|
|
7667
|
+
async function readCliPackageVersion() {
|
|
7668
|
+
for (const root of searchRoots()) {
|
|
7669
|
+
const packageJson = await readJson(join4(root, "package.json"));
|
|
7670
|
+
if (packageJson && typeof packageJson === "object" && packageJson.name === "anymorph" && typeof packageJson.version === "string") {
|
|
7671
|
+
return packageJson.version;
|
|
7672
|
+
}
|
|
7673
|
+
}
|
|
7674
|
+
return null;
|
|
7675
|
+
}
|
|
7656
7676
|
function searchRoots() {
|
|
7657
7677
|
const roots = /* @__PURE__ */ new Set();
|
|
7658
7678
|
let cwd = resolve2(process.cwd());
|
|
@@ -7898,10 +7918,10 @@ function shortPath(path2) {
|
|
|
7898
7918
|
// src/commands/geo.ts
|
|
7899
7919
|
function buildGeoCommand() {
|
|
7900
7920
|
const geo = new Command("geo").description("Manage local GEO repo setup and strategy runs");
|
|
7901
|
-
geo.command("init").description("Initialize GEO scaffold and skills in a tenant repo").option("--repo <path>", "Tenant repo path", ".").option("--skills-source <path>", "Use an explicit GEO skillpack source directory").option("--ref <ref>", "Skillpack ref label to write into agent/skillpack.json", "
|
|
7902
|
-
geo.command("sync").description("Sync managed GEO scaffold files without touching memory or run artifacts").option("--repo <path>", "Tenant repo path", ".").option("--skills-source <path>", "Use an explicit GEO skillpack source directory").option("--ref <ref>", "Skillpack ref label to write into agent/skillpack.json", "
|
|
7903
|
-
geo.command("doctor").description("Check whether a tenant repo GEO scaffold matches the installed skillpack").option("--repo <path>", "Tenant repo path", ".").option("--skills-source <path>", "Use an explicit GEO skillpack source directory").option("--json", "Output as JSON").action(geoDoctorCommand);
|
|
7904
|
-
geo.command("prepare <workspace>").description("Prepare a local GEO strategy run package").option("--repo <path>", "Use an explicit tenant repo path").option("--days <days>", "Signal lookback window in days", parsePositiveInt).option("--skills-source <path>", "Use an explicit GEO skillpack source directory").option("--skip-scaffold", "Skip GEO scaffold sync before writing the run package").option("--json", "Output as JSON").action(geoPrepareCommand);
|
|
7921
|
+
geo.command("init").description("Initialize GEO scaffold and skills in a tenant repo").option("--repo <path>", "Tenant repo path", ".").option("--skills-source <path>", "Use an explicit GEO skillpack source directory instead of the bundled skillpack").option("--ref <ref>", "Skillpack ref label to write into agent/skillpack.json", "bundled").option("--json", "Output as JSON").action(geoInitCommand);
|
|
7922
|
+
geo.command("sync").description("Sync managed GEO scaffold files without touching memory or run artifacts").option("--repo <path>", "Tenant repo path", ".").option("--skills-source <path>", "Use an explicit GEO skillpack source directory instead of the bundled skillpack").option("--ref <ref>", "Skillpack ref label to write into agent/skillpack.json", "bundled").option("--json", "Output as JSON").action(geoSyncCommand);
|
|
7923
|
+
geo.command("doctor").description("Check whether a tenant repo GEO scaffold matches the installed skillpack").option("--repo <path>", "Tenant repo path", ".").option("--skills-source <path>", "Use an explicit GEO skillpack source directory instead of the bundled skillpack").option("--json", "Output as JSON").action(geoDoctorCommand);
|
|
7924
|
+
geo.command("prepare <workspace>").description("Prepare a local GEO strategy run package").option("--repo <path>", "Use an explicit tenant repo path").option("--days <days>", "Signal lookback window in days", parsePositiveInt).option("--skills-source <path>", "Use an explicit GEO skillpack source directory instead of the bundled skillpack").option("--skip-scaffold", "Skip GEO scaffold sync before writing the run package").option("--json", "Output as JSON").action(geoPrepareCommand);
|
|
7905
7925
|
geo.command("validate <runId>").description("Validate local GEO strategy run artifacts before pushing").option("--repo <path>", "Use an explicit tenant repo path").option("--json", "Output as JSON").action(geoValidateCommand);
|
|
7906
7926
|
geo.command("intents <runId>").description("Show the pre-fetched intents for a local GEO strategy run").option("--repo <path>", "Use an explicit tenant repo path").option("--json", "Output as JSON").action(geoIntentsCommand);
|
|
7907
7927
|
geo.command("status <runId>").description("Show backend sync status for a GEO strategy run").option("--json", "Output as JSON").action(geoStatusCommand);
|
|
@@ -8158,7 +8178,7 @@ function printScaffoldError(prefix, err) {
|
|
|
8158
8178
|
|
|
8159
8179
|
// src/index.ts
|
|
8160
8180
|
var program2 = new Command();
|
|
8161
|
-
program2.name("anymorph").description("Check your brand's AI visibility \u2014 powered by Anymorph").version("0.2.
|
|
8181
|
+
program2.name("anymorph").description("Check your brand's AI visibility \u2014 powered by Anymorph").version("0.2.3");
|
|
8162
8182
|
program2.command("login").description("Sign in to your Anymorph account").action(loginCommand);
|
|
8163
8183
|
program2.command("check <domain>").description("Check AI visibility for a domain").option("--json", "Output as JSON").action(checkCommand);
|
|
8164
8184
|
program2.command("status").description("Show current auth status").action(statusCommand);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: brand-owned-diagnosis
|
|
3
|
+
description: Use when diagnosing customer-owned discovered pages for GEO strategy actions, owned-site visibility gaps, content coverage issues, or technical page fixes.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Brand-Owned Diagnosis
|
|
7
|
+
|
|
8
|
+
Use this skill for customer-owned pages that are not Anymorph-generated GEO pages.
|
|
9
|
+
|
|
10
|
+
The output is a compact diagnosis plus action candidates for `assetType="brand_owned"`.
|
|
11
|
+
|
|
12
|
+
## Scope
|
|
13
|
+
|
|
14
|
+
Diagnose:
|
|
15
|
+
|
|
16
|
+
- Existing brand-owned page coverage.
|
|
17
|
+
- Content clarity, proof, comparison, and entity gaps.
|
|
18
|
+
- Technical or crawl blockers on customer-owned pages.
|
|
19
|
+
- GSC, SERP, AI response, and competitor gaps tied to a known owned URL.
|
|
20
|
+
|
|
21
|
+
Do not propose:
|
|
22
|
+
|
|
23
|
+
- Generated GEO page work.
|
|
24
|
+
- Third-party outreach or external profile work.
|
|
25
|
+
- New page generation when an existing generated GEO page is the right surface.
|
|
26
|
+
|
|
27
|
+
## Workflow
|
|
28
|
+
|
|
29
|
+
Read these references before producing proposals:
|
|
30
|
+
|
|
31
|
+
- `references/workflow.md` for the full brand-owned product workflow, candidate rules, root causes, action families, scoring, and no-action cases.
|
|
32
|
+
- `references/diagnosis-contract.md` for the exact runtime diagnosis contract and artifact submission shape.
|
|
33
|
+
|
|
34
|
+
1. Read shared run context and the brand-owned candidate slice.
|
|
35
|
+
2. Use `list_geo_strategy_candidates` before broad SQL.
|
|
36
|
+
3. Use `get_geo_intent_diagnostic` for intent-level explanation.
|
|
37
|
+
4. Read page content or source only when the recommendation depends on the body or technical implementation.
|
|
38
|
+
5. Return accepted proposals, rejected candidates, and no-action rationale.
|
|
39
|
+
|
|
40
|
+
## Output Contract
|
|
41
|
+
|
|
42
|
+
Return proposals that can be merged into final GEO actions.
|
|
43
|
+
|
|
44
|
+
Each proposal should include:
|
|
45
|
+
|
|
46
|
+
- intent or proposed intent.
|
|
47
|
+
- existing page URL or page id when known.
|
|
48
|
+
- root cause.
|
|
49
|
+
- operation family.
|
|
50
|
+
- priority and confidence.
|
|
51
|
+
- evidence references.
|
|
52
|
+
- concise change brief.
|
|
53
|
+
|
|
54
|
+
Use no action when the owned page is not the bottleneck.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# GEO Strategy: Brand-Owned Diagnosis
|
|
2
|
+
|
|
3
|
+
You diagnose customer-owned discovered pages.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
Work only on pages where the tenant/customer site owns the page and the page is not an Anymorph-generated GEO page.
|
|
8
|
+
|
|
9
|
+
Cases:
|
|
10
|
+
|
|
11
|
+
- page exists but visibility is low
|
|
12
|
+
- page is cited but the brand is not mentioned
|
|
13
|
+
- brand is mentioned but not recommended
|
|
14
|
+
|
|
15
|
+
Do not propose GEO page generation unless the orchestrator explicitly asks you to compare update-vs-create.
|
|
16
|
+
|
|
17
|
+
## Evidence Order
|
|
18
|
+
|
|
19
|
+
Use the cheapest sufficient evidence.
|
|
20
|
+
|
|
21
|
+
1. Common run context and candidate rows from the orchestrator.
|
|
22
|
+
2. `list_geo_strategy_candidates` for the first brand-owned candidate slice.
|
|
23
|
+
3. `get_geo_intent_diagnostic` for one intent before deeper checks.
|
|
24
|
+
4. `get_page_insights`, `get_page_visibility`, or `list_ai_responses` for page/prompt evidence.
|
|
25
|
+
5. `get_page_content` or `get_page_source_code` only when content or technical diagnosis depends on the page body.
|
|
26
|
+
6. `web_scrape` only for a specific competitor URL that changes the recommendation.
|
|
27
|
+
|
|
28
|
+
Do not scrape broadly.
|
|
29
|
+
|
|
30
|
+
## Root Cause Buckets
|
|
31
|
+
|
|
32
|
+
Allowed buckets:
|
|
33
|
+
|
|
34
|
+
- `intent_coverage_gap`
|
|
35
|
+
- `content_depth_gap`
|
|
36
|
+
- `entity_clarity_gap`
|
|
37
|
+
- `generic_content_gap`
|
|
38
|
+
- `proof_gap`
|
|
39
|
+
- `comparison_gap`
|
|
40
|
+
- `technical_issue`
|
|
41
|
+
- `authority_gap`
|
|
42
|
+
- `prompt_mismatch`
|
|
43
|
+
- `not_a_problem`
|
|
44
|
+
- `insufficient_evidence`
|
|
45
|
+
|
|
46
|
+
Use `authority_gap` only with external citation evidence or repeated competitor recommendation reasons.
|
|
47
|
+
|
|
48
|
+
## Action Families
|
|
49
|
+
|
|
50
|
+
Allowed families:
|
|
51
|
+
|
|
52
|
+
- `refresh_existing_page`
|
|
53
|
+
- `retarget_existing_page`
|
|
54
|
+
- `improve_entity_clarity`
|
|
55
|
+
- `add_proof`
|
|
56
|
+
- `add_comparison_coverage`
|
|
57
|
+
- `fix_technical_issue`
|
|
58
|
+
- `no_action`
|
|
59
|
+
|
|
60
|
+
## Output
|
|
61
|
+
|
|
62
|
+
Produce one `brand_owned` diagnosis object in this shape.
|
|
63
|
+
|
|
64
|
+
Do not write intermediate diagnosis JSON files directly.
|
|
65
|
+
|
|
66
|
+
Do not include `workspaceId`, `runId`, `channel`, final action id, or final `assetType`; the orchestrator can derive them.
|
|
67
|
+
|
|
68
|
+
Use this shape:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"summary": "Short diagnosis.",
|
|
73
|
+
"proposals": [
|
|
74
|
+
{
|
|
75
|
+
"intentId": "intent_123",
|
|
76
|
+
"candidateType": "page_exists_low_visibility",
|
|
77
|
+
"target": { "pageId": "page_123", "url": "https://example.com/page" },
|
|
78
|
+
"rootCauses": [
|
|
79
|
+
{ "bucket": "proof_gap", "confidence": 0.72, "evidence": ["Specific evidence summary"] }
|
|
80
|
+
],
|
|
81
|
+
"actionFamily": "add_proof",
|
|
82
|
+
"operations": ["Add customer proof near the answer block"],
|
|
83
|
+
"priority": "high",
|
|
84
|
+
"confidence": "medium",
|
|
85
|
+
"evidence": [
|
|
86
|
+
{ "type": "signal", "ref": "geo_recommendation_quadrants:intent_123", "summary": "Mentioned but not recommended dominates." }
|
|
87
|
+
],
|
|
88
|
+
"whyNow": "Why this matters this week.",
|
|
89
|
+
"risks": ["Uncertainty or dependency"]
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
"rejected": [
|
|
93
|
+
{ "ref": "intent_456", "reason": "Suppressed by recent action mask." }
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
```
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Brand-Owned Diagnosis Workflow
|
|
2
|
+
|
|
3
|
+
## Role
|
|
4
|
+
|
|
5
|
+
The `brand_owned` channel diagnosis diagnoses and proposes actions for customer-owned discovered pages.
|
|
6
|
+
|
|
7
|
+
It works on pages where:
|
|
8
|
+
|
|
9
|
+
- `source = discovered`
|
|
10
|
+
- the page belongs to the tenant/customer site
|
|
11
|
+
- the action would improve an existing natural page or recommend a customer-site content action
|
|
12
|
+
|
|
13
|
+
## Non-Goals
|
|
14
|
+
|
|
15
|
+
- Do not iterate generated GEO pages.
|
|
16
|
+
- Do not decide final routes for generated pages.
|
|
17
|
+
- Do not propose third-party outreach.
|
|
18
|
+
- Do not perform deep URL tree planning in MVP.
|
|
19
|
+
- Do not require `PageContentLabel`.
|
|
20
|
+
|
|
21
|
+
## Inputs
|
|
22
|
+
|
|
23
|
+
- candidate rows routed by the orchestrator
|
|
24
|
+
- tenant `agent/BRAND.md`
|
|
25
|
+
- tenant `agent/STRATEGY.md`
|
|
26
|
+
- tenant `agent/LEARNINGS.md`
|
|
27
|
+
- relevant rows from:
|
|
28
|
+
- `geo_pages`
|
|
29
|
+
- `geo_intent_coverage`
|
|
30
|
+
- `geo_recommendation_quadrants`
|
|
31
|
+
- `geo_page_intent_visibility_gaps`
|
|
32
|
+
- `geo_page_performance`
|
|
33
|
+
- `geo_strategy_actions_recent`
|
|
34
|
+
- page scrape when needed
|
|
35
|
+
- AI answer samples when needed
|
|
36
|
+
- competitor page scrape when needed
|
|
37
|
+
|
|
38
|
+
## Workflow
|
|
39
|
+
|
|
40
|
+
### 1. Filter Candidates
|
|
41
|
+
|
|
42
|
+
Keep candidates where:
|
|
43
|
+
|
|
44
|
+
- page source is `discovered`
|
|
45
|
+
- page has an intent
|
|
46
|
+
- intent is weak, or quadrant state indicates a fixable issue
|
|
47
|
+
|
|
48
|
+
Drop candidates when:
|
|
49
|
+
|
|
50
|
+
- page is not indexable and the tenant strategy forbids technical page edits
|
|
51
|
+
- recent action mask suppresses the same action
|
|
52
|
+
- evidence is too thin to justify an action
|
|
53
|
+
|
|
54
|
+
### 2. Classify Candidate Case
|
|
55
|
+
|
|
56
|
+
Assign one primary case.
|
|
57
|
+
|
|
58
|
+
#### A. Page Exists But Visibility Is Low
|
|
59
|
+
|
|
60
|
+
Use when:
|
|
61
|
+
|
|
62
|
+
- discovered page exists
|
|
63
|
+
- `current_visibility` is low
|
|
64
|
+
- quadrant is mostly `absent`, `cited_unnamed`, or `mentioned_not_recommended`
|
|
65
|
+
|
|
66
|
+
Diagnosis questions:
|
|
67
|
+
|
|
68
|
+
1. Does the page directly answer the intent?
|
|
69
|
+
2. Is coverage deep enough for representative prompts?
|
|
70
|
+
3. Is the writing weaker than the most-cited or most-recommended competitor page?
|
|
71
|
+
4. Is there a visible technical issue?
|
|
72
|
+
5. Is authority the likely bottleneck, or only a weak hypothesis?
|
|
73
|
+
|
|
74
|
+
#### B. Cited But Not Mentioned
|
|
75
|
+
|
|
76
|
+
Use when:
|
|
77
|
+
|
|
78
|
+
- our page/source is cited
|
|
79
|
+
- brand is not clearly mentioned
|
|
80
|
+
|
|
81
|
+
Diagnosis questions:
|
|
82
|
+
|
|
83
|
+
1. Is the page clearly tied to the tenant brand?
|
|
84
|
+
2. Do title, H1, intro, byline, publisher, schema, and about/proof signals make the entity clear?
|
|
85
|
+
3. Is the content too generic to make the brand worth mentioning?
|
|
86
|
+
|
|
87
|
+
#### C. Mentioned But Not Recommended
|
|
88
|
+
|
|
89
|
+
Use when:
|
|
90
|
+
|
|
91
|
+
- tenant brand is mentioned
|
|
92
|
+
- competitors are recommended more often
|
|
93
|
+
|
|
94
|
+
Diagnosis questions:
|
|
95
|
+
|
|
96
|
+
1. Which brands were recommended?
|
|
97
|
+
2. What reasons did the AI answer give or imply?
|
|
98
|
+
3. What content-level weakness exists on the tenant page?
|
|
99
|
+
|
|
100
|
+
### 3. Gather Evidence
|
|
101
|
+
|
|
102
|
+
Use the cheapest sufficient evidence.
|
|
103
|
+
|
|
104
|
+
Default evidence:
|
|
105
|
+
|
|
106
|
+
- view rows
|
|
107
|
+
- page title/H1/path/status
|
|
108
|
+
- quadrant rates
|
|
109
|
+
- page performance summary
|
|
110
|
+
- AI answer excerpt
|
|
111
|
+
|
|
112
|
+
Fetch page scrape when:
|
|
113
|
+
|
|
114
|
+
- diagnosis depends on content coverage, proof, comparison, or entity clarity
|
|
115
|
+
|
|
116
|
+
Fetch competitor page scrape when:
|
|
117
|
+
|
|
118
|
+
- the answer repeatedly recommends or cites a competitor page
|
|
119
|
+
- the proposed action depends on competitor comparison
|
|
120
|
+
|
|
121
|
+
Do not scrape everything.
|
|
122
|
+
|
|
123
|
+
### 4. Pick Root Cause Buckets
|
|
124
|
+
|
|
125
|
+
Allowed buckets:
|
|
126
|
+
|
|
127
|
+
- `intent_coverage_gap`
|
|
128
|
+
- `content_depth_gap`
|
|
129
|
+
- `entity_clarity_gap`
|
|
130
|
+
- `generic_content_gap`
|
|
131
|
+
- `proof_gap`
|
|
132
|
+
- `comparison_gap`
|
|
133
|
+
- `technical_issue`
|
|
134
|
+
- `authority_gap`
|
|
135
|
+
- `prompt_mismatch`
|
|
136
|
+
- `not_a_problem`
|
|
137
|
+
- `insufficient_evidence`
|
|
138
|
+
|
|
139
|
+
Use `authority_gap` only when supported by external citation evidence or repeated competitor recommendation reasons.
|
|
140
|
+
|
|
141
|
+
### 5. Route Action
|
|
142
|
+
|
|
143
|
+
Allowed action families:
|
|
144
|
+
|
|
145
|
+
- `refresh_existing_page`
|
|
146
|
+
- `retarget_existing_page`
|
|
147
|
+
- `improve_entity_clarity`
|
|
148
|
+
- `add_proof`
|
|
149
|
+
- `add_comparison_coverage`
|
|
150
|
+
- `fix_technical_issue`
|
|
151
|
+
- `no_action`
|
|
152
|
+
|
|
153
|
+
Prefer update actions over create actions when an existing discovered page clearly owns the intent.
|
|
154
|
+
|
|
155
|
+
### 6. Output
|
|
156
|
+
|
|
157
|
+
Return a compact diagnosis for each accepted action:
|
|
158
|
+
|
|
159
|
+
- candidate type
|
|
160
|
+
- page URL/pageId
|
|
161
|
+
- intentId
|
|
162
|
+
- root cause buckets with confidence
|
|
163
|
+
- recommended action family
|
|
164
|
+
- concrete operations
|
|
165
|
+
- evidence references
|
|
166
|
+
- why other actions were rejected
|
|
167
|
+
|
|
168
|
+
## Examples
|
|
169
|
+
|
|
170
|
+
### Covered But Weak
|
|
171
|
+
|
|
172
|
+
If a discovered page exists, visibility is low, and the page only gives generic education while competitor pages provide comparison criteria and proof:
|
|
173
|
+
|
|
174
|
+
- root cause: `comparison_gap`, `proof_gap`
|
|
175
|
+
- action family: `add_comparison_coverage`
|
|
176
|
+
- operation: add comparison criteria and customer proof to the existing page
|
|
177
|
+
|
|
178
|
+
### Cited But Not Mentioned
|
|
179
|
+
|
|
180
|
+
If the page is cited but the AI answer does not name the tenant brand:
|
|
181
|
+
|
|
182
|
+
- root cause: `entity_clarity_gap`
|
|
183
|
+
- action family: `improve_entity_clarity`
|
|
184
|
+
- operation: strengthen brand naming, publisher schema, and product/company relationship in the answer block
|
|
185
|
+
|
|
186
|
+
## Guardrails
|
|
187
|
+
|
|
188
|
+
- Do not propose creating a generated GEO page from this channel diagnosis unless the orchestrator explicitly routes no-page candidates here.
|
|
189
|
+
- Do not over-index on page type labels.
|
|
190
|
+
- Do not call content "thin" without page scrape or word-count/section evidence.
|
|
191
|
+
- Do not diagnose authority from low visibility alone.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: geo-generating-actions
|
|
3
|
+
description: Use when generating recurring or on-demand GEO strategy actions from tenant memory, run context, channel diagnoses, and evidence-backed opportunity candidates.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GEO Generating Actions
|
|
7
|
+
|
|
8
|
+
Use this skill to orchestrate GEO action generation.
|
|
9
|
+
|
|
10
|
+
This skill owns the final decision. Channel diagnosis should be handled by product diagnosis skills, then merged and judged here.
|
|
11
|
+
|
|
12
|
+
## Channel Skills
|
|
13
|
+
|
|
14
|
+
Use these skills for channel-specific diagnosis:
|
|
15
|
+
|
|
16
|
+
- `$brand-owned-diagnosis` for customer-owned pages.
|
|
17
|
+
- `$geo-pages-diagnosis` for generated GEO pages.
|
|
18
|
+
- `$third-party-diagnosis` for Earn and external authority work.
|
|
19
|
+
|
|
20
|
+
## Required Reference
|
|
21
|
+
|
|
22
|
+
Read `references/orchestrator.workflow.md` before final action selection. It contains the full production workflow: context construction, channel invocation order, proposal merge rules, conflict resolution, no-action discipline, and final artifact contract.
|
|
23
|
+
|
|
24
|
+
## Workflow
|
|
25
|
+
|
|
26
|
+
1. Read host-created run files and stable tenant memory.
|
|
27
|
+
2. Build one compact shared run context.
|
|
28
|
+
3. Invoke or apply the three channel diagnosis skills.
|
|
29
|
+
4. Read channel outputs and reject weak, duplicate, or conflicting proposals.
|
|
30
|
+
5. Prefer no action over low-evidence action.
|
|
31
|
+
6. Submit final actions through runtime artifact tools; do not write `actions.json` directly.
|
|
32
|
+
7. Write rationale and status files only under the current run path.
|
|
33
|
+
8. Update durable tenant memory only when the run changes stable strategy or repeated learnings.
|
|
34
|
+
|
|
35
|
+
## Final Decision Rules
|
|
36
|
+
|
|
37
|
+
- Emit at most 20 actions.
|
|
38
|
+
- Use only `create` or `update` operations.
|
|
39
|
+
- Use `brand_owned` only for customer-owned discovered pages.
|
|
40
|
+
- Use `geo_page` only for generated or managed GEO page work.
|
|
41
|
+
- Use `third_party` only for off-page Earn work.
|
|
42
|
+
- Every action must include either an existing `intentId` or a non-null `proposedIntent`.
|
|
43
|
+
- Third-party actions must name the exact domain and, when known, the exact publish surface.
|