# Bulk Claim Import Guide **Problem:** Creating claims one-by-one via CLI is tedious. A 340-line shell script to import 22 claims is error-prone and obscures the actual claim data. **Solution:** Use `aphoria claims import` to import claims in bulk from TOML files with validation, progress reporting, and merge strategies. --- ## Quick Start ### 1. Generate a Template ```bash aphoria claims import --template > my-claims.toml ``` This creates an example TOML file with comprehensive inline documentation. ### 2. Edit the Template Open `my-claims.toml` and replace the example claims with your own: ```toml [[claim]] id = "myapp-http-tls-cert-validation-001" concept_path = "myapp/httpclient/tls/certificate_validation" predicate = "enabled" value = true comparison = "equals" provenance = "OWASP A02:2021 - Cryptographic Failures" invariant = "HTTP clients MUST validate TLS certificates" consequence = "Disabled validation exposes MITM attacks" authority_tier = "regulatory" evidence = ["OWASP Top 10", "CWE-295"] category = "security" status = "active" created_by = "security-team" created_at = "2024-12-15T10:00:00Z" ``` ### 3. Validate ```bash aphoria claims import my-claims.toml --validate-only ``` This checks your TOML format and field values **without** writing to `.aphoria/claims.toml`. ### 4. Preview ```bash aphoria claims import my-claims.toml --dry-run ``` Shows what would be added, skipped, or overwritten. ### 5. Import ```bash aphoria claims import my-claims.toml ``` Writes claims to `.aphoria/claims.toml` and displays a detailed report. --- ## TOML Format Reference ### Required Fields Every claim must have these fields: | Field | Type | Description | Example | |-------|------|-------------|---------| | `id` | string | Unique kebab-case identifier | `"myapp-feature-001"` | | `concept_path` | string | Hierarchical path to concept | `"myapp/module/feature"` | | `predicate` | string | Property being claimed | `"enabled"`, `"max_version"` | | `value` | bool/number/string | Expected value | `true`, `50`, `"SeqCst"` | | `comparison` | string | How to compare | `"equals"`, `"absent"` | | `provenance` | string | Where this rule came from | `"Architecture decision by tech lead"` | | `invariant` | string | What MUST remain true | `"Core MUST NOT import tokio"` | | `consequence` | string | What breaks if violated | `"Makes library async-only"` | | `authority_tier` | string | Authority level | `"expert"`, `"regulatory"` | | `category` | string | Claim category | `"security"`, `"architecture"` | | `created_by` | string | Author name | `"tech-lead"` | | `created_at` | string | ISO 8601 timestamp | `"2024-12-15T10:00:00Z"` | ### Optional Fields | Field | Type | Description | Default | |-------|------|-------------|---------| | `evidence` | array[string] | Supporting references | `[]` | | `status` | string | `"active"`, `"deprecated"`, `"superseded"` | `"active"` | | `supersedes` | string | ID of claim this replaces | (none) | | `updated_at` | string | ISO 8601 timestamp | (none) | ### Comparison Modes | Mode | Meaning | Example Use Case | |------|---------|------------------| | `equals` | Value must exactly match | `max_pool_size = 50` | | `not_equals` | Value must differ | `log_level != "debug"` | | `present` | Value must exist | `tls_config` present | | `absent` | Value must not exist | `tokio` absent from imports | | `contains` | Value must contain substring | Error message contains "timeout" | | `not_contains` | Value must not contain substring | URL must not contain "http:" | ### Authority Tiers From strongest to weakest: 1. **`regulatory`** - Legal/regulatory mandate (FDA, GDPR) 2. **`clinical`** - Peer-reviewed clinical evidence 3. **`observational`** - Real-world data, case studies 4. **`expert`** - Senior engineer/architect decision 5. **`community`** - Team consensus, convention 6. **`anecdotal`** - Individual experience, suggestion --- ## Import Modes ### Dry-Run Mode Preview changes without writing to disk: ```bash aphoria claims import my-claims.toml --dry-run ``` **Output:** ``` Aphoria Claims Import ======================================== 🔍 Dry-run mode (no changes written) Summary: Total claims in file: 22 Added: 18 Skipped: 3 Overwritten: 1 Details: ✓ ADD httpclient-connect-timeout-001 ⊗ SKIP httpclient-tls-cert-validation-001 (already exists) ↻ UPDATE aphoria-no-unwrap-001 ``` ### Validate-Only Mode Check format and validity without importing: ```bash aphoria claims import my-claims.toml --validate-only ``` **Success:** ``` ✓ Validation passed Total claims: 22 Warnings: 2 File is ready for import. ``` **Failure:** ``` ❌ Validation Failed Found 3 error(s) in import file: • Claim 'bad-id-001!' - id: Claim ID must be kebab-case (lowercase alphanumeric + hyphens): 'bad-id-001!' • Claim 'myapp-feature-001' - authority_tier: Unknown authority tier: 'super_expert' • Claim at index 5 - provenance: provenance cannot be empty Fix these errors and try again. ``` --- ## Merge Strategies Control what happens when a claim ID already exists: ### Skip Existing (Default) ```bash aphoria claims import my-claims.toml --merge skip_existing ``` - Adds new claims - **Skips** claims with duplicate IDs - Safe for re-running imports ### Overwrite ```bash aphoria claims import my-claims.toml --merge overwrite ``` - Adds new claims - **Replaces** existing claims with same ID - Use when updating claims in bulk ### Fail on Duplicate ```bash aphoria claims import my-claims.toml --merge fail_on_duplicate ``` - Adds new claims - **Exits with error** if any ID exists - Use for strict imports where duplicates indicate mistakes --- ## Output Formats ### Table Format (Default) Human-readable output with symbols: ```bash aphoria claims import my-claims.toml ``` **Output:** ``` Aphoria Claims Import ======================================== ✓ Import Complete Summary: Total claims in file: 22 Added: 18 Skipped: 3 Overwritten: 1 Details: ✓ ADD httpclient-connect-timeout-001 ✓ ADD httpclient-request-timeout-001 ⊗ SKIP httpclient-tls-cert-validation-001 (already exists) ↻ UPDATE aphoria-no-unwrap-001 Warnings: ⚠ httpclient-request-timeout-001: Duplicate concept_path ``` ### JSON Format Machine-readable output for tooling integration: ```bash aphoria claims import my-claims.toml --format json ``` **Output:** ```json { "summary": { "total_in_file": 22, "added": 18, "skipped": 3, "overwritten": 1, "failed": 0 }, "details": [ { "action": "added", "claim_id": "httpclient-connect-timeout-001", "reason": null }, { "action": "skipped", "claim_id": "httpclient-tls-cert-validation-001", "reason": "already exists" } ], "warnings": [ "httpclient-request-timeout-001: Duplicate concept_path" ] } ``` --- ## Common Workflows ### Converting Shell Scripts to TOML **Before:** 340-line shell script ```bash #!/bin/bash # create-claims.sh aphoria claims create \ --id httpclient-connect-timeout-001 \ --concept-path "httpclient/config/connect_timeout" \ --predicate "min_value" \ --value "5000" \ --comparison "equals" \ --provenance "Load testing results 2024-12-10" \ --invariant "Connect timeout MUST be at least 5 seconds" \ --consequence "Shorter timeouts cause spurious errors" \ --tier "expert" \ --evidence "tests/http_tests.rs" \ --category "networking" \ --by "sre-team" # Repeat 21 more times... ``` **After:** 200-line TOML file + 1-line command ```toml # httpclient-claims.toml [[claim]] id = "httpclient-connect-timeout-001" concept_path = "httpclient/config/connect_timeout" predicate = "min_value" value = 5000 comparison = "equals" provenance = "Load testing results 2024-12-10" invariant = "Connect timeout MUST be at least 5 seconds" consequence = "Shorter timeouts cause spurious errors" authority_tier = "expert" evidence = ["tests/http_tests.rs"] category = "networking" status = "active" created_by = "sre-team" created_at = "2024-12-15T10:00:00Z" # 21 more claims... ``` ```bash aphoria claims import httpclient-claims.toml ``` **Time saved:** 15 minutes → 1 second ### Importing from External Sources When importing security standards or RFCs: ```bash # Apply authority tier override aphoria claims import owasp-top-10.toml \ --authority-tier regulatory \ --source-guide "OWASP Top 10 2021" ``` This: - Overrides all `authority_tier` fields in the TOML - Tracks the import in `.aphoria/ingested_guides.toml` - Links imported claims to their source ### Updating Existing Claims ```bash # Create updated claims file cat > updates.toml <<'EOF' [[claim]] id = "myapp-pool-max-size-001" # ... updated fields ... EOF # Apply updates aphoria claims import updates.toml --merge overwrite ``` --- ## Validation Rules ### ID Format **Valid:** - `myapp-feature-001` - `http-tls-cert-validation` - `core-no-tokio` **Invalid:** - `MyApp-Feature-001` (uppercase) - `-myapp-feature` (leading hyphen) - `myapp--feature` (consecutive hyphens) - `myapp_feature` (underscores) - Empty string - Over 64 characters ### Required Field Validation All fields must be non-empty strings (after trimming): - `provenance` - `invariant` - `consequence` - `category` - `created_by` ### Authority Tier Validation Must be one of: `regulatory`, `clinical`, `observational`, `expert`, `community`, `anecdotal` ### Duplicate Detection **Errors:** - Duplicate `id` within import file - Duplicate `id` when using `--merge fail_on_duplicate` **Warnings:** - Duplicate `concept_path` + `predicate` combination - `id` already exists in `.aphoria/claims.toml` --- ## Troubleshooting ### Parse Errors **Error:** `Error parsing import file: TOML parse error at line 15, column 10` **Fix:** Check TOML syntax. Common issues: - Missing quotes around string values - Unclosed brackets `[` or `]` - Typo in field name (e.g., `categoey` instead of `category`) ### Validation Errors **Error:** `Claim ID must be kebab-case` **Fix:** Use lowercase letters, numbers, and hyphens only. No underscores, spaces, or uppercase. **Error:** `Unknown authority tier: 'super_expert'` **Fix:** Use one of the 6 valid tiers: regulatory, clinical, observational, expert, community, anecdotal. ### Import Conflicts **Warning:** `Claim ID 'myapp-feature-001' already exists in claims file` **Options:** 1. Use `--merge skip_existing` (default) - skips the duplicate 2. Use `--merge overwrite` - replaces the existing claim 3. Change the ID in your import file to make it unique --- ## Examples See `applications/aphoria/examples/` for complete examples: - **`import-template.toml`** - Template with comprehensive comments - **`import-httpclient.toml`** - Real-world example (22 claims) --- ## Integration with Skills The `/aphoria-claims` skill can generate bulk import files: ```bash # After reviewing a PR diff, the skill generates: cat > generated-claims.toml <