Add segment coverage ledger and mid-project plan for Crusader decompilation
- Created `crusader_segment_coverage_ledger.csv` to track segment coverage status, types, and known functions. - Introduced `plan-mid.md` as a mid-project tracker outlining progress, objectives, and implementation priorities for the decompilation effort. - Added scripts in `pyghidra_plans` to assist with instruction window dumping and reference inspection for the object at `0x4588`. - Implemented functionality to scan for instruction uses of specific targets related to the decompilation project.
This commit is contained in:
parent
55b3187469
commit
519af09912
42 changed files with 2444 additions and 3 deletions
261
.github/instructions/agent-skills.instructions.md
vendored
Normal file
261
.github/instructions/agent-skills.instructions.md
vendored
Normal file
|
|
@ -0,0 +1,261 @@
|
||||||
|
---
|
||||||
|
description: 'Guidelines for creating high-quality Agent Skills for GitHub Copilot'
|
||||||
|
applyTo: '**/.github/skills/**/SKILL.md, **/.claude/skills/**/SKILL.md'
|
||||||
|
---
|
||||||
|
|
||||||
|
# Agent Skills File Guidelines
|
||||||
|
|
||||||
|
Instructions for creating effective and portable Agent Skills that enhance GitHub Copilot with specialized capabilities, workflows, and bundled resources.
|
||||||
|
|
||||||
|
## What Are Agent Skills?
|
||||||
|
|
||||||
|
Agent Skills are self-contained folders with instructions and bundled resources that teach AI agents specialized capabilities. Unlike custom instructions (which define coding standards), skills enable task-specific workflows that can include scripts, examples, templates, and reference data.
|
||||||
|
|
||||||
|
Key characteristics:
|
||||||
|
- **Portable**: Works across VS Code, Copilot CLI, and Copilot coding agent
|
||||||
|
- **Progressive loading**: Only loaded when relevant to the user's request
|
||||||
|
- **Resource-bundled**: Can include scripts, templates, examples alongside instructions
|
||||||
|
- **On-demand**: Activated automatically based on prompt relevance
|
||||||
|
|
||||||
|
## Directory Structure
|
||||||
|
|
||||||
|
Skills are stored in specific locations:
|
||||||
|
|
||||||
|
| Location | Scope | Recommendation |
|
||||||
|
|----------|-------|----------------|
|
||||||
|
| `.github/skills/<skill-name>/` | Project/repository | Recommended for project skills |
|
||||||
|
| `.claude/skills/<skill-name>/` | Project/repository | Legacy, for backward compatibility |
|
||||||
|
| `~/.github/skills/<skill-name>/` | Personal (user-wide) | Recommended for personal skills |
|
||||||
|
| `~/.claude/skills/<skill-name>/` | Personal (user-wide) | Legacy, for backward compatibility |
|
||||||
|
|
||||||
|
Each skill **must** have its own subdirectory containing at minimum a `SKILL.md` file.
|
||||||
|
|
||||||
|
## Required SKILL.md Format
|
||||||
|
|
||||||
|
### Frontmatter (Required)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
name: webapp-testing
|
||||||
|
description: Toolkit for testing local web applications using Playwright. Use when asked to verify frontend functionality, debug UI behavior, capture browser screenshots, check for visual regressions, or view browser console logs. Supports Chrome, Firefox, and WebKit browsers.
|
||||||
|
license: Complete terms in LICENSE.txt
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
| Field | Required | Constraints |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `name` | Yes | Lowercase, hyphens for spaces, max 64 characters (e.g., `webapp-testing`) |
|
||||||
|
| `description` | Yes | Clear description of capabilities AND use cases, max 1024 characters |
|
||||||
|
| `license` | No | Reference to LICENSE.txt (e.g., `Complete terms in LICENSE.txt`) or SPDX identifier |
|
||||||
|
|
||||||
|
### Description Best Practices
|
||||||
|
|
||||||
|
**CRITICAL**: The `description` field is the PRIMARY mechanism for automatic skill discovery. Copilot reads ONLY the `name` and `description` to decide whether to load a skill. If your description is vague, the skill will never be activated.
|
||||||
|
|
||||||
|
**What to include in description:**
|
||||||
|
1. **WHAT** the skill does (capabilities)
|
||||||
|
2. **WHEN** to use it (specific triggers, scenarios, file types, or user requests)
|
||||||
|
3. **Keywords** that users might mention in their prompts
|
||||||
|
|
||||||
|
**Good description:**
|
||||||
|
```yaml
|
||||||
|
description: Toolkit for testing local web applications using Playwright. Use when asked to verify frontend functionality, debug UI behavior, capture browser screenshots, check for visual regressions, or view browser console logs. Supports Chrome, Firefox, and WebKit browsers.
|
||||||
|
```
|
||||||
|
|
||||||
|
**Poor description:**
|
||||||
|
```yaml
|
||||||
|
description: Web testing helpers
|
||||||
|
```
|
||||||
|
|
||||||
|
The poor description fails because:
|
||||||
|
- No specific triggers (when should Copilot load this?)
|
||||||
|
- No keywords (what user prompts would match?)
|
||||||
|
- No capabilities (what can it actually do?)
|
||||||
|
|
||||||
|
### Body Content
|
||||||
|
|
||||||
|
The body contains detailed instructions that Copilot loads AFTER the skill is activated. Recommended sections:
|
||||||
|
|
||||||
|
| Section | Purpose |
|
||||||
|
|---------|---------|
|
||||||
|
| `# Title` | Brief overview of what this skill enables |
|
||||||
|
| `## When to Use This Skill` | List of scenarios (reinforces description triggers) |
|
||||||
|
| `## Prerequisites` | Required tools, dependencies, environment setup |
|
||||||
|
| `## Step-by-Step Workflows` | Numbered steps for common tasks |
|
||||||
|
| `## Troubleshooting` | Common issues and solutions table |
|
||||||
|
| `## References` | Links to bundled docs or external resources |
|
||||||
|
|
||||||
|
## Bundling Resources
|
||||||
|
|
||||||
|
Skills can include additional files that Copilot accesses on-demand:
|
||||||
|
|
||||||
|
### Supported Resource Types
|
||||||
|
|
||||||
|
| Folder | Purpose | Loaded into Context? | Example Files |
|
||||||
|
|--------|---------|---------------------|---------------|
|
||||||
|
| `scripts/` | Executable automation that performs specific operations | When executed | `helper.py`, `validate.sh`, `build.ts` |
|
||||||
|
| `references/` | Documentation the AI agent reads to inform decisions | Yes, when referenced | `api_reference.md`, `schema.md`, `workflow_guide.md` |
|
||||||
|
| `assets/` | **Static files used AS-IS** in output (not modified by the AI agent) | No | `logo.png`, `brand-template.pptx`, `custom-font.ttf` |
|
||||||
|
| `templates/` | **Starter code/scaffolds that the AI agent MODIFIES** and builds upon | Yes, when referenced | `viewer.html` (insert algorithm), `hello-world/` (extend) |
|
||||||
|
|
||||||
|
### Directory Structure Example
|
||||||
|
|
||||||
|
```
|
||||||
|
.github/skills/my-skill/
|
||||||
|
├── SKILL.md # Required: Main instructions
|
||||||
|
├── LICENSE.txt # Recommended: License terms (Apache 2.0 typical)
|
||||||
|
├── scripts/ # Optional: Executable automation
|
||||||
|
│ ├── helper.py # Python script
|
||||||
|
│ └── helper.ps1 # PowerShell script
|
||||||
|
├── references/ # Optional: Documentation loaded into context
|
||||||
|
│ ├── api_reference.md
|
||||||
|
│ ├── workflow-setup.md # Detailed workflow (>5 steps)
|
||||||
|
│ └── workflow-deployment.md
|
||||||
|
├── assets/ # Optional: Static files used AS-IS in output
|
||||||
|
│ ├── baseline.png # Reference image for comparison
|
||||||
|
│ └── report-template.html
|
||||||
|
└── templates/ # Optional: Starter code the AI agent modifies
|
||||||
|
├── scaffold.py # Code scaffold the AI agent customizes
|
||||||
|
└── config.template # Config template the AI agent fills in
|
||||||
|
```
|
||||||
|
|
||||||
|
> **LICENSE.txt**: When creating a skill, download the Apache 2.0 license text from https://www.apache.org/licenses/LICENSE-2.0.txt and save as `LICENSE.txt`. Update the copyright year and owner in the appendix section.
|
||||||
|
|
||||||
|
### Assets vs Templates: Key Distinction
|
||||||
|
|
||||||
|
**Assets** are static resources **consumed unchanged** in the output:
|
||||||
|
- A `logo.png` that gets embedded into a generated document
|
||||||
|
- A `report-template.html` copied as output format
|
||||||
|
- A `custom-font.ttf` applied to text rendering
|
||||||
|
|
||||||
|
**Templates** are starter code/scaffolds that **the AI agent actively modifies**:
|
||||||
|
- A `scaffold.py` where the AI agent inserts logic
|
||||||
|
- A `config.template` where the AI agent fills in values based on user requirements
|
||||||
|
- A `hello-world/` project directory that the AI agent extends with new features
|
||||||
|
|
||||||
|
**Rule of thumb**: If the AI agent reads and builds upon the file content → `templates/`. If the file is used as-is in output → `assets/`.
|
||||||
|
|
||||||
|
### Referencing Resources in SKILL.md
|
||||||
|
|
||||||
|
Use relative paths to reference files within the skill directory:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Available Scripts
|
||||||
|
|
||||||
|
Run the [helper script](./scripts/helper.py) to automate common tasks.
|
||||||
|
|
||||||
|
See [API reference](./references/api_reference.md) for detailed documentation.
|
||||||
|
|
||||||
|
Use the [scaffold](./templates/scaffold.py) as a starting point.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Progressive Loading Architecture
|
||||||
|
|
||||||
|
Skills use three-level loading for efficiency:
|
||||||
|
|
||||||
|
| Level | What Loads | When |
|
||||||
|
|-------|------------|------|
|
||||||
|
| 1. Discovery | `name` and `description` only | Always (lightweight metadata) |
|
||||||
|
| 2. Instructions | Full `SKILL.md` body | When request matches description |
|
||||||
|
| 3. Resources | Scripts, examples, docs | Only when Copilot references them |
|
||||||
|
|
||||||
|
This means:
|
||||||
|
- Install many skills without consuming context
|
||||||
|
- Only relevant content loads per task
|
||||||
|
- Resources don't load until explicitly needed
|
||||||
|
|
||||||
|
## Content Guidelines
|
||||||
|
|
||||||
|
### Writing Style
|
||||||
|
|
||||||
|
- Use imperative mood: "Run", "Create", "Configure" (not "You should run")
|
||||||
|
- Be specific and actionable
|
||||||
|
- Include exact commands with parameters
|
||||||
|
- Show expected outputs where helpful
|
||||||
|
- Keep sections focused and scannable
|
||||||
|
|
||||||
|
### Script Requirements
|
||||||
|
|
||||||
|
When including scripts, prefer cross-platform languages:
|
||||||
|
|
||||||
|
| Language | Use Case |
|
||||||
|
|----------|----------|
|
||||||
|
| Python | Complex automation, data processing |
|
||||||
|
| pwsh | PowerShell Core scripting |
|
||||||
|
| Node.js | JavaScript-based tooling |
|
||||||
|
| Bash/Shell | Simple automation tasks |
|
||||||
|
|
||||||
|
Best practices:
|
||||||
|
- Include help/usage documentation (`--help` flag)
|
||||||
|
- Handle errors gracefully with clear messages
|
||||||
|
- Avoid storing credentials or secrets
|
||||||
|
- Use relative paths where possible
|
||||||
|
|
||||||
|
### When to Bundle Scripts
|
||||||
|
|
||||||
|
Include scripts in your skill when:
|
||||||
|
- The same code would be rewritten repeatedly by the agent
|
||||||
|
- Deterministic reliability is critical (e.g., file manipulation, API calls)
|
||||||
|
- Complex logic benefits from being pre-tested rather than generated each time
|
||||||
|
- The operation has a self-contained purpose that can evolve independently
|
||||||
|
- Testability matters — scripts can be unit tested and validated
|
||||||
|
- Predictable behavior is preferred over dynamic generation
|
||||||
|
|
||||||
|
Scripts enable evolution: even simple operations benefit from being implemented as scripts when they may grow in complexity, need consistent behavior across invocations, or require future extensibility.
|
||||||
|
|
||||||
|
### Security Considerations
|
||||||
|
|
||||||
|
- Scripts rely on existing credential helpers (no credential storage)
|
||||||
|
- Include `--force` flags only for destructive operations
|
||||||
|
- Warn users before irreversible actions
|
||||||
|
- Document any network operations or external calls
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Parameter Table Pattern
|
||||||
|
|
||||||
|
Document parameters clearly:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
| Parameter | Required | Default | Description |
|
||||||
|
|-----------|----------|---------|-------------|
|
||||||
|
| `--input` | Yes | - | Input file or URL to process |
|
||||||
|
| `--action` | Yes | - | Action to perform |
|
||||||
|
| `--verbose` | No | `false` | Enable verbose output |
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation Checklist
|
||||||
|
|
||||||
|
Before publishing a skill:
|
||||||
|
|
||||||
|
- [ ] `SKILL.md` has valid frontmatter with `name` and `description`
|
||||||
|
- [ ] `name` is lowercase with hyphens, ≤64 characters
|
||||||
|
- [ ] `description` clearly states **WHAT** it does, **WHEN** to use it, and relevant **KEYWORDS**
|
||||||
|
- [ ] Body includes when to use, prerequisites, and step-by-step workflows
|
||||||
|
- [ ] SKILL.md body kept under 500 lines (split large content into `references/` folder)
|
||||||
|
- [ ] Large workflows (>5 steps) split into `references/` folder with clear links from SKILL.md
|
||||||
|
- [ ] Scripts include help documentation and error handling
|
||||||
|
- [ ] Relative paths used for all resource references
|
||||||
|
- [ ] No hardcoded credentials or secrets
|
||||||
|
|
||||||
|
## Workflow Execution Pattern
|
||||||
|
|
||||||
|
When executing multi-step workflows, create a TODO list where each step references the relevant documentation:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## TODO
|
||||||
|
- [ ] Step 1: Configure environment - see [workflow-setup.md](./references/workflow-setup.md#environment)
|
||||||
|
- [ ] Step 2: Build project - see [workflow-setup.md](./references/workflow-setup.md#build)
|
||||||
|
- [ ] Step 3: Deploy to staging - see [workflow-deployment.md](./references/workflow-deployment.md#staging)
|
||||||
|
- [ ] Step 4: Run validation - see [workflow-deployment.md](./references/workflow-deployment.md#validation)
|
||||||
|
- [ ] Step 5: Deploy to production - see [workflow-deployment.md](./references/workflow-deployment.md#production)
|
||||||
|
```
|
||||||
|
|
||||||
|
This ensures traceability and allows resuming workflows if interrupted.
|
||||||
|
|
||||||
|
## Related Resources
|
||||||
|
|
||||||
|
- [Agent Skills Specification](https://agentskills.io/)
|
||||||
|
- [VS Code Agent Skills Documentation](https://code.visualstudio.com/docs/copilot/customization/agent-skills)
|
||||||
|
- [Reference Skills Repository](https://github.com/anthropics/skills)
|
||||||
|
- [Awesome Copilot Skills](https://github.com/github/awesome-copilot/blob/main/docs/README.skills.md)
|
||||||
997
.github/instructions/agents.instructions.md
vendored
Normal file
997
.github/instructions/agents.instructions.md
vendored
Normal file
|
|
@ -0,0 +1,997 @@
|
||||||
|
---
|
||||||
|
description: 'Guidelines for creating custom agent files for GitHub Copilot'
|
||||||
|
applyTo: '**/*.agent.md'
|
||||||
|
---
|
||||||
|
|
||||||
|
# Custom Agent File Guidelines
|
||||||
|
|
||||||
|
Instructions for creating effective and maintainable custom agent files that provide specialized expertise for specific development tasks in GitHub Copilot.
|
||||||
|
|
||||||
|
## Project Context
|
||||||
|
|
||||||
|
- Target audience: Developers creating custom agents for GitHub Copilot
|
||||||
|
- File format: Markdown with YAML frontmatter
|
||||||
|
- File naming convention: lowercase with hyphens (e.g., `test-specialist.agent.md`)
|
||||||
|
- Location: `.github/agents/` directory (repository-level) or `agents/` directory (organization/enterprise-level)
|
||||||
|
- Purpose: Define specialized agents with tailored expertise, tools, and instructions for specific tasks
|
||||||
|
- Official documentation: https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-custom-agents
|
||||||
|
|
||||||
|
## Required Frontmatter
|
||||||
|
|
||||||
|
Every agent file must include YAML frontmatter with the following fields:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
description: 'Brief description of the agent purpose and capabilities'
|
||||||
|
name: 'Agent Display Name'
|
||||||
|
tools: ['read', 'edit', 'search']
|
||||||
|
model: 'Claude Sonnet 4.5'
|
||||||
|
target: 'vscode'
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
### Core Frontmatter Properties
|
||||||
|
|
||||||
|
#### **description** (REQUIRED)
|
||||||
|
- Single-quoted string, clearly stating the agent's purpose and domain expertise
|
||||||
|
- Should be concise (50-150 characters) and actionable
|
||||||
|
- Example: `'Focuses on test coverage, quality, and testing best practices'`
|
||||||
|
|
||||||
|
#### **name** (OPTIONAL)
|
||||||
|
- Display name for the agent in the UI
|
||||||
|
- If omitted, defaults to filename (without `.md` or `.agent.md`)
|
||||||
|
- Use title case and be descriptive
|
||||||
|
- Example: `'Testing Specialist'`
|
||||||
|
|
||||||
|
#### **tools** (OPTIONAL)
|
||||||
|
- List of tool names or aliases the agent can use
|
||||||
|
- Supports comma-separated string or YAML array format
|
||||||
|
- If omitted, agent has access to all available tools
|
||||||
|
- See "Tool Configuration" section below for details
|
||||||
|
|
||||||
|
#### **model** (STRONGLY RECOMMENDED)
|
||||||
|
- Specifies which AI model the agent should use
|
||||||
|
- Supported in VS Code, JetBrains IDEs, Eclipse, and Xcode
|
||||||
|
- Example: `'Claude Sonnet 4.5'`, `'gpt-4'`, `'gpt-4o'`
|
||||||
|
- Choose based on agent complexity and required capabilities
|
||||||
|
|
||||||
|
#### **target** (OPTIONAL)
|
||||||
|
- Specifies target environment: `'vscode'` or `'github-copilot'`
|
||||||
|
- If omitted, agent is available in both environments
|
||||||
|
- Use when agent has environment-specific features
|
||||||
|
|
||||||
|
#### **user-invocable** (OPTIONAL)
|
||||||
|
- Boolean controlling whether the agent appears in the agents dropdown in chat
|
||||||
|
- Default: `true` if omitted
|
||||||
|
- Set to `false` to create agents that are only accessible as subagents or programmatically
|
||||||
|
|
||||||
|
#### **disable-model-invocation** (OPTIONAL)
|
||||||
|
- Boolean controlling whether the agent can be invoked as a subagent by other agents
|
||||||
|
- Default: `false` if omitted
|
||||||
|
- Set to `true` to prevent subagent invocation while keeping it available in the picker
|
||||||
|
|
||||||
|
#### **metadata** (OPTIONAL, GitHub.com only)
|
||||||
|
- Object with name-value pairs for agent annotation
|
||||||
|
- Example: `metadata: { category: 'testing', version: '1.0' }`
|
||||||
|
- Not supported in VS Code
|
||||||
|
|
||||||
|
#### **mcp-servers** (OPTIONAL, Organization/Enterprise only)
|
||||||
|
- Configure MCP servers available only to this agent
|
||||||
|
- Only supported for organization/enterprise level agents
|
||||||
|
- See "MCP Server Configuration" section below
|
||||||
|
|
||||||
|
#### **handoffs** (OPTIONAL, VS Code only)
|
||||||
|
- Enable guided sequential workflows that transition between agents with suggested next steps
|
||||||
|
- List of handoff configurations, each specifying a target agent and optional prompt
|
||||||
|
- After a chat response completes, handoff buttons appear allowing users to move to the next agent
|
||||||
|
- Only supported in VS Code (version 1.106+)
|
||||||
|
- See "Handoffs Configuration" section below for details
|
||||||
|
|
||||||
|
## Handoffs Configuration
|
||||||
|
|
||||||
|
Handoffs enable you to create guided sequential workflows that transition seamlessly between custom agents. This is useful for orchestrating multi-step development workflows where users can review and approve each step before moving to the next one.
|
||||||
|
|
||||||
|
### Common Handoff Patterns
|
||||||
|
|
||||||
|
- **Planning → Implementation**: Generate a plan in a planning agent, then hand off to an implementation agent to start coding
|
||||||
|
- **Implementation → Review**: Complete implementation, then switch to a code review agent to check for quality and security issues
|
||||||
|
- **Write Failing Tests → Write Passing Tests**: Generate failing tests, then hand off to implement the code that makes those tests pass
|
||||||
|
- **Research → Documentation**: Research a topic, then transition to a documentation agent to write guides
|
||||||
|
|
||||||
|
### Handoff Frontmatter Structure
|
||||||
|
|
||||||
|
Define handoffs in the agent file's YAML frontmatter using the `handoffs` field:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
description: 'Brief description of the agent'
|
||||||
|
name: 'Agent Name'
|
||||||
|
tools: ['search', 'read']
|
||||||
|
handoffs:
|
||||||
|
- label: Start Implementation
|
||||||
|
agent: implementation
|
||||||
|
prompt: 'Now implement the plan outlined above.'
|
||||||
|
send: false
|
||||||
|
- label: Code Review
|
||||||
|
agent: code-review
|
||||||
|
prompt: 'Please review the implementation for quality and security issues.'
|
||||||
|
send: false
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
### Handoff Properties
|
||||||
|
|
||||||
|
Each handoff in the list must include the following properties:
|
||||||
|
|
||||||
|
| Property | Type | Required | Description |
|
||||||
|
|----------|------|----------|-------------|
|
||||||
|
| `label` | string | Yes | The display text shown on the handoff button in the chat interface |
|
||||||
|
| `agent` | string | Yes | The target agent identifier to switch to (name or filename without `.agent.md`) |
|
||||||
|
| `prompt` | string | No | The prompt text to pre-fill in the target agent's chat input |
|
||||||
|
| `send` | boolean | No | If `true`, automatically submits the prompt to the target agent (default: `false`) |
|
||||||
|
|
||||||
|
### Handoff Behavior
|
||||||
|
|
||||||
|
- **Button Display**: Handoff buttons appear as interactive suggestions after a chat response completes
|
||||||
|
- **Context Preservation**: When users select a handoff button, they switch to the target agent with conversation context maintained
|
||||||
|
- **Pre-filled Prompt**: If a `prompt` is specified, it appears pre-filled in the target agent's chat input
|
||||||
|
- **Manual vs Auto**: When `send: false`, users must review and manually send the pre-filled prompt; when `send: true`, the prompt is automatically submitted
|
||||||
|
|
||||||
|
### Handoff Configuration Guidelines
|
||||||
|
|
||||||
|
#### When to Use Handoffs
|
||||||
|
|
||||||
|
- **Multi-step workflows**: Breaking down complex tasks across specialized agents
|
||||||
|
- **Quality gates**: Ensuring review steps between implementation phases
|
||||||
|
- **Guided processes**: Directing users through a structured development process
|
||||||
|
- **Skill transitions**: Moving from planning/design to implementation/testing specialists
|
||||||
|
|
||||||
|
#### Best Practices
|
||||||
|
|
||||||
|
- **Clear Labels**: Use action-oriented labels that clearly indicate the next step
|
||||||
|
- ✅ Good: "Start Implementation", "Review for Security", "Write Tests"
|
||||||
|
- ❌ Avoid: "Next", "Go to agent", "Do something"
|
||||||
|
|
||||||
|
- **Relevant Prompts**: Provide context-aware prompts that reference the completed work
|
||||||
|
- ✅ Good: `'Now implement the plan outlined above.'`
|
||||||
|
- ❌ Avoid: Generic prompts without context
|
||||||
|
|
||||||
|
- **Selective Use**: Don't create handoffs to every possible agent; focus on logical workflow transitions
|
||||||
|
- Limit to 2-3 most relevant next steps per agent
|
||||||
|
- Only add handoffs for agents that naturally follow in the workflow
|
||||||
|
|
||||||
|
- **Agent Dependencies**: Ensure target agents exist before creating handoffs
|
||||||
|
- Handoffs to non-existent agents will be silently ignored
|
||||||
|
- Test handoffs to verify they work as expected
|
||||||
|
|
||||||
|
- **Prompt Content**: Keep prompts concise and actionable
|
||||||
|
- Refer to work from the current agent without duplicating content
|
||||||
|
- Provide any necessary context the target agent might need
|
||||||
|
|
||||||
|
### Example: Complete Workflow
|
||||||
|
|
||||||
|
Here's an example of three agents with handoffs creating a complete workflow:
|
||||||
|
|
||||||
|
**Planning Agent** (`planner.agent.md`):
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
description: 'Generate an implementation plan for new features or refactoring'
|
||||||
|
name: 'Planner'
|
||||||
|
tools: ['search', 'read']
|
||||||
|
handoffs:
|
||||||
|
- label: Implement Plan
|
||||||
|
agent: implementer
|
||||||
|
prompt: 'Implement the plan outlined above.'
|
||||||
|
send: false
|
||||||
|
---
|
||||||
|
# Planner Agent
|
||||||
|
You are a planning specialist. Your task is to:
|
||||||
|
1. Analyze the requirements
|
||||||
|
2. Break down the work into logical steps
|
||||||
|
3. Generate a detailed implementation plan
|
||||||
|
4. Identify testing requirements
|
||||||
|
|
||||||
|
Do not write any code - focus only on planning.
|
||||||
|
```
|
||||||
|
|
||||||
|
**Implementation Agent** (`implementer.agent.md`):
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
description: 'Implement code based on a plan or specification'
|
||||||
|
name: 'Implementer'
|
||||||
|
tools: ['read', 'edit', 'search', 'execute']
|
||||||
|
handoffs:
|
||||||
|
- label: Review Implementation
|
||||||
|
agent: reviewer
|
||||||
|
prompt: 'Please review this implementation for code quality, security, and adherence to best practices.'
|
||||||
|
send: false
|
||||||
|
---
|
||||||
|
# Implementer Agent
|
||||||
|
You are an implementation specialist. Your task is to:
|
||||||
|
1. Follow the provided plan or specification
|
||||||
|
2. Write clean, maintainable code
|
||||||
|
3. Include appropriate comments and documentation
|
||||||
|
4. Follow project coding standards
|
||||||
|
|
||||||
|
Implement the solution completely and thoroughly.
|
||||||
|
```
|
||||||
|
|
||||||
|
**Review Agent** (`reviewer.agent.md`):
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
description: 'Review code for quality, security, and best practices'
|
||||||
|
name: 'Reviewer'
|
||||||
|
tools: ['read', 'search']
|
||||||
|
handoffs:
|
||||||
|
- label: Back to Planning
|
||||||
|
agent: planner
|
||||||
|
prompt: 'Review the feedback above and determine if a new plan is needed.'
|
||||||
|
send: false
|
||||||
|
---
|
||||||
|
# Code Review Agent
|
||||||
|
You are a code review specialist. Your task is to:
|
||||||
|
1. Check code quality and maintainability
|
||||||
|
2. Identify security issues and vulnerabilities
|
||||||
|
3. Verify adherence to project standards
|
||||||
|
4. Suggest improvements
|
||||||
|
|
||||||
|
Provide constructive feedback on the implementation.
|
||||||
|
```
|
||||||
|
|
||||||
|
This workflow allows a developer to:
|
||||||
|
1. Start with the Planner agent to create a detailed plan
|
||||||
|
2. Hand off to the Implementer agent to write code based on the plan
|
||||||
|
3. Hand off to the Reviewer agent to check the implementation
|
||||||
|
4. Optionally hand off back to planning if significant issues are found
|
||||||
|
|
||||||
|
### Version Compatibility
|
||||||
|
|
||||||
|
- **VS Code**: Handoffs are supported in VS Code 1.106 and later
|
||||||
|
- **GitHub.com**: Not currently supported; agent transition workflows use different mechanisms
|
||||||
|
- **Other IDEs**: Limited or no support; focus on VS Code implementations for maximum compatibility
|
||||||
|
|
||||||
|
## Tool Configuration
|
||||||
|
|
||||||
|
### Tool Specification Strategies
|
||||||
|
|
||||||
|
**Enable all tools** (default):
|
||||||
|
```yaml
|
||||||
|
# Omit tools property entirely, or use:
|
||||||
|
tools: ['*']
|
||||||
|
```
|
||||||
|
|
||||||
|
**Enable specific tools**:
|
||||||
|
```yaml
|
||||||
|
tools: ['read', 'edit', 'search', 'execute']
|
||||||
|
```
|
||||||
|
|
||||||
|
**Enable MCP server tools**:
|
||||||
|
```yaml
|
||||||
|
tools: ['read', 'edit', 'github/*', 'playwright/navigate']
|
||||||
|
```
|
||||||
|
|
||||||
|
**Disable all tools**:
|
||||||
|
```yaml
|
||||||
|
tools: []
|
||||||
|
```
|
||||||
|
|
||||||
|
### Standard Tool Aliases
|
||||||
|
|
||||||
|
All aliases are case-insensitive:
|
||||||
|
|
||||||
|
| Alias | Alternative Names | Category | Description |
|
||||||
|
|-------|------------------|----------|-------------|
|
||||||
|
| `execute` | shell, Bash, powershell | Shell execution | Execute commands in appropriate shell |
|
||||||
|
| `read` | Read, NotebookRead, view | File reading | Read file contents |
|
||||||
|
| `edit` | Edit, MultiEdit, Write, NotebookEdit | File editing | Edit and modify files |
|
||||||
|
| `search` | Grep, Glob, search | Code search | Search for files or text in files |
|
||||||
|
| `agent` | custom-agent, Task | Agent invocation | Invoke other custom agents |
|
||||||
|
| `web` | WebSearch, WebFetch | Web access | Fetch web content and search |
|
||||||
|
| `todo` | TodoWrite | Task management | Create and manage task lists (VS Code only) |
|
||||||
|
|
||||||
|
### Built-in MCP Server Tools
|
||||||
|
|
||||||
|
**GitHub MCP Server**:
|
||||||
|
```yaml
|
||||||
|
tools: ['github/*'] # All GitHub tools
|
||||||
|
tools: ['github/get_file_contents', 'github/search_repositories'] # Specific tools
|
||||||
|
```
|
||||||
|
- All read-only tools available by default
|
||||||
|
- Token scoped to source repository
|
||||||
|
|
||||||
|
**Playwright MCP Server**:
|
||||||
|
```yaml
|
||||||
|
tools: ['playwright/*'] # All Playwright tools
|
||||||
|
tools: ['playwright/navigate', 'playwright/screenshot'] # Specific tools
|
||||||
|
```
|
||||||
|
- Configured to access localhost only
|
||||||
|
- Useful for browser automation and testing
|
||||||
|
|
||||||
|
### Tool Selection Best Practices
|
||||||
|
|
||||||
|
- **Principle of Least Privilege**: Only enable tools necessary for the agent's purpose
|
||||||
|
- **Security**: Limit `execute` access unless explicitly required
|
||||||
|
- **Focus**: Fewer tools = clearer agent purpose and better performance
|
||||||
|
- **Documentation**: Comment why specific tools are required for complex configurations
|
||||||
|
|
||||||
|
## Sub-Agent Invocation (Agent Orchestration)
|
||||||
|
|
||||||
|
Agents can invoke other agents using the **agent invocation tool** (the `agent` tool) to orchestrate multi-step workflows.
|
||||||
|
|
||||||
|
The recommended approach is **prompt-based orchestration**:
|
||||||
|
- The orchestrator defines a step-by-step workflow in natural language.
|
||||||
|
- Each step is delegated to a specialized agent.
|
||||||
|
- The orchestrator passes only the essential context (e.g., base path, identifiers) and requires each sub-agent to read its own `.agent.md` spec for tools/constraints.
|
||||||
|
|
||||||
|
### How It Works
|
||||||
|
|
||||||
|
1) Enable agent invocation by including `agent` in the orchestrator's tools list:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
tools: ['read', 'edit', 'search', 'agent']
|
||||||
|
```
|
||||||
|
|
||||||
|
2) For each step, invoke a sub-agent by providing:
|
||||||
|
- **Agent name** (the identifier users select/invoke)
|
||||||
|
- **Agent spec path** (the `.agent.md` file to read and follow)
|
||||||
|
- **Minimal shared context** (e.g., `basePath`, `projectName`, `logFile`)
|
||||||
|
|
||||||
|
### Prompt Pattern (Recommended)
|
||||||
|
|
||||||
|
Use a consistent “wrapper prompt” for every step so sub-agents behave predictably:
|
||||||
|
|
||||||
|
```text
|
||||||
|
This phase must be performed as the agent "<AGENT_NAME>" defined in "<AGENT_SPEC_PATH>".
|
||||||
|
|
||||||
|
IMPORTANT:
|
||||||
|
- Read and apply the entire .agent.md spec (tools, constraints, quality standards).
|
||||||
|
- Work on "<WORK_UNIT_NAME>" with base path: "<BASE_PATH>".
|
||||||
|
- Perform the necessary reads/writes under this base path.
|
||||||
|
- Return a clear summary (actions taken + files produced/modified + issues).
|
||||||
|
```
|
||||||
|
|
||||||
|
Optional: if you need a lightweight, structured wrapper for traceability, embed a small JSON block in the prompt (still human-readable and tool-agnostic):
|
||||||
|
|
||||||
|
```text
|
||||||
|
{
|
||||||
|
"step": "<STEP_ID>",
|
||||||
|
"agent": "<AGENT_NAME>",
|
||||||
|
"spec": "<AGENT_SPEC_PATH>",
|
||||||
|
"basePath": "<BASE_PATH>"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Orchestrator Structure (Keep It Generic)
|
||||||
|
|
||||||
|
For maintainable orchestrators, document these structural elements:
|
||||||
|
|
||||||
|
- **Dynamic parameters**: what values are extracted from the user (e.g., `projectName`, `fileName`, `basePath`).
|
||||||
|
- **Sub-agent registry**: a list/table mapping each step to `agentName` + `agentSpecPath`.
|
||||||
|
- **Step ordering**: explicit sequence (Step 1 → Step N).
|
||||||
|
- **Trigger conditions** (optional but recommended): define when a step runs vs is skipped.
|
||||||
|
- **Logging strategy** (optional but recommended): a single log/report file updated after each step.
|
||||||
|
|
||||||
|
Avoid embedding orchestration “code” (JavaScript, Python, etc.) inside the orchestrator prompt; prefer deterministic, tool-driven coordination.
|
||||||
|
|
||||||
|
### Basic Pattern
|
||||||
|
|
||||||
|
Structure each step invocation with:
|
||||||
|
|
||||||
|
1. **Step description**: Clear one-line purpose (used for logs and traceability)
|
||||||
|
2. **Agent identity**: `agentName` + `agentSpecPath`
|
||||||
|
3. **Context**: A small, explicit set of variables (paths, IDs, environment name)
|
||||||
|
4. **Expected outputs**: Files to create/update and where they should be written
|
||||||
|
5. **Return summary**: Ask the sub-agent to return a short, structured summary
|
||||||
|
|
||||||
|
### Example: Multi-Step Processing
|
||||||
|
|
||||||
|
```text
|
||||||
|
Step 1: Transform raw input data
|
||||||
|
Agent: data-processor
|
||||||
|
Spec: .github/agents/data-processor.agent.md
|
||||||
|
Context: projectName=${projectName}, basePath=${basePath}
|
||||||
|
Input: ${basePath}/raw/
|
||||||
|
Output: ${basePath}/processed/
|
||||||
|
Expected: write ${basePath}/processed/summary.md
|
||||||
|
|
||||||
|
Step 2: Analyze processed data (depends on Step 1 output)
|
||||||
|
Agent: data-analyst
|
||||||
|
Spec: .github/agents/data-analyst.agent.md
|
||||||
|
Context: projectName=${projectName}, basePath=${basePath}
|
||||||
|
Input: ${basePath}/processed/
|
||||||
|
Output: ${basePath}/analysis/
|
||||||
|
Expected: write ${basePath}/analysis/report.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Points
|
||||||
|
|
||||||
|
- **Pass variables in prompts**: Use `${variableName}` for all dynamic values
|
||||||
|
- **Keep prompts focused**: Clear, specific tasks for each sub-agent
|
||||||
|
- **Return summaries**: Each sub-agent should report what it accomplished
|
||||||
|
- **Sequential execution**: Run steps in order when dependencies exist between outputs/inputs
|
||||||
|
- **Error handling**: Check results before proceeding to dependent steps
|
||||||
|
|
||||||
|
### ⚠️ Tool Availability Requirement
|
||||||
|
|
||||||
|
**Critical**: If a sub-agent requires specific tools (e.g., `edit`, `execute`, `search`), the orchestrator must include those tools in its own `tools` list. Sub-agents cannot access tools that aren't available to their parent orchestrator.
|
||||||
|
|
||||||
|
**Example**:
|
||||||
|
```yaml
|
||||||
|
# If your sub-agents need to edit files, execute commands, or search code
|
||||||
|
tools: ['read', 'edit', 'search', 'execute', 'agent']
|
||||||
|
```
|
||||||
|
|
||||||
|
The orchestrator's tool permissions act as a ceiling for all invoked sub-agents. Plan your tool list carefully to ensure all sub-agents have the tools they need.
|
||||||
|
|
||||||
|
### ⚠️ Important Limitation
|
||||||
|
|
||||||
|
**Sub-agent orchestration is NOT suitable for large-scale data processing.** Avoid using multi-step sub-agent pipelines when:
|
||||||
|
- Processing hundreds or thousands of files
|
||||||
|
- Handling large datasets
|
||||||
|
- Performing bulk transformations on big codebases
|
||||||
|
- Orchestrating more than 5-10 sequential steps
|
||||||
|
|
||||||
|
Each sub-agent invocation adds latency and context overhead. For high-volume processing, implement logic directly in a single agent instead. Use orchestration only for coordinating specialized tasks on focused, manageable datasets.
|
||||||
|
|
||||||
|
## Agent Prompt Structure
|
||||||
|
|
||||||
|
The markdown content below the frontmatter defines the agent's behavior, expertise, and instructions. Well-structured prompts typically include:
|
||||||
|
|
||||||
|
1. **Agent Identity and Role**: Who the agent is and its primary role
|
||||||
|
2. **Core Responsibilities**: What specific tasks the agent performs
|
||||||
|
3. **Approach and Methodology**: How the agent works to accomplish tasks
|
||||||
|
4. **Guidelines and Constraints**: What to do/avoid and quality standards
|
||||||
|
5. **Output Expectations**: Expected output format and quality
|
||||||
|
|
||||||
|
### Prompt Writing Best Practices
|
||||||
|
|
||||||
|
- **Be Specific and Direct**: Use imperative mood ("Analyze", "Generate"); avoid vague terms
|
||||||
|
- **Define Boundaries**: Clearly state scope limits and constraints
|
||||||
|
- **Include Context**: Explain domain expertise and reference relevant frameworks
|
||||||
|
- **Focus on Behavior**: Describe how the agent should think and work
|
||||||
|
- **Use Structured Format**: Headers, bullets, and lists make prompts scannable
|
||||||
|
|
||||||
|
## Variable Definition and Extraction
|
||||||
|
|
||||||
|
Agents can define dynamic parameters to extract values from user input and use them throughout the agent's behavior and sub-agent communications. This enables flexible, context-aware agents that adapt to user-provided data.
|
||||||
|
|
||||||
|
### When to Use Variables
|
||||||
|
|
||||||
|
**Use variables when**:
|
||||||
|
- Agent behavior depends on user input
|
||||||
|
- Need to pass dynamic values to sub-agents
|
||||||
|
- Want to make agents reusable across different contexts
|
||||||
|
- Require parameterized workflows
|
||||||
|
- Need to track or reference user-provided context
|
||||||
|
|
||||||
|
**Examples**:
|
||||||
|
- Extract project name from user prompt
|
||||||
|
- Capture certification name for pipeline processing
|
||||||
|
- Identify file paths or directories
|
||||||
|
- Extract configuration options
|
||||||
|
- Parse feature names or module identifiers
|
||||||
|
|
||||||
|
### Variable Declaration Pattern
|
||||||
|
|
||||||
|
Define variables section early in the agent prompt to document expected parameters:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Agent Name
|
||||||
|
|
||||||
|
## Dynamic Parameters
|
||||||
|
|
||||||
|
- **Parameter Name**: Description and usage
|
||||||
|
- **Another Parameter**: How it's extracted and used
|
||||||
|
|
||||||
|
## Your Mission
|
||||||
|
|
||||||
|
Process [PARAMETER_NAME] to accomplish [task].
|
||||||
|
```
|
||||||
|
|
||||||
|
### Variable Extraction Methods
|
||||||
|
|
||||||
|
#### 1. **Explicit User Input**
|
||||||
|
Ask the user to provide the variable if not detected in the prompt:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Your Mission
|
||||||
|
|
||||||
|
Process the project by analyzing your codebase.
|
||||||
|
|
||||||
|
### Step 1: Identify Project
|
||||||
|
If no project name is provided, **ASK THE USER** for:
|
||||||
|
- Project name or identifier
|
||||||
|
- Base path or directory location
|
||||||
|
- Configuration type (if applicable)
|
||||||
|
|
||||||
|
Use this information to contextualize all subsequent tasks.
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. **Implicit Extraction from Prompt**
|
||||||
|
Automatically extract variables from the user's natural language input:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Example: Extract certification name from user input
|
||||||
|
const userInput = "Process My Certification";
|
||||||
|
|
||||||
|
// Extract key information
|
||||||
|
const certificationName = extractCertificationName(userInput);
|
||||||
|
// Result: "My Certification"
|
||||||
|
|
||||||
|
const basePath = `certifications/${certificationName}`;
|
||||||
|
// Result: "certifications/My Certification"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. **Contextual Variable Resolution**
|
||||||
|
Use file context or workspace information to derive variables:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Variable Resolution Strategy
|
||||||
|
|
||||||
|
1. **From User Prompt**: First, look for explicit mentions in user input
|
||||||
|
2. **From File Context**: Check current file name or path
|
||||||
|
3. **From Workspace**: Use workspace folder or active project
|
||||||
|
4. **From Settings**: Reference configuration files
|
||||||
|
5. **Ask User**: If all else fails, request missing information
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using Variables in Agent Prompts
|
||||||
|
|
||||||
|
#### Variable Substitution in Instructions
|
||||||
|
|
||||||
|
Use template variables in agent prompts to make them dynamic:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Agent Name
|
||||||
|
|
||||||
|
## Dynamic Parameters
|
||||||
|
- **Project Name**: ${projectName}
|
||||||
|
- **Base Path**: ${basePath}
|
||||||
|
- **Output Directory**: ${outputDir}
|
||||||
|
|
||||||
|
## Your Mission
|
||||||
|
|
||||||
|
Process the **${projectName}** project located at `${basePath}`.
|
||||||
|
|
||||||
|
## Process Steps
|
||||||
|
|
||||||
|
1. Read input from: `${basePath}/input/`
|
||||||
|
2. Process files according to project configuration
|
||||||
|
3. Write results to: `${outputDir}/`
|
||||||
|
4. Generate summary report
|
||||||
|
|
||||||
|
## Quality Standards
|
||||||
|
|
||||||
|
- Maintain project-specific coding standards for **${projectName}**
|
||||||
|
- Follow directory structure: `${basePath}/[structure]`
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Passing Variables to Sub-Agents
|
||||||
|
|
||||||
|
When invoking a sub-agent, pass all context through substituted variables in the prompt. Prefer passing **paths and identifiers**, not entire file contents.
|
||||||
|
|
||||||
|
Example (prompt template):
|
||||||
|
|
||||||
|
```text
|
||||||
|
This phase must be performed as the agent "documentation-writer" defined in ".github/agents/documentation-writer.agent.md".
|
||||||
|
|
||||||
|
IMPORTANT:
|
||||||
|
- Read and apply the entire .agent.md spec.
|
||||||
|
- Project: "${projectName}"
|
||||||
|
- Base path: "projects/${projectName}"
|
||||||
|
- Input: "projects/${projectName}/src/"
|
||||||
|
- Output: "projects/${projectName}/docs/"
|
||||||
|
|
||||||
|
Task:
|
||||||
|
1. Read source files under the input path.
|
||||||
|
2. Generate documentation.
|
||||||
|
3. Write outputs under the output path.
|
||||||
|
4. Return a concise summary (files created/updated, key decisions, issues).
|
||||||
|
```
|
||||||
|
|
||||||
|
The sub-agent receives all necessary context embedded in the prompt. Variables are resolved before sending the prompt, so the sub-agent works with concrete paths and values, not variable placeholders.
|
||||||
|
|
||||||
|
### Real-World Example: Code Review Orchestrator
|
||||||
|
|
||||||
|
Example of a simple orchestrator that validates code through multiple specialized agents:
|
||||||
|
|
||||||
|
1) Determine shared context:
|
||||||
|
- `repositoryName`, `prNumber`
|
||||||
|
- `basePath` (e.g., `projects/${repositoryName}/pr-${prNumber}`)
|
||||||
|
|
||||||
|
2) Invoke specialized agents sequentially (each agent reads its own `.agent.md` spec):
|
||||||
|
|
||||||
|
```text
|
||||||
|
Step 1: Security Review
|
||||||
|
Agent: security-reviewer
|
||||||
|
Spec: .github/agents/security-reviewer.agent.md
|
||||||
|
Context: repositoryName=${repositoryName}, prNumber=${prNumber}, basePath=projects/${repositoryName}/pr-${prNumber}
|
||||||
|
Output: projects/${repositoryName}/pr-${prNumber}/security-review.md
|
||||||
|
|
||||||
|
Step 2: Test Coverage
|
||||||
|
Agent: test-coverage
|
||||||
|
Spec: .github/agents/test-coverage.agent.md
|
||||||
|
Context: repositoryName=${repositoryName}, prNumber=${prNumber}, basePath=projects/${repositoryName}/pr-${prNumber}
|
||||||
|
Output: projects/${repositoryName}/pr-${prNumber}/coverage-report.md
|
||||||
|
|
||||||
|
Step 3: Aggregate
|
||||||
|
Agent: review-aggregator
|
||||||
|
Spec: .github/agents/review-aggregator.agent.md
|
||||||
|
Context: repositoryName=${repositoryName}, prNumber=${prNumber}, basePath=projects/${repositoryName}/pr-${prNumber}
|
||||||
|
Output: projects/${repositoryName}/pr-${prNumber}/final-review.md
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Example: Conditional Step Orchestration (Code Review)
|
||||||
|
|
||||||
|
This example shows a more complete orchestration with **pre-flight checks**, **conditional steps**, and **required vs optional** behavior.
|
||||||
|
|
||||||
|
**Dynamic parameters (inputs):**
|
||||||
|
- `repositoryName`, `prNumber`
|
||||||
|
- `basePath` (e.g., `projects/${repositoryName}/pr-${prNumber}`)
|
||||||
|
- `logFile` (e.g., `${basePath}/.review-log.md`)
|
||||||
|
|
||||||
|
**Pre-flight checks (recommended):**
|
||||||
|
- Verify expected folders/files exist (e.g., `${basePath}/changes/`, `${basePath}/reports/`).
|
||||||
|
- Detect high-level characteristics that influence step triggers (e.g., repo language, presence of `package.json`, `pom.xml`, `requirements.txt`, test folders).
|
||||||
|
- Log the findings once at the start.
|
||||||
|
|
||||||
|
**Step trigger conditions:**
|
||||||
|
|
||||||
|
| Step | Status | Trigger Condition | On Failure |
|
||||||
|
|------|--------|-------------------|-----------|
|
||||||
|
| 1: Security Review | **Required** | Always run | Stop pipeline |
|
||||||
|
| 2: Dependency Audit | Optional | If a dependency manifest exists (`package.json`, `pom.xml`, etc.) | Continue |
|
||||||
|
| 3: Test Coverage Check | Optional | If test projects/files are present | Continue |
|
||||||
|
| 4: Performance Checks | Optional | If perf-sensitive code changed OR a perf config exists | Continue |
|
||||||
|
| 5: Aggregate & Verdict | **Required** | Always run if Step 1 completed | Stop pipeline |
|
||||||
|
|
||||||
|
**Execution flow (natural language):**
|
||||||
|
1. Initialize `basePath` and create/update `logFile`.
|
||||||
|
2. Run pre-flight checks and record them.
|
||||||
|
3. Execute Step 1 → N sequentially.
|
||||||
|
4. For each step:
|
||||||
|
- If trigger condition is false: mark as **SKIPPED** and continue.
|
||||||
|
- Otherwise: invoke the sub-agent using the wrapper prompt and capture its summary.
|
||||||
|
- Mark as **SUCCESS** or **FAILED**.
|
||||||
|
- If the step is **Required** and failed: stop the pipeline and write a failure summary.
|
||||||
|
5. End with a final summary section (overall status, artifacts, next actions).
|
||||||
|
|
||||||
|
**Sub-agent invocation prompt (example):**
|
||||||
|
|
||||||
|
```text
|
||||||
|
This phase must be performed as the agent "security-reviewer" defined in ".github/agents/security-reviewer.agent.md".
|
||||||
|
|
||||||
|
IMPORTANT:
|
||||||
|
- Read and apply the entire .agent.md spec.
|
||||||
|
- Work on repository "${repositoryName}" PR "${prNumber}".
|
||||||
|
- Base path: "${basePath}".
|
||||||
|
|
||||||
|
Task:
|
||||||
|
1. Review the changes under "${basePath}/changes/".
|
||||||
|
2. Write findings to "${basePath}/reports/security-review.md".
|
||||||
|
3. Return a short summary with: critical findings, recommended fixes, files created/modified.
|
||||||
|
```
|
||||||
|
|
||||||
|
**Logging format (example):**
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Step 2: Dependency Audit
|
||||||
|
**Status:** ✅ SUCCESS / ⚠️ SKIPPED / ❌ FAILED
|
||||||
|
**Trigger:** package.json present
|
||||||
|
**Started:** 2026-01-16T10:30:15Z
|
||||||
|
**Completed:** 2026-01-16T10:31:05Z
|
||||||
|
**Duration:** 00:00:50
|
||||||
|
**Artifacts:** reports/dependency-audit.md
|
||||||
|
**Summary:** [brief agent summary]
|
||||||
|
```
|
||||||
|
|
||||||
|
This pattern applies to any orchestration scenario: extract variables, call sub-agents with clear context, await results.
|
||||||
|
|
||||||
|
|
||||||
|
### Variable Best Practices
|
||||||
|
|
||||||
|
#### 1. **Clear Documentation**
|
||||||
|
Always document what variables are expected:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Required Variables
|
||||||
|
- **projectName**: The name of the project (string, required)
|
||||||
|
- **basePath**: Root directory for project files (path, required)
|
||||||
|
|
||||||
|
## Optional Variables
|
||||||
|
- **mode**: Processing mode - quick/standard/detailed (enum, default: standard)
|
||||||
|
- **outputFormat**: Output format - markdown/json/html (enum, default: markdown)
|
||||||
|
|
||||||
|
## Derived Variables
|
||||||
|
- **outputDir**: Automatically set to ${basePath}/output
|
||||||
|
- **logFile**: Automatically set to ${basePath}/.log.md
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. **Consistent Naming**
|
||||||
|
Use consistent variable naming conventions:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Good: Clear, descriptive naming
|
||||||
|
const variables = {
|
||||||
|
projectName, // What project to work on
|
||||||
|
basePath, // Where project files are located
|
||||||
|
outputDirectory, // Where to save results
|
||||||
|
processingMode, // How to process (detail level)
|
||||||
|
configurationPath // Where config files are
|
||||||
|
};
|
||||||
|
|
||||||
|
// Avoid: Ambiguous or inconsistent
|
||||||
|
const bad_variables = {
|
||||||
|
name, // Too generic
|
||||||
|
path, // Unclear which path
|
||||||
|
mode, // Too short
|
||||||
|
config // Too vague
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. **Validation and Constraints**
|
||||||
|
Document valid values and constraints:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Variable Constraints
|
||||||
|
|
||||||
|
**projectName**:
|
||||||
|
- Type: string (alphanumeric, hyphens, underscores allowed)
|
||||||
|
- Length: 1-100 characters
|
||||||
|
- Required: yes
|
||||||
|
- Pattern: `/^[a-zA-Z0-9_-]+$/`
|
||||||
|
|
||||||
|
**processingMode**:
|
||||||
|
- Type: enum
|
||||||
|
- Valid values: "quick" (< 5min), "standard" (5-15min), "detailed" (15+ min)
|
||||||
|
- Default: "standard"
|
||||||
|
- Required: no
|
||||||
|
```
|
||||||
|
|
||||||
|
## MCP Server Configuration (Organization/Enterprise Only)
|
||||||
|
|
||||||
|
MCP servers extend agent capabilities with additional tools. Only supported for organization and enterprise-level agents.
|
||||||
|
|
||||||
|
### Configuration Format
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
name: my-custom-agent
|
||||||
|
description: 'Agent with MCP integration'
|
||||||
|
tools: ['read', 'edit', 'custom-mcp/tool-1']
|
||||||
|
mcp-servers:
|
||||||
|
custom-mcp:
|
||||||
|
type: 'local'
|
||||||
|
command: 'some-command'
|
||||||
|
args: ['--arg1', '--arg2']
|
||||||
|
tools: ["*"]
|
||||||
|
env:
|
||||||
|
ENV_VAR_NAME: ${{ secrets.API_KEY }}
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
### MCP Server Properties
|
||||||
|
|
||||||
|
- **type**: Server type (`'local'` or `'stdio'`)
|
||||||
|
- **command**: Command to start the MCP server
|
||||||
|
- **args**: Array of command arguments
|
||||||
|
- **tools**: Tools to enable from this server (`["*"]` for all)
|
||||||
|
- **env**: Environment variables (supports secrets)
|
||||||
|
|
||||||
|
### Environment Variables and Secrets
|
||||||
|
|
||||||
|
Secrets must be configured in repository settings under "copilot" environment.
|
||||||
|
|
||||||
|
**Supported syntax**:
|
||||||
|
```yaml
|
||||||
|
env:
|
||||||
|
# Environment variable only
|
||||||
|
VAR_NAME: COPILOT_MCP_ENV_VAR_VALUE
|
||||||
|
|
||||||
|
# Variable with header
|
||||||
|
VAR_NAME: $COPILOT_MCP_ENV_VAR_VALUE
|
||||||
|
VAR_NAME: ${COPILOT_MCP_ENV_VAR_VALUE}
|
||||||
|
|
||||||
|
# GitHub Actions-style (YAML only)
|
||||||
|
VAR_NAME: ${{ secrets.COPILOT_MCP_ENV_VAR_VALUE }}
|
||||||
|
VAR_NAME: ${{ var.COPILOT_MCP_ENV_VAR_VALUE }}
|
||||||
|
```
|
||||||
|
|
||||||
|
## File Organization and Naming
|
||||||
|
|
||||||
|
### Repository-Level Agents
|
||||||
|
- Location: `.github/agents/`
|
||||||
|
- Scope: Available only in the specific repository
|
||||||
|
- Access: Uses repository-configured MCP servers
|
||||||
|
|
||||||
|
### Organization/Enterprise-Level Agents
|
||||||
|
- Location: `.github-private/agents/` (then move to `agents/` root)
|
||||||
|
- Scope: Available across all repositories in org/enterprise
|
||||||
|
- Access: Can configure dedicated MCP servers
|
||||||
|
|
||||||
|
### Naming Conventions
|
||||||
|
- Use lowercase with hyphens: `test-specialist.agent.md`
|
||||||
|
- Name should reflect agent purpose
|
||||||
|
- Filename becomes default agent name (if `name` not specified)
|
||||||
|
- Allowed characters: `.`, `-`, `_`, `a-z`, `A-Z`, `0-9`
|
||||||
|
|
||||||
|
## Agent Processing and Behavior
|
||||||
|
|
||||||
|
### Versioning
|
||||||
|
- Based on Git commit SHAs for the agent file
|
||||||
|
- Create branches/tags for different agent versions
|
||||||
|
- Instantiated using latest version for repository/branch
|
||||||
|
- PR interactions use same agent version for consistency
|
||||||
|
|
||||||
|
### Name Conflicts
|
||||||
|
Priority (highest to lowest):
|
||||||
|
1. Repository-level agent
|
||||||
|
2. Organization-level agent
|
||||||
|
3. Enterprise-level agent
|
||||||
|
|
||||||
|
Lower-level configurations override higher-level ones with the same name.
|
||||||
|
|
||||||
|
### Tool Processing
|
||||||
|
- `tools` list filters available tools (built-in and MCP)
|
||||||
|
- No tools specified = all tools enabled
|
||||||
|
- Empty list (`[]`) = all tools disabled
|
||||||
|
- Specific list = only those tools enabled
|
||||||
|
- Unrecognized tool names are ignored (allows environment-specific tools)
|
||||||
|
|
||||||
|
### MCP Server Processing Order
|
||||||
|
1. Out-of-the-box MCP servers (e.g., GitHub MCP)
|
||||||
|
2. Custom agent MCP configuration (org/enterprise only)
|
||||||
|
3. Repository-level MCP configurations
|
||||||
|
|
||||||
|
Each level can override settings from previous levels.
|
||||||
|
|
||||||
|
## Agent Creation Checklist
|
||||||
|
|
||||||
|
### Frontmatter
|
||||||
|
- [ ] `description` field present and descriptive (50-150 chars)
|
||||||
|
- [ ] `description` wrapped in single quotes
|
||||||
|
- [ ] `name` specified (optional but recommended)
|
||||||
|
- [ ] `tools` configured appropriately (or intentionally omitted)
|
||||||
|
- [ ] `model` specified for optimal performance
|
||||||
|
- [ ] `target` set if environment-specific
|
||||||
|
- [ ] Use `user-invocable: false` to hide from picker while allowing subagent invocation
|
||||||
|
- [ ] Use `disable-model-invocation: true` to prevent subagent invocation while keeping picker visibility
|
||||||
|
|
||||||
|
|
||||||
|
### Prompt Content
|
||||||
|
- [ ] Clear agent identity and role defined
|
||||||
|
- [ ] Core responsibilities listed explicitly
|
||||||
|
- [ ] Approach and methodology explained
|
||||||
|
- [ ] Guidelines and constraints specified
|
||||||
|
- [ ] Output expectations documented
|
||||||
|
- [ ] Examples provided where helpful
|
||||||
|
- [ ] Instructions are specific and actionable
|
||||||
|
- [ ] Scope and boundaries clearly defined
|
||||||
|
- [ ] Total content under 30,000 characters
|
||||||
|
|
||||||
|
### File Structure
|
||||||
|
- [ ] Filename follows lowercase-with-hyphens convention
|
||||||
|
- [ ] File placed in correct directory (`.github/agents/` or `agents/`)
|
||||||
|
- [ ] Filename uses only allowed characters
|
||||||
|
- [ ] File extension is `.agent.md`
|
||||||
|
|
||||||
|
### Quality Assurance
|
||||||
|
- [ ] Agent purpose is unique and not duplicative
|
||||||
|
- [ ] Tools are minimal and necessary
|
||||||
|
- [ ] Instructions are clear and unambiguous
|
||||||
|
- [ ] Agent has been tested with representative tasks
|
||||||
|
- [ ] Documentation references are current
|
||||||
|
- [ ] Security considerations addressed (if applicable)
|
||||||
|
|
||||||
|
## Common Agent Patterns
|
||||||
|
|
||||||
|
### Testing Specialist
|
||||||
|
**Purpose**: Focus on test coverage and quality
|
||||||
|
**Tools**: All tools (for comprehensive test creation)
|
||||||
|
**Approach**: Analyze, identify gaps, write tests, avoid production code changes
|
||||||
|
|
||||||
|
### Implementation Planner
|
||||||
|
**Purpose**: Create detailed technical plans and specifications
|
||||||
|
**Tools**: Limited to `['read', 'search', 'edit']`
|
||||||
|
**Approach**: Analyze requirements, create documentation, avoid implementation
|
||||||
|
|
||||||
|
### Code Reviewer
|
||||||
|
**Purpose**: Review code quality and provide feedback
|
||||||
|
**Tools**: `['read', 'search']` only
|
||||||
|
**Approach**: Analyze, suggest improvements, no direct modifications
|
||||||
|
|
||||||
|
### Refactoring Specialist
|
||||||
|
**Purpose**: Improve code structure and maintainability
|
||||||
|
**Tools**: `['read', 'search', 'edit']`
|
||||||
|
**Approach**: Analyze patterns, propose refactorings, implement safely
|
||||||
|
|
||||||
|
### Security Auditor
|
||||||
|
**Purpose**: Identify security issues and vulnerabilities
|
||||||
|
**Tools**: `['read', 'search', 'web']`
|
||||||
|
**Approach**: Scan code, check against OWASP, report findings
|
||||||
|
|
||||||
|
## Common Mistakes to Avoid
|
||||||
|
|
||||||
|
### Frontmatter Errors
|
||||||
|
- ❌ Missing `description` field
|
||||||
|
- ❌ Description not wrapped in quotes
|
||||||
|
- ❌ Invalid tool names without checking documentation
|
||||||
|
- ❌ Incorrect YAML syntax (indentation, quotes)
|
||||||
|
|
||||||
|
### Tool Configuration Issues
|
||||||
|
- ❌ Granting excessive tool access unnecessarily
|
||||||
|
- ❌ Missing required tools for agent's purpose
|
||||||
|
- ❌ Not using tool aliases consistently
|
||||||
|
- ❌ Forgetting MCP server namespace (`server-name/tool`)
|
||||||
|
|
||||||
|
### Prompt Content Problems
|
||||||
|
- ❌ Vague, ambiguous instructions
|
||||||
|
- ❌ Conflicting or contradictory guidelines
|
||||||
|
- ❌ Lack of clear scope definition
|
||||||
|
- ❌ Missing output expectations
|
||||||
|
- ❌ Overly verbose instructions (exceeding character limits)
|
||||||
|
- ❌ No examples or context for complex tasks
|
||||||
|
|
||||||
|
### Organizational Issues
|
||||||
|
- ❌ Filename doesn't reflect agent purpose
|
||||||
|
- ❌ Wrong directory (confusing repo vs org level)
|
||||||
|
- ❌ Using spaces or special characters in filename
|
||||||
|
- ❌ Duplicate agent names causing conflicts
|
||||||
|
|
||||||
|
## Testing and Validation
|
||||||
|
|
||||||
|
### Manual Testing
|
||||||
|
1. Create the agent file with proper frontmatter
|
||||||
|
2. Reload VS Code or refresh GitHub.com
|
||||||
|
3. Select the agent from the dropdown in Copilot Chat
|
||||||
|
4. Test with representative user queries
|
||||||
|
5. Verify tool access works as expected
|
||||||
|
6. Confirm output meets expectations
|
||||||
|
|
||||||
|
### Integration Testing
|
||||||
|
- Test agent with different file types in scope
|
||||||
|
- Verify MCP server connectivity (if configured)
|
||||||
|
- Check agent behavior with missing context
|
||||||
|
- Test error handling and edge cases
|
||||||
|
- Validate agent switching and handoffs
|
||||||
|
|
||||||
|
### Quality Checks
|
||||||
|
- Run through agent creation checklist
|
||||||
|
- Review against common mistakes list
|
||||||
|
- Compare with example agents in repository
|
||||||
|
- Get peer review for complex agents
|
||||||
|
- Document any special configuration needs
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
|
||||||
|
### Official Documentation
|
||||||
|
- [Creating Custom Agents](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-custom-agents)
|
||||||
|
- [Custom Agents Configuration](https://docs.github.com/en/copilot/reference/custom-agents-configuration)
|
||||||
|
- [Custom Agents in VS Code](https://code.visualstudio.com/docs/copilot/customization/custom-agents)
|
||||||
|
- [MCP Integration](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/extend-coding-agent-with-mcp)
|
||||||
|
|
||||||
|
### Community Resources
|
||||||
|
- [Awesome Copilot Agents Collection](https://github.com/github/awesome-copilot/tree/main/agents)
|
||||||
|
- [Customization Library Examples](https://docs.github.com/en/copilot/tutorials/customization-library/custom-agents)
|
||||||
|
- [Your First Custom Agent Tutorial](https://docs.github.com/en/copilot/tutorials/customization-library/custom-agents/your-first-custom-agent)
|
||||||
|
|
||||||
|
### Related Files
|
||||||
|
- [Prompt Files Guidelines](./prompt.instructions.md) - For creating prompt files
|
||||||
|
- [Instructions Guidelines](./instructions.instructions.md) - For creating instruction files
|
||||||
|
|
||||||
|
## Version Compatibility Notes
|
||||||
|
|
||||||
|
### GitHub.com (Coding Agent)
|
||||||
|
- ✅ Fully supports all standard frontmatter properties
|
||||||
|
- ✅ Repository and org/enterprise level agents
|
||||||
|
- ✅ MCP server configuration (org/enterprise)
|
||||||
|
- ❌ Does not support `model`, `argument-hint`, `handoffs` properties
|
||||||
|
|
||||||
|
### VS Code / JetBrains / Eclipse / Xcode
|
||||||
|
- ✅ Supports `model` property for AI model selection
|
||||||
|
- ✅ Supports `argument-hint` and `handoffs` properties
|
||||||
|
- ✅ User profile and workspace-level agents
|
||||||
|
- ❌ Cannot configure MCP servers at repository level
|
||||||
|
- ⚠️ Some properties may behave differently
|
||||||
|
|
||||||
|
When creating agents for multiple environments, focus on common properties and test in all target environments. Use `target` property to create environment-specific agents when necessary.
|
||||||
5
.github/instructions/ghidra.instructions.md
vendored
5
.github/instructions/ghidra.instructions.md
vendored
|
|
@ -28,12 +28,17 @@ applyTo: "**"
|
||||||
- **When `decompile_function` output is too large** (>~50KB), the result is written to a temp JSON file that `read_file` returns as empty `{}`. Use `disassemble_function` instead — it returns inline assembly directly and is fully navigable for large functions.
|
- **When `decompile_function` output is too large** (>~50KB), the result is written to a temp JSON file that `read_file` returns as empty `{}`. Use `disassemble_function` instead — it returns inline assembly directly and is fully navigable for large functions.
|
||||||
- Add a short decompiler comment when a rename is mapped from verified notes so the provenance stays visible in Ghidra.
|
- Add a short decompiler comment when a rename is mapped from verified notes so the provenance stays visible in Ghidra.
|
||||||
- Keep `crusader_decompilation_notes.md` updated after each verified batch.
|
- Keep `crusader_decompilation_notes.md` updated after each verified batch.
|
||||||
|
- Keep `crusader_segment_coverage_ledger.csv` updated after each verified batch whenever a segment can be promoted or reclassified.
|
||||||
|
- Keep the progress section in `plan-mid.md` updated after each verified batch so the next pass can resume from the exact stopping point.
|
||||||
|
- Keep `ghidra_mcp_wishlist.md` updated whenever the workflow hits a missing MCP capability and has to fall back to PyGhidra or another local-only path.
|
||||||
|
- Each wishlist entry should be short and concrete: what MCP lacked, what command/script/tool had to replace it, and what a useful MCP endpoint or behavior would look like.
|
||||||
- Record raw-import addresses alongside original segment-relative offsets when porting names.
|
- Record raw-import addresses alongside original segment-relative offsets when porting names.
|
||||||
- **Always use `rename_function_by_address`** — `rename_function` (by name) fails with "must have required property 'old_name'" and is broken. Use `"function_address": "000c:XXXX"` format.
|
- **Always use `rename_function_by_address`** — `rename_function` (by name) fails with "must have required property 'old_name'" and is broken. Use `"function_address": "000c:XXXX"` format.
|
||||||
|
|
||||||
# PyGhidra Fallback
|
# PyGhidra Fallback
|
||||||
|
|
||||||
- Use the local PyGhidra toolkit in `tools/pyghidra_crusader` when MCP is missing an operation such as function creation, deletion, or batched scripted edits.
|
- Use the local PyGhidra toolkit in `tools/pyghidra_crusader` when MCP is missing an operation such as function creation, deletion, or batched scripted edits.
|
||||||
|
- When PyGhidra is needed because MCP lacks a required operation, append a note to `ghidra_mcp_wishlist.md` in the same batch if the gap is not already documented.
|
||||||
- The workspace-local Python environment for this toolkit is `.venv-pyghidra311`, created from `C:\Users\Maddo\.pyenv\pyenv-win\versions\3.11.6\python.exe` and installed from the bundled Ghidra 11.3.2 offline packages.
|
- The workspace-local Python environment for this toolkit is `.venv-pyghidra311`, created from `C:\Users\Maddo\.pyenv\pyenv-win\versions\3.11.6\python.exe` and installed from the bundled Ghidra 11.3.2 offline packages.
|
||||||
- Default install dir for the toolkit is `I:\Apps\ghidra_11.3.2_PUBLIC`.
|
- Default install dir for the toolkit is `I:\Apps\ghidra_11.3.2_PUBLIC`.
|
||||||
- Invoke the toolkit with `\.venv-pyghidra311\Scripts\python.exe -m tools.pyghidra_crusader ...` from the repo root.
|
- Invoke the toolkit with `\.venv-pyghidra311\Scripts\python.exe -m tools.pyghidra_crusader ...` from the repo root.
|
||||||
|
|
|
||||||
256
.github/instructions/instructions.instructions.md
vendored
Normal file
256
.github/instructions/instructions.instructions.md
vendored
Normal file
|
|
@ -0,0 +1,256 @@
|
||||||
|
---
|
||||||
|
description: 'Guidelines for creating high-quality custom instruction files for GitHub Copilot'
|
||||||
|
applyTo: '**/*.instructions.md'
|
||||||
|
---
|
||||||
|
|
||||||
|
# Custom Instructions File Guidelines
|
||||||
|
|
||||||
|
Instructions for creating effective and maintainable custom instruction files that guide GitHub Copilot in generating domain-specific code and following project conventions.
|
||||||
|
|
||||||
|
## Project Context
|
||||||
|
|
||||||
|
- Target audience: Developers and GitHub Copilot working with domain-specific code
|
||||||
|
- File format: Markdown with YAML frontmatter
|
||||||
|
- File naming convention: lowercase with hyphens (e.g., `react-best-practices.instructions.md`)
|
||||||
|
- Location: `.github/instructions/` directory
|
||||||
|
- Purpose: Provide context-aware guidance for code generation, review, and documentation
|
||||||
|
|
||||||
|
## Required Frontmatter
|
||||||
|
|
||||||
|
Every instruction file must include YAML frontmatter with the following fields:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
description: 'Brief description of the instruction purpose and scope'
|
||||||
|
applyTo: 'glob pattern for target files (e.g., **/*.ts, **/*.py)'
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
### Frontmatter Guidelines
|
||||||
|
|
||||||
|
- **description**: Single-quoted string, 1-500 characters, clearly stating the purpose
|
||||||
|
- **applyTo**: Glob pattern(s) specifying which files these instructions apply to
|
||||||
|
- Single pattern: `'**/*.ts'`
|
||||||
|
- Multiple patterns: `'**/*.ts, **/*.tsx, **/*.js'`
|
||||||
|
- Specific files: `'src/**/*.py'`
|
||||||
|
- All files: `'**'`
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
A well-structured instruction file should include the following sections:
|
||||||
|
|
||||||
|
### 1. Title and Overview
|
||||||
|
|
||||||
|
- Clear, descriptive title using `#` heading
|
||||||
|
- Brief introduction explaining the purpose and scope
|
||||||
|
- Optional: Project context section with key technologies and versions
|
||||||
|
|
||||||
|
### 2. Core Sections
|
||||||
|
|
||||||
|
Organize content into logical sections based on the domain:
|
||||||
|
|
||||||
|
- **General Instructions**: High-level guidelines and principles
|
||||||
|
- **Best Practices**: Recommended patterns and approaches
|
||||||
|
- **Code Standards**: Naming conventions, formatting, style rules
|
||||||
|
- **Architecture/Structure**: Project organization and design patterns
|
||||||
|
- **Common Patterns**: Frequently used implementations
|
||||||
|
- **Security**: Security considerations (if applicable)
|
||||||
|
- **Performance**: Optimization guidelines (if applicable)
|
||||||
|
- **Testing**: Testing standards and approaches (if applicable)
|
||||||
|
|
||||||
|
### 3. Examples and Code Snippets
|
||||||
|
|
||||||
|
Provide concrete examples with clear labels:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
### Good Example
|
||||||
|
\`\`\`language
|
||||||
|
// Recommended approach
|
||||||
|
code example here
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### Bad Example
|
||||||
|
\`\`\`language
|
||||||
|
// Avoid this pattern
|
||||||
|
code example here
|
||||||
|
\`\`\`
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Validation and Verification (Optional but Recommended)
|
||||||
|
|
||||||
|
- Build commands to verify code
|
||||||
|
- Linting and formatting tools
|
||||||
|
- Testing requirements
|
||||||
|
- Verification steps
|
||||||
|
|
||||||
|
## Content Guidelines
|
||||||
|
|
||||||
|
### Writing Style
|
||||||
|
|
||||||
|
- Use clear, concise language
|
||||||
|
- Write in imperative mood ("Use", "Implement", "Avoid")
|
||||||
|
- Be specific and actionable
|
||||||
|
- Avoid ambiguous terms like "should", "might", "possibly"
|
||||||
|
- Use bullet points and lists for readability
|
||||||
|
- Keep sections focused and scannable
|
||||||
|
|
||||||
|
### Best Practices
|
||||||
|
|
||||||
|
- **Be Specific**: Provide concrete examples rather than abstract concepts
|
||||||
|
- **Show Why**: Explain the reasoning behind recommendations when it adds value
|
||||||
|
- **Use Tables**: For comparing options, listing rules, or showing patterns
|
||||||
|
- **Include Examples**: Real code snippets are more effective than descriptions
|
||||||
|
- **Stay Current**: Reference current versions and best practices
|
||||||
|
- **Link Resources**: Include official documentation and authoritative sources
|
||||||
|
|
||||||
|
### Common Patterns to Include
|
||||||
|
|
||||||
|
1. **Naming Conventions**: How to name variables, functions, classes, files
|
||||||
|
2. **Code Organization**: File structure, module organization, import order
|
||||||
|
3. **Error Handling**: Preferred error handling patterns
|
||||||
|
4. **Dependencies**: How to manage and document dependencies
|
||||||
|
5. **Comments and Documentation**: When and how to document code
|
||||||
|
6. **Version Information**: Target language/framework versions
|
||||||
|
|
||||||
|
## Patterns to Follow
|
||||||
|
|
||||||
|
### Bullet Points and Lists
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Security Best Practices
|
||||||
|
|
||||||
|
- Always validate user input before processing
|
||||||
|
- Use parameterized queries to prevent SQL injection
|
||||||
|
- Store secrets in environment variables, never in code
|
||||||
|
- Implement proper authentication and authorization
|
||||||
|
- Enable HTTPS for all production endpoints
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tables for Structured Information
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Common Issues
|
||||||
|
|
||||||
|
| Issue | Solution | Example |
|
||||||
|
| ---------------- | ------------------- | ----------------------------- |
|
||||||
|
| Magic numbers | Use named constants | `const MAX_RETRIES = 3` |
|
||||||
|
| Deep nesting | Extract functions | Refactor nested if statements |
|
||||||
|
| Hardcoded values | Use configuration | Store API URLs in config |
|
||||||
|
```
|
||||||
|
|
||||||
|
### Code Comparison
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
### Good Example - Using TypeScript interfaces
|
||||||
|
\`\`\`typescript
|
||||||
|
interface User {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUser(id: string): User {
|
||||||
|
// Implementation
|
||||||
|
}
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### Bad Example - Using any type
|
||||||
|
\`\`\`typescript
|
||||||
|
function getUser(id: any): any {
|
||||||
|
// Loses type safety
|
||||||
|
}
|
||||||
|
\`\`\`
|
||||||
|
```
|
||||||
|
|
||||||
|
### Conditional Guidance
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Framework Selection
|
||||||
|
|
||||||
|
- **For small projects**: Use Minimal API approach
|
||||||
|
- **For large projects**: Use controller-based architecture with clear separation
|
||||||
|
- **For microservices**: Consider domain-driven design patterns
|
||||||
|
```
|
||||||
|
|
||||||
|
## Patterns to Avoid
|
||||||
|
|
||||||
|
- **Overly verbose explanations**: Keep it concise and scannable
|
||||||
|
- **Outdated information**: Always reference current versions and practices
|
||||||
|
- **Ambiguous guidelines**: Be specific about what to do or avoid
|
||||||
|
- **Missing examples**: Abstract rules without concrete code examples
|
||||||
|
- **Contradictory advice**: Ensure consistency throughout the file
|
||||||
|
- **Copy-paste from documentation**: Add value by distilling and contextualizing
|
||||||
|
|
||||||
|
## Testing Your Instructions
|
||||||
|
|
||||||
|
Before finalizing instruction files:
|
||||||
|
|
||||||
|
1. **Test with Copilot**: Try the instructions with actual prompts in VS Code
|
||||||
|
2. **Verify Examples**: Ensure code examples are correct and run without errors
|
||||||
|
3. **Check Glob Patterns**: Confirm `applyTo` patterns match intended files
|
||||||
|
|
||||||
|
## Example Structure
|
||||||
|
|
||||||
|
Here's a minimal example structure for a new instruction file:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
description: 'Brief description of purpose'
|
||||||
|
applyTo: '**/*.ext'
|
||||||
|
---
|
||||||
|
|
||||||
|
# Technology Name Development
|
||||||
|
|
||||||
|
Brief introduction and context.
|
||||||
|
|
||||||
|
## General Instructions
|
||||||
|
|
||||||
|
- High-level guideline 1
|
||||||
|
- High-level guideline 2
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- Specific practice 1
|
||||||
|
- Specific practice 2
|
||||||
|
|
||||||
|
## Code Standards
|
||||||
|
|
||||||
|
### Naming Conventions
|
||||||
|
- Rule 1
|
||||||
|
- Rule 2
|
||||||
|
|
||||||
|
### File Organization
|
||||||
|
- Structure 1
|
||||||
|
- Structure 2
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Pattern 1
|
||||||
|
Description and example
|
||||||
|
|
||||||
|
\`\`\`language
|
||||||
|
code example
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### Pattern 2
|
||||||
|
Description and example
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- Build command: `command to verify`
|
||||||
|
- Linting: `command to lint`
|
||||||
|
- Testing: `command to test`
|
||||||
|
```
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
|
||||||
|
- Review instructions when dependencies or frameworks are updated
|
||||||
|
- Update examples to reflect current best practices
|
||||||
|
- Remove outdated patterns or deprecated features
|
||||||
|
- Add new patterns as they emerge in the community
|
||||||
|
- Keep glob patterns accurate as project structure evolves
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
|
||||||
|
- [Custom Instructions Documentation](https://code.visualstudio.com/docs/copilot/customization/custom-instructions)
|
||||||
|
- [Awesome Copilot Instructions](https://github.com/github/awesome-copilot/tree/main/instructions)
|
||||||
88
.github/instructions/prompt.instructions.md
vendored
Normal file
88
.github/instructions/prompt.instructions.md
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
---
|
||||||
|
description: 'Guidelines for creating high-quality prompt files for GitHub Copilot'
|
||||||
|
applyTo: '**/*.prompt.md'
|
||||||
|
---
|
||||||
|
|
||||||
|
# Copilot Prompt Files Guidelines
|
||||||
|
|
||||||
|
Instructions for creating effective and maintainable prompt files that guide GitHub Copilot in delivering consistent, high-quality outcomes across any repository.
|
||||||
|
|
||||||
|
## Scope and Principles
|
||||||
|
- Target audience: maintainers and contributors authoring reusable prompts for Copilot Chat.
|
||||||
|
- Goals: predictable behaviour, clear expectations, minimal permissions, and portability across repositories.
|
||||||
|
- Primary references: VS Code documentation on prompt files and organization-specific conventions.
|
||||||
|
|
||||||
|
## Frontmatter Requirements
|
||||||
|
|
||||||
|
Every prompt file should include YAML frontmatter with the following fields:
|
||||||
|
|
||||||
|
### Required/Recommended Fields
|
||||||
|
|
||||||
|
| Field | Required | Description |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `description` | Recommended | A short description of the prompt (single sentence, actionable outcome) |
|
||||||
|
| `name` | Optional | The name shown after typing `/` in chat. Defaults to filename if not specified |
|
||||||
|
| `agent` | Recommended | The agent to use: `ask`, `edit`, `agent`, or a custom agent name. Defaults to current agent |
|
||||||
|
| `model` | Optional | The language model to use. Defaults to the currently selected model |
|
||||||
|
| `tools` | Optional | List of tool/tool set names available for this prompt |
|
||||||
|
| `argument-hint` | Optional | Hint text shown in chat input to guide user interaction |
|
||||||
|
|
||||||
|
### Guidelines
|
||||||
|
|
||||||
|
- Use consistent quoting (single quotes recommended) and keep one field per line for readability and version control clarity
|
||||||
|
- If `tools` are specified and the current agent is `ask` or `edit`, the default agent becomes `agent`
|
||||||
|
- Preserve any additional metadata (`language`, `tags`, `visibility`, etc.) required by your organization
|
||||||
|
|
||||||
|
## File Naming and Placement
|
||||||
|
- Use kebab-case filenames ending with `.prompt.md` and store them under `.github/prompts/` unless your workspace standard specifies another directory.
|
||||||
|
- Provide a short filename that communicates the action (for example, `generate-readme.prompt.md` rather than `prompt1.prompt.md`).
|
||||||
|
|
||||||
|
## Body Structure
|
||||||
|
- Start with an `#` level heading that matches the prompt intent so it surfaces well in Quick Pick search.
|
||||||
|
- Organize content with predictable sections. Recommended baseline: `Mission` or `Primary Directive`, `Scope & Preconditions`, `Inputs`, `Workflow` (step-by-step), `Output Expectations`, and `Quality Assurance`.
|
||||||
|
- Adjust section names to fit the domain, but retain the logical flow: why → context → inputs → actions → outputs → validation.
|
||||||
|
- Reference related prompts or instruction files using relative links to aid discoverability.
|
||||||
|
|
||||||
|
## Input and Context Handling
|
||||||
|
- Use `${input:variableName[:placeholder]}` for required values and explain when the user must supply them. Provide defaults or alternatives where possible.
|
||||||
|
- Call out contextual variables such as `${selection}`, `${file}`, `${workspaceFolder}` only when they are essential, and describe how Copilot should interpret them.
|
||||||
|
- Document how to proceed when mandatory context is missing (for example, “Request the file path and stop if it remains undefined”).
|
||||||
|
|
||||||
|
## Tool and Permission Guidance
|
||||||
|
- Limit `tools` to the smallest set that enables the task. List them in the preferred execution order when the sequence matters.
|
||||||
|
- If the prompt inherits tools from a chat mode, mention that relationship and state any critical tool behaviours or side effects.
|
||||||
|
- Warn about destructive operations (file creation, edits, terminal commands) and include guard rails or confirmation steps in the workflow.
|
||||||
|
|
||||||
|
## Instruction Tone and Style
|
||||||
|
- Write in direct, imperative sentences targeted at Copilot (for example, “Analyze”, “Generate”, “Summarize”).
|
||||||
|
- Keep sentences short and unambiguous, following Google Developer Documentation translation best practices to support localization.
|
||||||
|
- Avoid idioms, humor, or culturally specific references; favor neutral, inclusive language.
|
||||||
|
|
||||||
|
## Output Definition
|
||||||
|
- Specify the format, structure, and location of expected results (for example, “Create `docs/adr/adr-XXXX.md` using the template below”).
|
||||||
|
- Include success criteria and failure triggers so Copilot knows when to halt or retry.
|
||||||
|
- Provide validation steps—manual checks, automated commands, or acceptance criteria lists—that reviewers can execute after running the prompt.
|
||||||
|
|
||||||
|
## Examples and Reusable Assets
|
||||||
|
- Embed Good/Bad examples or scaffolds (Markdown templates, JSON stubs) that the prompt should produce or follow.
|
||||||
|
- Maintain reference tables (capabilities, status codes, role descriptions) inline to keep the prompt self-contained. Update these tables when upstream resources change.
|
||||||
|
- Link to authoritative documentation instead of duplicating lengthy guidance.
|
||||||
|
|
||||||
|
## Quality Assurance Checklist
|
||||||
|
- [ ] Frontmatter fields are complete, accurate, and least-privilege.
|
||||||
|
- [ ] Inputs include placeholders, default behaviours, and fallbacks.
|
||||||
|
- [ ] Workflow covers preparation, execution, and post-processing without gaps.
|
||||||
|
- [ ] Output expectations include formatting and storage details.
|
||||||
|
- [ ] Validation steps are actionable (commands, diff checks, review prompts).
|
||||||
|
- [ ] Security, compliance, and privacy policies referenced by the prompt are current.
|
||||||
|
- [ ] Prompt executes successfully in VS Code (`Chat: Run Prompt`) using representative scenarios.
|
||||||
|
|
||||||
|
## Maintenance Guidance
|
||||||
|
- Version-control prompts alongside the code they affect; update them when dependencies, tooling, or review processes change.
|
||||||
|
- Review prompts periodically to ensure tool lists, model requirements, and linked documents remain valid.
|
||||||
|
- Coordinate with other repositories: when a prompt proves broadly useful, extract common guidance into instruction files or shared prompt packs.
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
- [Prompt Files Documentation](https://code.visualstudio.com/docs/copilot/customization/prompt-files#_prompt-file-format)
|
||||||
|
- [Awesome Copilot Prompt Files](https://github.com/github/awesome-copilot/tree/main/prompts)
|
||||||
|
- [Tool Configuration](https://code.visualstudio.com/docs/copilot/chat/chat-agent-mode#_agent-mode-tools)
|
||||||
147
.github/skills/make-skill-template/SKILL.md
vendored
Normal file
147
.github/skills/make-skill-template/SKILL.md
vendored
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
---
|
||||||
|
name: make-skill-template
|
||||||
|
description: 'Create new Agent Skills for GitHub Copilot from prompts or by duplicating this template. Use when asked to "create a skill", "make a new skill", "scaffold a skill", or when building specialized AI capabilities with bundled resources. Generates SKILL.md files with proper frontmatter, directory structure, and optional scripts/references/assets folders.'
|
||||||
|
---
|
||||||
|
|
||||||
|
# Make Skill Template
|
||||||
|
|
||||||
|
A meta-skill for creating new Agent Skills. Use this skill when you need to scaffold a new skill folder, generate a SKILL.md file, or help users understand the Agent Skills specification.
|
||||||
|
|
||||||
|
## When to Use This Skill
|
||||||
|
|
||||||
|
- User asks to "create a skill", "make a new skill", or "scaffold a skill"
|
||||||
|
- User wants to add a specialized capability to their GitHub Copilot setup
|
||||||
|
- User needs help structuring a skill with bundled resources
|
||||||
|
- User wants to duplicate this template as a starting point
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Understanding of what the skill should accomplish
|
||||||
|
- A clear, keyword-rich description of capabilities and triggers
|
||||||
|
- Knowledge of any bundled resources needed (scripts, references, assets, templates)
|
||||||
|
|
||||||
|
## Creating a New Skill
|
||||||
|
|
||||||
|
### Step 1: Create the Skill Directory
|
||||||
|
|
||||||
|
Create a new folder with a lowercase, hyphenated name:
|
||||||
|
|
||||||
|
```
|
||||||
|
skills/<skill-name>/
|
||||||
|
└── SKILL.md # Required
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 2: Generate SKILL.md with Frontmatter
|
||||||
|
|
||||||
|
Every skill requires YAML frontmatter with `name` and `description`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
name: <skill-name>
|
||||||
|
description: '<What it does>. Use when <specific triggers, scenarios, keywords users might say>.'
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Frontmatter Field Requirements
|
||||||
|
|
||||||
|
| Field | Required | Constraints |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `name` | **Yes** | 1-64 chars, lowercase letters/numbers/hyphens only, must match folder name |
|
||||||
|
| `description` | **Yes** | 1-1024 chars, must describe WHAT it does AND WHEN to use it |
|
||||||
|
| `license` | No | License name or reference to bundled LICENSE.txt |
|
||||||
|
| `compatibility` | No | 1-500 chars, environment requirements if needed |
|
||||||
|
| `metadata` | No | Key-value pairs for additional properties |
|
||||||
|
| `allowed-tools` | No | Space-delimited list of pre-approved tools (experimental) |
|
||||||
|
|
||||||
|
#### Description Best Practices
|
||||||
|
|
||||||
|
**CRITICAL**: The `description` is the PRIMARY mechanism for automatic skill discovery. Include:
|
||||||
|
|
||||||
|
1. **WHAT** the skill does (capabilities)
|
||||||
|
2. **WHEN** to use it (triggers, scenarios, file types)
|
||||||
|
3. **Keywords** users might mention in prompts
|
||||||
|
|
||||||
|
**Good example:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
description: 'Toolkit for testing local web applications using Playwright. Use when asked to verify frontend functionality, debug UI behavior, capture browser screenshots, or view browser console logs. Supports Chrome, Firefox, and WebKit.'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Poor example:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
description: 'Web testing helpers'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Write the Skill Body
|
||||||
|
|
||||||
|
After the frontmatter, add markdown instructions. Recommended sections:
|
||||||
|
|
||||||
|
| Section | Purpose |
|
||||||
|
|---------|---------|
|
||||||
|
| `# Title` | Brief overview |
|
||||||
|
| `## When to Use This Skill` | Reinforces description triggers |
|
||||||
|
| `## Prerequisites` | Required tools, dependencies |
|
||||||
|
| `## Step-by-Step Workflows` | Numbered steps for tasks |
|
||||||
|
| `## Troubleshooting` | Common issues and solutions |
|
||||||
|
| `## References` | Links to bundled docs |
|
||||||
|
|
||||||
|
### Step 4: Add Optional Directories (If Needed)
|
||||||
|
|
||||||
|
| Folder | Purpose | When to Use |
|
||||||
|
|--------|---------|-------------|
|
||||||
|
| `scripts/` | Executable code (Python, Bash, JS) | Automation that performs operations |
|
||||||
|
| `references/` | Documentation agent reads | API references, schemas, guides |
|
||||||
|
| `assets/` | Static files used AS-IS | Images, fonts, templates |
|
||||||
|
| `templates/` | Starter code agent modifies | Scaffolds to extend |
|
||||||
|
|
||||||
|
## Example: Complete Skill Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
my-awesome-skill/
|
||||||
|
├── SKILL.md # Required instructions
|
||||||
|
├── LICENSE.txt # Optional license file
|
||||||
|
├── scripts/
|
||||||
|
│ └── helper.py # Executable automation
|
||||||
|
├── references/
|
||||||
|
│ ├── api-reference.md # Detailed docs
|
||||||
|
│ └── examples.md # Usage examples
|
||||||
|
├── assets/
|
||||||
|
│ └── diagram.png # Static resources
|
||||||
|
└── templates/
|
||||||
|
└── starter.ts # Code scaffold
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Start: Duplicate This Template
|
||||||
|
|
||||||
|
1. Copy the `make-skill-template/` folder
|
||||||
|
2. Rename to your skill name (lowercase, hyphens)
|
||||||
|
3. Update `SKILL.md`:
|
||||||
|
- Change `name:` to match folder name
|
||||||
|
- Write a keyword-rich `description:`
|
||||||
|
- Replace body content with your instructions
|
||||||
|
4. Add bundled resources as needed
|
||||||
|
5. Validate with `npm run skill:validate`
|
||||||
|
|
||||||
|
## Validation Checklist
|
||||||
|
|
||||||
|
- [ ] Folder name is lowercase with hyphens
|
||||||
|
- [ ] `name` field matches folder name exactly
|
||||||
|
- [ ] `description` is 10-1024 characters
|
||||||
|
- [ ] `description` explains WHAT and WHEN
|
||||||
|
- [ ] `description` is wrapped in single quotes
|
||||||
|
- [ ] Body content is under 500 lines
|
||||||
|
- [ ] Bundled assets are under 5MB each
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
| Issue | Solution |
|
||||||
|
|-------|----------|
|
||||||
|
| Skill not discovered | Improve description with more keywords and triggers |
|
||||||
|
| Validation fails on name | Ensure lowercase, no consecutive hyphens, matches folder |
|
||||||
|
| Description too short | Add capabilities, triggers, and keywords |
|
||||||
|
| Assets not found | Use relative paths from skill root |
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- Agent Skills official spec: <https://agentskills.io/specification>
|
||||||
BIN
ASYLUM.DLL
Normal file
BIN
ASYLUM.DLL
Normal file
Binary file not shown.
12
CRUSADER.CFG
Normal file
12
CRUSADER.CFG
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
irq=5
|
||||||
|
dma=1
|
||||||
|
port=0x220
|
||||||
|
soundcard=3
|
||||||
|
sound=on
|
||||||
|
music=on
|
||||||
|
fullinstall=true
|
||||||
|
bigvideo=true
|
||||||
|
subtitles=true
|
||||||
|
cdletter=D
|
||||||
|
flicpath=\flics
|
||||||
|
newvideo=true
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
STATIC/ANIM.DAT
Normal file
BIN
STATIC/ANIM.DAT
Normal file
Binary file not shown.
BIN
STATIC/COMBAT.DAT
Normal file
BIN
STATIC/COMBAT.DAT
Normal file
Binary file not shown.
BIN
STATIC/DAMAGE.FLX
Normal file
BIN
STATIC/DAMAGE.FLX
Normal file
Binary file not shown.
BIN
STATIC/DIFF.PAL
Normal file
BIN
STATIC/DIFF.PAL
Normal file
Binary file not shown.
BIN
STATIC/DTABLE.FLX
Normal file
BIN
STATIC/DTABLE.FLX
Normal file
Binary file not shown.
BIN
STATIC/FIXED.DAT
Normal file
BIN
STATIC/FIXED.DAT
Normal file
Binary file not shown.
BIN
STATIC/FONTS.FLX
Normal file
BIN
STATIC/FONTS.FLX
Normal file
Binary file not shown.
BIN
STATIC/GAMEPAL.PAL
Normal file
BIN
STATIC/GAMEPAL.PAL
Normal file
Binary file not shown.
BIN
STATIC/GLOB.FLX
Normal file
BIN
STATIC/GLOB.FLX
Normal file
Binary file not shown.
BIN
STATIC/GUMPS.FLX
Normal file
BIN
STATIC/GUMPS.FLX
Normal file
Binary file not shown.
BIN
STATIC/MISC.PAL
Normal file
BIN
STATIC/MISC.PAL
Normal file
Binary file not shown.
BIN
STATIC/MISC2.PAL
Normal file
BIN
STATIC/MISC2.PAL
Normal file
Binary file not shown.
BIN
STATIC/MOUSE.SHP
Normal file
BIN
STATIC/MOUSE.SHP
Normal file
Binary file not shown.
BIN
STATIC/SHAPES.FLX
Normal file
BIN
STATIC/SHAPES.FLX
Normal file
Binary file not shown.
BIN
STATIC/STAR.PAL
Normal file
BIN
STATIC/STAR.PAL
Normal file
Binary file not shown.
BIN
STATIC/STUFF.DAT
Normal file
BIN
STATIC/STUFF.DAT
Normal file
Binary file not shown.
BIN
STATIC/TRIG.DAT
Normal file
BIN
STATIC/TRIG.DAT
Normal file
Binary file not shown.
BIN
STATIC/TYPEFLAG.DAT
Normal file
BIN
STATIC/TYPEFLAG.DAT
Normal file
Binary file not shown.
BIN
STATIC/WPNOVLAY.DAT
Normal file
BIN
STATIC/WPNOVLAY.DAT
Normal file
Binary file not shown.
BIN
STATIC/XFORMPAL.DAT
Normal file
BIN
STATIC/XFORMPAL.DAT
Normal file
Binary file not shown.
BIN
USECODE/EUSECODE.FLX
Normal file
BIN
USECODE/EUSECODE.FLX
Normal file
Binary file not shown.
BIN
USECODE/OVERLOAD.DAT
Normal file
BIN
USECODE/OVERLOAD.DAT
Normal file
Binary file not shown.
BIN
USECODE/UNKCOFF.DAT
Normal file
BIN
USECODE/UNKCOFF.DAT
Normal file
Binary file not shown.
BIN
USECODE/UNKDS.DAT
Normal file
BIN
USECODE/UNKDS.DAT
Normal file
Binary file not shown.
|
|
@ -1757,7 +1757,7 @@ Current structural read of the cache globals:
|
||||||
- Current verified behavior for `runtime_cache_reset_sequence`:
|
- Current verified behavior for `runtime_cache_reset_sequence`:
|
||||||
- Calls `0008:7bfe`.
|
- Calls `0008:7bfe`.
|
||||||
- Calls `game_mode_init(*(0x27c4))`.
|
- Calls `game_mode_init(*(0x27c4))`.
|
||||||
- Executes one still-unresolved follow-up callsite at `0004:25a4`.
|
- Calls an import-resolved follow-up site at `0004:25a4`, now annotated as `NE IMPORT -> ASYLUM.24`.
|
||||||
- Then resets cache runtime state, clears tracked handles, refreshes tracked-entry/cache helpers, and resumes the wider runtime reset flow.
|
- Then resets cache runtime state, clears tracked handles, refreshes tracked-entry/cache helpers, and resumes the wider runtime reset flow.
|
||||||
- Known caller so far: `0004:262d` inside the tiny wrapper at `0004:2620`, which sets byte `+0x40` on the object at `0x6828` before invoking the reset sequence.
|
- Known caller so far: `0004:262d` inside the tiny wrapper at `0004:2620`, which sets byte `+0x40` on the object at `0x6828` before invoking the reset sequence.
|
||||||
- `0004:eb1f` had also been truncated. It has now been repaired to the full body `0004:eb1f-eb9b` and renamed `entity_dispatch_entry_ctor_0f3a_with_cache_reset`.
|
- `0004:eb1f` had also been truncated. It has now been repaired to the full body `0004:eb1f-eb9b` and renamed `entity_dispatch_entry_ctor_0f3a_with_cache_reset`.
|
||||||
|
|
@ -1765,10 +1765,104 @@ Current structural read of the cache globals:
|
||||||
- Allocates/initializes an entity dispatch entry when needed.
|
- Allocates/initializes an entity dispatch entry when needed.
|
||||||
- Stamps entry type `0x0f3a`.
|
- Stamps entry type `0x0f3a`.
|
||||||
- Stores its two word payload fields from the incoming args.
|
- Stores its two word payload fields from the incoming args.
|
||||||
- Runs local setup through `0004:ebf4`.
|
- Runs local setup through the embedded helper at `0004:ebf4`, which dispatches `entity_dispatch_reset_all(*0x7e22, 0x00f0)` and, when the local flag plus global `0x0ee1` allow it, allocates a type `0x0f5e` dispatch entry and passes it to `entity_pair_sync_b`.
|
||||||
- When `tracked_entity_bucket_system_enabled` is set, performs the tracked-handle removal / clear / cache-compaction sequence before finalizing through `0009:b1c3`.
|
- When `tracked_entity_bucket_system_enabled` is set, performs the tracked-handle removal / clear / cache-compaction sequence before finalizing through `0009:b1c3` in phase `0`.
|
||||||
- The sibling at `0004:eb9c` remains separate and valid; it builds the same `0x0f3a` entry type without the extra cache-reset tail, so the repaired `0004:eb1f` boundary stops cleanly at `0004:eb9b`.
|
- The sibling at `0004:eb9c` remains separate and valid; it builds the same `0x0f3a` entry type without the extra cache-reset tail, so the repaired `0004:eb1f` boundary stops cleanly at `0004:eb9b`.
|
||||||
|
|
||||||
|
### Follow-up: new local helper classification around the repaired seg004 path
|
||||||
|
|
||||||
|
- `0004:ea00` is now a real function object named `entity_dispatch_entry_alloc_type_0f5e` with body `0004:ea00-0004:ea46`.
|
||||||
|
- Verified behavior for `entity_dispatch_entry_alloc_type_0f5e`:
|
||||||
|
- Reuses the incoming FAR pointer when non-null; otherwise allocates `0x33` bytes through `mem_alloc_far`.
|
||||||
|
- Initializes the entry through `entity_dispatch_entry_init`.
|
||||||
|
- Stamps the entry type word at `+0x00` to `0x0f5e` before returning it.
|
||||||
|
- `0009:b1c3` remains conservatively unnamed, but it is now annotated as a phase-selected finalize helper:
|
||||||
|
- Both known call sites pass only phase bytes `0` or `1`.
|
||||||
|
- It forwards that byte twice to the object rooted at `0x4588` through vtable slot `+0x08`.
|
||||||
|
- It then sweeps the table rooted at `0x8724` up to count `0x879c`, calling `FUN_0009_a961` on each entry.
|
||||||
|
- That evidence is strong enough for comments, but not yet enough to promote `0009:b1c3` or `0x4588` to a more specific subsystem name.
|
||||||
|
|
||||||
|
### Follow-up: seg082 allocator cluster (`0009:a229`, `0009:af87`, `0009:b06b`, `0009:b1c3`)
|
||||||
|
|
||||||
|
- `0009:a229` is now verified as the public size-only wrapper around the seg082 allocator path.
|
||||||
|
- Caller evidence:
|
||||||
|
- `saveslot_table_clear` requests `0x2800` bytes through `0009:a229`, stores the returned FAR pointer at `0x2ba3/0x2ba5`, then zeroes the result in `0x400`-byte chunks.
|
||||||
|
- The wrapper lazily initializes the allocator on first use through `0009:bcb9`, then calls `0009:b06b(size, default_tag, 0xff)`.
|
||||||
|
- `0009:bcb9` is now annotated as the one-time lazy initializer for this path.
|
||||||
|
- It parses an optional `-x` tuning value from the PSP command line, clamps the derived percentage into `0x14..0x50`, then seeds local seg082 helpers before setting init flag `0x4096 = 1`.
|
||||||
|
- Table structure around `0x8724` is tighter now:
|
||||||
|
- `0x8724` is an array of `0x0c`-byte allocator heads.
|
||||||
|
- `0x879c` is the active head count / table limit.
|
||||||
|
- The per-node size/value encoding used under each head is manipulated through `0009:c628` and `0009:c6ae`, which read/write a packed 32-bit quantity split across `word + byte + byte` fields.
|
||||||
|
- `0009:af87` is now annotated as the free-space probe for the same cluster.
|
||||||
|
- It walks the node chain rooted at `0x8724`.
|
||||||
|
- For each node, it accumulates `node_size - 9` into a running total and tracks the largest single free block.
|
||||||
|
- Known callers include `cache_init` and the seg013 path at `0004:833b`, both of which use it to size subsequent allocation work.
|
||||||
|
- `0009:b06b` has been traced further as the internal sweep allocator for this cluster.
|
||||||
|
- It validates the requested size, reserves a temporary work token through `0009:e15f`, and scans the `0x8724` table in `0x0c`-byte entries via the local helper at `0009:a336`.
|
||||||
|
- On a successful fit, it commits the result through `0009:e2b4`, clears failure flag `0x4098`, and returns the allocated FAR pointer.
|
||||||
|
- When a pass does not find a fit, it interleaves up to two finalize phases through `0009:b1c3(phase)` before the final retry, then releases the work token through `0009:e1f6`.
|
||||||
|
- The formerly missing callee at `0009:a336` has now been recovered in-place as `allocator_head_try_alloc_block` with body `0009:a336-0009:a5d0`.
|
||||||
|
- It is the per-head first-fit allocator helper used by `0009:b06b` while sweeping the `0x8724` head table.
|
||||||
|
- It normalizes the requested size (rounds odd small requests up, page-aligns large non-page-aligned requests), adds the local `0x0a` node header overhead, and enforces a minimum allocation size of `0x10` bytes.
|
||||||
|
- It walks the node chain for one allocator head until it finds a free span large enough.
|
||||||
|
- On success it unlinks the chosen free node, either consumes it whole or splits off a remainder node when at least `0x10` bytes remain, stores the owner/tag word, and returns `payload_ptr + 0x0a`.
|
||||||
|
- On failure for that head it returns `0`, which matches the calling pattern in `0009:b06b`.
|
||||||
|
- Boundary follow-up from the same read-only scan:
|
||||||
|
- The adjacent missing body at `0009:a5d1` has now also been recovered in-place as `allocator_head_free_block` with body `0009:a5d1-0009:a960`.
|
||||||
|
- It is the per-head free helper paired with `allocator_head_try_alloc_block`.
|
||||||
|
- It rebuilds the node header from a payload pointer (`payload - 0x0a`), validates the owner/tag word against the expected caller-supplied tag, reinserts the block into one allocator head, and coalesces with adjacent free neighbors when possible.
|
||||||
|
- Its earlier branch targets `0009:a7a1` and `0009:a7b8` are now confirmed to be internal labels, not separate function entries.
|
||||||
|
- `0009:a961` is now better constrained as the per-head finalize sweep used by `0009:b1c3`.
|
||||||
|
- It walks one `0x8724` head's node chain, skips odd-tagged spans, coalesces or rewrites eligible spans, and updates head/back-pointer links when deferred space needs to be merged back into the chain.
|
||||||
|
- This strengthens the current interpretation that `0009:b1c3` is a phase-selected allocator-finalize pass rather than a cache-specific public API.
|
||||||
|
- `0009:b224` is now named `allocator_free_block_by_ptr`.
|
||||||
|
- Current verified behavior: converts the payload pointer back through the local header helpers, scans the `0x8724` head table for the owning range, dispatches to `allocator_head_free_block`, and aborts if no owning head is found.
|
||||||
|
- Known wrappers `0009:a24f` and `0009:a27a` are now clearly small checked entry points into this free-by-pointer path.
|
||||||
|
- With both recovered bodies in place, the seg082 cluster now has a verified alloc/free pair at the per-head level:
|
||||||
|
- `allocator_head_try_alloc_block` (`0009:a336`)
|
||||||
|
- `allocator_head_free_block` (`0009:a5d1`)
|
||||||
|
- `allocator_free_block_by_ptr` (`0009:b224`)
|
||||||
|
- `0009:b1c3` now has a corrected single-byte phase parameter in Ghidra; the object at `0x4588` is still left unnamed because its subsystem role is not yet strong enough.
|
||||||
|
- This narrows the remaining ambiguity around `0009:b1c3`: the unresolved part is now the role of the object at `0x4588`, not the local allocator mechanics around `0x8724`. `ASYLUM.24` is still not identified from the current evidence.
|
||||||
|
|
||||||
|
### Follow-up: `0x4588` object-role evidence (Priority 1 start)
|
||||||
|
|
||||||
|
- A direct instruction scan found real uses of `0x4588` / `0x458a` even though normal static reference APIs were not materializing them.
|
||||||
|
- Current verified behavior from those uses:
|
||||||
|
- `entity_conditional_render_dispatch` (`0009:9216`) calls through the runtime-installed object at `0x4588` via vtable slot `+0x0c` when the entity flags allow the alternate path and `param_2 == 0`.
|
||||||
|
- `000a:4a56` is a one-shot teardown/reset path for the same object: it checks a local once-flag at `0x4595`, clears `0x4588` when non-null, optionally performs a vtable `+0x0c` callback when `0x4590 != 0x458c`, then calls vtable slot `+0x04` followed by `FUN_0009_0d30()`.
|
||||||
|
- A read-only data probe of `0x4588` in the current database returned all zero bytes, so the object pointer is null-initialized statically and likely installed later at runtime.
|
||||||
|
- Conservative conclusion:
|
||||||
|
- The `0x4588` object now looks like a runtime-installed callback / dispatch object that participates in conditional render or presentation-side flow and has an explicit teardown path.
|
||||||
|
- That is enough for comments and ledger progress, but still not enough to safely rename `0009:b1c3` or the global itself to a concrete subsystem name.
|
||||||
|
|
||||||
|
### Follow-up: `0x4588` install/clear windows from the no-function hit list
|
||||||
|
|
||||||
|
- A read-only PyGhidra instruction-window pass against an unlocked project clone confirmed that the planned no-function hit list is real code, not aligned data.
|
||||||
|
- New verified lifecycle evidence:
|
||||||
|
- `000a:4932` and `000a:4936` store the same incoming dword into `0x4590` and `0x458c`, then `000a:493e` stores the incoming FAR object pointer into `0x4588`.
|
||||||
|
- `0004:5b8c` and `0004:5bbf` both clear `0x4588` immediately before the fatal/reporting-style seg091 call through `000a:454d`.
|
||||||
|
- `0004:5ea7` and `0004:6430` both clear `0x4588` and then immediately run the one-shot teardown path `000a:4a56(1)`.
|
||||||
|
- `000a:b9e5`, `000a:ba66`, `000d:9d5e`, and `000d:a3b7` all push a two-word value pair followed by the `0x4588` FAR pointer and call the object's vtable slot `+0x0c`.
|
||||||
|
- `entity_conditional_render_dispatch` remains the only named caller found so far for the same slot, but it passes a single literal `0x0101` argument instead of a two-word pair.
|
||||||
|
- Conservative conclusion after the window pass:
|
||||||
|
- `0x4588` is definitely a nullable runtime-installed FAR object with explicit install, clear, callback, and teardown transitions.
|
||||||
|
- The unresolved part is now its concrete subsystem identity, not whether the object lifecycle is real.
|
||||||
|
- The best next cheap win is no longer broad instruction searching; it is caller-side recovery around the still-unbounded `000a:b9e5` / `000a:ba66` and `000d:9d5e` / `000d:a3b7` windows.
|
||||||
|
|
||||||
|
### Follow-up: `ASYLUM.24` vs nearby `ASYLUM` ordinals
|
||||||
|
|
||||||
|
- `ASYLUM.24` remains unresolved by name, but its call pattern is now narrower.
|
||||||
|
- In `runtime_cache_reset_sequence` (`0004:2592`), it is a parameterless import call placed after `game_mode_init(*(0x27c4))` and before `cache_reset_runtime_state` plus the tracked-handle/cache-side reset tail.
|
||||||
|
- That makes it look like a module-level reset/init hook rather than a per-object method.
|
||||||
|
- Nearby `ASYLUM` ordinals in the seg011 caller at `0004:6f15` show a different pattern:
|
||||||
|
- `ASYLUM.36` returns an object-like handle that is used immediately through indirect vtable calls.
|
||||||
|
- `ASYLUM.37` is then called with explicit arguments against that object flow.
|
||||||
|
- Current conservative conclusion:
|
||||||
|
- `ASYLUM.24` is probably from the same external module family, but it does not currently match the object-construction / object-method calling pattern observed for `ASYLUM.36` and `ASYLUM.37`.
|
||||||
|
- Keep the import unresolved by name until another caller or string anchor narrows the exact module role.
|
||||||
|
|
||||||
### Repair note: overlapping bad function body
|
### Repair note: overlapping bad function body
|
||||||
|
|
||||||
- Recovery of `cache_init` required a conservative boundary repair: a stray function object `FUN_000a_eee3` had incorrectly claimed body range `000a:6710-000a:fe79`, blocking creation of the real `cache_init` body.
|
- Recovery of `cache_init` required a conservative boundary repair: a stray function object `FUN_000a_eee3` had incorrectly claimed body range `000a:6710-000a:fe79`, blocking creation of the real `cache_init` body.
|
||||||
|
|
|
||||||
146
crusader_segment_coverage_ledger.csv
Normal file
146
crusader_segment_coverage_ledger.csv
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
"Segment","Type","FileOffset","Length","CoverageStatus","KnownSubsystem","KeyNamedFunctions","Blockers","NotesSource"
|
||||||
|
"1","code","0x37600","0x8400","Deep","Gameplay cursor/input/projectiles","cursor_update_hover; entity_fire_weapon; projectile_update_tick","Broader gameplay subsystem still spans adjacent segments","crusader_decompilation_notes.md; plan-mid.md"
|
||||||
|
"2","code","0x40000","0x2B0","None","","","","crusader_ne_segments.csv"
|
||||||
|
"3","code","0x40400","0x55A","None","","","","crusader_ne_segments.csv"
|
||||||
|
"4","code","0x40A00","0x10B1","Foothold","Reset/cache entry path","runtime_cache_reset_sequence","ASYLUM.24 and downstream reset callers still need tighter classification","crusader_decompilation_notes.md; plan-mid.md"
|
||||||
|
"5","code","0x41E00","0x8D7","None","","","","crusader_ne_segments.csv"
|
||||||
|
"6","code","0x42C00","0x75E","None","","","","crusader_ne_segments.csv"
|
||||||
|
"7","code","0x43600","0x484","None","","","","crusader_ne_segments.csv"
|
||||||
|
"8","code","0x43C00","0x1386","None","","","","crusader_ne_segments.csv"
|
||||||
|
"9","code","0x45400","0x495","None","","","","crusader_ne_segments.csv"
|
||||||
|
"10","code","0x45A00","0xD92","None","","","","crusader_ne_segments.csv"
|
||||||
|
"11","code","0x46E00","0x5B1","None","","","","crusader_ne_segments.csv"
|
||||||
|
"12","code","0x47600","0x94B","None","","","","crusader_ne_segments.csv"
|
||||||
|
"13","code","0x48200","0x1F6C","None","","","","crusader_ne_segments.csv"
|
||||||
|
"14","code","0x4AA00","0x526","None","","","","crusader_ne_segments.csv"
|
||||||
|
"15","code","0x4B200","0x1C68","None","","","","crusader_ne_segments.csv"
|
||||||
|
"16","code","0x4D400","0x677","None","","","","crusader_ne_segments.csv"
|
||||||
|
"17","code","0x4DC00","0x1A7","None","","","","crusader_ne_segments.csv"
|
||||||
|
"18","code","0x4E000","0x7E9","None","","","","crusader_ne_segments.csv"
|
||||||
|
"19","code","0x4EA00","0xB4D","None","","","","crusader_ne_segments.csv"
|
||||||
|
"20","code","0x4F800","0x878","None","","","","crusader_ne_segments.csv"
|
||||||
|
"21","code","0x50200","0x4486","Partial","Timer/event dispatch and entity counting","entity_count_by_type_a; input_keyboard_handler copy","Needs broader caller-driven expansion","crusader_decompilation_notes.md; plan-mid.md"
|
||||||
|
"22","code","0x55000","0x2BD6","None","","","","crusader_ne_segments.csv"
|
||||||
|
"23","code","0x58200","0x5D6","None","","","","crusader_ne_segments.csv"
|
||||||
|
"24","code","0x58A00","0x6D7","None","","","","crusader_ne_segments.csv"
|
||||||
|
"25","code","0x59200","0x1976","None","","","","crusader_ne_segments.csv"
|
||||||
|
"26","code","0x5AE00","0x4DE","None","","","","crusader_ne_segments.csv"
|
||||||
|
"27","code","0x5B400","0x57B","None","","","","crusader_ne_segments.csv"
|
||||||
|
"28","code","0x5BA00","0x788","None","","","","crusader_ne_segments.csv"
|
||||||
|
"29","code","0x5C400","0x190A","None","","","","crusader_ne_segments.csv"
|
||||||
|
"30","code","0x5E000","0x5071","None","","","","crusader_ne_segments.csv"
|
||||||
|
"31","code","0x64000","0x6EE","None","","","","crusader_ne_segments.csv"
|
||||||
|
"32","code","0x64800","0x56A","None","","","","crusader_ne_segments.csv"
|
||||||
|
"33","code","0x65000","0x10D7","None","","","","crusader_ne_segments.csv"
|
||||||
|
"34","code","0x66600","0x253A","None","","","","crusader_ne_segments.csv"
|
||||||
|
"35","code","0x69400","0xF67","None","","","","crusader_ne_segments.csv"
|
||||||
|
"36","code","0x6A600","0x69F","None","","","","crusader_ne_segments.csv"
|
||||||
|
"37","code","0x6AE00","0x636","None","","","","crusader_ne_segments.csv"
|
||||||
|
"38","code","0x6B600","0x2318","None","","","","crusader_ne_segments.csv"
|
||||||
|
"39","code","0x6E200","0x3416","None","","","","crusader_ne_segments.csv"
|
||||||
|
"40","code","0x72200","0x1E7A","None","","","","crusader_ne_segments.csv"
|
||||||
|
"41","code","0x74600","0x28D","None","","","","crusader_ne_segments.csv"
|
||||||
|
"42","code","0x74A00","0xC9C","None","","","","crusader_ne_segments.csv"
|
||||||
|
"43","code","0x75A00","0x336F","Partial","Gameplay targeting/facing repair cluster","entity_set_at_target_update_facing; seg043_func_0090; seg043_func_021c","Two repaired functions remain positional and thunk-heavy","crusader_decompilation_notes.md; plan-mid.md"
|
||||||
|
"44","code","0x79400","0x7F8","None","","","","crusader_ne_segments.csv"
|
||||||
|
"45","code","0x79E00","0x200","None","","","","crusader_ne_segments.csv"
|
||||||
|
"46","code","0x7A200","0x7DC","None","","","","crusader_ne_segments.csv"
|
||||||
|
"47","code","0x7AC00","0x9B4","None","","","","crusader_ne_segments.csv"
|
||||||
|
"48","code","0x7B800","0x63","None","","","","crusader_ne_segments.csv"
|
||||||
|
"49","code","0x7BA00","0x1E3F","None","","","","crusader_ne_segments.csv"
|
||||||
|
"50","code","0x7DE00","0x9C8","None","","","","crusader_ne_segments.csv"
|
||||||
|
"51","code","0x7EA00","0x1D02","None","","","","crusader_ne_segments.csv"
|
||||||
|
"52","code","0x80A00","0x1D65","None","","","","crusader_ne_segments.csv"
|
||||||
|
"53","code","0x82C00","0x10DE","None","","","","crusader_ne_segments.csv"
|
||||||
|
"54","code","0x84000","0x5","None","","","Short stub-sized segment","crusader_ne_segments.csv"
|
||||||
|
"55","code","0x84200","0xA06","None","","","","crusader_ne_segments.csv"
|
||||||
|
"56","code","0x85000","0x706","None","","","","crusader_ne_segments.csv"
|
||||||
|
"57","code","0x85A00","0x79B","None","","","","crusader_ne_segments.csv"
|
||||||
|
"58","code","0x86400","0x44B","None","","","","crusader_ne_segments.csv"
|
||||||
|
"59","code","0x86A00","0x4288","None","","","","crusader_ne_segments.csv"
|
||||||
|
"60","code","0x8B600","0x231","None","","","","crusader_ne_segments.csv"
|
||||||
|
"61","code","0x8BA00","0x1B6C","None","","","","crusader_ne_segments.csv"
|
||||||
|
"62","code","0x8DA00","0x85F","None","","","","crusader_ne_segments.csv"
|
||||||
|
"63","code","0x8E400","0x519","None","","","","crusader_ne_segments.csv"
|
||||||
|
"64","code","0x8EA00","0x3B1","None","","","","crusader_ne_segments.csv"
|
||||||
|
"65","code","0x8F000","0x5BD","None","","","","crusader_ne_segments.csv"
|
||||||
|
"66","code","0x8F800","0x4A9","None","","","","crusader_ne_segments.csv"
|
||||||
|
"67","code","0x8FE00","0x839","None","","","","crusader_ne_segments.csv"
|
||||||
|
"68","code","0x90800","0xB4A","None","","","","crusader_ne_segments.csv"
|
||||||
|
"69","code","0x91800","0x2A0","None","","","","crusader_ne_segments.csv"
|
||||||
|
"70","code","0x91C00","0xF24","None","","","","crusader_ne_segments.csv"
|
||||||
|
"71","code","0x92E00","0x6C2","None","","","","crusader_ne_segments.csv"
|
||||||
|
"72","code","0x93600","0xCA1","None","","","","crusader_ne_segments.csv"
|
||||||
|
"73","code","0x94600","0x9AA","None","","","","crusader_ne_segments.csv"
|
||||||
|
"74","code","0x95200","0x337","None","","","","crusader_ne_segments.csv"
|
||||||
|
"75","code","0x95600","0x1428","None","","","","crusader_ne_segments.csv"
|
||||||
|
"76","code","0x96E00","0x627","None","","","","crusader_ne_segments.csv"
|
||||||
|
"77","code","0x97600","0x616","None","","","","crusader_ne_segments.csv"
|
||||||
|
"78","code","0x97E00","0x634","None","","","","crusader_ne_segments.csv"
|
||||||
|
"79","code","0x98600","0x421","None","","","","crusader_ne_segments.csv"
|
||||||
|
"80","code","0x98C00","0xF27","Foothold","Conditional render/callback dispatch","entity_conditional_render_dispatch","0x4588 callback object still lacks a concrete subsystem name","crusader_decompilation_notes.md"
|
||||||
|
"81","code","0x99E00","0x320","None","","","","crusader_ne_segments.csv"
|
||||||
|
"82","code","0x9A200","0x1C8A","Partial","Allocator sweep and per-head allocation","allocator_head_try_alloc_block; allocator_head_free_block; public size wrapper","0x4588 object and finalize path still unresolved","crusader_decompilation_notes.md; plan-mid.md"
|
||||||
|
"83","code","0x9C400","0x31E","Foothold","Allocator node/header helpers","event_queue_push; packed size/header helpers","Mostly structural helper layer","crusader_decompilation_notes.md"
|
||||||
|
"84","code","0x9C800","0x1478","None","","","","crusader_ne_segments.csv"
|
||||||
|
"85","code","0x9E000","0x404","Foothold","Allocator work token helpers","token reserve/release and commit helpers","Needs clearer subsystem naming","crusader_decompilation_notes.md"
|
||||||
|
"86","code","0x9E600","0x40F6","None","","","","crusader_ne_segments.csv"
|
||||||
|
"87","code","0xA2800","0x50C","None","","","","crusader_ne_segments.csv"
|
||||||
|
"88","code","0xA2E00","0x523","None","","","","crusader_ne_segments.csv"
|
||||||
|
"89","code","0xA3400","0x373","None","","","","crusader_ne_segments.csv"
|
||||||
|
"90","code","0xA3800","0x9C6","None","","","","crusader_ne_segments.csv"
|
||||||
|
"91","code","0xA4400","0x6FA","Partial","Init/context and RNG helpers","seg091_func_00fd; seg091_func_014d; rng_set_seed; rng_next_modulo","00fd and 014d still positional","crusader_decompilation_notes.md; plan-mid.md"
|
||||||
|
"92","code","0xA4E00","0x59E","None","","","","crusader_ne_segments.csv"
|
||||||
|
"93","code","0xA5600","0x4F1","None","","","","crusader_ne_segments.csv"
|
||||||
|
"94","code","0xA5E00","0x606","Partial","Tracked handle table control","tracked_entity_handle_table_init; tracked_entity_handle_table_shutdown; tracked_entity_handle_table_clear_and_dispatch","Downstream dispatch tail still unresolved","crusader_decompilation_notes.md"
|
||||||
|
"95","code","0xA6600","0xC9F","Partial","Cache manager init/reset and 0x4588 runtime callback lifecycle","cache_init; cache_reset_runtime_state; cache_shutdown","Concrete 0x4588 callback object name and nearby no-function callers remain unresolved","crusader_decompilation_notes.md; plan-mid.md"
|
||||||
|
"96","code","0xA7600","0x582","None","","","","crusader_ne_segments.csv"
|
||||||
|
"97","code","0xA7E00","0xDB0","None","","","","crusader_ne_segments.csv"
|
||||||
|
"98","code","0xA8E00","0x68A","None","","","","crusader_ne_segments.csv"
|
||||||
|
"99","code","0xA9600","0x355","None","","","Possible raw 000e animation overlap mapping not yet normalized","crusader_ne_segments.csv"
|
||||||
|
"100","code","0xA9C00","0x697","None","","","Possible raw 000e animation overlap mapping not yet normalized","crusader_ne_segments.csv"
|
||||||
|
"101","code","0xAA400","0x17BC","None","","","Possible raw 000e animation overlap mapping not yet normalized","crusader_ne_segments.csv"
|
||||||
|
"102","code","0xAC000","0x73C","None","","","Possible raw 000e parser mapping not yet normalized","crusader_ne_segments.csv"
|
||||||
|
"103","code","0xACA00","0x16CD","None","","","Possible raw 000e parser mapping not yet normalized","crusader_ne_segments.csv"
|
||||||
|
"104","code","0xAE600","0x41B","None","","","","crusader_ne_segments.csv"
|
||||||
|
"105","code","0xAEC00","0x9F6","None","","","","crusader_ne_segments.csv"
|
||||||
|
"106","code","0xAF800","0x1795","None","","","","crusader_ne_segments.csv"
|
||||||
|
"107","code","0xB1400","0x40C","None","","","","crusader_ne_segments.csv"
|
||||||
|
"108","code","0xB1A00","0x113F","None","","","","crusader_ne_segments.csv"
|
||||||
|
"109","code","0xB2E00","0x1424","None","","","High-value gap around 000b:2e00 still unresolved","crusader_ne_segments.csv; crusader_decomp_progress.md"
|
||||||
|
"110","code","0xB4400","0x4C4","None","","","","crusader_ne_segments.csv"
|
||||||
|
"111","code","0xB4A00","0x489","None","","","","crusader_ne_segments.csv"
|
||||||
|
"112","code","0xB5000","0x1670","None","","","","crusader_ne_segments.csv"
|
||||||
|
"113","code","0xB6A00","0x4A6","None","","","","crusader_ne_segments.csv"
|
||||||
|
"114","code","0xB7000","0xDF1","None","","","","crusader_ne_segments.csv"
|
||||||
|
"115","code","0xB8000","0x978","None","","","","crusader_ne_segments.csv"
|
||||||
|
"116","code","0xB8C00","0xAA3","None","","","","crusader_ne_segments.csv"
|
||||||
|
"117","code","0xB9A00","0x3157","None","","","","crusader_ne_segments.csv"
|
||||||
|
"118","code","0xBD400","0xA0A","None","","","","crusader_ne_segments.csv"
|
||||||
|
"119","code","0xBE200","0x419","None","","","","crusader_ne_segments.csv"
|
||||||
|
"120","code","0xBE800","0x9AE","None","","","","crusader_ne_segments.csv"
|
||||||
|
"121","code","0xBF400","0xACE","None","","","","crusader_ne_segments.csv"
|
||||||
|
"122","code","0xC0200","0x3149","None","","","","crusader_ne_segments.csv"
|
||||||
|
"123","code","0xC3C00","0xE6D","None","","","","crusader_ne_segments.csv"
|
||||||
|
"124","code","0xC4E00","0x3DD","None","","","","crusader_ne_segments.csv"
|
||||||
|
"125","code","0xC5400","0x1A3E","None","","","","crusader_ne_segments.csv"
|
||||||
|
"126","code","0xC7400","0x402A","None","","","","crusader_ne_segments.csv"
|
||||||
|
"127","code","0xCC600","0x8F6","None","","","","crusader_ne_segments.csv"
|
||||||
|
"128","code","0xCD200","0x5D0","None","","","","crusader_ne_segments.csv"
|
||||||
|
"129","code","0xCDA00","0xD77","None","","","","crusader_ne_segments.csv"
|
||||||
|
"130","code","0xCEA00","0x47D","None","","","","crusader_ne_segments.csv"
|
||||||
|
"131","code","0xCF000","0x44D","None","","","","crusader_ne_segments.csv"
|
||||||
|
"132","code","0xCF600","0x3EB8","None","","","","crusader_ne_segments.csv"
|
||||||
|
"133","code","0xD3800","0x215A","None","","","","crusader_ne_segments.csv"
|
||||||
|
"134","code","0xD6000","0xEF0","None","","","","crusader_ne_segments.csv"
|
||||||
|
"135","code","0xD7000","0x3B7","None","","","","crusader_ne_segments.csv"
|
||||||
|
"136","code","0xD7600","0x5BD","None","","","","crusader_ne_segments.csv"
|
||||||
|
"137","code","0xD7E00","0xFBB","None","","","","crusader_ne_segments.csv"
|
||||||
|
"138","code","0xD9200","0x32E4","None","","","","crusader_ne_segments.csv"
|
||||||
|
"139","code","0xDCC00","0x984","None","","","","crusader_ne_segments.csv"
|
||||||
|
"140","code","0xDD800","0xC6F","None","","","","crusader_ne_segments.csv"
|
||||||
|
"141","code","0xDE600","0x2B","None","","","Short stub-sized segment","crusader_ne_segments.csv"
|
||||||
|
"142","code","0xDE800","0x4371","None","","","","crusader_ne_segments.csv"
|
||||||
|
"143","code","0xE3400","0x6F5","None","","","","crusader_ne_segments.csv"
|
||||||
|
"144","data","0xE3C00","0x8DBC","None","","","Large data segment not yet classified","crusader_ne_segments.csv"
|
||||||
|
"145","data","0x0","0x0","None","","","Zero-length data segment placeholder","crusader_ne_segments.csv"
|
||||||
|
308
plan-mid.md
Normal file
308
plan-mid.md
Normal file
|
|
@ -0,0 +1,308 @@
|
||||||
|
# Crusader Decompilation Mid-Project Plan
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
This file is the workspace-facing mid-project tracker for the Crusader decompilation effort.
|
||||||
|
It is intended to answer four questions clearly:
|
||||||
|
|
||||||
|
1. How far along is the project?
|
||||||
|
2. What is already solid?
|
||||||
|
3. What still blocks broader decompilation?
|
||||||
|
4. What should be implemented next?
|
||||||
|
|
||||||
|
The estimates below are intentionally conservative. They measure verified behavioral understanding, not just renamed symbols.
|
||||||
|
|
||||||
|
## Progress Snapshot
|
||||||
|
|
||||||
|
## Working Progress
|
||||||
|
|
||||||
|
### Last Confirmed State
|
||||||
|
|
||||||
|
- Priority 0 has started: `crusader_segment_coverage_ledger.csv` exists and contains a first-pass 145-row ledger.
|
||||||
|
- The currently seeded ledger rows are conservative and strongest around seg001, seg004, seg021, seg043, seg080, seg082/083/085, seg091, seg094, and seg095.
|
||||||
|
- Priority 1 has started on the cache/backend cluster: the seg082 allocator mechanics are now materially recovered (`allocator_head_try_alloc_block`, `allocator_head_free_block`, `allocator_free_block_by_ptr`), and the next unresolved clue is that `0x4588` behaves like a runtime-installed callback/dispatch object used by `entity_conditional_render_dispatch` plus a one-shot teardown path.
|
||||||
|
- The `0x4588` blocker is tighter than before: no-function windows now confirm a direct install at `000a:493e`, repeated clear paths in seg004, and additional vtable `+0x0c` callbacks from unresolved `000a:` and `000d:` callers, but the concrete subsystem name is still unresolved.
|
||||||
|
|
||||||
|
### Current Focus
|
||||||
|
|
||||||
|
1. Finish Priority 0 refinement by promoting more exact segment rows where notes already support a verified foothold.
|
||||||
|
2. Continue the Priority 1 pass by tracing the remaining caller-side `0x4588` / `0009:b1c3` object-role evidence rather than the already-recovered allocator mechanics.
|
||||||
|
|
||||||
|
### Next Resume Point
|
||||||
|
|
||||||
|
1. Update the ledger for any additional exact segment anchors found in the reset/cache or render-path notes.
|
||||||
|
2. Recover or classify the still-unbounded callback callers around `000a:b9e5` / `000a:ba66` and `000d:9d5e` / `000d:a3b7`; they now look like the best remaining cheap wins on the `0x4588` path.
|
||||||
|
3. Revisit the nearby install/lifecycle gap around `000a:493e` / `000a:4a56` only if those caller windows need a stronger object-owner model.
|
||||||
|
4. Continue `ASYLUM.24` only after the `0x4588` path has no further cheap wins.
|
||||||
|
|
||||||
|
### Headline Estimate
|
||||||
|
|
||||||
|
- Overall useful decompilation progress: about 25%
|
||||||
|
- Reasonable uncertainty band: about 20% to 30%
|
||||||
|
|
||||||
|
This is the best single-number estimate for the full game right now.
|
||||||
|
|
||||||
|
### Supporting Metrics
|
||||||
|
|
||||||
|
| Metric | Estimate | Meaning |
|
||||||
|
|---|---:|---|
|
||||||
|
| Top 100 far-call target coverage | about 80% | Roughly 80 of the top 100 most-called far-call targets have been named or materially classified |
|
||||||
|
| Whole-program behavioral coverage | about 25% | Verified subsystem and function understanding across the executable |
|
||||||
|
| Segment spread with meaningful analysis | about 10% to 15% | Segments with more than a trivial foothold or isolated note |
|
||||||
|
| Tooling maturity for continued work | about 75% | Core repair, lookup, and fallback automation needed for continued progress |
|
||||||
|
|
||||||
|
### Why These Numbers Differ
|
||||||
|
|
||||||
|
- The hot-target metric is much higher because the project has already focused on the most shared and most-called helpers.
|
||||||
|
- The whole-program metric is lower because most of the 145 NE segments still have not had systematic coverage passes.
|
||||||
|
- The segment-spread metric is lower still because only a subset of segments have coherent subsystem-level treatment.
|
||||||
|
|
||||||
|
## What Is Already In Place
|
||||||
|
|
||||||
|
### Workflow and Tooling
|
||||||
|
|
||||||
|
- Raw full-EXE Ghidra target is established and in active use.
|
||||||
|
- Verified raw-import mapping exists for seg001 and seg021.
|
||||||
|
- NE relocation parsing has been implemented.
|
||||||
|
- Internal literal far-call fixups have been applied to the raw import.
|
||||||
|
- PyGhidra fallback tooling exists for create/delete function work and batch scripted edits.
|
||||||
|
- Conservative boundary-repair workflow already exists and has been used successfully.
|
||||||
|
- Notes are detailed enough to support a formal executable-wide tracker.
|
||||||
|
|
||||||
|
### Objective Milestones Already Reached
|
||||||
|
|
||||||
|
- 145 NE segments identified from the internal NE header.
|
||||||
|
- 8851 internal literal CALLF sites patched to real targets in the raw import.
|
||||||
|
- 2841 non-CALLF far-pointer relocations identified and deferred.
|
||||||
|
- 119 import callsites annotated.
|
||||||
|
- Top 100 far-call target list processed through five tiers, with about 80 named or materially classified.
|
||||||
|
|
||||||
|
## Strongly Advanced Areas
|
||||||
|
|
||||||
|
### Core Gameplay and Entity Work
|
||||||
|
|
||||||
|
- seg001 gameplay, cursor, entity lifecycle, projectile, combat, and AI footholds are strong.
|
||||||
|
- A verified seg001 raw-port path is working and already used for multiple projectile helpers.
|
||||||
|
- Entity table, class-table, and several global gameplay fields are partially mapped.
|
||||||
|
|
||||||
|
### Timer, Event, and State Systems
|
||||||
|
|
||||||
|
- seg021 timer and event-dispatch work has meaningful coverage.
|
||||||
|
- 000c state-dispatch, cursor-nav, UI-listbox, palette-fade, and mini-VM clusters have footholds.
|
||||||
|
|
||||||
|
### Rendering and Camera
|
||||||
|
|
||||||
|
- 0007 rendering, draw-list, tile-visibility, and camera work has strong structural coverage.
|
||||||
|
- `world_to_screen_coords` and adjacent geometric helpers are understood well enough to support further caller analysis.
|
||||||
|
|
||||||
|
### Dispatch and Pair-Sync Helpers
|
||||||
|
|
||||||
|
- 0008 dispatch-entry helper families have multiple verified rename batches.
|
||||||
|
- Pair-sync and target-state helper clusters are no longer isolated unknowns.
|
||||||
|
|
||||||
|
### Cache, Tracked Handles, and Bucket Logic
|
||||||
|
|
||||||
|
- 000a cache manager layer is structurally mapped.
|
||||||
|
- 000a tracked-handle table is structurally mapped.
|
||||||
|
- 000d tracked bucket / proximity / visibility bucket logic has several meaningful behavioral names.
|
||||||
|
- The client/cache distinction is much clearer than before.
|
||||||
|
|
||||||
|
### Parser and Animation Framework
|
||||||
|
|
||||||
|
- 000e parser cluster has a stable set of verified names.
|
||||||
|
- 000e animation framework has a real foothold: chunk lookup, audio load, tick, frame advance, and constructor variants are partly mapped.
|
||||||
|
|
||||||
|
### Local Repair Successes
|
||||||
|
|
||||||
|
- seg043 overlap repair succeeded and recovered multiple valid function objects.
|
||||||
|
- seg091 boundary recovery succeeded and exposed RNG helpers plus local init/context helpers.
|
||||||
|
- Recent seg004 reset-path recovery and cache-reset follow-up added a new high-value analysis cluster.
|
||||||
|
|
||||||
|
## What Still Blocks Broader Coverage
|
||||||
|
|
||||||
|
### High-Value Classification Gaps
|
||||||
|
|
||||||
|
- The object rooted at `0x4588` is still not classified well enough to safely rename `0009:b1c3`.
|
||||||
|
- `ASYLUM.24` is only known as an import site, not yet a confidently identified routine.
|
||||||
|
- Some structural names in the cache/backend/finalize cluster are waiting on object-role confirmation.
|
||||||
|
|
||||||
|
### Boundary and Decompiler Gaps
|
||||||
|
|
||||||
|
- Some high-caller targets still require conservative boundary repair or follow-up validation.
|
||||||
|
- Certain functions still decompile poorly because of overlaps, thunk-heavy paths, or unresolved downstream targets.
|
||||||
|
- `000e:ffb0` remains a notable animation/video-side blocker because of overlapping instructions.
|
||||||
|
|
||||||
|
### Coverage Management Gap
|
||||||
|
|
||||||
|
- A first-pass normalized segment-by-segment coverage ledger now exists for all 145 NE segments.
|
||||||
|
- The remaining gap is refinement rather than absence: most segments still need manual promotion from `None` to `Foothold` / `Partial` / `Deep` as coverage expands.
|
||||||
|
|
||||||
|
### Deferred Data Work
|
||||||
|
|
||||||
|
- Non-CALLF far-pointer relocations still exist and will matter for deeper object/table recovery.
|
||||||
|
- They are no longer the main blocker, but they remain a real second-pass problem.
|
||||||
|
|
||||||
|
## Current Best Assessment Of Remaining Work
|
||||||
|
|
||||||
|
The project has solved most of the architectural uncertainty needed to keep going efficiently.
|
||||||
|
The remaining effort is mainly a scaling problem:
|
||||||
|
|
||||||
|
- expand coverage across many more segments,
|
||||||
|
- remove the last high-value boundary blockers,
|
||||||
|
- convert structural names into subsystem names when evidence is strong enough,
|
||||||
|
- and normalize progress tracking so the whole program can be managed deliberately.
|
||||||
|
|
||||||
|
In practical terms, this looks like a true mid-project state rather than an early exploratory state or a late polish state.
|
||||||
|
|
||||||
|
## Implementation Priorities
|
||||||
|
|
||||||
|
### Priority 0: Coverage Ledger
|
||||||
|
|
||||||
|
First pass completed: an executable-wide coverage ledger now exists for all 145 NE segments in `crusader_segment_coverage_ledger.csv`.
|
||||||
|
|
||||||
|
Next work under Priority 0:
|
||||||
|
|
||||||
|
1. Promote additional segments from `None` where notes already support a verified foothold.
|
||||||
|
2. Normalize raw-address subsystem islands (notably the `000e:` parser/animation cluster) back onto exact NE segment rows.
|
||||||
|
3. Keep the ledger updated together with `crusader_decompilation_notes.md` after each verified batch.
|
||||||
|
|
||||||
|
Minimum columns:
|
||||||
|
|
||||||
|
| Column | Meaning |
|
||||||
|
|---|---|
|
||||||
|
| Segment | NE segment number |
|
||||||
|
| Type | Code or data |
|
||||||
|
| File offset | From the NE segment table |
|
||||||
|
| Length | Segment length |
|
||||||
|
| Coverage status | None, foothold, partial, deep |
|
||||||
|
| Known subsystem | Best current classification |
|
||||||
|
| Key named functions | Short summary only |
|
||||||
|
| Blockers | Boundary, import, thunk, overlap, unknown object, etc. |
|
||||||
|
| Notes source | Notes section or evidence anchor |
|
||||||
|
|
||||||
|
This is the most important missing artifact because it will make the percentage estimates maintainable.
|
||||||
|
|
||||||
|
### Priority 1: Finish The New Cache/Backend Cluster
|
||||||
|
|
||||||
|
Work the newest verified reset-path cluster to closure:
|
||||||
|
|
||||||
|
1. Trace more callers of `0009:b06b`.
|
||||||
|
2. Trace more callers of `FUN_0009_a961`.
|
||||||
|
3. Classify the object rooted at `0x4588`.
|
||||||
|
4. Revisit `0009:b1c3` once the object role is clearer.
|
||||||
|
|
||||||
|
This is currently the best next analysis target because it closes a live cluster that already has fresh verified work around it.
|
||||||
|
|
||||||
|
### Priority 2: Resolve `ASYLUM.24`
|
||||||
|
|
||||||
|
Identify what imported routine `ASYLUM.24` actually is.
|
||||||
|
|
||||||
|
Goal:
|
||||||
|
|
||||||
|
- tighten the description of `runtime_cache_reset_sequence`,
|
||||||
|
- determine whether the import belongs to cache/resource/backend/media initialization,
|
||||||
|
- and improve naming confidence around the reset path.
|
||||||
|
|
||||||
|
### Priority 3: Continue Small-Batch Boundary Repair
|
||||||
|
|
||||||
|
Use the existing conservative repair approach for remaining high-value blockers.
|
||||||
|
|
||||||
|
Good candidates include:
|
||||||
|
|
||||||
|
- unresolved high-caller function objects,
|
||||||
|
- ranges that still steal bytes from adjacent real bodies,
|
||||||
|
- and overlaps that block decompilation of already-active subsystems.
|
||||||
|
|
||||||
|
### Priority 4: Finish Partial Subsystem Islands Before Expanding Broadly
|
||||||
|
|
||||||
|
Recommended order:
|
||||||
|
|
||||||
|
1. seg043 plus connected seg004 reset and dispatch paths
|
||||||
|
2. 000e animation/video overlap at `000e:ffb0`
|
||||||
|
3. 000c UI-listbox, mini-VM, and cursor-nav families
|
||||||
|
4. Remaining structural 0007 and 0008 helper cohorts
|
||||||
|
|
||||||
|
The goal is to reduce the number of half-understood islands before starting broad segment sweeps.
|
||||||
|
|
||||||
|
### Priority 5: Broaden Coverage Across The Remaining Executable
|
||||||
|
|
||||||
|
Once the ledger exists and the current hot cluster is closed, broaden analysis segment by segment.
|
||||||
|
|
||||||
|
Preferred method:
|
||||||
|
|
||||||
|
1. Group segments by adjacency and call relationships.
|
||||||
|
2. Identify entry points and hot callees first.
|
||||||
|
3. Classify globals and tables next.
|
||||||
|
4. Promote helper names only when supported by strong evidence.
|
||||||
|
|
||||||
|
## Recommended Tracking Model
|
||||||
|
|
||||||
|
Use these status values for segment coverage:
|
||||||
|
|
||||||
|
| Status | Meaning |
|
||||||
|
|---|---|
|
||||||
|
| None | No meaningful verified analysis yet |
|
||||||
|
| Foothold | One or two verified entry points or helper names, but no subsystem picture |
|
||||||
|
| Partial | Several verified names plus some globals/tables or object fields |
|
||||||
|
| Deep | Coherent subsystem-level understanding with multiple verified related functions |
|
||||||
|
|
||||||
|
Use these status values for subsystem maturity:
|
||||||
|
|
||||||
|
| Status | Meaning |
|
||||||
|
|---|---|
|
||||||
|
| Unknown | Not enough evidence to classify |
|
||||||
|
| Structural | Behavior is partly mapped but still generic |
|
||||||
|
| Behavioral | Confident subsystem role is known |
|
||||||
|
| Stable | Multiple connected functions and data objects support the classification |
|
||||||
|
|
||||||
|
## Suggested Immediate Work Queue
|
||||||
|
|
||||||
|
### Queue A: Highest Leverage
|
||||||
|
|
||||||
|
1. Expand the first-pass segment coverage ledger beyond the currently seeded segments.
|
||||||
|
2. Trace `0009:b06b`, `FUN_0009_a961`, and `0009:b1c3`.
|
||||||
|
3. Identify `ASYLUM.24`.
|
||||||
|
|
||||||
|
### Queue B: Repair And Stabilize
|
||||||
|
|
||||||
|
1. Review remaining high-caller gap functions.
|
||||||
|
2. Repair any still-blocking overlaps in small batches.
|
||||||
|
3. Re-decompile repaired ranges and keep only evidence-backed names.
|
||||||
|
|
||||||
|
### Queue C: Broaden Carefully
|
||||||
|
|
||||||
|
1. Expand into adjacent segments connected to already-understood clusters.
|
||||||
|
2. Avoid speculative naming.
|
||||||
|
3. Update the notes and the coverage ledger together after each verified batch.
|
||||||
|
|
||||||
|
## Concrete Progress Interpretation
|
||||||
|
|
||||||
|
If a single number is needed, use 25%.
|
||||||
|
|
||||||
|
If a more honest dashboard is acceptable, use all three:
|
||||||
|
|
||||||
|
- 80% of top-100 hot targets processed
|
||||||
|
- 25% overall behavioral decompilation progress
|
||||||
|
- 10% to 15% segment spread with meaningful analysis
|
||||||
|
|
||||||
|
That combination best reflects the actual state of the project.
|
||||||
|
|
||||||
|
## Source Anchors
|
||||||
|
|
||||||
|
Primary sources for this file:
|
||||||
|
|
||||||
|
- `crusader_segment_coverage_ledger.csv`
|
||||||
|
- `crusader_decompilation_notes.md`
|
||||||
|
- `crusader_ne_segments.csv`
|
||||||
|
- `tier4_output.txt`
|
||||||
|
- `tier5_output.txt`
|
||||||
|
- repo memory progress summary
|
||||||
|
|
||||||
|
## Next Update Rule
|
||||||
|
|
||||||
|
Update this file when one of the following happens:
|
||||||
|
|
||||||
|
- the overall estimate changes materially,
|
||||||
|
- a new subsystem reaches behavioral or stable status,
|
||||||
|
- a major blocker such as `0x4588`, `0009:b1c3`, or `ASYLUM.24` is resolved,
|
||||||
|
- or the segment coverage ledger is created and becomes the new primary progress source.
|
||||||
76
pyghidra_plans/dump_instruction_windows.py
Normal file
76
pyghidra_plans/dump_instruction_windows.py
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
TARGETS = [
|
||||||
|
"0004:5b8c",
|
||||||
|
"0004:5bbf",
|
||||||
|
"0004:5ea7",
|
||||||
|
"0004:6430",
|
||||||
|
"0009:92ad",
|
||||||
|
"0009:b1cd",
|
||||||
|
"000a:493e",
|
||||||
|
"000a:4a68",
|
||||||
|
"000a:b9e5",
|
||||||
|
"000a:ba66",
|
||||||
|
"000d:9d5e",
|
||||||
|
"000d:a3b7",
|
||||||
|
]
|
||||||
|
|
||||||
|
BEFORE_COUNT = 6
|
||||||
|
AFTER_COUNT = 8
|
||||||
|
|
||||||
|
|
||||||
|
listing = program.getListing()
|
||||||
|
address_factory = program.getAddressFactory()
|
||||||
|
|
||||||
|
|
||||||
|
def as_address(text):
|
||||||
|
segment_text, offset_text = text.split(":")
|
||||||
|
return address_factory.getAddress(f"{segment_text}:{offset_text}")
|
||||||
|
|
||||||
|
|
||||||
|
def collect_window(center):
|
||||||
|
instructions = []
|
||||||
|
|
||||||
|
current = listing.getInstructionContaining(center)
|
||||||
|
if current is None:
|
||||||
|
current = listing.getInstructionAt(center)
|
||||||
|
if current is None:
|
||||||
|
current = listing.getInstructionBefore(center)
|
||||||
|
if current is not None and current.getNext() is not None and current.getNext().getAddress() <= center:
|
||||||
|
current = current.getNext()
|
||||||
|
if current is None:
|
||||||
|
return instructions
|
||||||
|
|
||||||
|
cursor = current
|
||||||
|
for _ in range(BEFORE_COUNT):
|
||||||
|
cursor = cursor.getPrevious()
|
||||||
|
if cursor is None:
|
||||||
|
break
|
||||||
|
if cursor is None:
|
||||||
|
cursor = current
|
||||||
|
while cursor.getPrevious() is not None and len(instructions) < BEFORE_COUNT:
|
||||||
|
cursor = cursor.getPrevious()
|
||||||
|
|
||||||
|
while cursor is not None:
|
||||||
|
instructions.append(cursor)
|
||||||
|
if cursor == current:
|
||||||
|
break
|
||||||
|
cursor = cursor.getNext()
|
||||||
|
|
||||||
|
cursor = current.getNext()
|
||||||
|
while cursor is not None and len(instructions) < BEFORE_COUNT + AFTER_COUNT + 1:
|
||||||
|
instructions.append(cursor)
|
||||||
|
cursor = cursor.getNext()
|
||||||
|
|
||||||
|
return instructions
|
||||||
|
|
||||||
|
|
||||||
|
for target_text in TARGETS:
|
||||||
|
target = as_address(target_text)
|
||||||
|
print(f"=== {target} ===")
|
||||||
|
window = collect_window(target)
|
||||||
|
if not window:
|
||||||
|
print("<no instruction window>\n")
|
||||||
|
continue
|
||||||
|
for insn in window:
|
||||||
|
marker = "=>" if insn.getAddress() == target else " "
|
||||||
|
print(f"{marker} {insn.getAddress()} {insn}")
|
||||||
|
print("")
|
||||||
34
pyghidra_plans/inspect_4588_refs.py
Normal file
34
pyghidra_plans/inspect_4588_refs.py
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
from ghidra.program.model.symbol import RefType
|
||||||
|
|
||||||
|
|
||||||
|
TARGETS = {0x4588, 0x458A}
|
||||||
|
|
||||||
|
|
||||||
|
def format_addr(addr):
|
||||||
|
return addr.toString()
|
||||||
|
|
||||||
|
|
||||||
|
listing = program.getListing()
|
||||||
|
function_manager = program.getFunctionManager()
|
||||||
|
reference_manager = program.getReferenceManager()
|
||||||
|
|
||||||
|
seen = set()
|
||||||
|
|
||||||
|
for target in TARGETS:
|
||||||
|
addr = program.getAddressFactory().getDefaultAddressSpace().getAddress(target)
|
||||||
|
|
||||||
|
print(f"TARGET {format_addr(addr)}")
|
||||||
|
refs = reference_manager.getReferencesTo(addr)
|
||||||
|
iterator = refs.iterator() if hasattr(refs, "iterator") else refs
|
||||||
|
for ref in iterator:
|
||||||
|
from_addr = ref.getFromAddress()
|
||||||
|
function = function_manager.getFunctionContaining(from_addr)
|
||||||
|
key = (str(from_addr), str(addr))
|
||||||
|
if key in seen:
|
||||||
|
continue
|
||||||
|
seen.add(key)
|
||||||
|
instruction = listing.getInstructionContaining(from_addr)
|
||||||
|
code_unit = listing.getCodeUnitContaining(from_addr)
|
||||||
|
text = instruction.toString() if instruction is not None else code_unit.toString()
|
||||||
|
function_name = function.getName() if function is not None else "<no function>"
|
||||||
|
print(f" FROM {format_addr(from_addr)} {function_name} {ref.getReferenceType()} {text}")
|
||||||
17
pyghidra_plans/scan_4588_instruction_uses.py
Normal file
17
pyghidra_plans/scan_4588_instruction_uses.py
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
TARGET_HEX = ("4588", "458a")
|
||||||
|
|
||||||
|
listing = program.getListing()
|
||||||
|
function_manager = program.getFunctionManager()
|
||||||
|
|
||||||
|
instruction = listing.getInstructions(True)
|
||||||
|
|
||||||
|
while instruction.hasNext():
|
||||||
|
insn = instruction.next()
|
||||||
|
text = insn.toString().lower()
|
||||||
|
if not any(token in text for token in TARGET_HEX):
|
||||||
|
continue
|
||||||
|
|
||||||
|
address = insn.getAddress()
|
||||||
|
function = function_manager.getFunctionContaining(address)
|
||||||
|
function_name = function.getName() if function is not None else "<no function>"
|
||||||
|
print(f"{address} {function_name} {insn}")
|
||||||
Loading…
Add table
Add a link
Reference in a new issue