Manifest-driven, hexagonal SDK generator for Elixir. Separates domain logic from infrastructure via ports and adapters.
lib/pristine/
├── core/ # Domain logic (pipeline, request, response, context)
├── ports/ # Interface contracts (transport, serializer, retry, etc.)
├── adapters/ # Implementations (finch, json, foundation, etc.)
├── codegen/ # Code generation pipeline
├── streaming/ # SSE support
├── manifest/ # Manifest loading and validation
examples/
├── tinkex/ # Tinkex SDK port (in progress)
docs/
├── 20250105/ # Current sprint documentation
foundation- Retry, backoff, circuit breaker, rate limitingsinter- Schema validation, JSON Schema generationmultipart_ex- Multipart/form-data encodingtelemetry_reporter- Telemetry batching and transport
# Run tests
mix test
# Run specific test file
mix test test/path/to/test.exs
# Type checking
mix dialyzer
# Linting
mix credo --strict
# Format
mix format
# All checks
mix test && mix dialyzer && mix credo --strictALL tests in this project MUST use supertester for proper test isolation. There are ZERO exceptions. Test ordering issues and flaky tests are unacceptable.
- Use
Supertester.ExUnitFoundationwithisolation: :full_isolationin all test modules - Zero
Process.sleep- Usecast_and_sync/2,wait_for_*helpers instead - Use
setup_isolated_genserver/3andsetup_isolated_supervisor/3for all OTP processes - All tests MUST run with
async: true- No sequential tests due to isolation issues - Automatic cleanup - Let supertester handle all resource cleanup
defmodule MyApp.MyTest do
use Supertester.ExUnitFoundation, isolation: :full_isolation
import Supertester.OTPHelpers
import Supertester.GenServerHelpers
import Supertester.Assertions
test "example with isolated GenServer" do
{:ok, server} = setup_isolated_genserver(MyServer)
:ok = cast_and_sync(server, :some_message)
assert_genserver_state(server, fn state -> state.count == 1 end)
end
end- ❌
Process.sleep/1in tests - ❌
async: falsedue to test isolation issues - ❌ Manual GenServer/Supervisor start without supertester
- ❌ Tests that depend on execution order
- ❌ Global state or named processes without isolation
# All tests must pass with any seed
mix test --seed 0
mix test --seed 12345
mix test # random seed- Hexagonal: Ports define contracts, adapters implement them
- Manifest-driven: API definitions in JSON/YAML drive code generation
- Type-safe: Sinter schemas validate requests/responses
- Observable: Telemetry throughout the pipeline
| Component | Lines | Can Replace? | Potential |
|---|---|---|---|
| Types (67 modules) | 4,201 | Generate from manifest | ~4,000 |
| API layer | 2,641 | Pristine pipeline | ~2,000 |
| Infrastructure | ~2,500 | Pristine ports | ~1,500 |
| Domain logic | ~13,000 | Keep (core SDK) | 0 |
| Total potential | - | - | ~7,500 |
docs/20260106/salvage-assessment/- What to keep vs discarddocs/20260106/tdd-downsize-plan/EXECUTION_PLAN.md- Detailed TDD phases