.agents/skills/oat-project-discover/SKILL.md
Use when starting a project or when requirements are still unclear. Runs structured discovery to gather requirements, constraints, and context.
npx skillsauth add tkstang/open-agent-toolkit oat-project-discoverInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Gather requirements and understand the problem space through natural collaborative dialogue.
Required: Knowledge base must exist. If missing, run the oat-repo-knowledge-index skill first.
OAT MODE: Discovery
Purpose: Gather requirements and understand the problem space through structured dialogue.
When executing this skill, provide lightweight progress feedback so the user can tell what’s happening after they confirm.
Print a phase banner once at start using horizontal separators, e.g.:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ OAT ▸ DISCOVERY ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Before multi-step work, print step indicators, e.g.:
[1/5] Resolving project + checking knowledge base…[2/5] Initializing discovery document…[3/5] Running interactive discovery…[4/5] Documenting decisions + boundaries…[5/5] Updating state + committing…BLOCKED Activities:
ALLOWED Activities:
Self-Correction Protocol: If you catch yourself:
Recovery:
OAT stores active project context in .oat/config.local.json (activeProject, local-only).
Recommendation: Prefer creating projects via the oat-project-new skill (scaffolds all artifacts up front). oat-project-new is the canonical "create project" step; this discovery skill should not be responsible for directory/template scaffolding.
PROJECT_PATH=$(oat config get activeProject 2>/dev/null || true)
PROJECTS_ROOT="${OAT_PROJECTS_ROOT:-$(oat config get projects.root 2>/dev/null || echo ".oat/projects/shared")}"
PROJECTS_ROOT="${PROJECTS_ROOT%/}"
If PROJECT_PATH is set and valid (directory exists):
project-name from the directory name (basename of the path){PROJECT_PATH}/state.md (if it exists) and show current statusoat-project-open skilloat-project-new skillIf PROJECT_PATH is missing/invalid:
oat-project-new skill with {project-name}oat-project-open skillactiveProject in .oat/config.local.json is set to a valid project directory.test -f .oat/repo/knowledge/project-index.md
If missing: Block and require the oat-repo-knowledge-index skill first.
Extract frontmatter values from .oat/repo/knowledge/project-index.md:
# Extract SHAs and generation date from frontmatter
SOURCE_HEAD_SHA=$(grep "^oat_source_head_sha:" .oat/repo/knowledge/project-index.md | awk '{print $2}')
SOURCE_MERGE_BASE_SHA=$(grep "^oat_source_main_merge_base_sha:" .oat/repo/knowledge/project-index.md | awk '{print $2}')
GENERATED_AT=$(grep "^oat_generated_at:" .oat/repo/knowledge/project-index.md | awk '{print $2}')
# Get current state
CURRENT_HEAD=$(git rev-parse HEAD)
CURRENT_MERGE_BASE=$(git merge-base HEAD origin/main 2>/dev/null || git rev-parse HEAD)
Enhanced staleness check:
Age check: Compare $GENERATED_AT vs today (warn if >7 days)
# Skip age check if GENERATED_AT is missing or invalid
if [ -n "$GENERATED_AT" ] && echo "$GENERATED_AT" | grep -qE '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'; then
# macOS: use date -j -f, Linux: use date -d
if date -j -f "%Y-%m-%d" "$GENERATED_AT" +%s >/dev/null 2>&1; then
GENERATED_TS=$(date -j -f "%Y-%m-%d" "$GENERATED_AT" +%s)
else
GENERATED_TS=$(date -d "$GENERATED_AT" +%s 2>/dev/null || echo "")
fi
if [ -n "$GENERATED_TS" ]; then
DAYS_OLD=$(( ($(date +%s) - $GENERATED_TS) / 86400 ))
else
DAYS_OLD="unknown"
fi
else
DAYS_OLD="unknown"
fi
Git diff check: Compare recorded index HEAD to current HEAD
# Use --numstat for reliable file count (one line per file)
if [ -n "$SOURCE_HEAD_SHA" ]; then
FILES_CHANGED=$(git diff --numstat "$SOURCE_HEAD_SHA..HEAD" 2>/dev/null | wc -l | tr -d ' ')
# Also get summary for display
CHANGES_SUMMARY=$(git diff --shortstat "$SOURCE_HEAD_SHA..HEAD" 2>/dev/null)
else
FILES_CHANGED="unknown"
CHANGES_SUMMARY=""
fi
Staleness thresholds:
If stale (age or changes exceed thresholds):
$CHANGES_SUMMARY if availableoat-repo-knowledge-index skill to refreshIf unable to determine staleness (missing SHAs/dates):
Copy template: .oat/templates/state.md → "$PROJECT_PATH/state.md"
Update frontmatter:
---
oat_phase: discovery
oat_phase_status: in_progress
oat_project_state_updated: '{ISO 8601 UTC timestamp, e.g. 2026-03-10T14:30:00Z}'
---
Update content:
{Project Name} with actual project nameCopy template: .oat/templates/discovery.md → "$PROJECT_PATH/discovery.md"
Update with user's initial request.
Read for context:
.oat/repo/knowledge/project-index.md.oat/repo/knowledge/architecture.md.oat/repo/knowledge/conventions.md.oat/repo/knowledge/concerns.mdBased on the initial request and knowledge base context, infer 3-5 "gray areas" - topics that need clarification.
Examples of gray areas:
Present as multi-select question using AskUserQuestion tool:
Which areas should we explore during discovery?
(Select all that apply)
□ {Gray area 1}
□ {Gray area 2}
□ {Gray area 3}
□ {Gray area 4}
□ {Gray area 5}
This focuses the conversation on what matters most to the user.
For each selected gray area:
oat_last_updated: {today}Question quality:
Before converging on an approach, invest in genuine divergent exploration. Simple projects are where unexamined assumptions cause the most wasted work.
Step 9a: Propose Approaches
Propose 2-3 genuinely distinct approaches (not minor variations). For each:
Document in discovery.md ## Solution Space section.
Step 9b: Validate Before Converging
Present the approaches to the user and get explicit buy-in on the chosen direction before moving to decisions and boundaries. Summarize:
When an approach is selected, document it in ## Options Considered with a "Summary" line explaining the choice.
Step 9c: Handle Scope Creep
Update discovery.md sections:
Required:
Capture during conversation:
Keep it outcome-level:
Read "$PROJECT_PATH/state.md" frontmatter:
oat_hill_checkpointsoat_hill_completedIf "discovery" is in oat_hill_checkpoints, require explicit user approval before advancing.
Approval prompt (required):
oat-project-spec?"Optional independent review path:
oat-project-review-provide artifact discoveryIf user does not approve yet:
oat_status: in_progressoat_ready_for: null"discovery" to oat_hill_completed.If discovery is not configured as a HiLL checkpoint, or user explicitly approves, continue to Step 12.
Update frontmatter:
---
oat_status: complete
oat_ready_for: oat-project-spec
---
Update "$PROJECT_PATH/state.md":
Frontmatter updates:
oat_phase: discoveryoat_phase_status: completeoat_project_state_updated: "{ISO 8601 UTC timestamp}""discovery" is in oat_hill_checkpoints: append "discovery" to oat_hill_completed arrayNote: Only append to oat_hill_completed when the phase is configured as a HiLL gate. This keeps oat_hill_completed meaning "HiLL gates passed" rather than "phases completed" (which is tracked by oat_phase and oat_phase_status).
Content updates:
Note: This shows what users will do when USING oat-project-discover. During implementation of OAT itself, use standard commit format.
git add "$PROJECT_PATH/"
git commit -m "docs: complete discovery for {project-name}
Key decisions:
- {Decision 1}
- {Decision 2}
Ready for specification phase"
Discovery phase complete for {project-name}.
Next: Create specification with the oat-project-spec skill
documentation
Use when OAT implementation changes and repository reference docs must be synchronized. Updates .oat/repo/reference to match current behavior.
business
Merge multiple analysis artifacts into a single coherent report with provenance tracking. Reads existing artifacts from /deep-research, /analyze, and /compare.
testing
Use when the user questions or suspects an agent claim is wrong. Adversarially gathers evidence to verify or refute the claim using the best sources available in the current environment.
tools
Use when prioritizing backlog work or evaluating a roadmap. Produces value-effort ratings, dependency mapping, and execution recommendations.