{"owner":"microsoft","repo":"ApplicationInspector","hasSkills":true,"totalSkillsCount":2,"totalTokensCount":4335,"categories":["copilot-instructions","anthropic-skill"],"hasMcp":false,"mcpConfig":null,"found":[".github/copilot-instructions.md","AppInspector/rules/samples/README.md"],"skills":{".github/copilot-instructions.md":"# GitHub Copilot Instructions for ApplicationInspector\n\n## Project Overview\n\nMicrosoft Application Inspector is a source code characterization tool that identifies coding features based on well-known library/API calls using regex patterns and rules. It supports multiple programming languages and generates reports in HTML, JSON, SARIF, and text formats.\n\n## Tech Stack\n\n- **Language**: C# (supports netstandard2.1; .NET 8.0+ for executables; aims to support all currently supported .NET versions)\n- **Build System**: dotnet CLI\n- **Test Framework**: xUnit\n- **Solution Structure**: Multi-project .NET solution with 7 projects\n- **Rule Format**: JSON files following rule-schema-v1.json schema definition in repository root\n\n## Project Structure\n\n- `AppInspector.CLI/` - Command-line interface application\n- `AppInspector/` - Core commands library (AppInspector.Commands.csproj)\n- `AppInspector.RulesEngine/` - Rule processing and pattern matching engine\n- `AppInspector.Common/` - Common utilities and types\n- `AppInspector.Logging/` - Logging infrastructure\n- `AppInspector.Tests/` - Test suite using xUnit\n- `AppInspector.Benchmarks/` - Performance benchmarks\n- `AppInspector/rules/default/` - Built-in detection rules organized by category\n\n## Build and Test Commands\n\n### Important Build Notes\n\n**Version Tracking**: This project uses Nerdbank.GitVersioning (nbgv) for version tracking, which requires a **deep clone** of the repository. Shallow clones will not work correctly with version generation.\n\n**NuGet Packages**: The repository uses a custom `nuget.config` that points to a private Azure DevOps feed. If you need to restore packages and don't have access to the private feed, you may need to temporarily modify `nuget.config` to pull from nuget.org instead:\n```xml\n<packageSources>\n  <clear />\n  <add key=\"nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />\n</packageSources>\n```\n**IMPORTANT**: Never check in changes to `nuget.config`. The private feed configuration should remain in the repository.\n\n### Building\n```bash\n# Build debug version\ndotnet build\n\n# Build release version\ndotnet build -c Release\n\n# Platform-specific publish\ndotnet publish -c Release -r win10-x64\ndotnet publish -c Release -r linux-x64\ndotnet publish -c Release -r osx-x64\n```\n\n### Testing\n```bash\n# Run all tests\ndotnet test\n\n# Run specific test project\ndotnet test AppInspector.Tests/AppInspector.Tests.csproj\n\n# Run tests with verbose output\ndotnet test --verbosity normal\n```\n\n### Running the CLI\n```bash\n# Analyze code\ndotnet run --project AppInspector.CLI -- analyze -s path/to/source\n\n# Verify rules\ndotnet run --project AppInspector.CLI -- verifyrules -r path/to/rules\n\n# Export tags\ndotnet run --project AppInspector.CLI -- exporttags\n```\n\n## Coding Standards and Conventions\n\n### General C# Guidelines\n\n- Follow standard C# naming conventions (PascalCase for public members, camelCase for private fields)\n- Use meaningful, descriptive names for variables, methods, and classes\n- Keep methods focused and single-purpose\n- Add XML documentation comments for public APIs\n- Use nullable reference types where appropriate\n- Prefer `var` for local variables when the type is obvious\n- Use LINQ for collection operations when it improves readability\n\n### Specific Project Conventions\n\n- **Namespace Structure**: Follow the project name structure (e.g., `Microsoft.ApplicationInspector.Commands`)\n- **Logging**: Use the logging infrastructure from `AppInspector.Logging` namespace\n- **Error Handling**: Return structured result types rather than throwing exceptions for expected failures\n- **Async/Await**: Use async methods for I/O operations; follow the Task-based Asynchronous Pattern (TAP)\n\n## Rule Development Guidelines\n\n### Rule File Structure\n\nRules are JSON files located in `AppInspector/rules/default/` organized by category:\n- `cryptography/` - Cryptographic operations\n- `security_feature/` - Security-related features (authentication, authorization, etc.)\n- `data_handling/` - Database, serialization, deserialization\n- `os/` - Operating system operations (file I/O, process execution, reflection)\n- `cloud_services/` - Cloud platform APIs\n- `frameworks/` - Framework detection\n- And more...\n\n### Rule Schema Requirements\n\nThe rule schema is defined in `rule-schema-v1.json` in the repository root.\n\nEach rule must include:\n- `id` - Unique identifier (format: AI######, e.g., AI038900)\n- `name` - Human-readable name\n- `tags` - Array of tags describing the feature (e.g., \"Authentication.Microsoft.Online\")\n- `patterns` - Array of pattern objects for detection\n- `description` - Optional detailed description\n- `severity` - Optional: Critical, Important, Moderate, BestPractice, ManualReview, Unspecified\n- `applies_to` - Optional: array of language identifiers (e.g., [\"csharp\", \"java\"])\n\n### Pattern Types\n\n- `string` - Literal string match\n- `regex` - Regular expression\n- `regexword` - Regex with word boundaries automatically added\n- `substring` - Substring match\n\n### Pattern Best Practices\n\n1. **Use specific patterns**: Prefer specific API/class names over generic words to reduce false positives\n2. **Word boundaries**: Use `\\b` in regex patterns or `regexword` type to prevent matching substrings\n3. **Avoid catastrophic backtracking**: Don't use unlimited repetition patterns like `.*` in regex\n4. **Test cases**: Include `must-match` and `must-not-match` test cases in rules for validation\n5. **Confidence levels**: Set appropriate confidence (high, medium, low) based on pattern specificity\n6. **Scopes**: Specify appropriate scopes (code, comment) to limit false positives\n7. **Conditions**: Use conditions with `same-line` search to ensure API methods are invoked, not just referenced\n8. **Pattern for invocation**: Use `.Method(` patterns instead of `Class.Method` to catch actual usage via variables\n\n### Example Rule Pattern\n\n```json\n{\n  \"name\": \"Authentication: Microsoft (Identity)\",\n  \"id\": \"AI038900\",\n  \"description\": \"Authentication using Microsoft Identity Platform (ADAL/MSAL)\",\n  \"tags\": [\"Authentication.Microsoft.Online\"],\n  \"severity\": \"critical\",\n  \"patterns\": [\n    {\n      \"pattern\": \"microsoft\\\\.msal\",\n      \"type\": \"regexword\",\n      \"scopes\": [\"code\"],\n      \"confidence\": \"high\"\n    },\n    {\n      \"pattern\": \"AcquireTokenForClient\",\n      \"type\": \"regexword\",\n      \"scopes\": [\"code\"],\n      \"confidence\": \"high\"\n    }\n  ]\n}\n```\n\nNote: This is a simplified example. Real rules may use alternation (e.g., `pattern1|pattern2`) to match multiple alternatives in a single pattern.\n\n### Rule ID Conventions\n\n- Rule IDs follow consistent patterns within categories\n- Authentication rules: AI038900 - AI041999 range\n- Ensure new rule IDs don't conflict with existing ones\n- Sequential numbering within a category\n\n## Testing Conventions\n\n### Test Organization\n\n- Tests use xUnit framework\n- Test classes organized under `AppInspector.Tests/Commands/`\n- Test data located in `AppInspector.Tests/TestData/`\n- Use descriptive test method names that explain what is being tested\n- Use test fixtures (`IClassFixture<>`) for shared setup/teardown\n\n### Test Patterns\n\n```csharp\n[Fact]\npublic void TestMethodName_Scenario_ExpectedBehavior()\n{\n    // Arrange\n    var options = new AnalyzeOptions { /* ... */ };\n    \n    // Act\n    var result = command.GetResult();\n    \n    // Assert\n    Assert.True(result.ResultCode == AnalyzeResult.ExitCode.Success);\n}\n```\n\n## Security Considerations\n\n- **No hardcoded secrets**: Never commit credentials, API keys, or sensitive data\n- **Input validation**: Validate all user inputs, especially file paths and patterns\n- **Safe regex**: Avoid regex patterns that can cause catastrophic backtracking\n- **Secure defaults**: Use secure defaults for cryptographic operations\n- **Sanitization**: Use appropriate sanitizers (e.g., `html_escape`) to prevent injection vulnerabilities\n\n## Performance Considerations\n\n- **Regex compilation**: Consider caching compiled regex patterns for frequently used rules\n- **File I/O**: Use async I/O for file operations\n- **Memory usage**: Be mindful of memory when processing large codebases\n- **Parallel processing**: Leverage parallel processing where appropriate for scanning multiple files\n\n## Common Pitfalls to Avoid\n\n1. **Rule regex performance**: Avoid complex regex patterns that can cause performance issues on large files\n2. **False positives**: Test rules thoroughly to minimize false positive detections\n3. **Breaking changes**: Maintain backward compatibility in rule schema and command-line interface\n4. **Platform dependencies**: Ensure code works across Windows, Linux, and macOS\n5. **Resource cleanup**: Properly dispose of file handles and other resources\n\n## Code Review Checklist\n\nBefore submitting changes:\n- [ ] Code builds without errors (`dotnet build`)\n- [ ] All tests pass (`dotnet test`)\n- [ ] New rules include test cases (must-match and must-not-match)\n- [ ] New rules validate successfully (`dotnet run --project AppInspector.CLI -- verifyrules`)\n- [ ] XML documentation added for public APIs\n- [ ] No hardcoded secrets or sensitive data\n- [ ] Changes are backward compatible\n- [ ] Performance impact considered for rule changes\n\n## Useful Commands\n\n```bash\n# Verify rule syntax\ndotnet run --project AppInspector.CLI -- verifyrules -r AppInspector/rules/default/\n\n# Pack rules into single file\ndotnet run --project AppInspector.CLI -- packrules -r AppInspector/rules/default/ -o packed-rules.json\n\n# Run benchmarks\ndotnet run --project AppInspector.Benchmarks -c Release\n\n# Clean build artifacts\ndotnet clean\n```\n\n## Resources\n\n- [Project Wiki](https://github.com/microsoft/ApplicationInspector/wiki)\n- [Understanding Rules](https://github.com/microsoft/ApplicationInspector/wiki/3.-Understanding-Rules)\n- [CLI Usage](https://github.com/microsoft/ApplicationInspector/wiki/1.-CLI-Usage)\n- [NuGet Support](https://github.com/microsoft/ApplicationInspector/wiki/2.-NuGet-Support)\n- [Rule Schema](https://github.com/microsoft/ApplicationInspector/blob/main/rule-schema-v1.json)\n\n## Getting Help\n\n- Review the [CONTRIBUTING.md](https://github.com/microsoft/ApplicationInspector/blob/main/CONTRIBUTING.md) for contribution guidelines\n- Check [BUILD.md](https://github.com/microsoft/ApplicationInspector/blob/main/BUILD.md) for detailed build instructions\n- See [SECURITY.md](https://github.com/microsoft/ApplicationInspector/blob/main/SECURITY.md) for security reporting procedures\n","AppInspector/rules/samples/README.md":"# Application Inspector Sample Rules\n\nThis directory contains comprehensive sample rules that demonstrate all available fields and features for creating custom Application Inspector rules.\n\n## Files\n\n### comprehensive_sample_rule.json\n\nA maximally specified sample rule file that demonstrates:\n\n- **All top-level rule fields**: id, name, description, tags, severity, applies_to, does_not_apply_to, applies_to_file_regex, exclude_file_regex, depends_on_tags, overrides\n- **Pattern matching types**: regex, regexword, string\n- **Pattern features**: scopes, modifiers, confidence levels\n- **Conditions**: same-file matching with both positive and negative conditions\n- **Self-testing**: must-match and must-not-match arrays for validation\n- **Structured data queries**: XPath for XML, JSONPath for JSON, YAMLPath for YAML\n- **Comments**: Using _comment fields for documentation\n\n## Usage\n\nThese sample rules are for reference and learning purposes. They demonstrate the full capabilities of the Application Inspector rule format.\n\nTo use these samples:\n\n1. Copy and modify them for your specific detection needs\n2. Adjust the patterns to match your target code constructs\n3. Update the tags to fit your categorization scheme\n4. Set appropriate severity levels\n5. Add must-match/must-not-match test cases to validate your rules\n\n## Field Descriptions\n\n### Required Fields\n\n- `id`: Unique identifier for the rule (e.g., \"AI001234\")\n- `name`: Human-readable name describing what the rule detects\n- `tags`: Array of categorization tags (at least one required)\n- `patterns`: Array of search patterns (at least one required)\n\n### Optional Fields\n\n- `description`: Detailed description of what the rule detects\n- `severity`: One of: critical, important, moderate, bestpractice, manualreview, unspecified (lowercase preferred; default: moderate)\n- `applies_to`: Array of file extensions or language identifiers\n- `does_not_apply_to`: Array of file extensions or language identifiers to exclude\n- `applies_to_file_regex`: Array of regex patterns for files to include\n- `exclude_file_regex`: Array of regex patterns for files to exclude\n- `depends_on_tags`: Array of tags that must be present for this rule to apply\n- `overrides`: Array of rule IDs that this rule supersedes\n- `conditions`: Array of additional matching conditions\n- `expression`: Boolean expression combining pattern and condition labels (see [Expressions](#expressions))\n- `must-match`: Array of test strings that should match (for validation)\n- `must-not-match`: Array of test strings that should not match (for validation)\n- `_comment`: Optional comment for documentation\n\n### Pattern Fields\n\n- `pattern`: The regex/string pattern to search for (required)\n- `type`: One of: regex (default), regexword, string, substring\n- `label`: Name for this pattern, for use in `expression` (default: the pattern's index)\n- `conditions`: Array of conditions that gate only this pattern's findings\n- `scopes`: Array of: code, comment, all, html\n- `confidence`: One of: high, medium, low, unspecified\n- `modifiers`: Array of regex modifiers: i, m, s, x (or full names)\n- `xpaths`: Array of XPath expressions for XML matching\n- `jsonpaths`: Array of JSONPath expressions for JSON matching\n- `ymlpaths`: Array of YAMLPath expressions for YAML matching\n- `_comment`: Optional comment for documentation\n\n### Condition Fields\n\n- `pattern`: A pattern object (same structure as patterns array)\n- `search_in`: Where to search - \"finding-region(-offset,length)\", \"finding-only\", \"same-line\", \"same-file\", \"only-before\", \"only-after\"\n- `negate_finding`: Boolean - if true, the finding is invalid if this condition matches\n- `label`: Name for this condition, for use in `expression` (default: the condition's clause index)\n- `applies_to`: Array of languages this condition applies to (default: all)\n- `does_not_apply_to`: Array of languages this condition does not apply to\n- `_comment`: Optional comment for documentation\n\n## Expressions\n\nBy default a rule matches when **any** pattern matches and **every** rule level condition holds:\n\n```text\n(pattern0 OR pattern1 OR ...) AND condition0 AND condition1 ...\n```\n\nTwo optional features let you go beyond that shape.\n\n### Scoping a condition to one pattern\n\nDeclare the condition on the pattern it guards rather than at rule level. Other patterns are unaffected,\nso they still report even when the condition excludes this pattern's finding.\n\n```json\n\"patterns\": [\n  {\n    \"pattern\": \"curl\", \"type\": \"substring\", \"label\": \"curl\",\n    \"conditions\": [\n      {\n        \"pattern\": { \"pattern\": \"--tlsv1.3\", \"type\": \"substring\" },\n        \"search_in\": \"same-line\",\n        \"negate_finding\": true\n      }\n    ]\n  },\n  { \"pattern\": \"wget\", \"type\": \"substring\", \"label\": \"wget\" }\n]\n```\n\n### Writing the expression yourself\n\nSet `expression` to combine labels with `AND`, `OR`, `XOR`, `NAND`, `NOR` and `NOT`. This makes\notherwise inexpressible rules possible, such as a disjunction of conditions or a negated conjunction:\n\n```json\n\"expression\": \"cookie AND NOT (secure AND httponly)\"\n```\n\nThat rule fires when *either* required flag is missing. Writing it as two negated conditions would\ninstead mean \"neither flag is present\", which stays silent on partially hardened code.\n\nEvery finding is judged against the expression on its own. A file containing one correctly hardened\ncookie and one missing a flag reports the second, because the first satisfying `secure AND httponly`\nsays nothing about the second.\n\nBecause a finding originates from exactly one pattern, every *other* pattern label is false while\nthat finding is judged. An expression over pattern labels alone can therefore select which patterns\noriginate findings, but it cannot require sibling patterns to co-occur: `a AND NOT b` reports exactly\nwhat `a` reports. Conditions add co-occurrence tests because they are evaluated against each finding\nand can be true or false independently of it.\n\n### Requiring that two patterns both appear\n\nThis is why verification rejects an expression that needs two pattern labels true at once, such as\n`a AND b`. That is a normal-form requirement rather than a restriction on `AND`: a condition is a\npattern plus a search window, so a term that only has to co-occur is written as a `same-file`\ncondition instead.\n\n```json\n\"expression\": \"p AND ois\",\n\"patterns\": [\n    { \"pattern\": \"readObject\", \"type\": \"substring\", \"label\": \"p\", \"scopes\": [ \"code\" ] }\n],\n\"conditions\": [\n    { \"pattern\": { \"pattern\": \"ObjectInputStream\", \"type\": \"substring\", \"scopes\": [ \"code\" ] },\n      \"search_in\": \"same-file\", \"label\": \"ois\" }\n]\n```\n\nThat reports each `readObject`, but only in a file that also contains `ObjectInputStream`.\n\nTo report the locations of *both* terms, declare each one twice, once as a pattern so it can\noriginate a finding and once as a `same-file` condition so it can constrain the other:\n\n```json\n\"expression\": \"(a OR b) AND ca AND cb\"\n```\n\nwith patterns `a` and `b`, and same-file conditions `ca` and `cb` carrying those same two patterns.\nEvery `a` and every `b` is then reported, but only in files that contain both.\n\n> **Expressions have no operator precedence.** They are evaluated strictly left to right, so\n> `a OR b AND c` means `(a OR b) AND c`, **not** `a OR (b AND c)`. Always use parentheses to make\n> grouping explicit; rule verification rejects an expression that mixes operators at the same level\n> without them.\n\nOther rules for expressions:\n\n- Labels may not contain spaces or parentheses, and must be unique within the rule.\n- Every label named in the expression must belong to a pattern or condition in the same rule.\n- Attach parentheses to labels: `(a OR b)` is valid, `( a OR b )` is not.\n- Parentheses must be balanced.\n- A rule that sets `expression` must express negation with `NOT` rather than `negate_finding`.\n- Conditions test captured pattern findings independently of label order in the expression. For example,\n  `c AND a` and `a AND c` are equivalent when `c` is a condition and `a` is a pattern.\n\n## Best Practices\n\n1. **Use lowercase for enums**: severity, type, confidence, and scopes should use lowercase values\n2. **Populate optional fields**: Only include optional fields like `recommendation` or `_comment` if they contain meaningful content\n3. **Test your rules**: Always include must-match and must-not-match examples\n4. **Use appropriate severity**: Choose severity levels that reflect the actual impact\n5. **Use specific patterns**: Make patterns as specific as possible to reduce false positives\n6. **Document with comments**: Use `_comment` fields to explain complex patterns or conditions\n7. **Parenthesise expressions**: Expressions fold left to right with no precedence, so group explicitly\n\n## Related Documentation\n\n- [Rule Schema](../../../rule-schema-v1.json)\n- [Application Inspector Wiki](https://github.com/microsoft/ApplicationInspector/wiki)\n"},"files":{".github/copilot-instructions.md":"# GitHub Copilot Instructions for ApplicationInspector\n\n## Project Overview\n\nMicrosoft Application Inspector is a source code characterization tool that identifies coding features based on well-known library/API calls using regex patterns and rules. It supports multiple programming languages and generates reports in HTML, JSON, SARIF, and text formats.\n\n## Tech Stack\n\n- **Language**: C# (supports netstandard2.1; .NET 8.0+ for executables; aims to support all currently supported .NET versions)\n- **Build System**: dotnet CLI\n- **Test Framework**: xUnit\n- **Solution Structure**: Multi-project .NET solution with 7 projects\n- **Rule Format**: JSON files following rule-schema-v1.json schema definition in repository root\n\n## Project Structure\n\n- `AppInspector.CLI/` - Command-line interface application\n- `AppInspector/` - Core commands library (AppInspector.Commands.csproj)\n- `AppInspector.RulesEngine/` - Rule processing and pattern matching engine\n- `AppInspector.Common/` - Common utilities and types\n- `AppInspector.Logging/` - Logging infrastructure\n- `AppInspector.Tests/` - Test suite using xUnit\n- `AppInspector.Benchmarks/` - Performance benchmarks\n- `AppInspector/rules/default/` - Built-in detection rules organized by category\n\n## Build and Test Commands\n\n### Important Build Notes\n\n**Version Tracking**: This project uses Nerdbank.GitVersioning (nbgv) for version tracking, which requires a **deep clone** of the repository. Shallow clones will not work correctly with version generation.\n\n**NuGet Packages**: The repository uses a custom `nuget.config` that points to a private Azure DevOps feed. If you need to restore packages and don't have access to the private feed, you may need to temporarily modify `nuget.config` to pull from nuget.org instead:\n```xml\n<packageSources>\n  <clear />\n  <add key=\"nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />\n</packageSources>\n```\n**IMPORTANT**: Never check in changes to `nuget.config`. The private feed configuration should remain in the repository.\n\n### Building\n```bash\n# Build debug version\ndotnet build\n\n# Build release version\ndotnet build -c Release\n\n# Platform-specific publish\ndotnet publish -c Release -r win10-x64\ndotnet publish -c Release -r linux-x64\ndotnet publish -c Release -r osx-x64\n```\n\n### Testing\n```bash\n# Run all tests\ndotnet test\n\n# Run specific test project\ndotnet test AppInspector.Tests/AppInspector.Tests.csproj\n\n# Run tests with verbose output\ndotnet test --verbosity normal\n```\n\n### Running the CLI\n```bash\n# Analyze code\ndotnet run --project AppInspector.CLI -- analyze -s path/to/source\n\n# Verify rules\ndotnet run --project AppInspector.CLI -- verifyrules -r path/to/rules\n\n# Export tags\ndotnet run --project AppInspector.CLI -- exporttags\n```\n\n## Coding Standards and Conventions\n\n### General C# Guidelines\n\n- Follow standard C# naming conventions (PascalCase for public members, camelCase for private fields)\n- Use meaningful, descriptive names for variables, methods, and classes\n- Keep methods focused and single-purpose\n- Add XML documentation comments for public APIs\n- Use nullable reference types where appropriate\n- Prefer `var` for local variables when the type is obvious\n- Use LINQ for collection operations when it improves readability\n\n### Specific Project Conventions\n\n- **Namespace Structure**: Follow the project name structure (e.g., `Microsoft.ApplicationInspector.Commands`)\n- **Logging**: Use the logging infrastructure from `AppInspector.Logging` namespace\n- **Error Handling**: Return structured result types rather than throwing exceptions for expected failures\n- **Async/Await**: Use async methods for I/O operations; follow the Task-based Asynchronous Pattern (TAP)\n\n## Rule Development Guidelines\n\n### Rule File Structure\n\nRules are JSON files located in `AppInspector/rules/default/` organized by category:\n- `cryptography/` - Cryptographic operations\n- `security_feature/` - Security-related features (authentication, authorization, etc.)\n- `data_handling/` - Database, serialization, deserialization\n- `os/` - Operating system operations (file I/O, process execution, reflection)\n- `cloud_services/` - Cloud platform APIs\n- `frameworks/` - Framework detection\n- And more...\n\n### Rule Schema Requirements\n\nThe rule schema is defined in `rule-schema-v1.json` in the repository root.\n\nEach rule must include:\n- `id` - Unique identifier (format: AI######, e.g., AI038900)\n- `name` - Human-readable name\n- `tags` - Array of tags describing the feature (e.g., \"Authentication.Microsoft.Online\")\n- `patterns` - Array of pattern objects for detection\n- `description` - Optional detailed description\n- `severity` - Optional: Critical, Important, Moderate, BestPractice, ManualReview, Unspecified\n- `applies_to` - Optional: array of language identifiers (e.g., [\"csharp\", \"java\"])\n\n### Pattern Types\n\n- `string` - Literal string match\n- `regex` - Regular expression\n- `regexword` - Regex with word boundaries automatically added\n- `substring` - Substring match\n\n### Pattern Best Practices\n\n1. **Use specific patterns**: Prefer specific API/class names over generic words to reduce false positives\n2. **Word boundaries**: Use `\\b` in regex patterns or `regexword` type to prevent matching substrings\n3. **Avoid catastrophic backtracking**: Don't use unlimited repetition patterns like `.*` in regex\n4. **Test cases**: Include `must-match` and `must-not-match` test cases in rules for validation\n5. **Confidence levels**: Set appropriate confidence (high, medium, low) based on pattern specificity\n6. **Scopes**: Specify appropriate scopes (code, comment) to limit false positives\n7. **Conditions**: Use conditions with `same-line` search to ensure API methods are invoked, not just referenced\n8. **Pattern for invocation**: Use `.Method(` patterns instead of `Class.Method` to catch actual usage via variables\n\n### Example Rule Pattern\n\n```json\n{\n  \"name\": \"Authentication: Microsoft (Identity)\",\n  \"id\": \"AI038900\",\n  \"description\": \"Authentication using Microsoft Identity Platform (ADAL/MSAL)\",\n  \"tags\": [\"Authentication.Microsoft.Online\"],\n  \"severity\": \"critical\",\n  \"patterns\": [\n    {\n      \"pattern\": \"microsoft\\\\.msal\",\n      \"type\": \"regexword\",\n      \"scopes\": [\"code\"],\n      \"confidence\": \"high\"\n    },\n    {\n      \"pattern\": \"AcquireTokenForClient\",\n      \"type\": \"regexword\",\n      \"scopes\": [\"code\"],\n      \"confidence\": \"high\"\n    }\n  ]\n}\n```\n\nNote: This is a simplified example. Real rules may use alternation (e.g., `pattern1|pattern2`) to match multiple alternatives in a single pattern.\n\n### Rule ID Conventions\n\n- Rule IDs follow consistent patterns within categories\n- Authentication rules: AI038900 - AI041999 range\n- Ensure new rule IDs don't conflict with existing ones\n- Sequential numbering within a category\n\n## Testing Conventions\n\n### Test Organization\n\n- Tests use xUnit framework\n- Test classes organized under `AppInspector.Tests/Commands/`\n- Test data located in `AppInspector.Tests/TestData/`\n- Use descriptive test method names that explain what is being tested\n- Use test fixtures (`IClassFixture<>`) for shared setup/teardown\n\n### Test Patterns\n\n```csharp\n[Fact]\npublic void TestMethodName_Scenario_ExpectedBehavior()\n{\n    // Arrange\n    var options = new AnalyzeOptions { /* ... */ };\n    \n    // Act\n    var result = command.GetResult();\n    \n    // Assert\n    Assert.True(result.ResultCode == AnalyzeResult.ExitCode.Success);\n}\n```\n\n## Security Considerations\n\n- **No hardcoded secrets**: Never commit credentials, API keys, or sensitive data\n- **Input validation**: Validate all user inputs, especially file paths and patterns\n- **Safe regex**: Avoid regex patterns that can cause catastrophic backtracking\n- **Secure defaults**: Use secure defaults for cryptographic operations\n- **Sanitization**: Use appropriate sanitizers (e.g., `html_escape`) to prevent injection vulnerabilities\n\n## Performance Considerations\n\n- **Regex compilation**: Consider caching compiled regex patterns for frequently used rules\n- **File I/O**: Use async I/O for file operations\n- **Memory usage**: Be mindful of memory when processing large codebases\n- **Parallel processing**: Leverage parallel processing where appropriate for scanning multiple files\n\n## Common Pitfalls to Avoid\n\n1. **Rule regex performance**: Avoid complex regex patterns that can cause performance issues on large files\n2. **False positives**: Test rules thoroughly to minimize false positive detections\n3. **Breaking changes**: Maintain backward compatibility in rule schema and command-line interface\n4. **Platform dependencies**: Ensure code works across Windows, Linux, and macOS\n5. **Resource cleanup**: Properly dispose of file handles and other resources\n\n## Code Review Checklist\n\nBefore submitting changes:\n- [ ] Code builds without errors (`dotnet build`)\n- [ ] All tests pass (`dotnet test`)\n- [ ] New rules include test cases (must-match and must-not-match)\n- [ ] New rules validate successfully (`dotnet run --project AppInspector.CLI -- verifyrules`)\n- [ ] XML documentation added for public APIs\n- [ ] No hardcoded secrets or sensitive data\n- [ ] Changes are backward compatible\n- [ ] Performance impact considered for rule changes\n\n## Useful Commands\n\n```bash\n# Verify rule syntax\ndotnet run --project AppInspector.CLI -- verifyrules -r AppInspector/rules/default/\n\n# Pack rules into single file\ndotnet run --project AppInspector.CLI -- packrules -r AppInspector/rules/default/ -o packed-rules.json\n\n# Run benchmarks\ndotnet run --project AppInspector.Benchmarks -c Release\n\n# Clean build artifacts\ndotnet clean\n```\n\n## Resources\n\n- [Project Wiki](https://github.com/microsoft/ApplicationInspector/wiki)\n- [Understanding Rules](https://github.com/microsoft/ApplicationInspector/wiki/3.-Understanding-Rules)\n- [CLI Usage](https://github.com/microsoft/ApplicationInspector/wiki/1.-CLI-Usage)\n- [NuGet Support](https://github.com/microsoft/ApplicationInspector/wiki/2.-NuGet-Support)\n- [Rule Schema](https://github.com/microsoft/ApplicationInspector/blob/main/rule-schema-v1.json)\n\n## Getting Help\n\n- Review the [CONTRIBUTING.md](https://github.com/microsoft/ApplicationInspector/blob/main/CONTRIBUTING.md) for contribution guidelines\n- Check [BUILD.md](https://github.com/microsoft/ApplicationInspector/blob/main/BUILD.md) for detailed build instructions\n- See [SECURITY.md](https://github.com/microsoft/ApplicationInspector/blob/main/SECURITY.md) for security reporting procedures\n","AppInspector/rules/samples/README.md":"# Application Inspector Sample Rules\n\nThis directory contains comprehensive sample rules that demonstrate all available fields and features for creating custom Application Inspector rules.\n\n## Files\n\n### comprehensive_sample_rule.json\n\nA maximally specified sample rule file that demonstrates:\n\n- **All top-level rule fields**: id, name, description, tags, severity, applies_to, does_not_apply_to, applies_to_file_regex, exclude_file_regex, depends_on_tags, overrides\n- **Pattern matching types**: regex, regexword, string\n- **Pattern features**: scopes, modifiers, confidence levels\n- **Conditions**: same-file matching with both positive and negative conditions\n- **Self-testing**: must-match and must-not-match arrays for validation\n- **Structured data queries**: XPath for XML, JSONPath for JSON, YAMLPath for YAML\n- **Comments**: Using _comment fields for documentation\n\n## Usage\n\nThese sample rules are for reference and learning purposes. They demonstrate the full capabilities of the Application Inspector rule format.\n\nTo use these samples:\n\n1. Copy and modify them for your specific detection needs\n2. Adjust the patterns to match your target code constructs\n3. Update the tags to fit your categorization scheme\n4. Set appropriate severity levels\n5. Add must-match/must-not-match test cases to validate your rules\n\n## Field Descriptions\n\n### Required Fields\n\n- `id`: Unique identifier for the rule (e.g., \"AI001234\")\n- `name`: Human-readable name describing what the rule detects\n- `tags`: Array of categorization tags (at least one required)\n- `patterns`: Array of search patterns (at least one required)\n\n### Optional Fields\n\n- `description`: Detailed description of what the rule detects\n- `severity`: One of: critical, important, moderate, bestpractice, manualreview, unspecified (lowercase preferred; default: moderate)\n- `applies_to`: Array of file extensions or language identifiers\n- `does_not_apply_to`: Array of file extensions or language identifiers to exclude\n- `applies_to_file_regex`: Array of regex patterns for files to include\n- `exclude_file_regex`: Array of regex patterns for files to exclude\n- `depends_on_tags`: Array of tags that must be present for this rule to apply\n- `overrides`: Array of rule IDs that this rule supersedes\n- `conditions`: Array of additional matching conditions\n- `expression`: Boolean expression combining pattern and condition labels (see [Expressions](#expressions))\n- `must-match`: Array of test strings that should match (for validation)\n- `must-not-match`: Array of test strings that should not match (for validation)\n- `_comment`: Optional comment for documentation\n\n### Pattern Fields\n\n- `pattern`: The regex/string pattern to search for (required)\n- `type`: One of: regex (default), regexword, string, substring\n- `label`: Name for this pattern, for use in `expression` (default: the pattern's index)\n- `conditions`: Array of conditions that gate only this pattern's findings\n- `scopes`: Array of: code, comment, all, html\n- `confidence`: One of: high, medium, low, unspecified\n- `modifiers`: Array of regex modifiers: i, m, s, x (or full names)\n- `xpaths`: Array of XPath expressions for XML matching\n- `jsonpaths`: Array of JSONPath expressions for JSON matching\n- `ymlpaths`: Array of YAMLPath expressions for YAML matching\n- `_comment`: Optional comment for documentation\n\n### Condition Fields\n\n- `pattern`: A pattern object (same structure as patterns array)\n- `search_in`: Where to search - \"finding-region(-offset,length)\", \"finding-only\", \"same-line\", \"same-file\", \"only-before\", \"only-after\"\n- `negate_finding`: Boolean - if true, the finding is invalid if this condition matches\n- `label`: Name for this condition, for use in `expression` (default: the condition's clause index)\n- `applies_to`: Array of languages this condition applies to (default: all)\n- `does_not_apply_to`: Array of languages this condition does not apply to\n- `_comment`: Optional comment for documentation\n\n## Expressions\n\nBy default a rule matches when **any** pattern matches and **every** rule level condition holds:\n\n```text\n(pattern0 OR pattern1 OR ...) AND condition0 AND condition1 ...\n```\n\nTwo optional features let you go beyond that shape.\n\n### Scoping a condition to one pattern\n\nDeclare the condition on the pattern it guards rather than at rule level. Other patterns are unaffected,\nso they still report even when the condition excludes this pattern's finding.\n\n```json\n\"patterns\": [\n  {\n    \"pattern\": \"curl\", \"type\": \"substring\", \"label\": \"curl\",\n    \"conditions\": [\n      {\n        \"pattern\": { \"pattern\": \"--tlsv1.3\", \"type\": \"substring\" },\n        \"search_in\": \"same-line\",\n        \"negate_finding\": true\n      }\n    ]\n  },\n  { \"pattern\": \"wget\", \"type\": \"substring\", \"label\": \"wget\" }\n]\n```\n\n### Writing the expression yourself\n\nSet `expression` to combine labels with `AND`, `OR`, `XOR`, `NAND`, `NOR` and `NOT`. This makes\notherwise inexpressible rules possible, such as a disjunction of conditions or a negated conjunction:\n\n```json\n\"expression\": \"cookie AND NOT (secure AND httponly)\"\n```\n\nThat rule fires when *either* required flag is missing. Writing it as two negated conditions would\ninstead mean \"neither flag is present\", which stays silent on partially hardened code.\n\nEvery finding is judged against the expression on its own. A file containing one correctly hardened\ncookie and one missing a flag reports the second, because the first satisfying `secure AND httponly`\nsays nothing about the second.\n\nBecause a finding originates from exactly one pattern, every *other* pattern label is false while\nthat finding is judged. An expression over pattern labels alone can therefore select which patterns\noriginate findings, but it cannot require sibling patterns to co-occur: `a AND NOT b` reports exactly\nwhat `a` reports. Conditions add co-occurrence tests because they are evaluated against each finding\nand can be true or false independently of it.\n\n### Requiring that two patterns both appear\n\nThis is why verification rejects an expression that needs two pattern labels true at once, such as\n`a AND b`. That is a normal-form requirement rather than a restriction on `AND`: a condition is a\npattern plus a search window, so a term that only has to co-occur is written as a `same-file`\ncondition instead.\n\n```json\n\"expression\": \"p AND ois\",\n\"patterns\": [\n    { \"pattern\": \"readObject\", \"type\": \"substring\", \"label\": \"p\", \"scopes\": [ \"code\" ] }\n],\n\"conditions\": [\n    { \"pattern\": { \"pattern\": \"ObjectInputStream\", \"type\": \"substring\", \"scopes\": [ \"code\" ] },\n      \"search_in\": \"same-file\", \"label\": \"ois\" }\n]\n```\n\nThat reports each `readObject`, but only in a file that also contains `ObjectInputStream`.\n\nTo report the locations of *both* terms, declare each one twice, once as a pattern so it can\noriginate a finding and once as a `same-file` condition so it can constrain the other:\n\n```json\n\"expression\": \"(a OR b) AND ca AND cb\"\n```\n\nwith patterns `a` and `b`, and same-file conditions `ca` and `cb` carrying those same two patterns.\nEvery `a` and every `b` is then reported, but only in files that contain both.\n\n> **Expressions have no operator precedence.** They are evaluated strictly left to right, so\n> `a OR b AND c` means `(a OR b) AND c`, **not** `a OR (b AND c)`. Always use parentheses to make\n> grouping explicit; rule verification rejects an expression that mixes operators at the same level\n> without them.\n\nOther rules for expressions:\n\n- Labels may not contain spaces or parentheses, and must be unique within the rule.\n- Every label named in the expression must belong to a pattern or condition in the same rule.\n- Attach parentheses to labels: `(a OR b)` is valid, `( a OR b )` is not.\n- Parentheses must be balanced.\n- A rule that sets `expression` must express negation with `NOT` rather than `negate_finding`.\n- Conditions test captured pattern findings independently of label order in the expression. For example,\n  `c AND a` and `a AND c` are equivalent when `c` is a condition and `a` is a pattern.\n\n## Best Practices\n\n1. **Use lowercase for enums**: severity, type, confidence, and scopes should use lowercase values\n2. **Populate optional fields**: Only include optional fields like `recommendation` or `_comment` if they contain meaningful content\n3. **Test your rules**: Always include must-match and must-not-match examples\n4. **Use appropriate severity**: Choose severity levels that reflect the actual impact\n5. **Use specific patterns**: Make patterns as specific as possible to reduce false positives\n6. **Document with comments**: Use `_comment` fields to explain complex patterns or conditions\n7. **Parenthesise expressions**: Expressions fold left to right with no precedence, so group explicitly\n\n## Related Documentation\n\n- [Rule Schema](../../../rule-schema-v1.json)\n- [Application Inspector Wiki](https://github.com/microsoft/ApplicationInspector/wiki)\n"},"items":[{"name":"copilot-instructions.md","path":".github/copilot-instructions.md","rawUrl":"https://raw.githubusercontent.com/microsoft/ApplicationInspector/HEAD/.github/copilot-instructions.md","title":"GitHub Copilot Instructions","category":"copilot-instructions","format":"markdown","content":"# GitHub Copilot Instructions for ApplicationInspector\n\n## Project Overview\n\nMicrosoft Application Inspector is a source code characterization tool that identifies coding features based on well-known library/API calls using regex patterns and rules. It supports multiple programming languages and generates reports in HTML, JSON, SARIF, and text formats.\n\n## Tech Stack\n\n- **Language**: C# (supports netstandard2.1; .NET 8.0+ for executables; aims to support all currently supported .NET versions)\n- **Build System**: dotnet CLI\n- **Test Framework**: xUnit\n- **Solution Structure**: Multi-project .NET solution with 7 projects\n- **Rule Format**: JSON files following rule-schema-v1.json schema definition in repository root\n\n## Project Structure\n\n- `AppInspector.CLI/` - Command-line interface application\n- `AppInspector/` - Core commands library (AppInspector.Commands.csproj)\n- `AppInspector.RulesEngine/` - Rule processing and pattern matching engine\n- `AppInspector.Common/` - Common utilities and types\n- `AppInspector.Logging/` - Logging infrastructure\n- `AppInspector.Tests/` - Test suite using xUnit\n- `AppInspector.Benchmarks/` - Performance benchmarks\n- `AppInspector/rules/default/` - Built-in detection rules organized by category\n\n## Build and Test Commands\n\n### Important Build Notes\n\n**Version Tracking**: This project uses Nerdbank.GitVersioning (nbgv) for version tracking, which requires a **deep clone** of the repository. Shallow clones will not work correctly with version generation.\n\n**NuGet Packages**: The repository uses a custom `nuget.config` that points to a private Azure DevOps feed. If you need to restore packages and don't have access to the private feed, you may need to temporarily modify `nuget.config` to pull from nuget.org instead:\n```xml\n<packageSources>\n  <clear />\n  <add key=\"nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />\n</packageSources>\n```\n**IMPORTANT**: Never check in changes to `nuget.config`. The private feed configuration should remain in the repository.\n\n### Building\n```bash\n# Build debug version\ndotnet build\n\n# Build release version\ndotnet build -c Release\n\n# Platform-specific publish\ndotnet publish -c Release -r win10-x64\ndotnet publish -c Release -r linux-x64\ndotnet publish -c Release -r osx-x64\n```\n\n### Testing\n```bash\n# Run all tests\ndotnet test\n\n# Run specific test project\ndotnet test AppInspector.Tests/AppInspector.Tests.csproj\n\n# Run tests with verbose output\ndotnet test --verbosity normal\n```\n\n### Running the CLI\n```bash\n# Analyze code\ndotnet run --project AppInspector.CLI -- analyze -s path/to/source\n\n# Verify rules\ndotnet run --project AppInspector.CLI -- verifyrules -r path/to/rules\n\n# Export tags\ndotnet run --project AppInspector.CLI -- exporttags\n```\n\n## Coding Standards and Conventions\n\n### General C# Guidelines\n\n- Follow standard C# naming conventions (PascalCase for public members, camelCase for private fields)\n- Use meaningful, descriptive names for variables, methods, and classes\n- Keep methods focused and single-purpose\n- Add XML documentation comments for public APIs\n- Use nullable reference types where appropriate\n- Prefer `var` for local variables when the type is obvious\n- Use LINQ for collection operations when it improves readability\n\n### Specific Project Conventions\n\n- **Namespace Structure**: Follow the project name structure (e.g., `Microsoft.ApplicationInspector.Commands`)\n- **Logging**: Use the logging infrastructure from `AppInspector.Logging` namespace\n- **Error Handling**: Return structured result types rather than throwing exceptions for expected failures\n- **Async/Await**: Use async methods for I/O operations; follow the Task-based Asynchronous Pattern (TAP)\n\n## Rule Development Guidelines\n\n### Rule File Structure\n\nRules are JSON files located in `AppInspector/rules/default/` organized by category:\n- `cryptography/` - Cryptographic operations\n- `security_feature/` - Security-related features (authentication, authorization, etc.)\n- `data_handling/` - Database, serialization, deserialization\n- `os/` - Operating system operations (file I/O, process execution, reflection)\n- `cloud_services/` - Cloud platform APIs\n- `frameworks/` - Framework detection\n- And more...\n\n### Rule Schema Requirements\n\nThe rule schema is defined in `rule-schema-v1.json` in the repository root.\n\nEach rule must include:\n- `id` - Unique identifier (format: AI######, e.g., AI038900)\n- `name` - Human-readable name\n- `tags` - Array of tags describing the feature (e.g., \"Authentication.Microsoft.Online\")\n- `patterns` - Array of pattern objects for detection\n- `description` - Optional detailed description\n- `severity` - Optional: Critical, Important, Moderate, BestPractice, ManualReview, Unspecified\n- `applies_to` - Optional: array of language identifiers (e.g., [\"csharp\", \"java\"])\n\n### Pattern Types\n\n- `string` - Literal string match\n- `regex` - Regular expression\n- `regexword` - Regex with word boundaries automatically added\n- `substring` - Substring match\n\n### Pattern Best Practices\n\n1. **Use specific patterns**: Prefer specific API/class names over generic words to reduce false positives\n2. **Word boundaries**: Use `\\b` in regex patterns or `regexword` type to prevent matching substrings\n3. **Avoid catastrophic backtracking**: Don't use unlimited repetition patterns like `.*` in regex\n4. **Test cases**: Include `must-match` and `must-not-match` test cases in rules for validation\n5. **Confidence levels**: Set appropriate confidence (high, medium, low) based on pattern specificity\n6. **Scopes**: Specify appropriate scopes (code, comment) to limit false positives\n7. **Conditions**: Use conditions with `same-line` search to ensure API methods are invoked, not just referenced\n8. **Pattern for invocation**: Use `.Method(` patterns instead of `Class.Method` to catch actual usage via variables\n\n### Example Rule Pattern\n\n```json\n{\n  \"name\": \"Authentication: Microsoft (Identity)\",\n  \"id\": \"AI038900\",\n  \"description\": \"Authentication using Microsoft Identity Platform (ADAL/MSAL)\",\n  \"tags\": [\"Authentication.Microsoft.Online\"],\n  \"severity\": \"critical\",\n  \"patterns\": [\n    {\n      \"pattern\": \"microsoft\\\\.msal\",\n      \"type\": \"regexword\",\n      \"scopes\": [\"code\"],\n      \"confidence\": \"high\"\n    },\n    {\n      \"pattern\": \"AcquireTokenForClient\",\n      \"type\": \"regexword\",\n      \"scopes\": [\"code\"],\n      \"confidence\": \"high\"\n    }\n  ]\n}\n```\n\nNote: This is a simplified example. Real rules may use alternation (e.g., `pattern1|pattern2`) to match multiple alternatives in a single pattern.\n\n### Rule ID Conventions\n\n- Rule IDs follow consistent patterns within categories\n- Authentication rules: AI038900 - AI041999 range\n- Ensure new rule IDs don't conflict with existing ones\n- Sequential numbering within a category\n\n## Testing Conventions\n\n### Test Organization\n\n- Tests use xUnit framework\n- Test classes organized under `AppInspector.Tests/Commands/`\n- Test data located in `AppInspector.Tests/TestData/`\n- Use descriptive test method names that explain what is being tested\n- Use test fixtures (`IClassFixture<>`) for shared setup/teardown\n\n### Test Patterns\n\n```csharp\n[Fact]\npublic void TestMethodName_Scenario_ExpectedBehavior()\n{\n    // Arrange\n    var options = new AnalyzeOptions { /* ... */ };\n    \n    // Act\n    var result = command.GetResult();\n    \n    // Assert\n    Assert.True(result.ResultCode == AnalyzeResult.ExitCode.Success);\n}\n```\n\n## Security Considerations\n\n- **No hardcoded secrets**: Never commit credentials, API keys, or sensitive data\n- **Input validation**: Validate all user inputs, especially file paths and patterns\n- **Safe regex**: Avoid regex patterns that can cause catastrophic backtracking\n- **Secure defaults**: Use secure defaults for cryptographic operations\n- **Sanitization**: Use appropriate sanitizers (e.g., `html_escape`) to prevent injection vulnerabilities\n\n## Performance Considerations\n\n- **Regex compilation**: Consider caching compiled regex patterns for frequently used rules\n- **File I/O**: Use async I/O for file operations\n- **Memory usage**: Be mindful of memory when processing large codebases\n- **Parallel processing**: Leverage parallel processing where appropriate for scanning multiple files\n\n## Common Pitfalls to Avoid\n\n1. **Rule regex performance**: Avoid complex regex patterns that can cause performance issues on large files\n2. **False positives**: Test rules thoroughly to minimize false positive detections\n3. **Breaking changes**: Maintain backward compatibility in rule schema and command-line interface\n4. **Platform dependencies**: Ensure code works across Windows, Linux, and macOS\n5. **Resource cleanup**: Properly dispose of file handles and other resources\n\n## Code Review Checklist\n\nBefore submitting changes:\n- [ ] Code builds without errors (`dotnet build`)\n- [ ] All tests pass (`dotnet test`)\n- [ ] New rules include test cases (must-match and must-not-match)\n- [ ] New rules validate successfully (`dotnet run --project AppInspector.CLI -- verifyrules`)\n- [ ] XML documentation added for public APIs\n- [ ] No hardcoded secrets or sensitive data\n- [ ] Changes are backward compatible\n- [ ] Performance impact considered for rule changes\n\n## Useful Commands\n\n```bash\n# Verify rule syntax\ndotnet run --project AppInspector.CLI -- verifyrules -r AppInspector/rules/default/\n\n# Pack rules into single file\ndotnet run --project AppInspector.CLI -- packrules -r AppInspector/rules/default/ -o packed-rules.json\n\n# Run benchmarks\ndotnet run --project AppInspector.Benchmarks -c Release\n\n# Clean build artifacts\ndotnet clean\n```\n\n## Resources\n\n- [Project Wiki](https://github.com/microsoft/ApplicationInspector/wiki)\n- [Understanding Rules](https://github.com/microsoft/ApplicationInspector/wiki/3.-Understanding-Rules)\n- [CLI Usage](https://github.com/microsoft/ApplicationInspector/wiki/1.-CLI-Usage)\n- [NuGet Support](https://github.com/microsoft/ApplicationInspector/wiki/2.-NuGet-Support)\n- [Rule Schema](https://github.com/microsoft/ApplicationInspector/blob/main/rule-schema-v1.json)\n\n## Getting Help\n\n- Review the [CONTRIBUTING.md](https://github.com/microsoft/ApplicationInspector/blob/main/CONTRIBUTING.md) for contribution guidelines\n- Check [BUILD.md](https://github.com/microsoft/ApplicationInspector/blob/main/BUILD.md) for detailed build instructions\n- See [SECURITY.md](https://github.com/microsoft/ApplicationInspector/blob/main/SECURITY.md) for security reporting procedures\n","isInternal":false,"tokens":2322,"sizeBytes":10415},{"name":"README.md","path":"AppInspector/rules/samples/README.md","rawUrl":"https://raw.githubusercontent.com/microsoft/ApplicationInspector/HEAD/AppInspector/rules/samples/README.md","title":"Samples Skill","category":"anthropic-skill","format":"markdown","content":"# Application Inspector Sample Rules\n\nThis directory contains comprehensive sample rules that demonstrate all available fields and features for creating custom Application Inspector rules.\n\n## Files\n\n### comprehensive_sample_rule.json\n\nA maximally specified sample rule file that demonstrates:\n\n- **All top-level rule fields**: id, name, description, tags, severity, applies_to, does_not_apply_to, applies_to_file_regex, exclude_file_regex, depends_on_tags, overrides\n- **Pattern matching types**: regex, regexword, string\n- **Pattern features**: scopes, modifiers, confidence levels\n- **Conditions**: same-file matching with both positive and negative conditions\n- **Self-testing**: must-match and must-not-match arrays for validation\n- **Structured data queries**: XPath for XML, JSONPath for JSON, YAMLPath for YAML\n- **Comments**: Using _comment fields for documentation\n\n## Usage\n\nThese sample rules are for reference and learning purposes. They demonstrate the full capabilities of the Application Inspector rule format.\n\nTo use these samples:\n\n1. Copy and modify them for your specific detection needs\n2. Adjust the patterns to match your target code constructs\n3. Update the tags to fit your categorization scheme\n4. Set appropriate severity levels\n5. Add must-match/must-not-match test cases to validate your rules\n\n## Field Descriptions\n\n### Required Fields\n\n- `id`: Unique identifier for the rule (e.g., \"AI001234\")\n- `name`: Human-readable name describing what the rule detects\n- `tags`: Array of categorization tags (at least one required)\n- `patterns`: Array of search patterns (at least one required)\n\n### Optional Fields\n\n- `description`: Detailed description of what the rule detects\n- `severity`: One of: critical, important, moderate, bestpractice, manualreview, unspecified (lowercase preferred; default: moderate)\n- `applies_to`: Array of file extensions or language identifiers\n- `does_not_apply_to`: Array of file extensions or language identifiers to exclude\n- `applies_to_file_regex`: Array of regex patterns for files to include\n- `exclude_file_regex`: Array of regex patterns for files to exclude\n- `depends_on_tags`: Array of tags that must be present for this rule to apply\n- `overrides`: Array of rule IDs that this rule supersedes\n- `conditions`: Array of additional matching conditions\n- `expression`: Boolean expression combining pattern and condition labels (see [Expressions](#expressions))\n- `must-match`: Array of test strings that should match (for validation)\n- `must-not-match`: Array of test strings that should not match (for validation)\n- `_comment`: Optional comment for documentation\n\n### Pattern Fields\n\n- `pattern`: The regex/string pattern to search for (required)\n- `type`: One of: regex (default), regexword, string, substring\n- `label`: Name for this pattern, for use in `expression` (default: the pattern's index)\n- `conditions`: Array of conditions that gate only this pattern's findings\n- `scopes`: Array of: code, comment, all, html\n- `confidence`: One of: high, medium, low, unspecified\n- `modifiers`: Array of regex modifiers: i, m, s, x (or full names)\n- `xpaths`: Array of XPath expressions for XML matching\n- `jsonpaths`: Array of JSONPath expressions for JSON matching\n- `ymlpaths`: Array of YAMLPath expressions for YAML matching\n- `_comment`: Optional comment for documentation\n\n### Condition Fields\n\n- `pattern`: A pattern object (same structure as patterns array)\n- `search_in`: Where to search - \"finding-region(-offset,length)\", \"finding-only\", \"same-line\", \"same-file\", \"only-before\", \"only-after\"\n- `negate_finding`: Boolean - if true, the finding is invalid if this condition matches\n- `label`: Name for this condition, for use in `expression` (default: the condition's clause index)\n- `applies_to`: Array of languages this condition applies to (default: all)\n- `does_not_apply_to`: Array of languages this condition does not apply to\n- `_comment`: Optional comment for documentation\n\n## Expressions\n\nBy default a rule matches when **any** pattern matches and **every** rule level condition holds:\n\n```text\n(pattern0 OR pattern1 OR ...) AND condition0 AND condition1 ...\n```\n\nTwo optional features let you go beyond that shape.\n\n### Scoping a condition to one pattern\n\nDeclare the condition on the pattern it guards rather than at rule level. Other patterns are unaffected,\nso they still report even when the condition excludes this pattern's finding.\n\n```json\n\"patterns\": [\n  {\n    \"pattern\": \"curl\", \"type\": \"substring\", \"label\": \"curl\",\n    \"conditions\": [\n      {\n        \"pattern\": { \"pattern\": \"--tlsv1.3\", \"type\": \"substring\" },\n        \"search_in\": \"same-line\",\n        \"negate_finding\": true\n      }\n    ]\n  },\n  { \"pattern\": \"wget\", \"type\": \"substring\", \"label\": \"wget\" }\n]\n```\n\n### Writing the expression yourself\n\nSet `expression` to combine labels with `AND`, `OR`, `XOR`, `NAND`, `NOR` and `NOT`. This makes\notherwise inexpressible rules possible, such as a disjunction of conditions or a negated conjunction:\n\n```json\n\"expression\": \"cookie AND NOT (secure AND httponly)\"\n```\n\nThat rule fires when *either* required flag is missing. Writing it as two negated conditions would\ninstead mean \"neither flag is present\", which stays silent on partially hardened code.\n\nEvery finding is judged against the expression on its own. A file containing one correctly hardened\ncookie and one missing a flag reports the second, because the first satisfying `secure AND httponly`\nsays nothing about the second.\n\nBecause a finding originates from exactly one pattern, every *other* pattern label is false while\nthat finding is judged. An expression over pattern labels alone can therefore select which patterns\noriginate findings, but it cannot require sibling patterns to co-occur: `a AND NOT b` reports exactly\nwhat `a` reports. Conditions add co-occurrence tests because they are evaluated against each finding\nand can be true or false independently of it.\n\n### Requiring that two patterns both appear\n\nThis is why verification rejects an expression that needs two pattern labels true at once, such as\n`a AND b`. That is a normal-form requirement rather than a restriction on `AND`: a condition is a\npattern plus a search window, so a term that only has to co-occur is written as a `same-file`\ncondition instead.\n\n```json\n\"expression\": \"p AND ois\",\n\"patterns\": [\n    { \"pattern\": \"readObject\", \"type\": \"substring\", \"label\": \"p\", \"scopes\": [ \"code\" ] }\n],\n\"conditions\": [\n    { \"pattern\": { \"pattern\": \"ObjectInputStream\", \"type\": \"substring\", \"scopes\": [ \"code\" ] },\n      \"search_in\": \"same-file\", \"label\": \"ois\" }\n]\n```\n\nThat reports each `readObject`, but only in a file that also contains `ObjectInputStream`.\n\nTo report the locations of *both* terms, declare each one twice, once as a pattern so it can\noriginate a finding and once as a `same-file` condition so it can constrain the other:\n\n```json\n\"expression\": \"(a OR b) AND ca AND cb\"\n```\n\nwith patterns `a` and `b`, and same-file conditions `ca` and `cb` carrying those same two patterns.\nEvery `a` and every `b` is then reported, but only in files that contain both.\n\n> **Expressions have no operator precedence.** They are evaluated strictly left to right, so\n> `a OR b AND c` means `(a OR b) AND c`, **not** `a OR (b AND c)`. Always use parentheses to make\n> grouping explicit; rule verification rejects an expression that mixes operators at the same level\n> without them.\n\nOther rules for expressions:\n\n- Labels may not contain spaces or parentheses, and must be unique within the rule.\n- Every label named in the expression must belong to a pattern or condition in the same rule.\n- Attach parentheses to labels: `(a OR b)` is valid, `( a OR b )` is not.\n- Parentheses must be balanced.\n- A rule that sets `expression` must express negation with `NOT` rather than `negate_finding`.\n- Conditions test captured pattern findings independently of label order in the expression. For example,\n  `c AND a` and `a AND c` are equivalent when `c` is a condition and `a` is a pattern.\n\n## Best Practices\n\n1. **Use lowercase for enums**: severity, type, confidence, and scopes should use lowercase values\n2. **Populate optional fields**: Only include optional fields like `recommendation` or `_comment` if they contain meaningful content\n3. **Test your rules**: Always include must-match and must-not-match examples\n4. **Use appropriate severity**: Choose severity levels that reflect the actual impact\n5. **Use specific patterns**: Make patterns as specific as possible to reduce false positives\n6. **Document with comments**: Use `_comment` fields to explain complex patterns or conditions\n7. **Parenthesise expressions**: Expressions fold left to right with no precedence, so group explicitly\n\n## Related Documentation\n\n- [Rule Schema](../../../rule-schema-v1.json)\n- [Application Inspector Wiki](https://github.com/microsoft/ApplicationInspector/wiki)\n","isInternal":false,"tokens":2013,"sizeBytes":8878}],"systemPromptSnippet":"<yakaai_skills repo=\"microsoft/ApplicationInspector\">\n<!-- File: .github/copilot-instructions.md (Tokens: ~2322 | Category: copilot-instructions) -->\n# GitHub Copilot Instructions for ApplicationInspector\n\n## Project Overview\n\nMicrosoft Application Inspector is a source code characterization tool that identifies coding features based on well-known library/API calls using regex patterns and rules. It supports multiple programming languages and generates reports in HTML, JSON, SARIF, and text formats.\n\n## Tech Stack\n\n- **Language**: C# (supports netstandard2.1; .NET 8.0+ for executables; aims to support all currently supported .NET versions)\n- **Build System**: dotnet CLI\n- **Test Framework**: xUnit\n- **Solution Structure**: Multi-project .NET solution with 7 projects\n- **Rule Format**: JSON files following rule-schema-v1.json schema definition in repository root\n\n## Project Structure\n\n- `AppInspector.CLI/` - Command-line interface application\n- `AppInspector/` - Core commands library (AppInspector.Commands.csproj)\n- `AppInspector.RulesEngine/` - Rule processing and pattern matching engine\n- `AppInspector.Common/` - Common utilities and types\n- `AppInspector.Logging/` - Logging infrastructure\n- `AppInspector.Tests/` - Test suite using xUnit\n- `AppInspector.Benchmarks/` - Performance benchmarks\n- `AppInspector/rules/default/` - Built-in detection rules organized by category\n\n## Build and Test Commands\n\n### Important Build Notes\n\n**Version Tracking**: This project uses Nerdbank.GitVersioning (nbgv) for version tracking, which requires a **deep clone** of the repository. Shallow clones will not work correctly with version generation.\n\n**NuGet Packages**: The repository uses a custom `nuget.config` that points to a private Azure DevOps feed. If you need to restore packages and don't have access to the private feed, you may need to temporarily modify `nuget.config` to pull from nuget.org instead:\n```xml\n<packageSources>\n  <clear />\n  <add key=\"nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />\n</packageSources>\n```\n**IMPORTANT**: Never check in changes to `nuget.config`. The private feed configuration should remain in the repository.\n\n### Building\n```bash\n# Build debug version\ndotnet build\n\n# Build release version\ndotnet build -c Release\n\n# Platform-specific publish\ndotnet publish -c Release -r win10-x64\ndotnet publish -c Release -r linux-x64\ndotnet publish -c Release -r osx-x64\n```\n\n### Testing\n```bash\n# Run all tests\ndotnet test\n\n# Run specific test project\ndotnet test AppInspector.Tests/AppInspector.Tests.csproj\n\n# Run tests with verbose output\ndotnet test --verbosity normal\n```\n\n### Running the CLI\n```bash\n# Analyze code\ndotnet run --project AppInspector.CLI -- analyze -s path/to/source\n\n# Verify rules\ndotnet run --project AppInspector.CLI -- verifyrules -r path/to/rules\n\n# Export tags\ndotnet run --project AppInspector.CLI -- exporttags\n```\n\n## Coding Standards and Conventions\n\n### General C# Guidelines\n\n- Follow standard C# naming conventions (PascalCase for public members, camelCase for private fields)\n- Use meaningful, descriptive names for variables, methods, and classes\n- Keep methods focused and single-purpose\n- Add XML documentation comments for public APIs\n- Use nullable reference types where appropriate\n- Prefer `var` for local variables when the type is obvious\n- Use LINQ for collection operations when it improves readability\n\n### Specific Project Conventions\n\n- **Namespace Structure**: Follow the project name structure (e.g., `Microsoft.ApplicationInspector.Commands`)\n- **Logging**: Use the logging infrastructure from `AppInspector.Logging` namespace\n- **Error Handling**: Return structured result types rather than throwing exceptions for expected failures\n- **Async/Await**: Use async methods for I/O operations; follow the Task-based Asynchronous Pattern (TAP)\n\n## Rule Development Guidelines\n\n### Rule File Structure\n\nRules are JSON files located in `AppInspector/rules/default/` organized by category:\n- `cryptography/` - Cryptographic operations\n- `security_feature/` - Security-related features (authentication, authorization, etc.)\n- `data_handling/` - Database, serialization, deserialization\n- `os/` - Operating system operations (file I/O, process execution, reflection)\n- `cloud_services/` - Cloud platform APIs\n- `frameworks/` - Framework detection\n- And more...\n\n### Rule Schema Requirements\n\nThe rule schema is defined in `rule-schema-v1.json` in the repository root.\n\nEach rule must include:\n- `id` - Unique identifier (format: AI######, e.g., AI038900)\n- `name` - Human-readable name\n- `tags` - Array of tags describing the feature (e.g., \"Authentication.Microsoft.Online\")\n- `patterns` - Array of pattern objects for detection\n- `description` - Optional detailed description\n- `severity` - Optional: Critical, Important, Moderate, BestPractice, ManualReview, Unspecified\n- `applies_to` - Optional: array of language identifiers (e.g., [\"csharp\", \"java\"])\n\n### Pattern Types\n\n- `string` - Literal string match\n- `regex` - Regular expression\n- `regexword` - Regex with word boundaries automatically added\n- `substring` - Substring match\n\n### Pattern Best Practices\n\n1. **Use specific patterns**: Prefer specific API/class names over generic words to reduce false positives\n2. **Word boundaries**: Use `\\b` in regex patterns or `regexword` type to prevent matching substrings\n3. **Avoid catastrophic backtracking**: Don't use unlimited repetition patterns like `.*` in regex\n4. **Test cases**: Include `must-match` and `must-not-match` test cases in rules for validation\n5. **Confidence levels**: Set appropriate confidence (high, medium, low) based on pattern specificity\n6. **Scopes**: Specify appropriate scopes (code, comment) to limit false positives\n7. **Conditions**: Use conditions with `same-line` search to ensure API methods are invoked, not just referenced\n8. **Pattern for invocation**: Use `.Method(` patterns instead of `Class.Method` to catch actual usage via variables\n\n### Example Rule Pattern\n\n```json\n{\n  \"name\": \"Authentication: Microsoft (Identity)\",\n  \"id\": \"AI038900\",\n  \"description\": \"Authentication using Microsoft Identity Platform (ADAL/MSAL)\",\n  \"tags\": [\"Authentication.Microsoft.Online\"],\n  \"severity\": \"critical\",\n  \"patterns\": [\n    {\n      \"pattern\": \"microsoft\\\\.msal\",\n      \"type\": \"regexword\",\n      \"scopes\": [\"code\"],\n      \"confidence\": \"high\"\n    },\n    {\n      \"pattern\": \"AcquireTokenForClient\",\n      \"type\": \"regexword\",\n      \"scopes\": [\"code\"],\n      \"confidence\": \"high\"\n    }\n  ]\n}\n```\n\nNote: This is a simplified example. Real rules may use alternation (e.g., `pattern1|pattern2`) to match multiple alternatives in a single pattern.\n\n### Rule ID Conventions\n\n- Rule IDs follow consistent patterns within categories\n- Authentication rules: AI038900 - AI041999 range\n- Ensure new rule IDs don't conflict with existing ones\n- Sequential numbering within a category\n\n## Testing Conventions\n\n### Test Organization\n\n- Tests use xUnit framework\n- Test classes organized under `AppInspector.Tests/Commands/`\n- Test data located in `AppInspector.Tests/TestData/`\n- Use descriptive test method names that explain what is being tested\n- Use test fixtures (`IClassFixture<>`) for shared setup/teardown\n\n### Test Patterns\n\n```csharp\n[Fact]\npublic void TestMethodName_Scenario_ExpectedBehavior()\n{\n    // Arrange\n    var options = new AnalyzeOptions { /* ... */ };\n    \n    // Act\n    var result = command.GetResult();\n    \n    // Assert\n    Assert.True(result.ResultCode == AnalyzeResult.ExitCode.Success);\n}\n```\n\n## Security Considerations\n\n- **No hardcoded secrets**: Never commit credentials, API keys, or sensitive data\n- **Input validation**: Validate all user inputs, especially file paths and patterns\n- **Safe regex**: Avoid regex patterns that can cause catastrophic backtracking\n- **Secure defaults**: Use secure defaults for cryptographic operations\n- **Sanitization**: Use appropriate sanitizers (e.g., `html_escape`) to prevent injection vulnerabilities\n\n## Performance Considerations\n\n- **Regex compilation**: Consider caching compiled regex patterns for frequently used rules\n- **File I/O**: Use async I/O for file operations\n- **Memory usage**: Be mindful of memory when processing large codebases\n- **Parallel processing**: Leverage parallel processing where appropriate for scanning multiple files\n\n## Common Pitfalls to Avoid\n\n1. **Rule regex performance**: Avoid complex regex patterns that can cause performance issues on large files\n2. **False positives**: Test rules thoroughly to minimize false positive detections\n3. **Breaking changes**: Maintain backward compatibility in rule schema and command-line interface\n4. **Platform dependencies**: Ensure code works across Windows, Linux, and macOS\n5. **Resource cleanup**: Properly dispose of file handles and other resources\n\n## Code Review Checklist\n\nBefore submitting changes:\n- [ ] Code builds without errors (`dotnet build`)\n- [ ] All tests pass (`dotnet test`)\n- [ ] New rules include test cases (must-match and must-not-match)\n- [ ] New rules validate successfully (`dotnet run --project AppInspector.CLI -- verifyrules`)\n- [ ] XML documentation added for public APIs\n- [ ] No hardcoded secrets or sensitive data\n- [ ] Changes are backward compatible\n- [ ] Performance impact considered for rule changes\n\n## Useful Commands\n\n```bash\n# Verify rule syntax\ndotnet run --project AppInspector.CLI -- verifyrules -r AppInspector/rules/default/\n\n# Pack rules into single file\ndotnet run --project AppInspector.CLI -- packrules -r AppInspector/rules/default/ -o packed-rules.json\n\n# Run benchmarks\ndotnet run --project AppInspector.Benchmarks -c Release\n\n# Clean build artifacts\ndotnet clean\n```\n\n## Resources\n\n- [Project Wiki](https://github.com/microsoft/ApplicationInspector/wiki)\n- [Understanding Rules](https://github.com/microsoft/ApplicationInspector/wiki/3.-Understanding-Rules)\n- [CLI Usage](https://github.com/microsoft/ApplicationInspector/wiki/1.-CLI-Usage)\n- [NuGet Support](https://github.com/microsoft/ApplicationInspector/wiki/2.-NuGet-Support)\n- [Rule Schema](https://github.com/microsoft/ApplicationInspector/blob/main/rule-schema-v1.json)\n\n## Getting Help\n\n- Review the [CONTRIBUTING.md](https://github.com/microsoft/ApplicationInspector/blob/main/CONTRIBUTING.md) for contribution guidelines\n- Check [BUILD.md](https://github.com/microsoft/ApplicationInspector/blob/main/BUILD.md) for detailed build instructions\n- See [SECURITY.md](https://github.com/microsoft/ApplicationInspector/blob/main/SECURITY.md) for security reporting procedures\n\n<!-- File: AppInspector/rules/samples/README.md (Tokens: ~2013 | Category: anthropic-skill) -->\n# Application Inspector Sample Rules\n\nThis directory contains comprehensive sample rules that demonstrate all available fields and features for creating custom Application Inspector rules.\n\n## Files\n\n### comprehensive_sample_rule.json\n\nA maximally specified sample rule file that demonstrates:\n\n- **All top-level rule fields**: id, name, description, tags, severity, applies_to, does_not_apply_to, applies_to_file_regex, exclude_file_regex, depends_on_tags, overrides\n- **Pattern matching types**: regex, regexword, string\n- **Pattern features**: scopes, modifiers, confidence levels\n- **Conditions**: same-file matching with both positive and negative conditions\n- **Self-testing**: must-match and must-not-match arrays for validation\n- **Structured data queries**: XPath for XML, JSONPath for JSON, YAMLPath for YAML\n- **Comments**: Using _comment fields for documentation\n\n## Usage\n\nThese sample rules are for reference and learning purposes. They demonstrate the full capabilities of the Application Inspector rule format.\n\nTo use these samples:\n\n1. Copy and modify them for your specific detection needs\n2. Adjust the patterns to match your target code constructs\n3. Update the tags to fit your categorization scheme\n4. Set appropriate severity levels\n5. Add must-match/must-not-match test cases to validate your rules\n\n## Field Descriptions\n\n### Required Fields\n\n- `id`: Unique identifier for the rule (e.g., \"AI001234\")\n- `name`: Human-readable name describing what the rule detects\n- `tags`: Array of categorization tags (at least one required)\n- `patterns`: Array of search patterns (at least one required)\n\n### Optional Fields\n\n- `description`: Detailed description of what the rule detects\n- `severity`: One of: critical, important, moderate, bestpractice, manualreview, unspecified (lowercase preferred; default: moderate)\n- `applies_to`: Array of file extensions or language identifiers\n- `does_not_apply_to`: Array of file extensions or language identifiers to exclude\n- `applies_to_file_regex`: Array of regex patterns for files to include\n- `exclude_file_regex`: Array of regex patterns for files to exclude\n- `depends_on_tags`: Array of tags that must be present for this rule to apply\n- `overrides`: Array of rule IDs that this rule supersedes\n- `conditions`: Array of additional matching conditions\n- `expression`: Boolean expression combining pattern and condition labels (see [Expressions](#expressions))\n- `must-match`: Array of test strings that should match (for validation)\n- `must-not-match`: Array of test strings that should not match (for validation)\n- `_comment`: Optional comment for documentation\n\n### Pattern Fields\n\n- `pattern`: The regex/string pattern to search for (required)\n- `type`: One of: regex (default), regexword, string, substring\n- `label`: Name for this pattern, for use in `expression` (default: the pattern's index)\n- `conditions`: Array of conditions that gate only this pattern's findings\n- `scopes`: Array of: code, comment, all, html\n- `confidence`: One of: high, medium, low, unspecified\n- `modifiers`: Array of regex modifiers: i, m, s, x (or full names)\n- `xpaths`: Array of XPath expressions for XML matching\n- `jsonpaths`: Array of JSONPath expressions for JSON matching\n- `ymlpaths`: Array of YAMLPath expressions for YAML matching\n- `_comment`: Optional comment for documentation\n\n### Condition Fields\n\n- `pattern`: A pattern object (same structure as patterns array)\n- `search_in`: Where to search - \"finding-region(-offset,length)\", \"finding-only\", \"same-line\", \"same-file\", \"only-before\", \"only-after\"\n- `negate_finding`: Boolean - if true, the finding is invalid if this condition matches\n- `label`: Name for this condition, for use in `expression` (default: the condition's clause index)\n- `applies_to`: Array of languages this condition applies to (default: all)\n- `does_not_apply_to`: Array of languages this condition does not apply to\n- `_comment`: Optional comment for documentation\n\n## Expressions\n\nBy default a rule matches when **any** pattern matches and **every** rule level condition holds:\n\n```text\n(pattern0 OR pattern1 OR ...) AND condition0 AND condition1 ...\n```\n\nTwo optional features let you go beyond that shape.\n\n### Scoping a condition to one pattern\n\nDeclare the condition on the pattern it guards rather than at rule level. Other patterns are unaffected,\nso they still report even when the condition excludes this pattern's finding.\n\n```json\n\"patterns\": [\n  {\n    \"pattern\": \"curl\", \"type\": \"substring\", \"label\": \"curl\",\n    \"conditions\": [\n      {\n        \"pattern\": { \"pattern\": \"--tlsv1.3\", \"type\": \"substring\" },\n        \"search_in\": \"same-line\",\n        \"negate_finding\": true\n      }\n    ]\n  },\n  { \"pattern\": \"wget\", \"type\": \"substring\", \"label\": \"wget\" }\n]\n```\n\n### Writing the expression yourself\n\nSet `expression` to combine labels with `AND`, `OR`, `XOR`, `NAND`, `NOR` and `NOT`. This makes\notherwise inexpressible rules possible, such as a disjunction of conditions or a negated conjunction:\n\n```json\n\"expression\": \"cookie AND NOT (secure AND httponly)\"\n```\n\nThat rule fires when *either* required flag is missing. Writing it as two negated conditions would\ninstead mean \"neither flag is present\", which stays silent on partially hardened code.\n\nEvery finding is judged against the expression on its own. A file containing one correctly hardened\ncookie and one missing a flag reports the second, because the first satisfying `secure AND httponly`\nsays nothing about the second.\n\nBecause a finding originates from exactly one pattern, every *other* pattern label is false while\nthat finding is judged. An expression over pattern labels alone can therefore select which patterns\noriginate findings, but it cannot require sibling patterns to co-occur: `a AND NOT b` reports exactly\nwhat `a` reports. Conditions add co-occurrence tests because they are evaluated against each finding\nand can be true or false independently of it.\n\n### Requiring that two patterns both appear\n\nThis is why verification rejects an expression that needs two pattern labels true at once, such as\n`a AND b`. That is a normal-form requirement rather than a restriction on `AND`: a condition is a\npattern plus a search window, so a term that only has to co-occur is written as a `same-file`\ncondition instead.\n\n```json\n\"expression\": \"p AND ois\",\n\"patterns\": [\n    { \"pattern\": \"readObject\", \"type\": \"substring\", \"label\": \"p\", \"scopes\": [ \"code\" ] }\n],\n\"conditions\": [\n    { \"pattern\": { \"pattern\": \"ObjectInputStream\", \"type\": \"substring\", \"scopes\": [ \"code\" ] },\n      \"search_in\": \"same-file\", \"label\": \"ois\" }\n]\n```\n\nThat reports each `readObject`, but only in a file that also contains `ObjectInputStream`.\n\nTo report the locations of *both* terms, declare each one twice, once as a pattern so it can\noriginate a finding and once as a `same-file` condition so it can constrain the other:\n\n```json\n\"expression\": \"(a OR b) AND ca AND cb\"\n```\n\nwith patterns `a` and `b`, and same-file conditions `ca` and `cb` carrying those same two patterns.\nEvery `a` and every `b` is then reported, but only in files that contain both.\n\n> **Expressions have no operator precedence.** They are evaluated strictly left to right, so\n> `a OR b AND c` means `(a OR b) AND c`, **not** `a OR (b AND c)`. Always use parentheses to make\n> grouping explicit; rule verification rejects an expression that mixes operators at the same level\n> without them.\n\nOther rules for expressions:\n\n- Labels may not contain spaces or parentheses, and must be unique within the rule.\n- Every label named in the expression must belong to a pattern or condition in the same rule.\n- Attach parentheses to labels: `(a OR b)` is valid, `( a OR b )` is not.\n- Parentheses must be balanced.\n- A rule that sets `expression` must express negation with `NOT` rather than `negate_finding`.\n- Conditions test captured pattern findings independently of label order in the expression. For example,\n  `c AND a` and `a AND c` are equivalent when `c` is a condition and `a` is a pattern.\n\n## Best Practices\n\n1. **Use lowercase for enums**: severity, type, confidence, and scopes should use lowercase values\n2. **Populate optional fields**: Only include optional fields like `recommendation` or `_comment` if they contain meaningful content\n3. **Test your rules**: Always include must-match and must-not-match examples\n4. **Use appropriate severity**: Choose severity levels that reflect the actual impact\n5. **Use specific patterns**: Make patterns as specific as possible to reduce false positives\n6. **Document with comments**: Use `_comment` fields to explain complex patterns or conditions\n7. **Parenthesise expressions**: Expressions fold left to right with no precedence, so group explicitly\n\n## Related Documentation\n\n- [Rule Schema](../../../rule-schema-v1.json)\n- [Application Inspector Wiki](https://github.com/microsoft/ApplicationInspector/wiki)\n</yakaai_skills>"}