skills — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited skills (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ 📓 MANDATORY: JOURNAL ENTRY — EVERY CODING SESSION, NO EXCEPTIONS 📓 ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
>
Before ending ANY session where code was written, modified, or deleted, you MUST append a journal entry to `Journal.md`. This is non-negotiable. If the user says "done", "thanks", "that's all", or the conversation ends after code changes — write the journal entry FIRST.
ALWAYS after EVERY coding session, APPEND a summary entry to Journal.md located in the parent folder of the current repository.
⚠️ APPEND ORDER: DATE ASCENDING (oldest first, newest last). New entries are ALWAYS added to the END of the file. Never insert entries above existing ones. The file reads chronologically from top to bottom.
Resolution rule: Identify the repo root (the folder containing .git), then go up one level. That parent folder holds Journal.md.
Example:
| Working repo | Journal location |
|---|---|
C:\Users\chris\Documents\Repos\MedRecPro\ | C:\Users\chris\Documents\Repos\Journal.md |
C:\Users\chris\Documents\Repos\SomeOtherProject\ | C:\Users\chris\Documents\Repos\Journal.md |
D:\Projects\ClientWork\AppX\ | D:\Projects\ClientWork\Journal.md |
If Journal.md does not exist at that location, create it.
Each entry MUST include:
2026-02-24 3:45 PM EST)Timestamp rule: You do NOT have access to the system clock. NEVER fabricate or guess a time — not even an approximate one. Instead, ASK the user for the current time before writing the journal entry. If the user is unavailable or does not respond, fall back to git log -1 --format="%ai" on the most recent commit as a last resort. Under no circumstances should you invent a timestamp.
Format:
---
### 2026-02-24 3:45 PM EST — Title of Work
Description of the work performed, key decisions made, and outcomes.
---⚠️ CRITICAL: Always leave a blank line before every --- separator. Without the blank line, Markdown treats the preceding text as a setext H2 heading (renders as oversized bold text instead of normal paragraph + horizontal rule).This file serves as persistent memory across sessions. Always append to the END — never overwrite, never insert above existing entries. Entries must remain in chronological (date ascending) order.
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ 🚨 NEW ENTRIES GO AT THE VERY BOTTOM OF Journal.md — NOWHERE ELSE 🚨 ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
>
DO NOT insert a new entry between existing entries. The ONLY correct location for a new journal entry is after the last `---` separator at the very end of the file. If the file has 300 lines, your new entry starts at line 301. Read the last few lines first to confirm you are appending, not inserting.
⚠️ FAILURE TO JOURNAL = INCOMPLETE SESSION. Treat this with the same priority as building the code — the session is not done until the journal entry is written.
Before beginning any implementation, work through these rationalization steps:
What is the core question or task?
What are the specific requirements, key components, or constraints?
What are the logical steps or processes needed?
How can you combine the information into a coherent solution?
What is the most helpful/accurate solution?
#### 1. Comment Header + Summary Block
All methods, classes, and properties must have:
/**************************************************************/
/// <summary>
/// Brief description of what this method/class/property does.
/// </summary>
/// <remarks>
/// Additional context, usage notes, performance characteristics.
/// </remarks>
/// <example>
/// <code>
/// var result = DoSomething(param1, param2);
/// </code>
/// </example>
/// <param name="param1">Description of first parameter.</param>
/// <returns>Description of what is returned.</returns>
/// <exception cref="ExceptionType">When this exception is thrown.</exception>
/// <seealso cref="RelatedClass"/>#### 2. SeeAlso References
<seealso cref="Label"/> for methods/properties related to the Label entity<seealso> for: related classes, related methods, interface implementations, parent/child relationships, dependencies#### 3. Region Blocks
#region implementation (all lowercase) within methods, classes, and properties#region blocks (public method groupings, logical groupings, commented-out code blocks)#### 4. Inline Comments
#### 5. Property Documentation
/// <summary> for properties when usage can be inferred<remarks> for behavioral notes, performance notes, or side effectsDocumentation should answer: What does this do? Why does it exist? How should it be used? When should it be used? What are the constraints?
When modifying existing files:
#region blocks#region/// <summary> documentation/// <summary> documentation/// <summary> where usage can be inferred/**************************************************************/ precedes all summaries<seealso> references added for related classes/methods<remarks> explain important details, performance notes, side effects<example> demonstrates typical usage where helpful#region implementation blocks organize code within methods/classes#region blocks retainedRAISERROR('...', 0, 1) WITH NOWAIT instead of PRINT for real-time progress in stored proceduresentityBuilder.ToView(viewName) works for both views AND tables — it just means "keyless, read-only, no migrations"[Table("vw_X")] to [Table("tmp_X")] on the entity class is sufficient to swap from view to table.HasNoKey() remains correct for tables without PKs (just indexes)Transform existing API endpoints and methods into fully-documented MCP (Model Context Protocol) tool endpoints using the ModelContextProtocol.AspNetCore package.
ModelContextProtocol.AspNetCore NuGet package installedusing ModelContextProtocol.Server;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace {Namespace}.McpTools;
/**************************************************************/
/// <summary>
/// {Tool class summary describing the domain/capability}
/// </summary>
/// <remarks>
/// ## Tool Workflow
/// {ASCII diagram showing tool relationships}
/// </remarks>
[McpServerToolType]
public class {Domain}Tools { }Each MCP tool method MUST include:
/**************************************************************/
/// <summary>
/// {One-line action summary starting with a verb}
/// </summary>
[McpServerTool(Name = "{snake_case_tool_name}")]
[Description("""
{EMOJI} {CATEGORY}: {One-line summary}
📋 WORKFLOW: {Position in tool chain}
├── {Prerequisite or input source}
├── Returns: {Key fields returned}
└── Next: {Downstream tool usage}
🎯 {USE CASE|SEARCH TIPS|EXAMPLE}: {Contextual guidance}
""")]| Emoji | Category | Use For |
|---|---|---|
| 🔍 | SEARCH | Tools that find/query data |
| 📄 | RETRIEVE | Tools that get complete records |
| 📋 | LIST | Tools that enumerate collections |
| ✏️ | CREATE | Tools that create new records |
| 🔄 | UPDATE | Tools that modify existing records |
| 🗑️ | DELETE | Tools that remove records |
| 📊 | ANALYZE | Tools that compute/aggregate |
| 🔗 | LINK | Tools that relate entities |
| Section | Use When |
|---|---|
🎯 SEARCH TIPS: | For search tools — explain query strategies |
🎯 USE CASE: | Explain when to use this tool |
🎯 EXAMPLE: | Provide concrete usage example |
🎯 NOTE: | Important caveats or behaviors |
Every parameter MUST have a [Description] attribute:
// ID/GUID parameters (downstream references)
[Description("{EntityName} identifier from '{source_tool_name}' results. Format: '{format_example}'")]
[Required]
Guid {entityId}
// Search/filter parameters
[Description("{What it filters}. Supports {matching_type} matching. Example: '{example_value}'")]
string? {searchParam} = null
// Pagination parameters
[Description("Page number, 1-based. Default: {default}")]
[Range(1, int.MaxValue)]
int pageNumber = {default}
[Description("Results per page ({min}-{max}). Default: {default}")]
[Range({min}, {max})]
int pageSize = {default}
// Enum/option parameters
[Description("{What it controls}. Options: {Option1}={meaning}, {Option2}={meaning}. Default: {default}")]
{EnumType} {param} = {EnumType}.{Default}
// Boolean flags
[Description("{What it enables/disables when true}. Default: {default}")]
bool {flagName} = {default}
// Date/time parameters
[Description("{What date this represents}. Format: ISO 8601 (yyyy-MM-dd). Example: '2024-01-15'")]
DateTime? {dateName} = null/**************************************************************/
/// <summary>
/// Result from {tool_name} tool.
/// </summary>
/// <remarks>
/// ## Field Usage
/// - {FieldName}: {Description} → Use with '{downstream_tool}'
/// </remarks>
public class {ToolName}ResultDto
{
[Description("{Brief description} - {downstream usage hint}")]
public {type} {FieldName} { get; set; }
}Entry Point Tool (no prerequisites):
📋 WORKFLOW: Start here when {use case}.
├── Returns: {Field1}, {Field2}, {Field3}
├── Next: Use {Field1} → '{tool_a}' for {purpose}
└── Next: Use {Field2} → '{tool_b}' for {purpose}Middle Chain Tool (has prerequisites and next steps):
📋 WORKFLOW: {Brief description of purpose}
├── PREREQUISITE: Get {InputField} from '{source_tool}'
├── Returns: {Field1}, {Field2}
└── Next: Use {Field1} → '{downstream_tool}' for {purpose}Terminal Tool (has prerequisites, no downstream):
📋 PREREQUISITE: Get {InputField} from '{source_tool}'.
📦 RETURNS: {Detailed description of complete data returned}
• {Section/field 1}
• {Section/field 2}Include in class-level <remarks>:
/// {entry_tool_1} ──┬──► {KeyField} ──► {middle_tool} ──► {KeyField} ──► {terminal_tool}
/// │
/// {entry_tool_2} ──┘| Pattern | Examples |
|---|---|
search_{entities} | search_products, search_labels |
get_{entity} | get_product, get_label_document |
list_{entities} | list_orders, list_products_by_category |
create_{entity} | create_order, create_comment |
update_{entity} | update_profile, update_order_status |
delete_{entity} | delete_comment, delete_draft |
{verb}_{entity} | validate_address, calculate_shipping |
| Type | Pattern | Examples |
|---|---|---|
| ID/GUID | {entity}Id, {entity}Guid | productId, documentGuid |
| Search | {field}Search, {field}Query | nameSearch, ingredientQuery |
| Filter | {field}Filter, {field} | statusFilter, category |
| Pagination | pageNumber, pageSize | Always use these exact names |
| Flags | include{Feature}, is{State} | includeDetails, isActive |
| Scenario | Attribute | Example |
|---|---|---|
| Required parameter | [Required] | [Required] Guid id |
| Numeric range | [Range(min, max)] | [Range(1, 100)] int pageSize |
| String length | [StringLength(max)] | [StringLength(500)] string query |
| Minimum length | [MinLength(min)] | [MinLength(3)] string search |
| Pattern/format | [RegularExpression] | [RegularExpression(@"^\d{4}$")] |
[McpServerTool] has explicit Name property[Description] starts with category emoji and one-line summary[Description] with concrete examples[Required] attribute[Range] validation[Description] indicating downstream usage❌ Vague: [Description("Gets data")] ✅ Specific: [Description("🔍 SEARCH: Find products by brand name, generic name, or UNII code")]
❌ Missing workflow: [Description("Returns a document by ID")] — Where does the ID come from? ✅ Clear workflow: Include 📋 PREREQUISITE: Get documentGuid from 'search_documents'
❌ No examples: [Description("The UNII code")] ✅ With examples: [Description("UNII code for exact match. Example: 'R16CO5Y76E' (aspirin)")]
#### 1. skills.md — Capability Contracts (PRIMARY)
#### 2. selectors.md — Skill Selection & Routing Rules
#### 3. /interfaces/* — Implementation Mappings
Each skill MUST contain:
Skills MUST NOT include:
Move content OUT of skills if it contains: multi-step workflows, fallback logic, performance optimizations, error handling, "if X fails then Y", data-sourcing rules, enforcement checklists.
Maximum nesting depth: 2
skills.md → skills/label.md → skills/label/indication-discovery.mdselectors.md)Contains: keyword lists, priority rules, decision trees, fallback loading, admin role checks. Selectors may reference skills by name and interface documents by link. Selectors MUST NOT define capabilities or describe system behavior beyond routing.
/interfaces/api/*.md)Contains: API paths, HTTP verbs, required parameters, output mappings, section codes, token size notes, step-by-step execution plans. Each interface doc maps one skill → one or more endpoints.
You MUST: preserve every real capability, preserve all critical constraints (relocate properly), merge overlapping/redundant skills. You MAY: shorten wording, normalize terminology, remove duplication, replace long rules with references.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.