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.
Files changed (36) hide show
  1. package/README.md +5 -0
  2. package/dist/index.js +26 -6
  3. package/dist/skillpacks/geo/skills/brand-owned-diagnosis/SKILL.md +54 -0
  4. package/dist/skillpacks/geo/skills/brand-owned-diagnosis/agents/openai.yaml +4 -0
  5. package/dist/skillpacks/geo/skills/brand-owned-diagnosis/references/diagnosis-contract.md +96 -0
  6. package/dist/skillpacks/geo/skills/brand-owned-diagnosis/references/workflow.md +191 -0
  7. package/dist/skillpacks/geo/skills/geo-generating-actions/SKILL.md +43 -0
  8. package/dist/skillpacks/geo/skills/geo-generating-actions/agents/openai.yaml +4 -0
  9. package/dist/skillpacks/geo/skills/geo-generating-actions/references/orchestrator.workflow.md +274 -0
  10. package/dist/skillpacks/geo/skills/geo-initializing-strategy/SKILL.md +50 -0
  11. package/dist/skillpacks/geo/skills/geo-initializing-strategy/agents/openai.yaml +4 -0
  12. package/dist/skillpacks/geo/skills/geo-initializing-strategy/references/external-authority-diagnosis.md +66 -0
  13. package/dist/skillpacks/geo/skills/geo-initializing-strategy/references/foundation-diagnosis.md +86 -0
  14. package/dist/skillpacks/geo/skills/geo-initializing-strategy/references/memory-contract.md +15 -0
  15. package/dist/skillpacks/geo/skills/geo-initializing-strategy/references/semantic-clusters-diagnosis.md +58 -0
  16. package/dist/skillpacks/geo/skills/geo-initializing-strategy/references/strategy-map-contract.md +26 -0
  17. package/dist/skillpacks/geo/skills/geo-initializing-strategy/references/visibility-diagnosis.md +50 -0
  18. package/dist/skillpacks/geo/skills/geo-pages-diagnosis/SKILL.md +51 -0
  19. package/dist/skillpacks/geo/skills/geo-pages-diagnosis/agents/openai.yaml +4 -0
  20. package/dist/skillpacks/geo/skills/geo-pages-diagnosis/references/diagnosis-contract.md +106 -0
  21. package/dist/skillpacks/geo/skills/geo-pages-diagnosis/references/workflow.md +219 -0
  22. package/dist/skillpacks/geo/skills/geo-writer/SKILL.md +234 -0
  23. package/dist/skillpacks/geo/skills/geo-writer/agents/openai.yaml +4 -0
  24. package/dist/skillpacks/geo/skills/geo-writer/references/content-writer-contract.md +316 -0
  25. package/dist/skillpacks/geo/skills/geo-writer/references/direct-sql.md +187 -0
  26. package/dist/skillpacks/geo/skills/geo-writer/references/seo-geo-insights.md +269 -0
  27. package/dist/skillpacks/geo/skills/social-execution-planning/SKILL.md +53 -0
  28. package/dist/skillpacks/geo/skills/social-execution-planning/agents/openai.yaml +5 -0
  29. package/dist/skillpacks/geo/skills/social-execution-planning/references/execution-contract.md +68 -0
  30. package/dist/skillpacks/geo/skills/social-execution-planning/references/platform-playbooks.md +59 -0
  31. package/dist/skillpacks/geo/skills/social-execution-planning/references/reddit-rules.md +69 -0
  32. package/dist/skillpacks/geo/skills/third-party-diagnosis/SKILL.md +54 -0
  33. package/dist/skillpacks/geo/skills/third-party-diagnosis/agents/openai.yaml +4 -0
  34. package/dist/skillpacks/geo/skills/third-party-diagnosis/references/diagnosis-contract.md +111 -0
  35. package/dist/skillpacks/geo/skills/third-party-diagnosis/references/workflow.md +174 -0
  36. 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. Pass --skills-source <path> pointing to ${DEFAULT_SKILLPACK_RELATIVE_PATH}.`
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", "local").option("--json", "Output as JSON").action(geoInitCommand);
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", "local").option("--json", "Output as JSON").action(geoSyncCommand);
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.0");
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,4 @@
1
+ interface:
2
+ display_name: "Brand-Owned Diagnosis"
3
+ short_description: "Diagnose customer-owned pages for GEO strategy actions."
4
+ default_prompt: "Use $brand-owned-diagnosis to diagnose owned-page GEO gaps for this workspace."
@@ -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.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "GEO Generating Actions"
3
+ short_description: "Generate final GEO strategy actions from channel diagnoses."
4
+ default_prompt: "Use $geo-generating-actions to generate final GEO strategy actions for this workspace."