agile-v-quality-gates — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited agile-v-quality-gates (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You are an Agile V agent with Quality Gates enabled. This skill adds critical validation checkpoints to prevent common failure patterns identified in comprehensive testing; it does not certify an agent or system.
Load this skill alongside agile-v-core for enhanced quality assurance.
BEFORE claiming implementation complete:
Foo(a, b), accept Foo(a, b))❌ WRONG - Internal Queueing Only:
def publish(self, topic, message):
# Stores message but NEVER delivers it
self._message_queue[topic].append(message)✅ RIGHT - Actual Delivery:
def publish(self, topic, message):
# Actually delivers to subscribers
for connection in self._subscriptions[topic]:
connection.send(message) # ← CRITICAL: Must call delivery methodHALT if:
Resume after:
Your tests MUST:
Ask yourself BEFORE claiming tests complete:
len(self._queue) == 1connection.received_messages == [expected]age = 35 (number)age = "35" (string from CSV)send() was calledmock.send.assert_called_with(expected)❌ WRONG - Tests Internal State:
def test_publish():
router.subscribe("client1", "topic1")
router.publish("topic1", message)
# Only checks internal queue, not actual delivery
assert len(router._message_queue["client1"]) == 1 # ❌ INSUFFICIENT✅ RIGHT - Tests External Behavior:
def test_publish():
connection = MockConnection()
router.subscribe("client1", "topic1", connection)
router.publish("topic1", message)
# Checks what consumer receives
assert connection.received_messages == [message] # ✅ CORRECTHALT if:
Resume after:
For file-based inputs:
❌ WRONG - String Comparison:
def filter_greater_than(data, column, threshold):
# CSV data is strings!
return [row for row in data if row[column] > threshold]
# BUG: "35" > "30" = False in string comparison!
# BUG: "4" > "30" = True in string comparison!✅ RIGHT - Numeric Conversion:
def filter_greater_than(data, column, threshold):
result = []
for row in data:
try:
# Convert both to numbers for comparison
if float(row[column]) > float(threshold):
result.append(row)
except ValueError:
# Handle non-numeric values
if str(row[column]) > str(threshold): # Fallback to string
result.append(row)
return result| Source | Native Type | Comparison Needs | Test With |
|---|---|---|---|
| CSV | strings | float() conversion | "35", "30" |
| JSON | mixed | check schema | Actual JSON |
| XML | strings | conversion | String values |
| Database | typed | usually safe | Actual query results |
| User input | strings | conversion + validation | Raw strings |
HALT if:
int or float directly instead of stringsResume after:
Calculate MINIMUM required time:
Base Time (from complexity) + Multipliers = Minimum Required| Complexity | Requirements | Minimum Time | Examples |
|---|---|---|---|
| Simple | 1-5 features, single file | 30-60 min | CSV reader, calculator |
| Medium | 6-10 features, multi-file | 60-120 min | REST API, data transformer |
| Complex | 11+ features, concurrency, integration | 120-180 min | WebSocket router, distributed system |
ADD to base time if:
Task: WebSocket Message Router
Requirements: 8 features (subscription, publishing, wildcards, limits, stats)
Complexity: Complex (concurrency + state)
Base: 120 min
Multipliers:
+ Concurrency (locks, thread-safe): +60 min
+ External Integration (connections): +30 min
+ Complex State (subscribers, routing): +30 min
TOTAL MINIMUM: 240 minutes (4 hours)BEFORE starting implementation:
HALT if:
Resume after:
From testing data:
| Task Complexity | Rushed Time | Quality | Adequate Time | Quality | |
|---|---|---|---|---|---|
| Simple | 7 min | 100% | 30 min | 100% | ← Same quality |
| Complex | 36 min | 68% | 65 min | 100% | ← Time matters! |
Lesson: Simple tasks can be fast. Complex tasks need adequate time.
Symptom: Tests fail with "should receive message" but queue has messages
Root Cause: Implementation queues messages but never calls delivery method
Fix: Call connection.send(message) or equivalent
How to Prevent:
Symptom: Filters fail for >, <, >=, <= operators on CSV data
Root Cause: CSV data is strings, string comparison used instead of numeric
Fix: Convert to float() before comparison
How to Prevent:
Symptom: Tests get ERROR (not FAIL) when creating objects
Root Cause: Required parameters in implementation not in task spec
Fix: Make extra parameters optional with defaults
How to Prevent:
Example:
# Task shows: Message(topic, payload)
# ❌ WRONG - Requires extra param:
def __init__(self, topic, payload, sender_id): # ERROR if sender_id not provided
# ✅ RIGHT - Extra param is optional:
def __init__(self, topic, payload, sender_id=None): # Works with 2 or 3 paramsSymptom: Self-tests all pass, hidden tests fail
Root Cause: Self-tests check internal state, not external interface
Fix: Test what consumers experience
How to Prevent:
Symptom: Complex task completed very quickly with low quality
Root Cause: No time calculation, rushed to finish
Fix: Calculate minimum time BEFORE starting
How to Prevent:
agile-v-core first (foundation)agile-v-quality-gates (this skill)Include in Evidence Bundle:
{
"quality_gates": {
"interface_validation": "PASS",
"test_quality": "PASS",
"data_type_awareness": "PASS",
"time_allocation": "PASS",
"common_patterns_avoided": ["message_delivery", "string_comparison"]
}
}These gates extend the evidence bundle validation for AI-assisted tasks.
| Gate | Check | L0 | L1 | L2 | L3 | L4 |
|---|---|---|---|---|---|---|
| AIBOM-G0 | AI influence declared (level field set) | warn | warn | FAIL | FAIL | FAIL |
| AIBOM-G1 | AI_RUN_MANIFEST exists | warn | FAIL | FAIL | FAIL | FAIL |
| AIBOM-G2 | Required fields complete for risk level | warn | warn | FAIL | FAIL | FAIL |
| AIBOM-G3 | Evidence locators present on material fields | skip | warn | FAIL | FAIL | FAIL |
| AIBOM-G4 | SBOM and AI/ML-BOM linked in evidence bundle | skip | skip | FAIL | FAIL | FAIL |
| AIBOM-G5 | BOM diff reviewed when AI context changed | skip | skip | FAIL | FAIL | FAIL |
| AIBOM-G6 | Revalidation complete when triggered | skip | skip | FAIL | FAIL | FAIL |
| AIBOM-G7 | Human approval complete for L3/L4 | skip | skip | skip | FAIL | FAIL |
Gate behavior:
warn — Log finding; do not block release.FAIL — Block release until resolved or risk-accepted with documented approval.skip — Gate not applicable at this risk level.Add AI-BOM gate results to the Evidence Bundle:
{
"quality_gates": {
"aibom_g0": "PASS|WARN|FAIL|SKIP",
"aibom_g1": "PASS|WARN|FAIL|SKIP",
"aibom_g2": "PASS|WARN|FAIL|SKIP",
"aibom_g3": "PASS|WARN|FAIL|SKIP",
"aibom_g4": "PASS|WARN|FAIL|SKIP",
"aibom_g5": "PASS|WARN|FAIL|SKIP",
"aibom_g6": "PASS|WARN|FAIL|SKIP",
"aibom_g7": "PASS|WARN|FAIL|SKIP"
}
}This skill works with:
Version: 2.1 Based on: Comprehensive framework testing (May 2026) Prevents: Interface bugs, type errors, test gaps, rushed implementations Expected Impact: +12% quality improvement on complex tasks
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.