Compilation Architecture
Understanding how PackC compiles prompts into packs.
Overview
Section titled “Overview”PackC transforms human-friendly YAML configurations into validated JSON packs through a multi-stage compilation pipeline.
Compilation Pipeline
Section titled “Compilation Pipeline”YAML Files → Parser → Validator → Pack Builder → JSON OutputStage 1: Configuration Loading
Section titled “Stage 1: Configuration Loading”Input: arena.yaml + prompt YAML files
# arena.yamlprompts: - prompts/support.yaml - prompts/sales.yamlProcess:
- Read arena.yaml
- Resolve file paths (relative to arena.yaml)
- Load each prompt YAML
- Parse YAML to PromptConfig structs
Output: In-memory PromptConfig objects
Stage 2: Prompt Registry
Section titled “Stage 2: Prompt Registry”Purpose: Central repository of all prompts
repo := memory.NewPromptRepository()registry := prompt.NewRegistryWithRepository(repo)Features:
- Deduplication by task_type
- Fast lookup by ID
- Validation on registration
Stage 3: Validation
Section titled “Stage 3: Validation”Checks:
- Required fields present (task_type, system_template)
- Template syntax valid
- Parameter types correct
- Tool references valid
- Media files exist
Output: Validated PromptConfig objects or errors
Stage 4: Pack Assembly
Section titled “Stage 4: Pack Assembly”Process:
- Create pack structure
- Add each prompt to prompts map
- Add fragments map
- Add metadata (compiler version, timestamp)
- Assign pack ID and version
Output: Complete Pack object
Stage 5: JSON Serialization
Section titled “Stage 5: JSON Serialization”Format: Indented JSON for readability
json.MarshalIndent(pack, "", " ")Options:
- Indent: 2 spaces
- Escape HTML: false
- Sort keys: consistent ordering
Output: .pack.json file
Compiler Components
Section titled “Compiler Components”PromptConfig Parser
Section titled “PromptConfig Parser”Parses YAML to PromptConfig:
func ParseConfig(data []byte) (*Config, error)Handles:
- YAML unmarshaling
- Type conversion
- Default values
- Validation
Pack Compiler
Section titled “Pack Compiler”Orchestrates compilation:
compiler := prompt.NewPackCompiler(registry)pack, err := compiler.CompileFromRegistry(packID, compilerVersion)Responsibilities:
- Iterate through registry
- Transform prompts
- Build pack structure
- Add metadata
Validator
Section titled “Validator”Validates prompts and packs:
warnings := pack.Validate()Returns list of validation warnings (non-fatal) or errors (fatal).
Template Processing
Section titled “Template Processing”Go Templates
Section titled “Go Templates”Default template engine:
system_template: | You are a helpful assistant. User: {{user_name}} Message: {{message}}Processing:
- Parse template text
- Check syntax errors
- Store as string (runtime parsing)
Why not pre-compile?
- Templates need runtime data
- Keeps packs language-agnostic
- SDK handles execution
Template Validation
Section titled “Template Validation”PackC validates template syntax:
_, err := template.New("test").Parse(tmpl)But doesn’t execute (no runtime data available).
Fragment Handling
Section titled “Fragment Handling”Fragment Definition
Section titled “Fragment Definition”# fragment.yamlfragments: company-info: content: "Company: " description: "Standard company info"Fragment Compilation
Section titled “Fragment Compilation”Two strategies:
1. Inline (default)
Fragment content embedded in prompt:
{ "prompts": { "support": { "system_template": "Company: {{company_name}}\n\nYou are support..." } }}2. Reference
Fragment stored separately:
{ "fragments": { "company-info": "Company: {{company_name}}..." }, "prompts": { "support": { "system_template": "{{company-info}}\n\nYou are support..." } }}Tradeoff:
- Inline: Faster execution, larger size
- Reference: Smaller size, runtime lookup
Error Handling
Section titled “Error Handling”Fatal Errors
Section titled “Fatal Errors”Stop compilation immediately:
- Invalid YAML syntax
- Missing required fields
- Template parse errors
- File not found
Warnings
Section titled “Warnings”Allow compilation but report issues:
- Missing descriptions
- Undefined tools
- Missing media files
- Large prompt size
Error Context
Section titled “Error Context”Provide helpful error messages:
Error parsing prompt config: yaml: line 5: mapping values are not allowedFile: prompts/support.yamlLine: 5Memory Management
Section titled “Memory Management”Small Footprint
Section titled “Small Footprint”PackC uses minimal memory:
- Streaming YAML parsing - Process files one at a time
- Lazy loading - Load prompts on demand
- Garbage collection - Release after compilation
- No caching - Don’t hold data post-compile
Large Projects
Section titled “Large Projects”For projects with 100+ prompts:
- Use single-prompt compilation for testing
- Compile subsets during development
- Full compilation only for releases
Compilation Modes
Section titled “Compilation Modes”Standard Mode
Section titled “Standard Mode”packc compile --config arena.yaml --output pack.json --id app- Full validation
- Complete metadata
Deterministic Builds
Section titled “Deterministic Builds”PackC produces deterministic output:
Given:
- Same source files
- Same packc version
- Same compilation flags
Result:
- Identical pack.json output
- Same checksums
- Reproducible builds
Implementation:
- Sorted keys in JSON
- Fixed timestamp format
- Consistent whitespace
Debugging Compilation
Section titled “Debugging Compilation”Use packc inspect to view the contents of a compiled pack:
packc inspect packs/app.pack.jsonUse packc validate to check a pack for errors:
packc validate packs/app.pack.jsonBuild Reproducibility
Section titled “Build Reproducibility”Version Locking
Section titled “Version Locking”Lock packc version:
# .packc-version0.1.0Input Hashing
Section titled “Input Hashing”Track source file changes:
find prompts/ -type f -exec sha256sum {} \; > prompts.sha256Build Manifest
Section titled “Build Manifest”Generate build info:
{ "packc_version": "0.1.0", "source_files": ["prompts/support.yaml"], "file_hashes": {"prompts/support.yaml": "abc123..."}, "build_time": "2025-01-16T10:30:00Z", "build_machine": "ci-runner-01"}Compiler Architecture
Section titled “Compiler Architecture”Modular Design
Section titled “Modular Design”PackCompiler├── Parser (YAML → PromptConfig)├── Validator (checks)├── Assembler (build pack)└── Serializer (write JSON)Each component is:
- Independent
- Testable
- Replaceable
Extension Points
Section titled “Extension Points”- Custom parsers - Support other input formats
- Custom validators - Add validation rules
- Custom serializers - Output other formats
Comparison with Other Compilers
Section titled “Comparison with Other Compilers”vs. TypeScript Compiler
Section titled “vs. TypeScript Compiler”| Feature | PackC | tsc |
|---|---|---|
| Input | YAML | TypeScript |
| Output | JSON | JavaScript |
| Type checking | Limited | Full |
| Optimization | Minimal | Extensive |
| Speed | ~100ms | ~1-10s |
vs. Babel
Section titled “vs. Babel”| Feature | PackC | Babel |
|---|---|---|
| Input | YAML | JavaScript |
| Output | JSON | JavaScript |
| Transformations | Few | Many |
| Plugins | Planned | Extensive |
| Speed | Fast | Moderate |
Summary
Section titled “Summary”PackC’s compilation architecture is:
- Pipeline-based - Clear stages from YAML to JSON
- Validated - Multiple validation checkpoints
- Extensible - Modular components
- Deterministic - Reproducible builds
- Fast - Milliseconds for typical projects
This design ensures reliable, consistent pack generation for production use.