
Survey
- 255 installs
- 40 repo stars
- Updated August 4, 2026
- akillness/oh-my-skills
survey is an agent skill that runs a bounded cross-platform landscape scan and writes validator-checked `.survey/{slug}/` research artifacts for developers who need evidence before planning or building.
About
survey is an oh-my-skills agent skill (version 2.1.7) for pre-implementation landscape research across Claude Code, Codex, Gemini CLI, and OpenCode. The workflow freezes one research question, runs four parallel lanes—context, solutions, actual behavior, and alternatives or platform-map—and saves reusable markdown into `.survey/{slug}/` with fixed headings for triage, context, solutions, and platform-map when relevant. A bundled `validate_survey_artifacts.py` script checks the artifact contract before handoff to planning or execution skills. Developers reach for survey when comparing agent platforms, mapping workflows, or surveying competitors and workarounds where claims must stay source-backed. The skill explicitly stays in research mode and routes architecture or implementation outward only after artifacts validate.
- Maps oh-my-skills catalog
- Compares skill coverage
- Supports enable/disable decisions
- Reduces duplicate tooling
- Speeds agent setup
Survey by the numbers
- 255 all-time installs (skills.sh)
- Ranked #164 of 782 Skill Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/akillness/oh-my-skills --skill surveyAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 255 |
|---|---|
| repo stars | ★ 40 |
| Last updated | August 4, 2026 |
| Repository | akillness/oh-my-skills ↗ |
How do you research a feature landscape before coding?
Inventory installed agent skills, compare capabilities, and decide which oh-my-skills modules to enable before starting a new coding workflow.
Who is it for?
Developers starting a new capability, tooling choice, or repo-maintenance rewrite who need source-backed landscape evidence before writing a plan or code.
Skip if: Developers who already know the solution and want immediate implementation, single-file bug fixes, or live browser-only exploration without durable artifacts.
When should I use this skill?
The user asks what exists, how platforms differ, or what the solution landscape looks like before committing to a build plan.
What you get
Validated `.survey/{slug}/` folder with triage.md, context.md, solutions.md, and optional platform-map.md plus a factual survey summary.
- validated .survey/{slug}/ markdown package
- factual survey summary
By the numbers
- Runs 4 parallel research lanes every survey pass
- Produces up to 4 markdown artifacts per `.survey/{slug}/` folder
- Skill version 2.1.7 in the 128-installable-skill oh-my-skills repo
Files
Survey
Use this skill when the job is discovering the landscape before committing to a plan.
survey stays portable by doing four things well: 1. freeze one bounded research question, 2. run the same 4 research lanes every time, 3. save reusable .survey/{slug}/ artifacts with fixed headings, 4. validate the artifact contract before handing off to planning or execution.
Read these support docs before running unfamiliar survey work:
- references/evidence-recovery-ladder.md
- references/platform-adapter-and-artifact-contract.md
- references/output-templates-and-validator.md
- references/keyword-sweep-and-relevance-rescue.md
- references/gh-search-empty-lane-recovery-playbook.md
When to use this skill
- The user asks what exists, what people actually use, or what the current solution landscape looks like.
- A feature, workflow, tooling choice, or operational pain needs context before planning or implementation.
- The topic spans multiple platforms or vendors and needs a vendor-neutral comparison.
- Repo maintenance needs one bounded research pass before rewriting a skill, SOP, or reusable workflow.
- The right next step depends on understanding workarounds, repeated complaints, and structural gaps rather than writing code immediately.
When not to use this skill
- The solution is already known and the user wants implementation now → implement or route to the execution skill directly.
- The task is a small bug fix, narrow code change, or single-file edit → do not force a survey first.
- The user needs an architecture plan, task plan, or immutable spec more than market/workflow discovery →
plan,jeo, orralph. - The request is mainly a live browse-and-click task → use a browser/operator skill instead of pretending the work is a survey.
Artifact contract
Keep the output package stable:
.survey/{slug}/
├── triage.md
├── context.md
├── solutions.md
└── platform-map.md # required for agent/tooling/platform topicsRequired meanings:
triage.md= problem, audience, why nowcontext.md= workflow context, affected users, workarounds, adjacent problems, user voicessolutions.md= solution list, categories, actual behavior, frequency, gaps, contradictions, key insightplatform-map.md=settings,rules,hooks,platform gapsnormalized across Claude / Codex / Gemini when relevant
Do not invent alternate filenames or free-form artifact shapes unless the user explicitly asks. Use python3 .agent-skills/survey/scripts/validate_survey_artifacts.py <path> after writing files whenever the survey output is meant to be reusable.
Instructions
Step 1: Classify one primary survey mode
Normalize the request before researching:
survey_run:
primary_mode: market-landscape | workflow-landscape | repo-maintenance | platform-comparison
scope: narrow | medium | broad
evidence_floor: primary-pages-first | indexed-snippets-allowed | thin-evidence-ok
output_language: repo-default | user-language
needs_platform_map: true | false
reuse_existing: true | false | unknownMode guide:
market-landscape→ products, categories, competitors, packaging, complaintsworkflow-landscape→ how people do the job now, workarounds, operational ritualsrepo-maintenance→ bounded research to improve an existing skill, SOP, or reusable workflowplatform-comparison→ normalize Claude / Codex / Gemini differences intosettings,rules,hooks
Choose one primary mode even if the topic touches more than one.
Step 2: Freeze the evidence contract
Before searching, make the rules explicit:
- search broadly in English unless the user requires another language
- write artifacts in the repo default or user language
- keep claims source-backed
- label downgraded evidence clearly:
direct page retrieval,indexed snippet,browser-rendered indexed snippet,feed recovery, orthin evidence - keep the task in research mode only
Use the cheap-first recovery order from references/evidence-recovery-ladder.md: 1. direct primary-page retrieval 2. stable official substitution 3. feed recovery 4. browser-rendered retrieval 5. indexed snippets 6. thin-evidence stop
Step 3: Triage the request and check reuse
Parse:
what— the pain point, idea, or capability to surveywho— who feels it or operates the workflowwhy— why it matters now
Then check whether .survey/{slug}/triage.md already exists.
- If it exists and the user is present, ask whether to reuse or overwrite.
- In unattended loops, reuse when the existing artifact still matches the same question; overwrite only when the scope has clearly changed.
Write triage.md with:
# Triage- Problem:- Audience:- Why now:
Step 4: Run the 4 lanes in parallel
Keep the lanes separate even if one is thinner.
Lane A — Context
Return:
## Workflow Context## Affected Users## Current Workarounds## Adjacent Problems## User Voices
Lane B — Solutions
Return:
## Solutions## Frequency Ranking## Categories## Curated Sources
Lane C — Actual behavior
Return:
## What People Actually Use## Common Workarounds## Pain Points With Current Solutions## Sources
Lane D — Alternatives or platform map
Default mode:
- JTBD alternatives
- indirect substitutes
- cross-industry parallels
For agent/tooling/platform topics, replace that with:
## Settings## Rules## Hooks## Platform Gaps
Use settings / rules / hooks as the common layer whenever Claude / Codex / Gemini differences are relevant.
Step 4.5: Apply a relevance gate for repo-maintenance surveys
When primary_mode: repo-maintenance, do not trust keyword hits at face value.
Run a compact gate before writing final recommendations:
- Positive signals (keep): clear relation to the target capability, recent maintenance, explicit license, concrete docs/examples.
- Negative signals (drop or mark risk): spam-like description, irrelevant domain despite keyword match, assessment/homework-only repos, stale/archived repos without strong justification, missing basic metadata, or unknown license without explicit justification.
- Metadata minimum: capture
license,pushed_at,archived,open_issues,forks, and one-line fit rationale for every candidate you keep. If first-pass metadata returns null/unknown license (for example GraphQLlicenseInfo), retry once via GitHub REST (gh api repos/<owner>/<repo> --jq .license.spdx_id) before classifying unknown-license. Unknown/missing license after fallback should be excluded by default unless a concrete exception rationale is documented. Ifopen_issues/forksare unavailable from the first pass, hydrate once viagh api repos/<owner>/<repo> --jq '{open_issues: .open_issues_count, forks: .forks_count}'and record retrieval provenance. - Freshness floor (recommendation-grade keep list): exclude candidates whose latest
pushed_atis older than 24 months by default. Keep stale candidates only with explicit exception rationale and risk note.
If search/extract tooling is degraded, fallback to direct GitHub API retrieval and mark provenance/risk explicitly instead of pretending confidence.
Step 4.6: Hourly candidate sweep (repo-maintenance cron loops)
When the survey is part of a recurring skill-maintenance loop, run one explicit keyword sweep before final recommendations.
Required keyword families:
agentic ai skillweb frontend skillweb backend skillcli open source skillgame development skill
Execution rules:
- Use a recency-first query window for hourly runs: default to
pushedwithin the last 24h~7d, then widen only through documented recovery stages. - Keep the raw keyword scan as discovery evidence (usually
browser-rendered retrievalwhen done through search pages). - Apply the Step 4.5 relevance gate before keeping any candidate.
- For each kept candidate, record at least:
license,pushed_at/updated,archived,open_issues,forks, and one-line fit rationale. - For recommendation-grade keeps, apply a default freshness floor (
pushed_atwithin the last 24 months). If kept despite staleness, document exception rationale and explicit risk. - Apply a default signal floor for recommendation-grade keeps: require at least one traction signal (for example, stars >= 3, or explicit maintainer/community adoption evidence with rationale). Keep broad discovery evidence even when the recommendation-grade list is stricter.
- For the
agentic ai skilllane, treat generic personal catch-all repositories named only like*/skillsas low-fit by default unless there is explicit workflow documentation + traction; keep them in raw evidence but do not promote to TOP recommendations without an exception rationale. - Apply a negation-aware intent guard before recommendation-grade promotion: when lane-intent token overlap appears only inside explicit negation phrases (for example
no cli,without cli,not a cli,non-cli), classify aslow-fitby default, keep in raw discovery evidence, and require an explicit exception rationale to promote. - If direct web search/extract tooling fails (auth/rate-limit/transport), switch to GitHub-native retrieval (
gh search+gh apiorgh repo view) and label provenance clearly. - Guard for GH CLI JSON-field drift in unattended loops: prefer
gh search repos --json fullName,...(or compose identity fromowner+name) instead of unsupported fields likenameWithOwner; if a field mismatch occurs, preserve stderr in evidence and rerun with supported fields before final lane status. - Guard for
gh search reposempty-success payloads in unattended loops: if exit code is 0 but payload is unexpectedly[](or trivially empty) for a known-populated probe/query, treat this as degraded transport and rerun via GitHub REST search before final lane status. - For the REST fallback path, prefer endpoint form
gh api "search/repositories?q=<query>&per_page=<n>&sort=updated&order=desc"and capture stderr artifacts; avoid relying on incompatible forms that can 404 in some environments. - In markdown artifacts validated with
--require-provenance, map GitHub search result evidence to validator-supported labels (indexed snippetfor search-result listings,direct page retrievalfor repo/API detail fetches) instead of ad-hoc labels likegithub search api. - If keyword hits are noisy or sparse, run lane-specific recovery templates from
references/keyword-sweep-and-relevance-rescue.mdbefore finalizing recommendations. - Use objective recovery triggers after the primary query (
raw_count < 8,kept_count == 0, orzero_star_raw/raw_count >= 0.70) so lane rescue is deterministic in unattended cron loops. - Metric integrity gate (mandatory): after each recovery query selection, recompute lane metrics from the final selected result set before writing artifacts (
raw_count,zero_star_raw,median_stars_raw,kept_count). Never emit impossible combinations likekept_count > raw_count. - If a lane still has
raw_count == 0after stage-1 recovery, run exactly one documented stage-2 recovery query for that lane before finalizinglane_status. - For noisy lanes where raw hits exist but recommendation-grade keeps remain
kept_count == 0after stage-1 recovery, run exactly one documented stage-2 recovery query before finalizing degraded status. - If a lane still ends with
raw_count == 0after documented recovery, set/reportdegraded_causeswith explicitno-results(do not leave it empty). - Recommendation thresholds after relevance gate: aim for at least 1 keep per lane where feasible, and
cli open source skillshould target 3+ kept entries for spotlight quality. - Emit explicit lane-level status in markdown (
lane_status: pass|degraded). If thresholds are missed, keep evidence and reportdegraded_causeswith compact taxonomy (license,stale,low-fit,archived,low-signal,no-results) plus examples/counts. - When a lane remains
raw_count == 0even after the documented stage-2 recovery query, set and reportdegraded_causesincludingno-results(do not leave degraded causes empty). - Alongside
lane_status, include compact lane-health metrics (kept_count,raw_count,median_stars_raw,zero_star_raw) so reviewers can track quality drift across hourly runs. - Add a cross-lane concentration check for recommendation-grade keeps: if
recommended_lane_count < 2, mark the run assingle_lane_concentration: true, keep degraded-lane evidence explicit, and avoid claiming broad coverage health. - Add a cross-lane recommendation dedup gate before final ranking: preserve raw discovery evidence unchanged, but compute a deduplicated recommendation-grade set keyed by repository identity (
fullNameorowner/name) and report both raw and dedup coverage metrics.
Reference: references/keyword-sweep-and-relevance-rescue.md
Step 5: Synthesize the artifacts
Keep the written files compact and schema-stable.
- Use the exact markdown templates in references/output-templates-and-validator.md.
- Keep the required filenames and headings unchanged.
- Preserve honest provenance labels when evidence is weak.
- For platform topics, make
platform-map.mdexplicit instead of burying platform differences insolutions.md. - For
repo-maintenance, show why each kept candidate passed the relevance gate (fit + metadata + risk).
Step 6: Validate the artifact contract
Run the validator after writing the files:
python3 .agent-skills/survey/scripts/validate_survey_artifacts.py .survey/<slug>
python3 .agent-skills/survey/scripts/validate_survey_artifacts.py .survey/<slug> --platform-topicUse --platform-topic when platform-map.md is required. If provenance labels matter for the run, also use:
python3 .agent-skills/survey/scripts/validate_survey_artifacts.py .survey/<slug> --require-provenanceIf the validator fails, fix the artifact files before handing off to planning or implementation.
Step 7: End with a factual survey summary
Return a short summary only after files are written and validated:
## Survey complete: {slug}- 1-2 context bullets including the main workaround
- 1-2 solution-landscape bullets including the key insight and key gap
- file list for the generated artifacts
Do not slide into planning or implementation unless the user explicitly asks for the next step.
Output rules
- Facts first, recommendations second only if requested.
- One bounded question per survey artifact.
- Keep solution names deduplicated, and deduplicate recommendation-grade repositories across lanes before final ranking while preserving raw evidence.
- Preserve evidence labels when sources are weak or indirect.
- Keep the output artifact schema identical across platforms.
- Route architecture/planning/execution work outward once the survey is done.
Examples
Example 1: Repo-maintenance survey
Input
survey which existing skill in this repo is the best bounded maintenance target next
Good output direction
- mode:
repo-maintenance - checks existing
.survey/{slug}first - uses repo-local graph/wiki evidence plus any necessary primary-source retrieval
- writes triage/context/solutions and a factual summary
- validates the output folder before any skill rewrite starts
Example 2: Platform comparison
Input
survey how Claude Code, Codex, and Gemini CLI differ for hooks, approvals, and research workers
Good output direction
- mode:
platform-comparison - writes
platform-map.md - normalizes differences into
settings,rules,hooks - validates with
--platform-topic - records portability gaps without treating vendor-specific features as the artifact contract
Best practices
1. Keep the front door small: classify mode, freeze evidence rules, run the 4 lanes, validate, and save the artifacts. 2. Push slow-changing retrieval/platform/template detail into references instead of bloating the main skill. 3. Prefer direct primary sources, but label every downgrade honestly. 4. Preserve the same artifact filenames and headings across Claude / Codex / Gemini runs. 5. If evidence is thin, narrow the claim instead of bluffing certainty. 6. Treat hook systems as accelerators around the validator, not replacements for checked-in artifact rules.
References
references/evidence-recovery-ladder.md— fallback ladder and provenance labels for weak search/extract environmentsreferences/platform-adapter-and-artifact-contract.md— portability rules forsettings,rules,hooks, and identical artifact output across platformsreferences/output-templates-and-validator.md— exact file templates plus validator usage for.survey/{slug}/references/keyword-sweep-and-relevance-rescue.md— required five-keyword sweep and noisy-query rescue gate for recurring repo-maintenance loopsscripts/validate_survey_artifacts.py— artifact-contract validator for survey output folders
{
"skill_name": "survey",
"evals": [
{
"id": 1,
"prompt": "survey this workflow: our normal web search API is returning 401 errors, but we still need a landscape scan of browser automation tools before planning implementation",
"expected_output": "The survey run keeps the 4-lane structure, writes `.survey/{slug}/` artifacts, and explicitly falls back from broken search/extract tooling to direct retrieval or labeled downgrade paths instead of stopping.",
"assertions": [
"Mentions direct primary-page retrieval or another explicit fallback after search/extract failure",
"Preserves the `.survey/{slug}/` artifact structure",
"Keeps the task in research mode rather than implementation mode"
]
},
{
"id": 2,
"prompt": "survey which existing skill in this repo is the best bounded maintenance target next, using the graph report and wiki first",
"expected_output": "A repo-maintenance survey that classifies the run, reuses repo-local evidence, and writes factual triage/context/solutions artifacts before any implementation starts.",
"assertions": [
"Classifies the request as repo-maintenance or equivalent",
"Uses repo-local evidence such as graph/wiki/skill files before broad external search",
"Does not jump straight into rewriting the target skill inside the survey step"
]
},
{
"id": 3,
"prompt": "survey how Claude Code, Codex, and Gemini CLI differ for hooks, approvals, and research-worker setup before we standardize one survey workflow",
"expected_output": "A platform-comparison survey that writes `platform-map.md` and normalizes the answer into `settings`, `rules`, `hooks`, and portability gaps rather than dumping vendor trivia.",
"assertions": [
"Includes `settings`, `rules`, and `hooks` as the comparison frame",
"Creates or explicitly requires `platform-map.md` for the topic",
"Calls out at least one portability gap instead of pretending the platforms are identical"
]
},
{
"id": 4,
"prompt": "fix this one-line TypeScript error in src/auth.ts",
"expected_output": "A response that does not activate a full survey flow when the task is just a narrow implementation fix.",
"assertions": [
"States that survey is not the right mode for a tiny bugfix or narrow code change",
"Routes to implementation or a more direct debugging/coding path",
"Does not prescribe full `.survey/{slug}/` artifact creation for the one-line fix"
]
},
{
"id": 5,
"prompt": "survey this repo-maintenance question, then leave the findings in a reusable folder for later automation",
"expected_output": "The survey writes the canonical `.survey/{slug}/` files and explicitly validates the artifact folder before handing off to planning or implementation.",
"assertions": [
"Mentions validating the artifact contract after writing files",
"Uses the repo-local validator script or equivalent validation command",
"Keeps the survey output in the canonical filenames instead of inventing a new folder layout"
]
},
{
"id": 6,
"prompt": "survey Claude Code vs Codex vs Gemini CLI for hooks and worker orchestration, and make the result portable for a cron loop",
"expected_output": "The survey requires `platform-map.md`, preserves the fixed headings, and treats hooks as optional accelerators around a portable artifact contract rather than the only source of truth.",
"assertions": [
"Requires `platform-map.md` or validates with a platform-topic mode",
"States that repo-local artifact files remain the durable source of truth",
"Treats hooks as optional runtime wrappers instead of assuming hook parity across platforms"
]
},
{
"id": 7,
"prompt": "run the hourly repo-maintenance survey with mandatory keyword families (agentic ai skill, web frontend skill, web backend skill, cli open source skill, game development skill) even if web search fails",
"expected_output": "The survey explicitly runs all five keyword families, applies relevance-gated metadata capture for kept candidates, and falls back to GitHub-native retrieval when search/extract tooling is degraded.",
"assertions": [
"Runs or explicitly requires all five keyword families for hourly repo-maintenance mode",
"Captures license, pushed_at/updated, archived, and fit rationale for kept candidates",
"Uses a fallback path (gh search/gh api/gh repo view) when direct search or extraction fails",
"Uses `gh search repos` JSON fields compatible with CLI output (e.g., fullName and license)"
]
},
{
"id": 8,
"prompt": "run an hourly keyword sweep and handle noisy frontend results where many matches are assessment repos with unknown licenses",
"expected_output": "The survey keeps keyword coverage evidence, retries null license metadata once via GitHub REST before final classification, excludes low-transfer assessment/homework repos, and requires explicit exception rationale only when license remains unknown after fallback.",
"assertions": [
"Applies a relevance gate that filters assessment/homework-only repositories by default",
"Retries null/unknown license metadata with `gh api repos/<owner>/<repo>` before drop/exception handling",
"Treats unknown/missing license after fallback as drop or exception-only with explicit rationale",
"Preserves provenance and lane coverage even when filtering aggressively"
]
},
{
"id": 9,
"prompt": "run the hourly survey and backend keyword hits include mostly stale repos last pushed more than 2 years ago",
"expected_output": "The survey keeps discovery evidence for lane coverage but applies a recommendation-grade freshness floor, dropping stale candidates by default unless an explicit exception rationale and risk note are provided.",
"assertions": [
"Enforces a default freshness floor using pushed_at recency (24 months) for recommendation-grade keeps",
"Allows stale candidates only when explicit exception rationale is documented",
"Maintains provenance and required-lane evidence even after freshness filtering"
]
},
{
"id": 10,
"prompt": "run the hourly five-lane keyword sweep where frontend and game lanes are sparse/noisy; keep the report merge-ready for cron automation",
"expected_output": "The survey uses lane-specific recovery templates for sparse/noisy lanes, records lane-level threshold outcomes (>=1 keep where feasible, CLI target 3+), and explicitly reports why any lane stays below threshold.",
"assertions": [
"Invokes lane-specific recovery queries from the keyword sweep reference when sparse/noisy conditions appear",
"Reports lane-level threshold status after relevance gating, including CLI 3+ spotlight target",
"Preserves evidence and provenance instead of silently dropping under-threshold lanes"
]
},
{
"id": 11,
"prompt": "run the hourly five-lane survey and two lanes still miss thresholds after recovery; produce a reviewer-ready markdown summary",
"expected_output": "The survey marks each lane with `lane_status` (`pass|degraded`) and reports `degraded_causes` using the compact taxonomy (`license`, `stale`, `low-fit`, `archived`, `low-signal`, `no-results`) with concrete examples or counts.",
"assertions": [
"Includes explicit lane_status labels in markdown output for each lane",
"Uses degraded_causes taxonomy (`license|stale|low-fit|archived|low-signal|no-results`) when thresholds are missed",
"When a degraded lane has raw_count==0 after documented recovery, includes `no-results` explicitly",
"Keeps provenance/evidence references while reporting degraded lanes"
]
},
{
"id": 12,
"prompt": "run a survey in a degraded source environment and keep artifact validation green",
"expected_output": "The survey uses validator-compatible provenance labels (including `thin evidence` when needed), explicitly maps GitHub-native retrieval to accepted labels (`indexed snippet`/`direct page retrieval`), and avoids unsupported labels that break `--require-provenance` checks.",
"assertions": [
"Uses a provenance label accepted by the validator (`direct page retrieval|feed recovery|browser-rendered retrieval|indexed snippet|browser-rendered indexed snippet|thin evidence`)",
"Avoids unsupported provenance labels in final markdown artifacts (e.g., does not emit ad-hoc labels like `github search api`)",
"Keeps the survey report explicit about reduced confidence when `thin evidence` is used"
]
},
{
"id": 13,
"prompt": "run the hourly five-lane survey and make lane status reviewer-ready for trend tracking",
"expected_output": "The survey reports lane_status with compact lane-health metrics (`kept_count`, `raw_count`, `median_stars_raw`, `zero_star_raw`) so reviewers can compare quality drift between hourly runs.",
"assertions": [
"Reports lane_status (`pass|degraded`) per lane in markdown",
"Includes lane-health metrics (`kept_count`, `raw_count`, `median_stars_raw`, `zero_star_raw`) alongside lane_status",
"Applies lane-metric integrity checks so empty lanes do not report impossible values (raw_count==0 => zero_star_raw=0, median_stars_raw=0; raw_count>=kept_count)",
"Keeps degraded_causes/provenance context when a lane is under threshold"
]
},
{
"id": 14,
"prompt": "run the hourly five-lane sweep where primary queries are noisy and mostly zero-star results; keep the run deterministic for unattended cron",
"expected_output": "The survey applies objective recovery triggers (`raw_count < 8`, `kept_count == 0`, or high zero-star ratio) before lane rescue, then documents provenance and lane_status outcomes for reviewer verification.",
"assertions": [
"Uses explicit numeric recovery triggers rather than ad-hoc judgment for rescue activation",
"Runs lane-specific recovery queries when trigger conditions are met",
"Preserves provenance and lane_status/degraded_causes reporting after recovery"
]
},
{
"id": 15,
"prompt": "run the hourly five-lane survey where one lane only has recently updated but very low-traction repositories; keep discovery evidence broad but recommendation-grade keeps strict",
"expected_output": "The survey preserves raw lane evidence but applies a recommendation-grade signal floor (for example stars>=3 or explicit adoption rationale), and reports `low-signal` in degraded causes when thresholds are missed.",
"assertions": [
"Keeps broad discovery evidence while applying stricter recommendation-grade keep rules",
"Requires a traction signal or explicit exception rationale for low-signal candidates",
"Reports `low-signal` explicitly in degraded_causes when applicable"
]
},
{
"id": 16,
"prompt": "run the hourly five-lane survey where backend remains raw_count=0 after stage-1 recovery query; keep the run deterministic for cron",
"expected_output": "The survey runs one documented stage-2 recovery query for that lane before final lane_status, then applies the same relevance/provenance/quality gates to any recovered hits.",
"assertions": [
"Escalates once with a documented stage-2 lane query when stage-1 still yields raw_count==0",
"Keeps recommendation-grade filters (license/freshness/signal) on stage-2 results",
"Reports provenance and final lane_status/degraded_causes after escalation"
]
},
{
"id": 17,
"prompt": "run the hourly five-lane survey where agentic results are dominated by personal repositories named only \"skills\"; keep recommendations reviewable",
"expected_output": "The survey preserves those hits as raw discovery evidence but classifies generic personal `*/skills` repos as low-fit by default unless concrete workflow docs plus traction justify an exception.",
"assertions": [
"Keeps noisy personal `*/skills` hits in evidence while preventing blind promotion into TOP recommendations",
"Requires explicit workflow-documentation and traction rationale for any exception",
"Maintains provenance and degraded-cause reporting when this noise pattern appears"
]
},
{
"id": 18,
"prompt": "run the hourly five-lane survey where only one lane produces recommendation-grade keeps and all other lanes are degraded",
"expected_output": "The survey explicitly reports cross-lane concentration (`recommended_lane_count`, `single_lane_concentration`) and avoids claiming broad coverage health when recommendations cluster in a single lane.",
"assertions": [
"Reports `recommended_lane_count` in markdown or structured summary",
"Sets or states `single_lane_concentration` when recommendation keeps come from a single lane",
"Keeps degraded-lane evidence and causes visible instead of hiding lane imbalance"
]
},
{
"id": 19,
"prompt": "run the hourly five-lane survey where frontend lane has raw hits but still kept_count=0 after stage-1 recovery due to low-signal noise",
"expected_output": "The survey performs one documented stage-2 query for the noisy lane (not only raw_count==0 lanes), then reapplies the same relevance/provenance gates before final lane_status.",
"assertions": [
"Escalates with one stage-2 lane query when raw hits exist but recommendation-grade keeps remain zero after stage-1",
"Reapplies license/freshness/signal/fit gates on stage-2 results",
"Reports provenance plus final lane_status/degraded_causes after noisy-lane escalation"
]
},
{
"id": 20,
"prompt": "run the hourly five-lane survey where game-development lane is sparse: stage-1 recovery returns raw_count=0, so the run must stay deterministic",
"expected_output": "The survey applies the documented game lane stage-2 recovery query, then reports final lane_status with explicit degraded causes if recommendation-grade keeps still fail thresholds.",
"assertions": [
"Runs the documented game-development stage-2 recovery query when stage-1 is empty or still keeps=0",
"Reapplies recommendation-grade gates (license/freshness/signal/fit) to stage-2 hits",
"Reports lane_status, lane metrics, and degraded_causes transparently after escalation"
]
},
{
"id": 21,
"prompt": "run hourly survey with a strict recency-first policy: start from pushed within 24h~7d and widen only when a lane is empty/noisy",
"expected_output": "The survey starts with a 24h~7d recency window for all mandatory lanes, records explicit stage recovery query widening, and preserves lane metric integrity after switching query windows.",
"assertions": [
"Applies an initial recency-first query window (24h~7d) per lane before broader recovery",
"Documents any query widening as stage-1/stage-2 recovery attempts with exact query strings",
"Recomputes raw_count/kept_count/zero_star_raw/median_stars_raw from the final selected set after recovery"
]
}
]
}
Evidence Recovery Ladder for survey
Use this note when a survey lane cannot rely on normal web-search or page-extract tooling.
1. Direct primary-page retrieval
Start with the canonical or most likely primary URL.
Recover at least:
- final URL / redirect target
<title>- meta description (if present)
- exact keyword presence for the claim you want to make
Recommended lightweight pattern:
python3+urllib.request- browser-like
User-Agent - note the recovery as
direct page retrieval
Good for:
- vendor docs
- standards pages
- product/use-case pages
- stable reference material
2. Stable official substitution
If a cited blog/resource URL 404s or drifts:
- prefer a durable official page that still covers the same workflow
- record that the original URL drifted
- do not pretend the substitute is the same document
Good for:
- product overview pages replacing dead announcement posts
- stable docs replacing drifted blog links
3. Structured publication fallback
If the site exposes a feed:
- check RSS / Atom autodiscovery or common feed endpoints
- recover canonical links, timestamps, and summaries
- treat feed summaries as weaker than the full page unless they include the full content
Record as:
feed recoverydirect page retrieval via feed-discovered URL
4. Browser-rendered retrieval
Escalate here when:
- direct fetch returns incomplete HTML
- the page is JS-rendered
- anti-bot noise hides the real content
- redirect/cookie behavior matters
Use a browser view to recover:
- visible title/snippet text
- rendered result blocks
- network/API endpoints if needed
Record as:
browser-rendered retrieval
5. Indexed snippet recovery
Use when the primary page or social post is not directly recoverable but search results still expose useful text.
Rules:
- label explicitly as
indexed snippetorbrowser-rendered indexed snippet - include confidence:
high,medium, orlow - use snippets for existence/topic/workflow phrasing, not as a perfect substitute for the full source
Confidence hints:
- high — URL + snippet recovered in the same run
- medium — platform/page inferred but original page not opened
- low — generic snippet with little workflow detail
6. Thin-evidence stop
If all recovery paths remain weak:
- say the evidence is thin
- preserve what was recovered
- continue the survey without inventing certainty
- downgrade the claim to a hypothesis if needed
Provenance labels
Use one of these labels in the survey artifact:
direct page retrievalfeed recoverybrowser-rendered retrievalindexed snippetbrowser-rendered indexed snippetthin evidence
Practical reminders
- Cheap-first escalation beats going straight to a full browser.
- Prefer primary sources over tertiary summaries when the claim matters.
- Stable official pages are often better than dead blog guesses.
- Snippets are useful, but they must stay visibly lower-confidence than direct retrieval.
GitHub-heavy survey fallback (keyword scans)
When the survey topic is mostly GitHub repositories and search reliability drops (API auth failure, secondary rate limits, noisy keyword matches): 1. Keep keyword-search evidence, but label it as browser-rendered retrieval and treat it as discovery, not final truth. 2. Re-verify shortlisted candidates via direct repo pages/API (direct page retrieval) for stars, license, archived status, and recent updates. 3. Prefer authenticated gh api retrieval when available to reduce unauthenticated rate-limit failures. 4. If one keyword surface is too noisy (common for frontend/backend/game "skill" queries), use stable seed repos that match the workflow intent and state that this is a quality filter, not keyword-only ranking. 5. If sandbox TLS trust is broken (CERTIFICATE_VERIFY_FAILED), use an unverified SSL context only for non-destructive metadata retrieval, and explicitly flag this as risk in artifacts/reports.
Keyword sweep quality rescue matrix (hourly maintenance)
When hourly runs require fixed keyword coverage (agentic ai skill, web frontend skill, web backend skill, cli open source skill, game development skill), use this matrix before selecting a candidate:
| Keyword bucket | Suggested seed repos (example) | Keep signals | Drop/risk signals |
|---|---|---|---|
| agentic ai skill | langchain-ai/langgraph, microsoft/autogen, crewAIInc/crewAI | active maintenance, explicit agent orchestration docs, permissive license | archived repos, model wrappers with no workflow guidance |
| web frontend skill | vercel/next.js, sveltejs/svelte, vuejs/core | framework/runtime relevance to UI workflows, recent pushes | generic UI collections without operational workflow |
| web backend skill | fastapi/fastapi, django/django, nestjs/nest | production backend patterns (API/auth/testing/deploy) | sample-only repos, dummy API datasets, missing license |
| cli open source skill | junegunn/fzf, charmbracelet/gum, sharkdp/bat | clear CLI operator value, documented commands, active releases | listicle/meta repos, shell config bundles unrelated to target workflow |
| game development skill | godotengine/godot, bevyengine/bevy, MonoGame/MonoGame | reproducible build/test/export workflows, active engine docs | archived game lists, showcase-only repos without operator workflow |
Mandatory metadata + fit rationale before proposing
For each kept candidate, record:
license(or explicit missing-license risk)pushed_atarchivedopen_issuesforks- one-line fit rationale tied to the exact skill scope
- if
open_issues/forksare missing on first pass, hydrate once viagh api repos/<owner>/<repo> --jq '{open_issues: .open_issues_count, forks: .forks_count}'
Do not promote a candidate to TOP proposals when it fails metadata minimums unless the report labels it explicitly as risk/experimental.
GH Search Empty-Lane Recovery Playbook
Use this playbook in hourly survey runs when gh search repos returns an empty list for a mandatory lane.
Trigger
- Lane query exit code is 0 but payload is
[] - Or lane has
raw_count == 0after the primary query
Mandatory recovery sequence
1. Keep original lane output as discovery evidence. 2. Run stage-1 recovery query with stars/freshness constraints. 3. If still raw_count == 0, run exactly one stage-2 query for the lane. 4. If GH search remains empty/noisy, run REST fallback:
gh api "search/repositories?q=<query>&per_page=20&sort=updated&order=desc"
5. Recompute lane metrics from the final selected result set before writing evidence.json.
Required evidence notes
lane_status: degradedwith causeno-resultswhen lane remains empty after documented recovery.transport_statusnote only when all five lanes are zero due to retrieval degradation.- Provenance label must use validator-supported terms (
indexed snippet,direct page retrieval, etc.).
Validation checklist
raw_count >= kept_count- if
raw_count == 0: setzero_star_raw = 0andmedian_stars_raw = 0 - run
validate_survey_artifacts.py --platform-topic --require-provenance
Keyword Sweep and Relevance Rescue (Hourly Repo-Maintenance)
Use this guide when a survey run is part of recurring skill maintenance (for example, hourly cron loops).
Required keyword families (hourly maintenance loop)
Run all five keyword families before final recommendations:
1. agentic ai skill 2. web frontend skill 3. web backend skill 4. cli open source skill 5. game development skill
Keep the raw sweep output as discovery evidence.
Why this exists
Broad keyword sweeps improve recall but can produce noisy or sparse results. Without a relevance gate, low-fit repositories pollute recommendations. Without a rescue path, empty lanes can be misread as ecosystem absence.
Compact relevance gate
For each candidate you keep, capture at minimum:
license(normalize payload shapes first:license.spdx_id,license.spdxId,license.key,license.name; if still null/unknown or empty-object like{"key":"","name":""}, enrich once withgh repo view <owner>/<repo> --json licenseInfoand then fallback togh api repos/<owner>/<repo> --jq .license.spdx_id)pushed_atorupdated_atarchivedopen_issuesforks- one-line fit rationale
- if
open_issues/forksare unavailable in first-pass metadata, hydrate once viagh api repos/<owner>/<repo> --jq '{open_issues: .open_issues_count, forks: .forks_count}'
Positive keep signals:
- Clearly related to the target capability
- Recently maintained
- Explicit license
- Concrete docs/examples
Freshness default for recommendation-grade keeps:
- Keep if
pushed_atis within the last 24 months. - Compute and record
months_since_push(or equivalent age bucket) for each recommendation-grade keep candidate so stale filtering is auditable. - Otherwise, drop by default or keep only with an explicit exception rationale and risk note.
- If a lane loses keeps primarily due to freshness, include
staleindegraded_causeswith a count/example in markdown.
Signal floor default for recommendation-grade keeps:
- Preserve broad discovery evidence, but do not promote low-traction candidates by default.
- Require at least one traction signal for keeps (for example, stars >= 3, or explicit maintainer/community adoption evidence with rationale).
- If a lane is sparse and a low-signal keep is still needed, document the exception rationale and risk note explicitly in markdown.
Drop or risk-mark signals:
- Keyword-only match but wrong domain
- Lane-intent token appears only in explicit negation phrases (for example
no cli,without cli,not a cli,non-cli) and no exception rationale is documented - Generic personal catch-all repos (especially
*/skills) without concrete workflow docs and traction - Assessment/homework/demo-only repos with low transferability
- Archived/stale without strong reason
- Missing basic metadata or unknown license without exception note
- Spam-like or boilerplate descriptions
- CLI negation patterns (
no cli,without cli,not a cli,non-cli) unless explicit exception rationale is documented
Lane-intent token-overlap gate (recommendation promotion guard):
- Build a compact lane token set (for example:
agentic|ai|skill,frontend|ui|design|component,backend|api|framework|observability,cli|terminal|command,game|engine|gamedev|pipeline). - For recommendation-grade keeps, require at least one lane-intent token (or documented synonym) in
fullNameor repository description. - If no overlap, keep the repository in raw discovery evidence but classify it as
low-fitfor promotion decisions. - Record at least one concrete off-topic example when this guard filters candidates, so reviewers can audit why precision improved.
Rescue path for sparse/noisy lanes
Trigger a recovery pass when any of the following is true after the primary keyword query:
raw_count < 8kept_count == 0zero_star_raw / raw_count >= 0.70(forraw_count > 0)aggregate_zero_star_ratio >= 0.50across all five keyword lanes (cross-lane raw-quality collapse trigger)- query transport degrades (auth/rate-limit/empty payload)
If direct web search/extract is degraded or returns mostly noise:
1. Switch to GitHub-native retrieval (gh search repos, gh api, gh repo view). 2. For gh search repos --json, prefer supported fields like fullName (or compose identity from owner + name) instead of unsupported fields such as nameWithOwner; when schema mismatch happens, persist stderr in evidence and rerun with supported fields before final lane status. 3. Guard for gh search repos empty-success payloads ([] with exit 0) using a known-populated probe/query; when triggered, mark lane retrieval as degraded and rerun via GitHub REST search endpoint form (gh api "search/repositories?q=<query>&per_page=<n>&sort=updated&order=desc"). 4. Add curated seed repositories relevant to the target capability. 5. Apply the same relevance gate to seed candidates. 6. Label provenance explicitly (direct page retrieval, browser-rendered retrieval, etc.). 7. Preserve raw discovery evidence even when all recommendation-grade keeps are filtered.
Lane-level recovery templates (hourly default)
Use these as fallback queries after the primary keyword family returns sparse/noisy matches.
Before running fallback queries, compute a rolling freshness floor once per run (24 months) and reuse it in every pushed: qualifier:
ROLLING_CUTOFF=$(python3 - <<'PY'
from datetime import datetime, timedelta
print((datetime.utcnow() - timedelta(days=730)).strftime('%Y-%m-%d'))
PY
)Then substitute ${ROLLING_CUTOFF} in templates:
agentic ai skilllaneai agent framework skills automation stars:>200 pushed:>=${ROLLING_CUTOFF}web frontend skilllane- Stage 1:
frontend ui component design system stars:>300 pushed:>=${ROLLING_CUTOFF} - Stage 2 (deterministic escalation when Stage 1 keeps remain
kept_count == 0due to noisy/low-signal hits):frontend engineering workflow design system toolkit stars:>120 pushed:>=${ROLLING_CUTOFF} web backend skilllane- Stage 1:
backend api framework observability stars:>300 pushed:>=${ROLLING_CUTOFF} - Stage 2 (deterministic escalation when Stage 1 still has
raw_count == 0):backend developer platform api template stars:>150 pushed:>=${ROLLING_CUTOFF} cli open source skilllanecommand line tool developer productivity stars:>200 pushed:>=${ROLLING_CUTOFF}github cli terminal tool stars:>200 pushed:>=${ROLLING_CUTOFF}game development skilllanegame engine tooling pipeline stars:>150 pushed:>=${ROLLING_CUTOFF}
Stage-2 escalation rule:
- If a lane remains
raw_count == 0after stage-1 recovery, run exactly one stage-2 query template for that lane before finalizinglane_status. - For lanes that are noisy (raw hits exist but recommendation-grade keeps remain
kept_count == 0after stage-1), run exactly one stage-2 query template before finalizing degraded status. - Keep provenance labels and apply the same relevance + metadata + signal/freshness gate to stage-2 hits.
- If
raw_count == 0after Stage 2, setdegraded_causesto includeno-results(alongside other causes) so empty lanes remain explicit in run reports.
Minimum recommendation thresholds (after relevance gate)
- At least 1 recommendation-grade keep per lane where feasible.
cli open source skilllane target: 3+ kept entries for spotlight quality.- For each lane, emit explicit
lane_statusin markdown:passordegraded. - If a lane is below threshold, keep discovery evidence and report
degraded_causesusing a compact taxonomy:license,stale,low-fit,archived,low-signal,no-results(include counts or concrete examples). - If a lane still has
raw_count == 0after stage-2 recovery, includeno-resultsexplicitly (never leave degraded causes empty for degraded lanes). - Add cross-lane concentration metrics for recommendation-grade keeps:
recommended_lane_countandsingle_lane_concentration(truewhen recommended keeps are concentrated in a single lane). - Before final ranking, compute a deduplicated recommendation-grade set keyed by repository identity (
fullNameorowner/name) and report both raw and dedup recommendation coverage metrics.
Open-PR first gate (hourly hard rule)
Apply this sequence at run start before any new branch/PR work:
- Query open PRs immediately (
gh pr list --state open). - If open PR count is
>=1, do not create a new branch/PR in that run. - Instead, triage existing PRs first: checks, conflict status, review state.
- If a PR is mergeable and checks are green, merge it first.
- If a PR is conflicting/duplicate, leave a blocker comment, close it, and clean its remote branch.
- Only when open PR count becomes
0may the run create a new branch and PR.
Checks-degraded escalation (PR lifecycle guard)
Use backlog-aware handling before opening a new hourly PR:
- Sample at least the two most recent carry-forward PRs with
gh pr checksbefore deciding mode. - If open PR backlog is high (default threshold:
>=10) and sampled carry-forward PRs showno checks reported, switch to checks-degraded mode for this run: generate artifacts + blocker report only, and do not open an additional PR. - If backlog is below the threshold, continue normal PR creation cadence, but keep merge gating strict.
- If sampled carry-forward PRs are also
DIRTYorCONFLICTINGwhile checks are absent, keep this run in blocker-report mode and avoid same-run conflict resolution churn.
When survey artifacts are valid but GitHub reports no checks reported on the current PR branch:
- Treat as hard blocker for merge in unattended hourly runs.
- Post a PR comment with exact blocker string and remediation steps (enable required checks or re-run workflows).
- Keep this run in
merge-blockedstate; do not force-merge. - Record
merge_blocked_reason: no-checks-reportedin the final run report.
Graphify compatibility note for unattended runs:
graphify save-resultcurrently requires--questionand--answer; do not pass unsupported flags such as--input.- If command contract mismatch occurs, persist stderr under the run folder and generate
graphify-refined.jsonfallback fromevidence.jsonso PR packaging still contains auditable knowledge artifacts.
Reporting checklist
Before final recommendations:
- [ ] All five keyword families executed
- [ ] Raw discovery evidence saved
- [ ] Relevance gate applied to kept candidates
- [ ] Metadata minimum recorded for each kept candidate
- [ ] Lane-level
lane_status(pass|degraded) included in markdown summary - [ ] For degraded lanes,
degraded_causes(license|stale|low-fit|archived|low-signal|low-signal-saturation|no-results) reported with examples/counts - [ ] Recommendation section reports both raw and deduplicated cross-lane coverage metrics
- [ ] Provenance labels present
- [ ] Risks for noisy or sparse lanes stated explicitly
Output Templates and Validator for survey
Use this note when writing or checking .survey/{slug}/ artifacts.
Required output package
.survey/{slug}/
├── triage.md
├── context.md
├── solutions.md
└── platform-map.md # required for agent/tooling/platform topicsRequired headings
triage.md
# Triage
- Problem: ...
- Audience: ...
- Why now: ...context.md
# Context: {project name}
## Workflow Context
...
## Affected Users
| Role | Responsibility | Skill Level |
|------|----------------|-------------|
| ... | ... | ... |
## Current Workarounds
1. ...
## Adjacent Problems
- ...
## User Voices
- "..." — sourcesolutions.md
# Solution Landscape: {project name}
## Solution List
| Name | Approach | Strengths | Weaknesses | Notes |
|------|----------|-----------|------------|-------|
| ... | ... | ... | ... | ... |
## Categories
...
## What People Actually Use
...
## Frequency Ranking
1. ...
## Key Gaps
- ...
## Contradictions
- ...
## Key Insight
...platform-map.md
# Platform Map: {project name}
## Settings
| Concern | Claude | Codex | Gemini | Common Layer |
|---------|--------|-------|--------|--------------|
| ... | ... | ... | ... | ... |
## Rules
| Concern | Claude / OMC | Codex / OMX | Gemini / OHMG | Common Layer |
|---------|---------------|-------------|---------------|--------------|
| ... | ... | ... | ... | ... |
## Hooks
| Lifecycle | Claude | Codex | Gemini | Common Layer |
|-----------|--------|-------|--------|--------------|
| ... | ... | ... | ... | ... |
## Platform Gaps
1. ...Validator commands
Default survey artifact check:
python3 .agent-skills/survey/scripts/validate_survey_artifacts.py .survey/<slug>Require platform-map.md plus its headings:
python3 .agent-skills/survey/scripts/validate_survey_artifacts.py .survey/<slug> --platform-topicRequire at least one survey provenance label somewhere in the artifacts:
python3 .agent-skills/survey/scripts/validate_survey_artifacts.py .survey/<slug> --require-provenanceEmit JSON for automation:
python3 .agent-skills/survey/scripts/validate_survey_artifacts.py .survey/<slug> --jsonWhat the validator checks
- target folder exists
- required files exist
- required headings exist in
triage.md,context.md, andsolutions.md platform-map.mdexists and containsSettings / Rules / Hooks / Platform Gapswhen--platform-topicis used- provenance labels appear somewhere when
--require-provenanceis used
Provenance labels accepted by the validator
direct page retrievalfeed recoverybrowser-rendered retrievalindexed snippetbrowser-rendered indexed snippetthin evidence
Scope guardrails
- The validator checks structure and basic provenance only.
- It does not score whether the research is strategically good.
- Keep strategic judgment in the survey lanes and the frozen evaluation harness, not in the script.
Run-slug guard (hourly automation)
- Always persist the current run slug once (for example
.survey/LATEST_SLUG) and pass it explicitly to every generator script via environment variable or argv. - Do not discover slug by listing
.survey/directories; mixed historical folders can silently target the wrong run and contaminate artifacts. - After generation, verify
git status --shortonly touches.survey/<current-slug>/paths before proceeding to PR.
Platform Adapter and Artifact Contract for survey
Use this note when the survey topic involves agent tooling, hooks, permissions, or cross-platform orchestration.
Why this reference exists
survey must stay portable across Claude / Codex / Gemini, but those platforms do not expose identical runtime features. The durable layer is the survey artifact contract, not the platform runtime.
Common abstraction layer
Normalize vendor-specific behavior into three buckets:
settings— model/config/project-level defaults, output mode, MCP enablement, approval defaultsrules— allow/deny policy, instruction files, subagent boundaries, sandbox/approval posturehooks— pre/post/error callbacks, notification handlers, validation wrappers, lifecycle automation
If a vendor feature maps cleanly into one of these, do not describe it as a one-off concept.
Portable baseline
Treat this as the portability floor:
1. Repo-local instructions are the source of truth
- Keep survey behavior in checked-in markdown or skill files.
- Do not duplicate the whole survey rubric into per-platform config blobs.
2. Assume least privilege
- The survey should still work in read-only or approval-heavy environments.
- Prefer one deterministic final write of the artifact files.
3. Hooks are optional accelerators
- Claude and Gemini have richer hook systems than the Codex docs in scope here.
- Validation must still be runnable as an ordinary post-generation step when no hook parity exists.
4. Subagents improve execution, not artifact shape
- Claude and Gemini both have strong subagent stories.
- Codex portability should not depend on first-class subagents.
- The 4-lane structure still matters, but the filenames and section headings must stay identical even when the runtime differs.
5. Project settings may be missing or untrusted
- Project-local config is useful, but the survey skill should not break when it is absent, ignored, or considered untrusted.
Artifact contract
Keep the same files everywhere:
.survey/{slug}/
├── triage.md
├── context.md
├── solutions.md
└── platform-map.md # only when the topic is platform/tooling relatedKeep the same headings everywhere:
triage.md→# Triagecontext.md→## Workflow Context,## Affected Users,## Current Workarounds,## Adjacent Problems,## User Voicessolutions.md→## Solution List,## Categories,## What People Actually Use,## Frequency Ranking,## Key Gaps,## Contradictions,## Key Insightplatform-map.md→## Settings,## Rules,## Hooks,## Platform Gaps
Do not let platform-native output modes replace the markdown artifact schema.
Platform notes
Claude
- Strong project-level settings and hook surfaces.
- Subagents are a first-class way to run specialized lanes.
- Good fit for parallel lanes and hook-backed validation.
- Still keep the artifact contract in repo-local instructions, not only in
.claude/config.
Codex
- Treat config/instruction files, sandbox mode, approvals, and MCP settings as the main documented portability surface.
- Do not rely on hook parity or undocumented subagent behavior.
- The artifact contract must survive plain instruction-file execution.
Gemini
- Strong settings layering, subagents, and command-based hooks.
- Good fit for lane specialization and post-generation validation.
- Still keep the markdown artifact schema explicit instead of assuming JSON output mode solves portability.
Recommended validation pattern
Use the same validation logic everywhere: 1. create the artifact files 2. check required headings and filenames 3. check citations / provenance labels exist where needed 4. verify that platform-map files use the settings / rules / hooks layer for platform topics
Default repo-local validator:
python3 .agent-skills/survey/scripts/validate_survey_artifacts.py .survey/<slug>
python3 .agent-skills/survey/scripts/validate_survey_artifacts.py .survey/<slug> --platform-topicIf a platform supports hooks, wrap the validator there. If it does not, run the validator as a normal command after writing files.
Anti-patterns
- Putting the only copy of survey behavior in platform-specific settings
- Using hook-specific magic as if all platforms support it
- Letting a platform-native output mode replace the markdown artifact contract
- Expanding platform-map into vendor trivia that does not map back to
settings,rules, orhooks - Treating thin evidence as if it were direct primary-source verification
#!/usr/bin/env python3
import argparse
import json
import sys
from pathlib import Path
PROVENANCE_LABELS = [
"direct page retrieval",
"feed recovery",
"browser-rendered retrieval",
"indexed snippet",
"browser-rendered indexed snippet",
"thin evidence",
]
REQUIRED_FILES = {
"triage.md": ["# Triage", "- Problem:", "- Audience:", "- Why now:"],
"context.md": [
"## Workflow Context",
"## Affected Users",
"## Current Workarounds",
"## Adjacent Problems",
"## User Voices",
],
"solutions.md": [
"## Solution List",
"## Categories",
"## What People Actually Use",
"## Frequency Ranking",
"## Key Gaps",
"## Contradictions",
"## Key Insight",
],
}
PLATFORM_HEADINGS = [
"## Settings",
"## Rules",
"## Hooks",
"## Platform Gaps",
]
def check_file(path: Path, headings: list[str], results: list[dict]) -> None:
if not path.exists():
results.append({"check": f"exists:{path.name}", "ok": False, "detail": "missing file"})
return
text = path.read_text(encoding="utf-8")
results.append({"check": f"exists:{path.name}", "ok": True, "detail": str(path)})
for heading in headings:
results.append(
{
"check": f"heading:{path.name}:{heading}",
"ok": heading in text,
"detail": "found" if heading in text else "missing heading",
}
)
def main() -> int:
parser = argparse.ArgumentParser(description="Validate `.survey/{slug}/` survey artifacts.")
parser.add_argument("path", help="Path to the survey artifact directory")
parser.add_argument("--platform-topic", action="store_true", help="Require platform-map.md and its headings")
parser.add_argument("--require-provenance", action="store_true", help="Require at least one provenance label in the artifact files")
parser.add_argument("--json", action="store_true", help="Emit machine-readable JSON")
args = parser.parse_args()
base = Path(args.path)
results: list[dict] = []
results.append({"check": "directory_exists", "ok": base.exists() and base.is_dir(), "detail": str(base)})
if not (base.exists() and base.is_dir()):
payload = {"ok": False, "path": str(base), "checks": results}
print(json.dumps(payload, indent=2) if args.json else f"ERROR: survey directory not found: {base}")
return 1
for filename, headings in REQUIRED_FILES.items():
check_file(base / filename, headings, results)
platform_file = base / "platform-map.md"
if args.platform_topic:
check_file(platform_file, PLATFORM_HEADINGS, results)
elif platform_file.exists():
check_file(platform_file, PLATFORM_HEADINGS, results)
if args.require_provenance:
combined = "\n".join(
p.read_text(encoding="utf-8")
for p in base.glob("*.md")
if p.is_file()
).lower()
found = [label for label in PROVENANCE_LABELS if label in combined]
results.append(
{
"check": "provenance_labels",
"ok": bool(found),
"detail": ", ".join(found) if found else "no provenance labels found",
}
)
ok = all(item["ok"] for item in results)
payload = {"ok": ok, "path": str(base), "checks": results}
if args.json:
print(json.dumps(payload, indent=2))
else:
print(f"Survey artifact validation: {'PASS' if ok else 'FAIL'}")
for item in results:
status = "OK" if item["ok"] else "FAIL"
print(f"- [{status}] {item['check']} :: {item['detail']}")
return 0 if ok else 1
if __name__ == "__main__":
sys.exit(main())
N:survey
D:Run a bounded cross-platform landscape scan before planning or implementation. Use when the real job is researching what exists, how people work around it, which solutions repeat, or how platform patterns map before deciding what to build. Produce reusable .survey/{slug}/ artifacts, validate the artifact contract, and route planning or execution outward only after the survey is done.
G:survey landscape-scan research discovery groundwork omc omx ohmg claude codex gemini hooks rules settings
U[12]:
Produce reusable .survey/{slug}/ artifacts before planning or implementation
Compare solutions workarounds and repeated complaints without drifting into coding
Normalize platform topics into settings rules hooks and platform gaps
Use a cheap-first evidence recovery ladder when search or extract tooling is weak
Run the mandatory five-keyword sweep for recurring repo-maintenance loops with lane-specific recovery templates and deterministic stage-2 escalation when a lane remains raw_count==0 or noisy-kept_count==0 after stage-1
Apply recommendation-grade freshness and signal-floor gating while preserving broad discovery evidence
Treat generic personal catch-all repos (especially */skills) as low-fit by default unless workflow docs + traction are explicit
Apply negation-aware intent gating so token overlap inside phrases like no cli or without cli is treated as low-fit unless an exception is justified
Emit lane-level status vocabulary (pass|degraded) and degraded-cause taxonomy for sparse/noisy lanes
Include compact lane-health metrics (kept_count raw_count median_stars_raw zero_star_raw) and apply a zero-star saturation guard before marking a lane pass
Detect cross-lane recommendation concentration with recommended_lane_count and single_lane_concentration flags
Deduplicate recommendation-grade repositories across lanes before final ranking while preserving raw evidence
Validate the artifact contract before handing off to planning or execution
S[12]{n,action,details}:
1,Classify mode,Choose one primary survey mode and decide whether platform-map.md is required
2,Freeze evidence rules,Set the source quality floor labels and recovery order before searching
3,Triage and reuse,Extract what who why and check whether an existing .survey/{slug} should be reused
4,Run 4 lanes,Research context solutions actual behavior and alternatives-or-platform-map in parallel
5,Keyword sweep (hourly loops),For recurring repo-maintenance runs execute all five keyword families, run lane recovery templates when needed, and escalate once with a documented stage-2 query if a lane still has raw_count==0
6,Mark lane status,After relevance gate add lane_status(pass|degraded) and degraded_causes(license|stale|low-fit|archived|low-signal|no-results) in markdown summaries (use no-results when raw_count stays 0 after documented recovery)
7,Record lane metrics,Alongside lane_status include kept_count raw_count median_stars_raw zero_star_raw so reviewers can detect quality drift
8,Check cross-lane concentration,Compute recommended_lane_count and set single_lane_concentration when recommendation-grade keeps cluster in one lane, then report a deduplicated recommendation set keyed by repository identity
9,Synthesize,Write triage.md context.md solutions.md and platform-map.md with the required headings
10,Validate,Run the survey artifact validator with platform-topic and provenance flags when needed
11,Summarize,Return a short factual survey summary and route planning or implementation outward
R[15]:
Never write implementation code in survey mode
Search broadly in English unless the user requires another language
Keep claims source-backed and label downgraded evidence clearly using validator-supported labels (map gh-search listings to indexed snippet and repo/API detail fetches to direct page retrieval); for gh search repos JSON output prefer fullName or owner+name over unsupported nameWithOwner and persist stderr before retrying
For hourly loops, start with a recency-first window (default pushed within last 24h~7d) and widen only via documented recovery stages
Drop assessment/homework-only and unknown-license noise unless exception rationale is explicit; when license is null on first pass or arrives as an empty object payload, retry once via gh api repos/<owner>/<repo> before classifying unknown
Treat generic personal catch-all repos (especially */skills) as low-fit unless workflow docs + traction are explicit
Treat lane-token hits inside explicit negation phrases (for example no cli, without cli, not a cli, non-cli) as low-fit unless a documented exception rationale exists
Apply a recommendation-grade freshness floor (drop stale pushed_at over 24 months unless exception rationale + risk note)
Apply a recommendation-grade signal floor (require traction signal such as stars>=3 or explicit adoption rationale)
Preserve the same artifact filenames and headings across platforms
Preserve lane-level threshold reporting (>=1 keep per lane where feasible; CLI lane target 3+) and run one documented stage-2 lane recovery when stage-1 still yields raw_count==0
Use lane_status(pass|degraded) and degraded_causes(license|stale|low-fit|archived|low-signal|no-results) for under-threshold lanes (no-results required when raw_count stays 0 after documented recovery)
Include lane metrics (kept_count raw_count median_stars_raw zero_star_raw) whenever lane_status is reported
Include cross-lane concentration signals (recommended_lane_count and single_lane_concentration) before claiming healthy recommendation coverage
Deduplicate recommendation-grade repositories across lanes before final ranking and report both raw and deduplicated coverage metrics
Use settings rules hooks as the common layer for Claude Codex Gemini comparisons
E[2]{desc,in,out}:
"Repo maintenance","survey which existing skill in this repo is the best bounded maintenance target next","Creates triage context and solutions artifacts, then validates the output folder before any skill rewrite starts"
"Platform comparison","survey how Claude Code Codex and Gemini CLI differ for hooks approvals and research-worker setup","Creates platform-map.md using settings rules hooks, validates with the platform-topic contract, and records portability gaps"
Related skills
How it compares
Pick survey over planning or implementation skills when the blocker is unknown landscape evidence, not missing tasks or code.
FAQ
What files does survey create?
survey writes a `.survey/{slug}/` folder with triage.md, context.md, solutions.md, and platform-map.md when the topic compares agent platforms. Headings and filenames are fixed so `validate_survey_artifacts.py` can check the contract mechanically before planning starts.
When should survey run instead of planning?
survey should run when developers need to learn what exists, which workarounds people use, or how Claude, Codex, and Gemini differ before choosing an approach. If the solution is already known and code should ship now, route directly to implementation instead.
How does survey validate its output?
survey validates artifacts with `python3 .agent-skills/survey/scripts/validate_survey_artifacts.py .survey/<slug>`. Platform comparisons add `--platform-topic`, and provenance-sensitive runs can pass `--require-provenance` so weak evidence stays labeled honestly.