D3
Standard: agentskills/agentskills

Day 3: In-Context Constraints & Anti-Patterns

12-Day Series
🗺️ SECTION 1 / SYSTEM BLUEPRINT & INTEGRATION

The "Where & Why": In-Context Architectural Guardrails และการหยุดยั้ง Hallucination Drift

🎯 Mental Map (146 Words): ใน Day 1 เรากำหนด Package Topology และ Day 2 เราสร้าง Semantic Router กรอง Intent เข้ามาอย่างแม่นยำ

ปัญหาและช่องโหว่ที่พบ: เมื่อ Host Agent ผ่าน Semantic Gate เข้ามาและเริ่มสร้างโค้ด LLM มักเกิด Hallucination Drift หรือ Architectural Decay เช่น ดึง Library เก่า (Mockito), ติด Annotation ผิดประเภท (@SpringBootTest), หรือสร้าง Code Smells เพราะในคำสั่งมีแต่เป้าหมายเชิงบวก (What to do) แต่ขาด Negative Constraints (What NOT to do)
เป้าหมายของ Day 3: เราจะฝัง In-Context Non-Negotiable Boundaries ตามมาตรฐาน RFC 2119 (MUST NOT, SHALL NOT) และ Anti-Pattern Tables ลงใน Body ของ SKILL.md เพื่อล็อกพฤติกรรม LLM ให้มี Deterministic Conformance 100%
In-Context Execution Barrier & Defense-in-Depth Pipeline Guardrail Topology v1.0
[Day 2 Semantic Router Matches Intent: Similarity > 0.85]
                      │
                      ▼ (Skill Hydrated into Active Context)
┌────────────────────────────────────────────────────────────────────────┐
│ ACTIVE CONTEXT WINDOW (Host Agent + LLM Attention Stack)                │
│                                                                        │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ YAML Frontmatter (Metadata, Targets, Tools)                        │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│                                                                        │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ 🛡️ IN-CONTEXT CONSTRAINTS & ARCHITECTURAL BOUNDARIES [DAY 3]       │ │
│ │  - RFC 2119 Invariants (MUST NOT inject Spring Context)             │ │
│ │  - Explicit Forbidden List (org.mockito.*, @DataJpaTest)           │ │
│ │  - Memory & Speed Budget (< 50ms runtime, pure isolated heap)       │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│                                                                        │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ Dynamic Execution & Code Generation Phase                          │ │
│ │ LLM evaluates proposed AST against Negative Constraint Matrix      │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│                                                                        │
└──────────────────────────────────┬─────────────────────────────────────┘
                                   │
                    ┌──────────────┴──────────────┐
                    ▼                             ▼
        [Violates Negative Rule?]     [All Constraints Clear?]
                    │                             │
                    ▼                             ▼
          ❌ HALT & SELF-CORRECT        ✅ COMPILE-READY ARTIFACT
        (Pre-commit AST Rejection)       (Zero Spring context, MockK)
        
PILLAR 01: DEFENSIVE INVARIANTS

Negative Contracts

กำหนดขอบเขตข้อห้ามเด็ดขาด (Invariants) เช่น ห้ามโหลด Spring Context ลงใน Unit Test เปรียบเสมือน Type System สกัด Compile Errors

PILLAR 02: ATTENTION ANCHORING

Anti-Drift Anchors

จัดวาง Constraints ไว้บนสุดของ Instruction Body เพื่อตรึง Attention Heads ของ LLM ไม่ให้หลุดลอยตามบริบทโค้ดขนาดยาว

PILLAR 03: DETERMINISTIC REJECTION

Zero Tolerance

ให้ LLM ปฏิเสธการสร้างโค้ดทันทีหาก Preconditions ขัดแย้ง แทนที่จะเดาจนเกิดภาพหลอน (Hallucination)

⚙️ SECTION 2 / ARCHITECTURAL DEEP DIVE

วิศวกรรม Negative Constraints: Type Systems, Attention Drift และ RFC 2119

ในหลักการ Software Engineering แบบดั้งเดิม เราใช้ Strong Type Systems, Immutable Data Structures และ Assertions เพื่อป้องกันสถานะที่ผิดพลาด (Invalid States) ไม่ให้เกิดขึ้นตั้งแต่ต้น ในทำนองเดียวกัน การเขียน Agent Skill ต้องไม่พึ่งพาเพียงคำขอร้องเชิงบวก แต่ต้องสร้าง Negative Invariants เพื่อตัด Search Space ของโมเดล LLM ให้เหลือเพียงโค้ดที่ถูกต้องเท่านั้น

มิติสถาปัตยกรรม (Architectural Dimension) Weak Prompting (คำสั่งเชิงบวกทั่วไป) Specification-First Guardrails (Day 3)
Instruction Syntax "Please use MockK and make tests clean and fast." "Tests MUST NOT import org.mockito.* under any circumstances. Tests SHALL NOT boot ApplicationContext."
Attention Drift Resilience ต่ำมาก: เมื่อเจอรหัสเดิมที่เป็น Mockito หรือ Java LLM จะดริฟต์ตามโค้ดเก่าทันที สูงมาก: มี Negative Anchor สกัดกั้นไม่ให้โมเดลหยิบ Pattern ในโค้ดเก่ามาใช้ซ้ำ
Behavior on Ambiguity โมเดลเดาสุ่ม นำพา Library ผิดประเภทเข้ามาใน Dependency Defensive Halt: โมเดลหยุดและแจ้ง violation ล่วงหน้าก่อนเขียนไฟล์
AST Verification Alignment ไม่สามารถเชื่อมต่อกับ Script เชิงสถิติได้ เพราะไม่มีเกณฑ์ชี้ชัด แมปเข้ากับ Bash/AST regex linter ได้ 1:1 ตรวจสอบได้แบบ Deterministic
Attention Saturation & Negative Anchoring

เมื่อ LLM อ่านเอกสารใน Context Window นานขึ้น Attention Weights จะกระจายตัวกว้างขึ้นและเจือจางลง ปรากฏการณ์นี้เรียกว่า Attention Degradation

Attention_Sink = Softmax(Q · K^T / √d_k) · V

การกำหนดคำว่า "FORBIDDEN", "MUST NOT" และระบุ Package Name ที่ห้ามใช้ตรงๆ จะสร้าง Dense Attention Peak ทำให้โมเดลจัดลำดับความสำคัญของกฎข้อห้ามเหนือกว่าตัวอย่างโค้ดในโปรเจกต์ที่อาจยังใช้เทคโนโลยีเก่าอยู่

RFC 2119 Normative Vocabulary in Agent Prompts

การเลือกคำศัพท์ในเอกสารสถาปัตยกรรมระดับองค์กรต้องอ้างอิงมาตรฐาน IETF RFC 2119:

  • MUST NOT / SHALL NOT: ข้อห้ามเด็ดขาด หากฝ่าฝืนถือเป็น Critical Specification Bug ทันที
  • SHOULD NOT: พฤติกรรมที่ไม่แนะนำ ยกเว้นมีเหตุผลทางสถาปัตยกรรมที่ระบุไว้อย่างชัดเจน
  • MUST / REQUIRED: ข้อกำหนดบังคับที่ Artifact ต้องมี (เช่น โครงสร้าง AAA เท่านั้น)
🧩 SECTION 3 / END-TO-END CODE BLUEPRINT

Production Artifact: In-Context Guarded Contract

ไฟล์ SKILL.md สมบูรณ์แบบที่นำ In-Context Constraints และ Anti-Pattern Defense เข้ามาติดตั้งเพื่อควบคุม Host Agent ในระบบ Maven / Kotlin / Spring Boot

Skill Directory Placement
.github/skills/spring-boot-unit-tester/
├── SKILL.md                          ◄── [TODAY'S ARTIFACT: In-Context Constraints & Anti-Patterns]
├── scripts/
│   ├── eval-triggers.sh              ◄── Day 2: Router Evaluation
│   └── verify-constraints.sh         ◄── Day 3: Static AST Anti-Pattern Linter
└── tests/
    └── routing-fixtures.json
        
FILE: .github/skills/spring-boot-unit-tester/SKILL.md Strict Specification Body
---
name: spring-boot-unit-tester
schema-version: "1.0.0"
description: >
  Generates and refactors isolated JVM unit tests for Kotlin and Spring Boot 3.x 
  using JUnit 5, MockK, and AssertJ. Use for service and domain layer tests. 
  DO NOT USE for integration tests, Testcontainers, @SpringBootTest, or database testing.
metadata:
  domain: "backend-quality"
  target-framework: "Spring Boot 3.x"
---

# Spring Boot Isolated Unit Test Engine Contract


## 1. Architectural Boundaries & Negative Constraints

As an autonomous code generation engine, you MUST adhere to the following normative invariants:

### 1.1 Strictly FORBIDDEN Constructs (MUST NOT)
- **NO Mockito Infiltration**: You MUST NOT import `org.mockito.*`, `org.springframework.boot.test.mock.mockito.*`, or use `@MockBean` / `@SpyBean`.
- **NO ApplicationContext Booting**: You MUST NOT annotate test classes with `@SpringBootTest`, `@DataJpaTest`, `@WebMvcTest`, or `@AutoConfigureTestDatabase`.
- **NO Spring Extension**: You MUST NOT use `@ExtendWith(SpringExtension.class)`. Pure JVM tests execute without Spring container overhead.
- **NO Reflection-Based State Injection**: You MUST NOT use `ReflectionTestUtils.setField()`. All dependencies MUST be injected via constructors.
- **NO Hardcoded Time or Latency**: You MUST NOT use `Thread.sleep()`. Use virtual clocks or explicit mock timings.

### 1.2 Required Structural Mandates (MUST)
- **Framework Stack**: MUST use JUnit 5 (`org.junit.jupiter.api.*`), MockK (`io.mockk.*`), and AssertJ (`org.assertj.core.api.Assertions.assertThat`).
- **Isolation Guarantee**: Tests MUST execute in under 50ms per test method strictly in-memory.
- **Explicit AAA Phases**: Every test method body MUST be divided using explicit single-line comments:
  `// Arrange`, `// Act`, and `// Assert`.


## 2. Anti-Pattern Triage & Replacement Matrix

| Anti-Pattern Observed | Severity | Permitted Architecture Alternative |
| :--- | :--- | :--- |
| `Mockito.when(mock.call()).thenReturn(val)` | CRITICAL | `every { mock.call() } returns val` |
| `@MockBean private lateinit var repo: Repo` | CRITICAL | Constructor injection: `val repo = mockk<Repo>()` |
| `assertEquals(expected, actual)` | MAJOR | `assertThat(actual).isEqualTo(expected)` |
| `@Test fun test_save() { ... }` (Snake case) | MINOR | Use backtick descriptions: @Test fun \`should calculate tax correctly\`() |

## 3. Defense-in-Depth Self-Check
Before finalizing output, execute an in-context AST scan on your generated code:
1. Did you accidentally retain any `import org.mockito.*` in the import header? -> REMOVE IMMEDIATELY.
2. Is there any Spring Context annotation present? -> STRIP AND INSTANTIATE RAW CLASS.
          
🛠️ SECTION 4 / HANDS-ON SCENARIO & LAB

Enterprise Incident: The Mockito Legacy Infiltration & Context Leak

สถานการณ์จริง: ใน Maven Multi-module Kotlin Project ขนาด 2 ล้านบรรทัด ทีมงานกำลัง refactor โค้ดเก่า แต่เมื่อเรียก GitHub Copilot หรือ Cursor ให้เขียน Unit Test ให้กับ PaymentSettlementService ตัว AI กลับเหลือบไปเห็น module ข้างเคียงที่ยังใช้ Mockito + @MockBean อยู่ AI จึง generate โค้ดที่ติด @SpringBootTest และ Mockito ส่งผลให้ CI/CD Pipeline จากเดิมที่รัน 10 วินาที พุ่งขึ้นเป็น 4 นาที และ Build พังเนื่องจาก Dependency Conflict

⚠️ LAB MISSION OBJECTIVES
  1. ฝัง Negative Architectural Constraints ลงใน SKILL.md ด้วยคำสำคัญ RFC 2119 อย่างเคร่งครัด
  2. สร้าง Deterministic Shell Verifier (verify-constraints.sh) ที่ทำหน้าที่เป็น Linter ตรวจจับ AST/Regex สำหรับ Annotation และ Import ต้องห้าม
  3. ทดสอบรัน Verifier บนโค้ดตัวอย่างเพื่อให้แน่ใจว่า Exit Code มีพฤติกรรมตามสัญญา (Exit 0 เมื่อถูกต้อง, Exit 1 เมื่อพบ Anti-pattern)
VALIDATION TOOL: scripts/verify-constraints.sh POSIX Bash AST/Regex Scanner
#!/usr/bin/env bash
# ==============================================================================
# verify-constraints.sh
# Deterministic AST & Regex Invariant Checker for Kotlin Unit Tests
# Enforces Day 3 In-Context Architectural Guardrails
# ==============================================================================
set -euo pipefail

TARGET_FILE="${1:-src/test/kotlin/com/enterprise/billing/PaymentSettlementServiceTest.kt}"

echo "🛡️ [1/4] Checking file presence: $TARGET_FILE"
if [[ ! -f "$TARGET_FILE" ]]; then
  echo "❌ Error: Target test file $TARGET_FILE does not exist!" >&2
  exit 1
fi

VIOLATIONS=0

echo "🔍 [2/4] Scanning for FORBIDDEN Mockito artifacts..."
if grep -En "org\.mockito|org\.springframework\.boot\.test\.mock\.mockito|Mockito\." "$TARGET_FILE"; then
  echo "  ❌ CRITICAL VIOLATION: Forbidden Mockito package or syntax detected!" >&2
  VIOLATIONS=$((VIOLATIONS + 1))
else
  echo "  ✅ Clean: No Mockito contamination."
fi

echo "🔍 [3/4] Scanning for FORBIDDEN Spring Context Annotations..."
FORBIDDEN_ANNOTATIONS=("@SpringBootTest" "@DataJpaTest" "@WebMvcTest" "@ExtendWith(SpringExtension" "@MockBean")
for anno in "${FORBIDDEN_ANNOTATIONS[@]}"; do
  if grep -Fn "$anno" "$TARGET_FILE"; then
    echo "  ❌ CRITICAL VIOLATION: Forbidden Context annotation '$anno' found!" >&2
    VIOLATIONS=$((VIOLATIONS + 1))
  fi
done

if [[ $VIOLATIONS -eq 0 ]]; then
  echo "  ✅ Clean: Zero Spring Context dependencies detected. Pure JVM memory isolation guaranteed."
fi

echo "🔍 [4/4] Verifying MANDATORY MockK and AAA conventions..."
if ! grep -q "io\.mockk" "$TARGET_FILE"; then
  echo "  ❌ VIOLATION: Missing required 'io.mockk' import!" >&2
  VIOLATIONS=$((VIOLATIONS + 1))
fi

if ! grep -q "// Arrange" "$TARGET_FILE" || ! grep -q "// Act" "$TARGET_FILE" || ! grep -q "// Assert" "$TARGET_FILE"; then
  echo "  ⚠️ WARNING: Test does not clearly follow mandatory // Arrange // Act // Assert comments."
fi

# Exit Code Evaluation
if [[ $VIOLATIONS -gt 0 ]]; then
  echo "🛑 REJECTED: Test failed with $VIOLATIONS architectural invariant violation(s)." >&2
  exit 1
fi

echo "🎉 PASSED: Generated unit test satisfies all enterprise architectural guardrails!"
exit 0
        
🎯 SECTION 5 / INTERACTIVE ARCHITECTURE & VERIFICATION QUIZ

ทดสอบสถาปัตยกรรม In-Context Constraints & Guardrails (Day 3)

Current Score
0 / 12

ตอบคำถามเชิงสถาปัตยกรรมทั้ง 12 ข้อด้านล่าง ระบบจะตรวจคำตอบและให้ Feedback ทันทีเมื่อคลิกเลือกช้อยส์ พร้อมแสดงคำอธิบายเชิงลึก