원클릭으로
stub-generator
Generate test stubs with PSE docstrings from STD YAML — language and framework driven by project config
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Generate test stubs with PSE docstrings from STD YAML — language and framework driven by project config
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Classify PR review comments on STP/STD documents into auto-fixable vs needs-human categories. Maps free-text feedback to QualityFlow domain rules for automated fix routing.
Resolve Jira ID to project configuration and load project context
Generate comprehensive v2.1-ENHANCED STD YAML with pattern metadata, variables, test structure from ALL STP scenarios (single file)
Orchestrate STP → STD pipeline (generates comprehensive STD YAML only)
Detect test conventions from a codebase to drive test generation without tier config
Discover code entry points from Jira data when no PR data exists
| name | stub-generator |
| description | Generate test stubs with PSE docstrings from STD YAML — language and framework driven by project config |
| model | claude-opus-4-6 |
Generates test stubs with PSE docstrings from STD YAML for design review (Phase 1). Reads project config to determine which languages and frameworks to target.
Output: Test stubs excluded from execution, containing PSE documentation (Preconditions/Steps/Expected) as the deliverable for human review.
Key Principle: The STD = the docstrings/comments in the test files (no separate document needed for review).
jira_id: Jira ticket ID (e.g., "MYPROJ-12345", "GH-2247")Prerequisites:
outputs/{JIRA_ID}/std/{JIRA_ID}_test_description.yaml{project_context.config_dir}/outputs/{JIRA_ID}/std/
├── {JIRA_ID}_test_description.yaml (STD YAML — already exists)
├── go-tests/ (if Go config enabled)
│ └── {feature}_stubs_test.go
└── python-tests/ (if Python config enabled)
└── test_{feature}_stubs.py
For other languages: outputs/{JIRA_ID}/std/{language}-tests/
Generate ONE test stub per STD scenario. No exceptions.
Pattern-based file grouping is allowed, but EVERY scenario must get a test stub in at least one language.
Load outputs/{JIRA_ID}/std/{JIRA_ID}_test_description.yaml
Extract:
len(scenarios)Scan {project_context.config_dir}/ for YAML files with
enabled: true and a language: field:
for f in {project_context.config_dir}/*.yaml; do
# Skip non-language files (project.yaml, repositories.yaml, etc.)
# A language config has: enabled, language, framework fields
done
Known file names: tier1.yaml, tier2.yaml
Each language config provides:
language — "go", "python", etc.framework — "testing", "ginkgo-v2", "pytest", etc.tier (OPTIONAL) — "Tier 1", "Tier 2", etc.imports — organized by categorydefault_package — package name for Go filesBefore mapping scenarios to language targets, remove scenarios with
coverage_status: EXISTING_COVERAGE from the working set. These represent
behaviors already covered by existing tests and do not need stubs generated.
Log the count: "Skipping {N} scenarios with existing coverage"
Scenarios with coverage_status: NEW or PARTIAL_COVERAGE (or no
coverage_status field) proceed to Step 3.
For each enabled language config:
If the config declares tier: "Tier 1" (or any tier value):
Filter STD scenarios to ONLY those matching that tier.
This is the tier-scoped mode — used by projects where
Tier 1 = Go/Ginkgo and Tier 2 = Python/pytest.
If the config has NO tier: field:
Generate stubs for ALL STD scenarios in this language.
This is the full-coverage mode — used by projects where there is a
single language and tiers are not relevant.
Result: A map of {language_config: [scenario1, scenario2, ...]}
Validation after mapping: Every STD scenario must be assigned to at least one language. If any scenario is unassigned (e.g., a Tier 2 scenario exists but no config maps to Tier 2), log a warning listing the unmapped scenarios.
For each enabled language config and its assigned scenarios, generate stub files using the appropriate framework section below.
For each scenario:
After all scenarios processed:
outputs/{JIRA_ID}/std/{language}-tests/CRITICAL VALIDATION — MANDATORY
After all files generated:
N_assignedN_stubsN_stubs == N_assigned for each languageGenerate summary per language:
Phase 1 stubs are design-only. The following MUST NOT appear:
@pytest.mark.polarion("PLACEHOLDER") when polarion: trueimport pytest when polarion: true (needed for the decorator)ginkgo-v2When framework: "ginkgo-v2" in the language config:
package {default_package} // from config
import (
. "github.com/onsi/ginkgo/v2" // from config dot_imports
)
/*
{Feature} Tests
STP: {STP_URL}
Jira: {JIRA_ID}
*/
var _ = Describe("[{JIRA_ID}] {Feature}", {domain_decorator}, func() {
/*
Markers:
- tier1
Preconditions:
- {shared preconditions}
*/
Context("{context name}", func() {
/*
Preconditions:
- {test-specific precondition}
Steps:
1. {step 1}
2. {step 2}
Expected:
- {expected outcome}
*/
PendingIt("[test_id:TS-{ID}-001] should {description}", func() {
Skip("Phase 1: Design only - awaiting implementation")
})
})
})
Rules:
default_packagedot_imports)PendingIt() with Skip() inside — excluded from execution/* */) ABOVE each PendingIt[test_id:TS-{JIRA_ID_SHORT}-{NNN}] label in descriptionDescribe block commentdecorators.SigNetwork)Output: outputs/{JIRA_ID}/std/go-tests/{feature}_stubs_test.go
testingWhen framework: "testing" in the language config:
//go:build {build_tags}
package {default_package} // from config
import "testing"
/*
{Feature} Tests
STP: {STP_URL}
Jira: {JIRA_ID}
*/
func TestFeatureName(t *testing.T) {
/*
Preconditions:
- {shared preconditions}
*/
/*
Preconditions:
- {test-specific precondition}
Steps:
1. {step 1}
2. {step 2}
Expected:
- {expected outcome}
*/
t.Run("should {description}", func(t *testing.T) {
t.Skip("Phase 1: Design only - awaiting implementation")
})
}
Rules:
default_packagebuild_tags → //go:build tag1"testing" (no testify needed for stubs)t.Skip() inside each subtest — excluded from execution/* */) ABOVE each t.Runfunc TestXxx(t *testing.T) groups related subtestsOutput: outputs/{JIRA_ID}/std/go-tests/{feature}_stubs_test.go
pytestWhen framework: "pytest" in the language config:
"""
{Feature Name} Tests
STP: {STP_URL}
Jira: {JIRA_ID}
"""
class TestFeatureName:
"""
Tests for {feature description}.
Markers:
- gating
Parametrize:
- storage_class: [default-storage-class, local-storage]
Preconditions:
- {Shared precondition 1 — resource creation}
- {Shared precondition 2 — baseline data recorded}
"""
__test__ = False
def test_specific_behavior(self):
"""
Test that {specific ONE thing being verified}.
Preconditions:
- {Test-specific precondition}
Steps:
1. {Discrete action}
Expected:
- {Concrete, verifiable assertion}
"""
Rules:
STP: as the keyword (not STP Reference:). Target repo CI checks
match on this exact keyword.__test__ = False on class level (grouped tests) or after function (standalone)pass — docstring is sufficient)def test_foo(self): — no fixture parameters in signatureimport pytest, no @pytest.fixture, no @pytest.mark.* decorators
Exception: import pytest + @pytest.mark.polarion("PLACEHOLDER") when
polarion: true in project configstp_reference.url exists in the STD YAML metadata
(set by std-orchestrator when the STP has been merged into the design-docs repo),
use that URL as {STP_URL}. Otherwise fall back to the local file path from
stp_reference.file. Merged URLs are preferred because they remain valid after
the output directory is cleaned up.python marker is implicit (NOT listed) — only list non-auto markers (e.g., gating, arm64)Markers: section only.
Include ONLY markers that will become real @pytest.mark.* decorators in Phase 2.
Priority values (P0/P1/P2) are NOT markers — they are STD metadata.
Tier classification (tier2, end_to_end) is implicit — do NOT list it.
Team/SIG markers (storage, network, compute) are implicit — do NOT list them.
If no non-implicit markers apply, omit the Markers: section entirely.Parametrize: section only[NEGATIVE] prefix for failure scenario testsStandalone test (no class needed):
def test_specific_behavior():
"""
Test that {specific ONE thing being verified}.
Steps:
1. {Discrete action}
Expected:
- {Concrete, verifiable assertion}
"""
test_specific_behavior.__test__ = False
Output: outputs/{JIRA_ID}/std/python-tests/test_{feature}_stubs.py
Specialized tests use the same Python/pytest framework as End-to-End tests. The stub-generator treats Specialized scenarios identically to End-to-End scenarios for stub generation. The distinction is documented via markers:
class TestSpecializedFeature:
"""
Tests for {feature description} (Specialized).
Markers:
- specialized
- {hardware_marker}
Preconditions:
- {Hardware-specific precondition}
"""
__test__ = False
def test_specific_behavior(self):
"""
Test that {specific ONE thing being verified}.
Preconditions:
- {Specialized infrastructure precondition}
Steps:
1. {Discrete action}
Expected:
- {Concrete, verifiable assertion}
"""
The specialized marker and any hardware-specific markers (gpu, sriov,
numa, ceph, etc.) are documented in the docstring Markers: section.
When project_context.repo_rules is available, the following rules
from the target repository's AGENTS.md override defaults:
python is implicit — Do NOT add @pytest.mark.python. Do NOT
include python in the Markers docstring section.pytest.skip/skipif are forbidden — Do not use in generated code.@pytest.mark.incremental for dependent tests within a class.resource_with_storage, not create_resource_with_storage.Class-level Preconditions include ONLY test-specific setup:
Do NOT include:
Tests assume the test environment described in the STP is already in place. Tests that share the same setup MUST be grouped in one class.
Shared Resource Repetition Rule: When a test method's Steps or Expected
reference a resource declared in the shared (class-level) Preconditions, that
resource MUST also appear in the test method's own Preconditions: section.
This follows the repo convention: "When a shared resource (e.g., a VM) is
directly used by a test, it must appear in both the shared and test-level
preconditions."
Use functional language for the repeated precondition — describe the state, not the mechanism:
Preconditions:\n - VM with Velero backup hooks disabledPreconditions:\n - VM with per-VM opt-out annotation setAll precondition text in stubs MUST describe the test state from the user's perspective, not the implementation mechanism. Apply the same rewrite principles as the STP Pre-Writing Abstraction Pass:
| Implementation Language | Functional Language |
|---|---|
| "per-VM opt-out annotation" | "VM with backup hooks disabled" |
| "CRD with spec.sourcePartition set" | "restore request targeting a specific partition" |
| "controller reconciles the CR" | "restore request is processed" |
| "rsync connection established" | "file transfer connection ready" |
| "filerestore.sh helper deployed" | "restore helper available on target VM" |
This applies to BOTH shared (class-level) and test-specific preconditions.
When polarion: true in the project's feature toggles, every test function MUST have
a @pytest.mark.polarion("PLACEHOLDER") decorator. This is the only @pytest.mark
decorator allowed in Phase 1 stubs.
When enabled, add import pytest at the top of each file and decorate every test:
import pytest
class TestFeatureName:
"""..."""
__test__ = False
@pytest.mark.polarion("PLACEHOLDER")
def test_specific_behavior(self):
"""
Test that {specific ONE thing being verified}.
...
"""
For standalone tests:
@pytest.mark.polarion("PLACEHOLDER")
def test_standalone_behavior():
"""..."""
test_standalone_behavior.__test__ = False
When polarion: false (or not set): Do NOT add the marker or import pytest.
The "PLACEHOLDER" value is intentional — it will be replaced with the actual Polarion
test case ID during Phase 2 implementation or by CI tooling.
Enforcement: When polarion: true, the stub-generator MUST NOT output any
Python test stub file without import pytest at the top and
@pytest.mark.polarion("PLACEHOLDER") on every def test_* function. Omitting
the marker is a generation error — Polarion-integrated projects require it for
test case traceability.
When tests within a class depend on execution order, use @pytest.mark.incremental
in the class Markers docstring section:
class TestSomeFeature:
"""
Tests for feature with ordered dependencies.
Markers:
- incremental
Preconditions:
- Running resource with feature configured
"""
__test__ = False
def test_resource_is_created(self):
"""Test that a resource with feature can be created."""
def test_resource_migration(self):
"""Test that a resource with feature can be migrated."""
If project_context.feature_toggles.polarion is false, omit Polarion
marker references from stubs (both Go and Python).
These rules are mandatory and apply to ALL frameworks. They define what goes in each PSE section regardless of language.
Single-Expected Rule: Each test MUST have exactly ONE Expected: statement
that captures the unified behavioral outcome. When the STD YAML assertions array
contains multiple entries, consolidate them into a single sentence describing the
overall expected result. The individual assertions inform the implementation (Phase 2),
not the design (Phase 1).
Expected:\n - Backup completes with status Completed\n - No hooks executedExpected: Backup completes successfully without hook executionIf multiple assertions test genuinely different aspects, that is a signal that the scenario should be split into separate tests (one per aspect). Flag this during generation and produce separate stubs.
Baseline vs Outcome verification:
| Action | PSE Section | Example |
|---|---|---|
| Create resource/config/pod | Preconditions | "Running resource with secondary interface" |
| Record baseline data | Preconditions | "Identifier and interface name recorded" |
| Verify baseline state | Preconditions | "Resource is in Ready state before test action" |
| Patch/Update resource | Steps | "Update resource spec to reference target config" |
| Wait for completion | Steps | "Wait for operation to complete" |
| Execute command | Steps | "Ping from resource-A to resource-B" |
| Verify/Confirm outcome | Expected | "Ping succeeds with 0% packet loss" |
| Assert state | Expected | "Resource is ready after operation" |
| STD YAML Field | PSE Section | Transformation |
|---|---|---|
test_objective.title | Brief description | "Test that {title}" (Python) / "should {title}" (Go) |
specific_preconditions[*].requirement | Preconditions | Bullet list |
test_steps.setup | Preconditions (context) | Add to preconditions |
test_steps.test_execution[*].action | Steps | Numbered list — filter "Verify/Confirm" actions to Expected |
test_objective.acceptance_criteria[0] | Expected | Natural language |
assertions[*].description | Expected (fallback) | Natural language |
| Title contains "fail"/"error"/"negative" | [NEGATIVE] marker | Prefix in description |
| Wording Pattern | Maps To |
|---|---|
X equals Y | assert x == y |
X does not equal Y | assert x != y |
Resource is "Ready" | assert resource.status == Ready |
File exists / Resource x exists | assert exists(x) |
X contains Y | assert y in x |
Ping succeeds / Operation succeeds | assert operation() (no exception) |
Ping fails / Operation fails | assert raises exception or returns failure |
Stub generation succeeds when:
[NEGATIVE]outputs/{JIRA_ID}/std/{language}-tests/STD not found:
/std-builder {JIRA_ID} first"No language configs found:
enabled: true"Unmapped scenarios (warning, not fatal):
End of Stub Generator Skill