← Phase 3
D8
Standard: agentskills/agentskills

Day 8: The references/ Layer & Context Budgeting

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

The "Where & Why": สถาปัตยกรรม Progressive Disclosure และการจัดการ Context Pollution

🎯 Mental Map (146 Words): ใน Phase 2 (Day 5-7) เราติดตั้ง CLI Sandbox, Stderr Triage, และ AST Symbol Extraction ทำให้ Agent มีเครื่องมือวิเคราะห์โค้ดจริง

ปัญหาคอขวดใหม่ที่พบใน Phase 3: เมื่อระบบต้องจำลองข้อมูลทดสอบ (Test Fixtures) สำหรับ Domain Objects หรือ DTOs ขนาดใหญ่ที่มี 30-50 ฟิลด์ หากเรายัด JSON Schemas, OpenAPI Specs, หรือ Database Contracts ทั้งหมดลงใน SKILL.md จะเกิด Context Window Flooding และ Attention Drift ทันที
เป้าหมายของ Day 8: เราจะติดตั้งเลเยอร์ references/ ตามมาตรฐาน agentskills พร้อมนำกลยุทธ์ Dynamic Progressive Disclosure มาใช้: ให้ SKILL.md เก็บเฉพาะ Pointer References น้ำหนักเบา และเปิดทางให้ Agent อ่าน Heavy Schemas เฉพาะเมื่อถึงจุดที่ต้อง Mock เท่านั้น
Tiered Progressive Disclosure & Context Hydration Flow Context Protocol v3.0
┌────────────────────────────────────────────────────────────────────────┐
│ TIER 1: FAST DISCOVERY (~100 Tokens)                                   │
│ Host Agent Session Startup scans Frontmatter description only          │
└───────────────────────────────────┬────────────────────────────────────┘
                                    │ (Intent Match > 0.80)
                                    ▼
┌────────────────────────────────────────────────────────────────────────┐
│ TIER 2: ACTIVE WORKING MEMORY (~800 Tokens)                            │
│ SKILL.md Hydration: Invariants (Day 3), PRS (Day 4), Tool Defs (Day 5) │
│ Contains POINTERS to External References (Zero Heavy Data Flooding)    │
└───────────────────────────────────┬────────────────────────────────────┘
                                    │
                                    ├────────────────────────────────────┐
                                    │ Need: Simple Mock?                 │ Need: Complex Nested DTO?
                                    ▼                                    ▼
┌──────────────────────────────────────────────────┐ ┌──────────────────────────────────────────────────┐
│ FAST IN-MEMORY SYNTHESIS                         │ │ 🎯 TIER 3: ON-DEMAND REFERENCES/ LAYER [TODAY]   │
│ Agent generates fixtures using standard AST info │ │ Agent reads: references/billing-schemas.json     │
│ Context remains ultralight (< 1,000 tokens)      │ │ Hydrates only the targeted 40-field schema slice │
└──────────────────────────────────────────────────┘ └──────────────────────────────────────────────────┘
        
PILLAR 01: PROGRESSIVE DISCLOSURE

Tiered Hydration

ไม่โหลดข้อมูลก้อนใหญ่เข้าสู่ Prompt ล่วงหน้า แต่ใช้ Pointer Rules ให้ Agent ดึงเฉพาะไฟล์ใน references/ ที่จำเป็นต่องานย่อย

PILLAR 02: ATTENTION BUDGETING

Eliminate Distraction

การแยก Heavy Contracts ออกจาก SKILL.md ช่วยรักษาความสนใจของโมเดลให้มุ่งเน้นที่ Invariants และ Test Behavior ได้อย่างแม่นยำ

PILLAR 03: CANONICAL DRIFT SHIELD

Single Source of Truth

เมื่อ Enterprise API Contract มีการปรับโครงสร้าง สามารถแก้ไขที่ไฟล์ใน references/ จุดเดียวโดยไม่ต้องตามแก้ Instruction หลัก

⚙️ SECTION 2 / ARCHITECTURAL DEEP DIVE

วิศวกรรม Context Budgeting: การเปลี่ยน Heavy Payloads สู่ On-Demand Pointer Architecture

ในระบบปฏิบัติการ (Operating Systems) คอมพิวเตอร์ไม่โหลดโปรแกรมขนาด 10 GB ทั้งหมดลงใน L1 Cache แต่ใช้กลไก Virtual Memory และ Paging เพื่อดึงข้อมูลเฉพาะหน้าที่ใช้งานจริง ในโลกของ LLM Context Window ก็มีพฤติกรรมดุจเดียวกัน: หากเรายัด DTO definitions และ Enterprise Schemas ทั้งหมดลงในไฟล์คำสั่งหลัก Attention Mechanism ของโมเดลจะถูกเจือจางด้วย Token นับพันตัวที่ไม่ได้ใช้งานในแต่ละรอบ

มิติสถาปัตยกรรม (Architectural Dimension) Monolithic Prompt (ยัดทุกอย่างใน SKILL.md) Ad-hoc Search (ให้ Agent ไล่ค้นหาไฟล์เอง) Tiered References Layer (Day 8 Standard)
Baseline Context Consumption วิกฤต (3,000 - 8,000 Tokens ต่อ Request) ต่ำตอนเริ่ม แต่บวมมหาศาลหลังการ Grep สะเปะสะปะ ต่ำที่สุด (< 850 Tokens สำหรับ Core Spec)
Attention Degradation Risk สูงมาก: โมเดลละเลย Negative Invariants ปานกลาง: โมเดลติดหล่มในไฟล์เก่าที่ค้นพบ ต่ำที่สุด: กฎหลักยังคงตรึง Attention สูงสุด
Complex Fixture Accuracy ปานกลาง: มักสุ่มเดาฟิลด์ย่อยที่ซ่อนอยู่ลึกๆ ต่ำ: มีโอกาสหยิบ Mock เก่าที่ไม่ตรงกับระบบปัจจุบัน แม่นยำ 100%: อ่าน Schema Canonical ล่าสุดตรงๆ
Maintenance Cost สูงมาก: แก้ DTO 1 ฟิลด์ต้องแก้ SKILL.md ทุกตัว ไม่มีการควบคุมมาตรฐาน ต่ำมาก: อัปเดตไฟล์ใน references/ แยกอิสระ
The Context Window as an L1 Cache

ในเชิงทฤษฎี Information Density ยิ่ง Token ที่ป้อนเข้าสู่ Active Window มีความสำคัญต่อการตัดสินใจมากเท่าใด ผลลัพธ์ก็จะยิ่งแม่นยำขึ้นเท่านั้น:

Efficiency = Critical_Decision_Tokens / Total_Window_Tokens

หากนำ Schema ขนาด 2,000 Tokens ยัดไว้ในคำสั่งตลอดเวลา อัตราส่วน Efficiency จะร่วงลงทันที การนำข้อมูลนั้นไปเก็บไว้ใน references/ แล้วทิ้งไว้เพียง Pointer Directive (เช่น "If mocking SettlementPayload, read references/settlement-schema.json") จะช่วยรักษา Efficiency ให้อยู่ในระดับสูงสุด

Pointer Directives vs Full Ingestion

สัญญาระหว่าง SKILL.md กับไดเรกทอรี references/ มีกฎเหล็ก 3 ประการ:

  • 1. Explicit Trigger Condition: ต้องระบุเงื่อนไขจำเพาะว่าจะเปิดอ่านเมื่อใด ไม่เขียนว่า "อ่านไฟล์นี้เสมอ"
  • 2. Relative Path Stability: เส้นทางไฟล์ต้องเป็น Relative Path เทียบจากโฟลเดอร์ Skill เสมอ
  • 3. Single Responsibility: แยก 1 ไฟล์ต่อ 1 โดเมน เช่น billing-dto.json, tax-contract.md ไม่รวมเป็นไฟล์ยักษ์
🧩 SECTION 3 / END-TO-END CODE BLUEPRINT

Production Artifact: Progressive References Architecture

ชุดเครื่องมือและไฟล์ตัวอย่างจริงตามมาตรฐาน agentskills/agentskills ที่แยก Heavy Billing Domain Schema ออกจาก SKILL.md พร้อมสคริปต์สืบค้น Reference สด

Skill Directory Placement
.github/skills/spring-boot-unit-tester/
├── SKILL.md                          ◄── [UPDATED: Added Tier 3 Progressive Pointer Rules]
├── scripts/
│   ├── run-unit-tests.sh             ◄── Day 5-6: Sandboxed Execution & Triage Runner
│   ├── extract-target-ast.py         ◄── Day 7: Lightweight AST Class Inspector
│   └── query-reference.sh            ◄── [TODAY'S ARTIFACT: Targeted Schema Slice Extractor]
└── references/                       ◄── [TODAY'S ARTIFACT: Heavy Domain Schemas Layer]
    └── billing-domain-contracts.json ◄── Canonical DTO Fixture Specification
        
FILE: .github/skills/spring-boot-unit-tester/SKILL.md Contract with Pointer Directive
---
name: spring-boot-unit-tester
schema-version: "1.0.0"
description: >
  Generates deterministic, isolated Kotlin unit tests for Spring Boot 3.x 
  using MockK and AssertJ. MUST NOT load Spring ApplicationContext.
tools:
  - name: inspect-class-context
    description: Extracts concise AST skeleton from target source file.
    file: scripts/inspect-class-context.sh
  - name: query-reference
    description: Queries on-demand domain DTO schemas and fixtures from references/ directory.
    file: scripts/query-reference.sh
  - name: run-unit-tests
    description: Runs sandboxed test execution with automatic stderr triage.
    file: scripts/run-unit-tests.sh
metadata:
  domain: "backend-quality"
  target-framework: "Spring Boot 3.x / Kotlin 1.9+"
---

# Spring Boot Unit Test Architect Specification

## 1. Architectural Invariants & Execution Protocol
1. Follow AAA pattern with isolated JVM memory execution (< 50ms per method).
2. MUST NOT use `@SpringBootTest`, `@DataJpaTest`, or `org.mockito.*`.
3. Pre-flight: Execute `inspect-class-context` to retrieve Constructor parameters and suspend methods.


## 2. On-Demand Domain References & Fixture Contracts
Do NOT guess domain fixture schemas or inject bloated dummy objects. 
When testing services that interact with complex billing or trading payloads, consult external references on-demand:

- **Settlement & Invoicing DTOs**: 
  When the target method consumes or returns `SettlementInstruction` or `InvoicePayload`, query:
  `bash .github/skills/spring-boot-unit-tester/scripts/query-reference.sh references/billing-domain-contracts.json SettlementInstruction`
  
- **Rules for Ingestion**:
  1. DO NOT read the entire `references/` directory in advance.
  2. Extract ONLY the target schema node needed to build the specific mock fixture.
  3. Keep fixture instantiation minimal: set mandatory fields accurately, leave optional fields empty.
          
FILE: references/billing-domain-contracts.json Heavy Domain Contract Offloaded
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "domain": "EnterpriseBilling",
  "version": "4.2.0",
  "schemas": {
    "SettlementInstruction": {
      "type": "object",
      "required": ["instructionId", "accountNumber", "settlementAmount", "currency", "clearingRail"],
      "properties": {
        "instructionId": { "type": "string", "format": "uuid", "example": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d" },
        "accountNumber": { "type": "string", "pattern": "^[A-Z0-9]{12,34}$", "example": "ACC-9988221100" },
        "settlementAmount": { "type": "string", "format": "decimal", "example": "1250000.50" },
        "currency": { "type": "string", "enum": ["USD", "EUR", "THB", "JPY"], "example": "USD" },
        "clearingRail": { "type": "string", "enum": ["FEDNOW", "TARGET2", "SWIFT", "PROMPTPAY"], "example": "SWIFT" },
        "metadata": {
          "type": "object",
          "properties": {
            "originatingBic": { "type": "string", "example": "CHASTHBNXXX" },
            "regulatoryTag": { "type": "string", "example": "SEC_RULE_15C3" },
            "auditTimestamp": { "type": "integer", "example": 1774218800 }
          }
        }
      }
    },
    "SettlementResult": {
      "type": "object",
      "required": ["settlementId", "status", "reconciliationCode"],
      "properties": {
        "settlementId": { "type": "string", "format": "uuid", "example": "e4eaaaf2-d142-11e1-b3e4-080027620cdd" },
        "status": { "type": "string", "enum": ["COMPLETED", "PENDING_MATCH", "REJECTED_FUNDS"], "example": "COMPLETED" },
        "reconciliationCode": { "type": "string", "example": "RC-2026-99" },
        "executionLatencyMs": { "type": "integer", "example": 14 }
      }
    }
  }
}
          
FILE: scripts/query-reference.sh POSIX Bash + Python Slicer
#!/usr/bin/env bash
# ==============================================================================
# scripts/query-reference.sh
# Standard: agentskills Standard v1.0 (Phase 3 Reference Architecture)
# Slices out a specific schema node from references/ on demand (< 150 tokens)
# ==============================================================================
set -euo pipefail

REF_FILE="${1:-}"
NODE_KEY="${2:-}"

# 1. Validation of Arguments
if [[ -z "${REF_FILE}" ]] || [[ ! -f "${REF_FILE}" ]]; then
    echo "### 🚨 REFERENCE QUERY ERROR" >&2
    echo "- **Category**: \`REFERENCE_FILE_NOT_FOUND\`" >&2
    echo "- **Error**: Reference file '${REF_FILE}' does not exist or was not specified." >&2
    exit 1
fi

# 2. Extract Specific Sub-Schema Using Zero-Dependency Python Slicer
python3 -c "
import sys, json

try:
    with open('${REF_FILE}', 'r', encoding='utf-8') as f:
        data = json.load(f)
    
    key = '${NODE_KEY}'
    schemas = data.get('schemas', {})
    
    if key and key in schemas:
        target = schemas[key]
        print(f'### 📑 CANONICAL REFERENCE SLICE: {key}')
        print(f'- **Required Fields**: \`{target.get(\"required\", [])}\`')
        print('- **Field Blueprint**:')
        for prop, details in target.get('properties', {}).items():
            t = details.get('type', 'any')
            ex = details.get('example', 'N/A')
            print(f'  - \`{prop}\` ({t}) -> Example: \`{ex}\`')
    else:
        print(f'### ⚠️ SCHEMA KEY NOT FOUND: {key}')
        print(f'- Available keys in reference: {list(schemas.keys())}')
        sys.exit(2)
except Exception as e:
    sys.stderr.write(f'Parsing error: {str(e)}\\n')
    sys.exit(1)
"
exit 0
          
🛠️ SECTION 4 / HANDS-ON SCENARIO & LAB

Enterprise Incident: The 45-Field Billing DTO Context Window Suffocation

สถานการณ์จริง: Host Agent กำลังเขียน Unit Test ให้กับ BillingSettlementService.kt ซึ่งต้องสร้าง Object จำลองของ SettlementInstruction ในขั้นตอน // Arrange เนื่องจากผู้เขียน Skill เดิมเผลอนำ JSON Schema ขนาด 15 KB (กว่า 3,500 Tokens) ใส่ไว้ในเนื้อหา SKILL.md โดยตรง ส่งผลให้ Context Window เต็ม Attention ของโมเดลเจือจาง และทำให้ Agent "ลืม" กฎใน Day 3 จนเผลอ Import org.mockito.Mockito กลับเข้ามาในโค้ดอีกครั้ง

⚠️ LAB MISSION OBJECTIVES
  1. ย้ายเนื้อหา Schema ทั้งหมดออกจาก SKILL.md ไปเก็บไว้ที่ references/billing-domain-contracts.json เพื่อคืนพื้นที่ Context Window กว่า 90%
  2. ทดสอบรันสคริปต์ query-reference.sh เพื่อสกัดเฉพาะ Node SettlementInstruction ออกมาเป็น Markdown Slice ขนาดไม่เกิน 95 Tokens
  3. พิสูจน์ว่า Host Agent สามารถนำ Field Blueprint ที่ได้ไปสร้าง Test Fixture ใน MockK ได้ถูกต้องสมบูรณ์ 100% โดยไม่ทำให้ Invariants หลุด
❌ MONOLITHIC INGESTION (15 KB / 3,500 Tokens)
# Inside SKILL.md body directly:
Here is the entire JSON schema of all 25 Enterprise
Billing DTOs, including Invoices, Statements, Taxes,
Regulatory reports, Ledger entries, KYC records...
{
  "$schema": "https://json-schema.org/...",
  "schemas": { ... 1,200 lines of JSON ... }
}
// Consequence: Attention Drift, Model forgets Negative Rules!
          
✅ ON-DEMAND REFERENCE SLICE (< 85 Tokens)
### 📑 CANONICAL REFERENCE SLICE: SettlementInstruction
- **Required Fields**: `['instructionId', 'accountNumber', 'settlementAmount', 'currency', 'clearingRail']`
- **Field Blueprint**:
  - `instructionId` (string) -> Example: `9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d`
  - `accountNumber` (string) -> Example: `ACC-9988221100`
  - `settlementAmount` (string) -> Example: `1250000.50`
  - `currency` (string) -> Example: `USD`
  - `clearingRail` (string) -> Example: `SWIFT`
          
TERMINAL PROOF: On-Demand Schema Slice Run Bash Output
$ bash .github/skills/spring-boot-unit-tester/scripts/query-reference.sh references/billing-domain-contracts.json SettlementInstruction
### 📑 CANONICAL REFERENCE SLICE: SettlementInstruction
- **Required Fields**: `['instructionId', 'accountNumber', 'settlementAmount', 'currency', 'clearingRail']`
- **Field Blueprint**:
  - `instructionId` (string) -> Example: `9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d`
  - `accountNumber` (string) -> Example: `ACC-9988221100`
  - `settlementAmount` (string) -> Example: `1250000.50`
  - `currency` (string) -> Example: `USD`
  - `clearingRail` (string) -> Example: `SWIFT`

$ echo $?
0
        
🎯 SECTION 5 / INTERACTIVE ARCHITECTURE & VERIFICATION QUIZ

ทดสอบสถาปัตยกรรม references/ Layer & Context Budgeting (Day 8)

Current Score
0 / 12

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