{"slug":"test-tagging","title":"test-tagging","summary":"Analyzes test suites in any language and tags each test with standardized traits (positive, negative, critical-path, boundary, smoke, regression, integration, performance, security). Use when the user wants to categorize, audit, or label tests with traits. Works across .NET (MSTe","platform":"Claude","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-08-24T05:37:34.70507Z","repo":{"url":"https://github.com/dotnet/skills","stars":5471,"forks":418,"license":"MIT","updatedAt":"2026-09-24T06:38:55Z"},"bodyHtml":"<hr>\n<h2>name: test-tagging\ndescription: \"Analyzes test suites in any language and tags each test with standardized traits (positive, negative, critical-path, boundary, smoke, regression, integration, performance, security). Use when the user wants to categorize, audit, or label tests with traits. Works across .NET (MSTest/xUnit/NUnit/TUnit), Python (pytest), TS/JS (Jest/Vitest), Java, Go, Ruby, Rust, Swift, Kotlin, PowerShell, and C++ — auto-editing when the framework has canonical tag syntax, otherwise report-only. Do not use for writing new tests, running tests, or migrating frameworks.\"\nlicense: MIT</h2>\n<h1>Test Trait Tagging</h1>\n<p>Analyze an existing test suite in any supported language and apply a standardized set of trait tags to each test method, giving teams visibility into their test distribution (positive vs. negative, critical-path coverage, smoke tests, etc.).</p>\n<blockquote>\n<p><strong>Language-specific guidance</strong>: Call the <code>test-analysis-extensions</code> skill to discover available extension files, then read the file matching the target codebase. The extension file documents framework-specific tag attributes and a \"tag-support capability\" (auto-edit, report-only, or convention-based) that drives whether this skill modifies source files or only emits a report.</p>\n</blockquote>\n<h2>When to Use</h2>\n<ul>\n<li>Auditing a test project to understand the mix of test types</li>\n<li>Adding trait attributes to untagged tests</li>\n<li>Generating a summary report of trait distribution across a test suite</li>\n<li>Reviewing whether critical paths have sufficient coverage</li>\n</ul>\n<h2>When Not to Use</h2>\n<ul>\n<li>Writing new tests from scratch (use <code>code-testing-agent</code> for any language, or <code>writing-mstest-tests</code> for MSTest)</li>\n<li>Running or filtering tests (use <code>run-tests</code> for .NET; equivalent native runners elsewhere)</li>\n<li>Migrating between test frameworks</li>\n</ul>\n<h2>Inputs</h2>\n<table>\n<thead>\n<tr>\n<th>Input</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Test project or files</td>\n<td>Yes</td>\n<td>Path to the test project, folder, or specific test files to analyze</td>\n</tr>\n<tr>\n<td>Scope</td>\n<td>No</td>\n<td><code>tag</code> (apply attributes when language supports auto-edit), <code>audit</code> (report only), or <code>both</code> (default: <code>both</code>). For languages with no canonical tag syntax, the skill emits a report regardless of scope.</td>\n</tr>\n<tr>\n<td>Framework</td>\n<td>No</td>\n<td>Auto-detected. Override when detection fails.</td>\n</tr>\n</tbody>\n</table>\n<h2>Trait Taxonomy</h2>\n<p>Use exactly these trait names and values. Do not invent new trait values outside this table.</p>\n<table>\n<thead>\n<tr>\n<th>Trait Value</th>\n<th>Meaning</th>\n<th>Heuristics</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>positive</code></td>\n<td>Verifies expected behavior under normal/valid conditions</td>\n<td>Asserts success, valid output, expected state, no exceptions for valid input</td>\n</tr>\n<tr>\n<td><code>negative</code></td>\n<td>Verifies correct handling of invalid input, errors, or edge cases</td>\n<td>Asserts exceptions, error codes, validation failures, rejects bad input</td>\n</tr>\n<tr>\n<td><code>boundary</code></td>\n<td>Tests limits, thresholds, empty/null/None/nil inputs, min/max values</td>\n<td>Operates on <code>0</code>, <code>-1</code>, <code>int.MaxValue</code> / <code>sys.maxsize</code> / <code>Number.MAX_SAFE_INTEGER</code> / <code>math.MaxInt64</code> / <code>i32::MAX</code>, empty string, null/None/nil/undefined, empty collection, boundary of valid range</td>\n</tr>\n<tr>\n<td><code>critical-path</code></td>\n<td>Core workflow that must never break; breakage blocks users</td>\n<td>Tests the primary success scenario of a key public API or user-facing feature</td>\n</tr>\n<tr>\n<td><code>smoke</code></td>\n<td>Quick sanity check that the system is operational</td>\n<td>Fast, no complex setup, verifies basic wiring (e.g., service resolves, endpoint returns 200)</td>\n</tr>\n<tr>\n<td><code>regression</code></td>\n<td>Reproduces a specific previously-reported bug</td>\n<td>References a bug ID, issue number, or describes a fix in its name or comments</td>\n</tr>\n<tr>\n<td><code>integration</code></td>\n<td>Crosses process, network, or persistence boundaries</td>\n<td>Uses real database, HTTP client, file system, external service, or multi-component setup</td>\n</tr>\n<tr>\n<td><code>end-to-end</code></td>\n<td>Full user workflow spanning the entire application stack</td>\n<td>Exercises a complete scenario from entry point to final result, distinct from single-boundary <code>integration</code></td>\n</tr>\n<tr>\n<td><code>performance</code></td>\n<td>Validates timing, throughput, or resource consumption</td>\n<td>Asserts on elapsed time, memory, allocations, or uses benchmark harness (BenchmarkDotNet, pytest-benchmark, benchmark.js, JMH, <code>go test -bench</code>, criterion.rs, XCTMetric, kotlinx-benchmark, Google Benchmark)</td>\n</tr>\n<tr>\n<td><code>security</code></td>\n<td>Verifies authentication, authorization, input sanitization, or secrets handling</td>\n<td>Tests for SQL injection, XSS, CSRF, unauthorized access, token validation, permission checks</td>\n</tr>\n<tr>\n<td><code>concurrency</code></td>\n<td>Validates thread safety, parallelism, or async correctness</td>\n<td>Uses <code>Task.WhenAll</code> / <code>Parallel.ForEach</code> / <code>SemaphoreSlim</code> (.NET); <code>asyncio.gather</code> / <code>threading.Lock</code> / <code>multiprocessing</code> (Python); <code>Promise.all</code> / worker threads (JS/TS); <code>CompletableFuture</code> / <code>ExecutorService</code> / <code>synchronized</code> (Java); <code>go func</code> / <code>sync.WaitGroup</code> / <code>sync.Mutex</code> / <code>chan</code> (Go); <code>Mutex</code> / <code>Thread.new</code> (Ruby); <code>tokio::spawn</code> / <code>Arc&lt;Mutex&lt;_&gt;&gt;</code> / <code>crossbeam</code> (Rust); <code>DispatchQueue</code> / <code>actor</code> (Swift); <code>coroutineScope</code> / <code>Mutex</code> (Kotlin); <code>Start-Job</code> / <code>RunspacePool</code> (PowerShell); <code>std::thread</code> / <code>std::mutex</code> (C++); reproduces race conditions</td>\n</tr>\n<tr>\n<td><code>resilience</code></td>\n<td>Tests retry logic, timeouts, circuit breakers, or graceful degradation</td>\n<td>Asserts behavior under transient failures, network drops, or service unavailability (e.g., Polly, tenacity, p-retry, resilience4j, hystrix, opossum, retry-go)</td>\n</tr>\n<tr>\n<td><code>destructive</code></td>\n<td>Mutates shared or external state that is hard to roll back</td>\n<td>Deletes records, drops resources, modifies global config -- useful for CI isolation decisions</td>\n</tr>\n<tr>\n<td><code>configuration</code></td>\n<td>Verifies settings loading, defaults, environment behavior</td>\n<td>Tests missing config keys, invalid values, environment variable fallbacks, options validation</td>\n</tr>\n<tr>\n<td><code>flaky</code></td>\n<td>Known to intermittently fail (meta-tag for test health tracking)</td>\n<td>Mark tests the team knows are unreliable; used to quarantine or prioritize stabilization</td>\n</tr>\n</tbody>\n</table>\n<p>A single test may have <strong>multiple traits</strong> (e.g., both <code>negative</code> and <code>boundary</code>). At minimum, every test should receive one of <code>positive</code> or <code>negative</code>.</p>\n<h2>Workflow</h2>\n<h3>Step 1: Detect the language, framework, and tagging capability</h3>\n<p>Identify the codebase's language and test framework. Call the <code>test-analysis-extensions</code> skill and read the matching extension file. The extension file declares a <strong>tag-support capability</strong> for each framework:</p>\n<ul>\n<li><strong><code>auto-edit</code></strong> — framework has canonical tag syntax this skill can safely insert (.NET <code>[TestCategory]</code> / <code>[Trait]</code> / <code>[Category]</code> / <code>[Property]</code>, pytest <code>@pytest.mark.&lt;name&gt;</code>, JUnit 5 <code>@Tag(\"...\")</code>, TestNG <code>groups = {\"...\"}</code>, RSpec metadata <code>it \"...\" , :tag =&gt; true</code>, Pester <code>-Tag '...'</code>, Kotest <code>@Tags(...)</code>, Swift Testing <code>@Tag(.tagName)</code>, Catch2 <code>[tag]</code>, doctest <code>* doctest::test_suite(\"tag\")</code> decorator).</li>\n<li><strong><code>report-only</code></strong> — framework has no canonical, agreed-upon tag attribute; report tags in a Markdown table only and do not edit source (Go standard <code>testing</code> without build-tag conventions, Jest/Vitest without consistent describe-prefix convention, Rust without project-specific cfg conventions, XCTest without a test plan, GoogleTest without test-name prefix conventions, Mocha without describe-prefix conventions).</li>\n<li><strong><code>convention-based</code></strong> — framework uses naming or file conventions for tagging (Go <code>//go:build integration</code> build tags, file-name suffixes like <code>*_integration_test.go</code>, GoogleTest <code>INTEGRATION_*</code> filter prefix). Only emit canonical edits when the user has confirmed the project convention; otherwise treat as <code>report-only</code>.</li>\n</ul>\n<p>Capture the capability before Step 4.</p>\n<h3>Step 2: Scan existing traits</h3>\n<p>Check which tests already have trait attributes. Use the loaded language extension as the source of truth — examples:</p>\n<table>\n<thead>\n<tr>\n<th>Framework</th>\n<th>Existing Attribute</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>MSTest</td>\n<td><code>[TestCategory(\"...\")]</code></td>\n<td><code>[TestCategory(\"positive\")]</code></td>\n</tr>\n<tr>\n<td>xUnit</td>\n<td><code>[Trait(\"Category\", \"...\")]</code></td>\n<td><code>[Trait(\"Category\", \"positive\")]</code></td>\n</tr>\n<tr>\n<td>NUnit</td>\n<td><code>[Category(\"...\")]</code></td>\n<td><code>[Category(\"positive\")]</code></td>\n</tr>\n<tr>\n<td>TUnit</td>\n<td><code>[Property(\"Category\", \"...\")]</code></td>\n<td><code>[Property(\"Category\", \"positive\")]</code></td>\n</tr>\n<tr>\n<td>JUnit 5</td>\n<td><code>@Tag(\"...\")</code></td>\n<td><code>@Tag(\"positive\")</code></td>\n</tr>\n<tr>\n<td>TestNG</td>\n<td><code>@Test(groups = {\"...\"})</code></td>\n<td><code>@Test(groups = {\"positive\"})</code></td>\n</tr>\n<tr>\n<td>pytest</td>\n<td><code>@pytest.mark.&lt;name&gt;</code></td>\n<td><code>@pytest.mark.positive</code></td>\n</tr>\n<tr>\n<td>RSpec</td>\n<td>metadata after <code>it</code></td>\n<td><code>it \"...\", :positive do</code></td>\n</tr>\n<tr>\n<td>Pester</td>\n<td><code>-Tag '...'</code></td>\n<td><code>It '...' -Tag 'positive'</code></td>\n</tr>\n<tr>\n<td>Kotest</td>\n<td><code>@Tags(...)</code></td>\n<td><code>@Tags(Positive)</code></td>\n</tr>\n<tr>\n<td>Swift Testing</td>\n<td><code>@Tag(.&lt;name&gt;)</code></td>\n<td><code>@Test(.tags(.positive))</code></td>\n</tr>\n<tr>\n<td>Catch2</td>\n<td><code>[tag]</code> in name</td>\n<td><code>TEST_CASE(\"...\", \"[positive]\")</code></td>\n</tr>\n<tr>\n<td>doctest</td>\n<td><code>* doctest::test_suite(\"...\")</code> decorator</td>\n<td><code>TEST_CASE(\"...\" *doctest::test_suite(\"positive\"))</code></td>\n</tr>\n</tbody>\n</table>\n<p>Record which tests already have tags to avoid duplication.</p>\n<h3>Step 3: Classify each test method</h3>\n<p>For each test method without traits, analyze:</p>\n<ol>\n<li><strong>Method name</strong> -- names containing <code>Invalid</code>, <code>Fail</code>, <code>Error</code>, <code>Throw</code>, <code>Reject</code>, <code>BadInput</code>, <code>Null</code>, <code>None</code>, <code>Nil</code>, <code>Negative</code>, <code>raises_</code>, <code>_throws_</code>, <code>_returns_error</code> suggest <code>negative</code></li>\n<li><strong>Assertion type</strong> -- <code>Assert.ThrowsException</code> / <code>Assert.Throws</code> / <code>Should().Throw()</code> / <code>pytest.raises</code> / <code>expect(fn).toThrow</code> / <code>assertThrows</code> / <code>assert.Error(t, err)</code> / <code>expect { ... }.to raise_error</code> / <code>#[should_panic]</code> / <code>XCTAssertThrowsError</code> / <code>Should -Throw</code> / <code>EXPECT_THROW</code> suggest <code>negative</code></li>\n<li><strong>Input values</strong> -- <code>null</code> / <code>None</code> / <code>nil</code> / <code>undefined</code>, <code>\"\"</code>, <code>0</code>, <code>-1</code>, <code>int.MaxValue</code> / <code>sys.maxsize</code> / <code>Number.MAX_SAFE_INTEGER</code> / <code>math.MaxInt64</code> / <code>i32::MAX</code>, empty collections suggest <code>boundary</code></li>\n<li><strong>Setup complexity</strong> -- minimal setup with basic assertions suggests <code>smoke</code>; external dependencies (file/db/net/env) suggest <code>integration</code></li>\n<li><strong>Comments and names</strong> -- references to issue numbers or \"regression\" / \"bug\" / \"fix for #...\" suggest <code>regression</code></li>\n<li><strong>Timing assertions</strong> -- <code>Stopwatch</code>, <code>BenchmarkDotNet</code>, elapsed-time checks; pytest-benchmark fixtures; benchmark.js; JMH <code>@Benchmark</code>; <code>go test -bench</code>; criterion.rs; XCTMetric; Google Benchmark; kotlinx-benchmark suggest <code>performance</code></li>\n<li><strong>Feature centrality</strong> -- tests on primary public API entry points or critical user workflows suggest <code>critical-path</code></li>\n<li><strong>Security patterns</strong> -- validates auth, checks permissions, sanitizes input, tests for injection, handles tokens/secrets suggest <code>security</code></li>\n<li><strong>Parallel/async constructs</strong> -- per-language concurrency primitives (see Trait Taxonomy table) suggest <code>concurrency</code></li>\n<li><strong>Fault injection</strong> -- simulates failures, tests retries, timeouts, or circuit breakers suggest <code>resilience</code></li>\n<li><strong>State mutation</strong> -- deletes external records, drops resources, modifies shared/global state suggest <code>destructive</code></li>\n<li><strong>Full-stack flow</strong> -- test spans entry point through data layer to final response, covering a complete user scenario suggest <code>end-to-end</code></li>\n<li><strong>Config/settings</strong> -- loads configuration, tests missing keys, validates options, checks environment variables suggest <code>configuration</code></li>\n<li><strong>Known instability</strong> -- test has skip / ignore annotations with comments about flakiness, or names contain \"flaky\" / \"intermittent\" suggest <code>flaky</code></li>\n<li><strong>Default</strong> -- if the test verifies a normal success path, tag <code>positive</code></li>\n</ol>\n<p>When in doubt between <code>positive</code> and <code>negative</code>, read the assertion: if it asserts success -&gt; <code>positive</code>; if it asserts failure -&gt; <code>negative</code>.</p>\n<h3>Step 4: Apply trait attributes (or report only)</h3>\n<p><strong>If the loaded language extension declares <code>auto-edit</code> for the framework</strong>, add the appropriate attribute to each test method. Place trait attributes adjacent to the existing test attribute. Examples:</p>\n<p><strong>MSTest:</strong></p>\n<pre><code>[TestMethod]\n[TestCategory(\"negative\")]\n[TestCategory(\"boundary\")]\npublic void Parse_NullInput_ThrowsArgumentNullException() { ... }\n</code></pre>\n<p><strong>xUnit:</strong></p>\n<pre><code>[Fact]\n[Trait(\"Category\", \"positive\")]\n[Trait(\"Category\", \"critical-path\")]\npublic void CreateOrder_ValidItems_ReturnsConfirmation() { ... }\n</code></pre>\n<p><strong>NUnit:</strong></p>\n<pre><code>[Test]\n[Category(\"regression\")]\n[Category(\"negative\")]\npublic void Calculate_OverflowInput_ReturnsError() // Fix for #1234\n{ ... }\n</code></pre>\n<p><strong>pytest:</strong></p>\n<pre><code>@pytest.mark.negative\n@pytest.mark.boundary\ndef test_parse_none_input_raises_value_error():\n    ...\n</code></pre>\n<p><strong>JUnit 5:</strong></p>\n<pre><code>@Test\n@Tag(\"positive\")\n@Tag(\"critical-path\")\nvoid createOrder_validItems_returnsConfirmation() { ... }\n</code></pre>\n<p><strong>TestNG:</strong></p>\n<pre><code>@Test(groups = {\"negative\", \"boundary\"})\npublic void parse_nullInput_throwsIllegalArgumentException() { ... }\n</code></pre>\n<p><strong>RSpec:</strong></p>\n<pre><code>it \"rejects null input\", :negative, :boundary do\n  ...\nend\n</code></pre>\n<p><strong>Pester:</strong></p>\n<pre><code>It 'Rejects null input' -Tag 'negative','boundary' {\n    ...\n}\n</code></pre>\n<p><strong>Kotest:</strong></p>\n<pre><code>@Tags(Negative, Boundary)\nclass ParserSpec : StringSpec({\n    \"rejects null input\" { ... }\n})\n</code></pre>\n<p><strong>Swift Testing:</strong></p>\n<pre><code>@Test(.tags(.negative, .boundary))\nfunc parseNullInputThrows() throws { ... }\n</code></pre>\n<p><strong>Catch2:</strong></p>\n<pre><code>TEST_CASE(\"Parse null input throws\", \"[negative][boundary]\") { ... }\n</code></pre>\n<p><strong>If the loaded language extension declares <code>report-only</code> for the framework</strong> (Go standard <code>testing</code>, plain Jest/Vitest without convention, Rust without project-specific cfg, plain XCTest, plain GoogleTest, plain Mocha), do NOT modify source files. Instead emit a Markdown table mapping each test to its suggested tags, and recommend a project-wide convention the team can adopt (build tags, file suffix, describe-block prefix, GoogleTest filter prefix, test-plan grouping, etc.).</p>\n<p><strong>If the loaded language extension declares <code>convention-based</code></strong> (e.g., Go <code>//go:build integration</code>, <code>*_integration_test.go</code>, GoogleTest <code>INTEGRATION_*</code> prefix), only emit canonical edits when the user has confirmed the project's convention. Otherwise treat as <code>report-only</code>.</p>\n<h3>Step 5: Generate trait summary</h3>\n<p>After tagging, produce a summary table:</p>\n<pre><code>## Trait Distribution\n\n| Trait         | Count | % of Total |\n|---------------|-------|------------|\n| positive      |    42 |      53.8% |\n| negative      |    22 |      28.2% |\n| boundary      |     8 |      10.3% |\n| critical-path |    12 |      15.4% |\n| smoke         |     3 |       3.8% |\n| regression    |     5 |       6.4% |\n| integration   |     4 |       5.1% |\n| end-to-end    |     2 |       2.6% |\n| performance   |     1 |       1.3% |\n| security      |     3 |       3.8% |\n| concurrency   |     2 |       2.6% |\n| resilience    |     1 |       1.3% |\n| destructive   |     1 |       1.3% |\n| configuration |     2 |       2.6% |\n| flaky         |     1 |       1.3% |\n| **Total tests** | **78** | -- |\n\nNote: Percentages exceed 100% because tests can have multiple traits.\n</code></pre>\n<p>Include observations such as:</p>\n<ul>\n<li>Ratio of positive to negative tests</li>\n<li>Whether critical-path tests exist for key public APIs</li>\n<li>Any tests that could not be confidently classified (list them for manual review)</li>\n</ul>\n<h2>Validation</h2>\n<ul>\n<li><input disabled=\"disabled\" type=\"checkbox\"> Every test method has at least one trait classification (<code>positive</code> or <code>negative</code> at minimum) — in the report for <code>report-only</code> frameworks, or as an attribute for <code>auto-edit</code> frameworks</li>\n<li><input disabled=\"disabled\" type=\"checkbox\"> No invented trait values outside the taxonomy table</li>\n<li><input disabled=\"disabled\" type=\"checkbox\"> Existing trait attributes were preserved, not duplicated</li>\n<li><input disabled=\"disabled\" type=\"checkbox\"> The trait summary table was generated</li>\n<li><input disabled=\"disabled\" type=\"checkbox\"> For <code>auto-edit</code> frameworks, the project still builds / tests still discover after changes (<code>dotnet build</code> / <code>pytest --collect-only</code> / <code>mvn test-compile</code> / <code>go vet ./...</code> / <code>cargo check --tests</code> / <code>npm run test:list</code> / <code>Invoke-Pester -PassThru -Skip</code> / equivalent)</li>\n<li><input disabled=\"disabled\" type=\"checkbox\"> For <code>report-only</code> frameworks, no source files were modified</li>\n<li><input disabled=\"disabled\" type=\"checkbox\"> For <code>convention-based</code> frameworks, edits were applied ONLY when a project convention was confirmed</li>\n</ul>\n<h2>Common Pitfalls</h2>\n<table>\n<thead>\n<tr>\n<th>Pitfall</th>\n<th>Solution</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Guessing traits without reading the test body</td>\n<td>Always read assertions and setup to classify accurately</td>\n</tr>\n<tr>\n<td>Tagging a test only as <code>boundary</code> without <code>positive</code>/<code>negative</code></td>\n<td>Every test should also be <code>positive</code> or <code>negative</code> -- <code>boundary</code> is additive</td>\n</tr>\n<tr>\n<td>Using the wrong attribute syntax for the detected framework</td>\n<td>Match the attribute style to the loaded language extension (don't put <code>[TestCategory]</code> in an xUnit project or <code>@pytest.mark.x</code> in a unittest test)</td>\n</tr>\n<tr>\n<td>Duplicating an existing category attribute</td>\n<td>Check for pre-existing traits in Step 2 before adding</td>\n</tr>\n<tr>\n<td>Over-tagging as <code>critical-path</code></td>\n<td>Reserve for tests on primary public entry points, not every helper</td>\n</tr>\n<tr>\n<td>Editing Go / plain Jest / plain Rust / plain XCTest / plain GoogleTest source</td>\n<td>These are <code>report-only</code> by default — emit a Markdown table instead. Only edit if the user confirms a project-wide convention (build tag, file suffix, describe-prefix, test-plan grouping).</td>\n</tr>\n<tr>\n<td>Inventing tag prefixes for convention-based frameworks</td>\n<td>Confirm the project's existing convention before adopting one — don't guess between <code>_integration_test.go</code>, <code>//go:build integration</code>, or <code>IntegrationTest</code> prefix</td>\n</tr>\n<tr>\n<td>Missing language-specific concurrency / async primitives</td>\n<td>Each language has its own primitives — read the loaded language extension and the Trait Taxonomy concurrency row before classifying as <code>concurrency</code></td>\n</tr>\n</tbody>\n</table>\n","files":[{"path":"SKILL.md","sizeBytes":21432,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"clean","suspicious":0,"notes":0,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-09-11T07:27:43.657899Z","sha256":"1C7E94AD6627DF8F103D52C7D0CC11F3CBCA7DEF127947E9AAD8FEA328B01AB0","sizeBytes":8622},"review":null,"source":{"repositoryUrl":"https://github.com/dotnet/skills","path":"plugins/dotnet-test/skills/test-tagging","license":"MIT","commit":"e115891bd2ac3c7eefd5e30a405f7b5638f5e429","subtreeSha":"753B1ED06CDDA673BA00B069DF3AEBEA7D606679A91EE485607BB7C1EB1BBDFB","lastSyncedAt":"2026-09-24T06:48:49.987562Z"},"reviewedAt":"2026-09-11T07:29:12.99717Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/dotnet/skills/tree/main/plugins/dotnet-test/skills/test-tagging"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install dotnet-skills@llmmart"},{"target":"git","command":"git clone https://github.com/dotnet/skills.git"}]}