Pactia Overview
Pactia is the intent language for the AI era. You write what must stay true — in plain prose, structured tags, or both — and share that intent across teams through versioned packages. Same .pactia works with any coding agent; the toolchain compiles it once and adapts output per consumer.
The one rule that matters: Pactia never requires more than prose. Every tag, macro, and keyword beyond
pactia+productis something you reach for when you want enforcement — never something you must learn on day one.
Three altitudes
Every Pactia file is legal at altitude 0. Tags are an opt-in upgrade, one fact at a time.
Prose is not a placeholder. A few well-written > lines can carry product definition, roles, API behavior, and agent policy — the same facts tags formalize later.
Altitude 0 — prose only
pactia 1.0
product MyApp {
> A mobile app for tracking personal fitness goals and sharing progress with friends.
>
> Users sign up with email. Each user owns their workouts; only the owner may edit or delete.
> Friends see shared workouts in a feed — read-only across users, no cross-account writes.
>
> Backend is Rust on actix-web with PostgreSQL. Mobile clients use REST over HTTPS.
> List endpoints use cursor pagination (default 20, max 100). Offsets are not supported.
>
> Auth: bearer JWT. Workout APIs require a logged-in customer; scope is owner rows only.
> Never commit secrets. Map all handler errors to our standard envelope before returning.
}
That file is complete. An agent can implement from prose alone.
Altitude 1 — light tagging
pactia 1.0
import @pactia/kernel;
import @pactia/rust-stack;
product MyApp {
> A mobile app for tracking personal fitness goals and sharing progress with friends.
> Users sign up with email. Each user owns their workouts; only the owner may edit or delete.
> List endpoints use cursor pagination. Never commit secrets; use our error envelope.
#rust-stack
module fitness {
service WorkoutService {
@auth Customer
@@output WorkoutListResponse
@api list_workouts {
> Customers browse their workout history, newest first, paginated.
}
@auth Customer
@@output WorkoutResponse
@api create_workout {
> Customer logs a new workout. Reject payloads over 4 KB.
}
}
}
}
Add tags only where enforcement or reuse helps. Everything else stays prose.
Altitude 2 — fully specified
pactia 1.0
import @pactia/kernel;
import @pactia/rust-stack;
product Fleet {
> B2B fleet management — customers manage their own vehicles; admins see all tenants.
> List endpoints are cursor-paginated. Mutations are audit-logged.
#rust-stack
module fleet {
service FleetService {
@auth { roles: [Customer, Admin] }
#list
#paginated
#owner
@@output VehicleListResponse
@api list_vehicles {
method: GET,
path: "/api/v1/vehicles",
> Customers see only vehicles where customerId matches their account.
}
}
}
}
Same language, same compiler — your chosen density.
Same story, less syntax
| Concern | Altitude 0 (prose) | Tag when you need… |
|---|---|---|
| Who may call an API | > Auth: bearer JWT; owner rows only |
@auth Customer |
| List behavior | > Cursor pagination, default 20 |
#list / #paginated |
| Response shape | > Return list + optional nextCursor |
@@output WorkoutListResponse |
| Wire route | > GET /workouts for history |
@api { method, path } |
Start with prose. Move right only when a gate or package reuse justifies the syntax.
Philosophy
Pactia answers: what should stay true about this product — and what context should every AI session inherit?
| Era | You write | Machine / AI does |
|---|---|---|
| 3GL (C, Rust) | Algorithms, types | Execute |
| 4GL (SQL, config) | Desired state | Reconcile |
| Pactia | Intent (prose + tags) | Implement; optional gates verify facts |
Pactia does not replace Rust, React, or Swift. It sits above them as a durable layer between humans, agents, and generated code.
From source to agent context
Humans author .pactia once. pactiac lowers it to neutral JSON IR. BSC renders agent briefs for your toolchain (Cursor, Claude Code, Copilot, …) and may optionally expand them with an LLM — grounded in IR, not free-form chat.
.pactia ──pactiac──▶ workspace.json (+ slice files) (*.module.json, *.model.json, *.service.json)
│
└── bsc render ──▶ agent briefs (target profile)
│
└── bsc expand (LLM, optional) ──▶ richer agent context
grounded in JSON · provenance: GENERATED| Phase | Role |
|---|---|
pactiac compile |
Lower intent to neutral IR (deterministic) |
bsc render |
Map IR → agent briefs per target |
bsc expand |
Optional richer context from IR |
Multiline prose
product InternalTools {
>> Every handler validates input at the boundary; domain layer assumes invariants already hold.
Retries are idempotent only where prose or tags say so — never blanket retry on POST. >>
> Shorter rules still use one line each.
> Never commit secrets.
}
Packages — share everything, not just code
Chat prompts die in history. Pactia packages let you pin and reuse intent the way Go modules pin code:
import @scope/name— pull in kernel tags, stack macros, compliance rules, or your org's standardscontext { path: "…" }— attach markdown specs, agent rules, schemas — versioned beside your productpactia.toml+pactia.lock— reproducible installs from git tags- Prose, tags, and macros travel together — one package can ship agent policy, API patterns, and platform defaults
Package manager (high level)
Like Rust has cargo and crates.io, Pactia has pactia (CLI) and pactia.io (registry of intent packages):
| Command | Purpose |
|---|---|
pactia init |
Start a workspace |
pactia add |
Add a dependency from git / registry |
pactia install |
Vendor packages per lockfile |
pactia build |
Compile workspace → IR |
You do not copy-paste agent rules between repos. You import a package and inherit prose, context files, macros, and tags in every session.
Sharing prose and context
pactia 1.0
import @pactia/kernel;
import @pactia/rust-stack;
import @acme/agent-standards;
product Payments {
> B2B payments API. Bearer JWT. Owner-scoped rows on every list.
context security_policy {
path: "./context/security.md",
> Normative auth, logging, and PII rules for all services in this product.
}
context openapi_style {
path: "./context/openapi-style.md",
> How we name operations, errors, and pagination in public APIs.
}
#rust-stack
module api {
> ${security_policy} applies to every handler in this module.
> ${openapi_style} applies to every @api block.
service PaymentService {
@auth Customer
@api list_payments {
> Cursor pagination, default 20. Customers see only their rows.
}
}
}
}
Publish @acme/agent-standards once; every product imports the same prose, context paths, and macros. See packages.md.
What Pactia is
- An intent language — durable
.pactiafiles, not disposable chat - Graded precision — prose-only to fully tagged; you choose the level
- Model and platform agnostic — same source → same IR → any agent
- Shareable through packages — git-pinned imports for prose, context, tags, and macros
- A whole-product spec — backend, web, mobile, desktop in one workspace
What Pactia is not
| Pactia is | Pactia is not |
|---|---|
| Intent for whole products | A replacement for Rust or React |
| Prose + optional tags | A mandate to specify everything |
| Shareable, versioned packages | Ephemeral ChatGPT one-offs |
| AI-neutral compiled output | A single-vendor prompt format |
Formalized facts are enforceable when you tag them; implementation stays free.
Design principles
- Intent over implementation — declare what must stay true.
- Graded precision — prose-only to fully tagged.
- Share through packages — reuse intent via imports, not copy-paste.
- AI-native artifact — permanent files every session inherits.
- Strict when structured — tags parse the same way everywhere.
- Free when prose — guidance until you promote a line to a tag.
Minimal example
Roles and entities tagged where structure helps; business rules stay prose until you need enforcement.
pactia 1.0
import @pactia/kyc-compliance;
import @pactia/rust-stack;
product P2PExchange {
> Peer-to-peer marketplace with escrow. KYC before first trade over the platform limit.
> Disputes: admins may freeze a trade; traders cannot self-resolve.
> Never hold card data; never log full bank account numbers.
#rust-stack
module exchange {
@actor traders { role: Trader, capabilities: [create_offers, take_trades], }
@actor admins { role: Admin, capabilities: [resolve_disputes], }
model {
@entity Trade {
@@pk id: uuid,
buyerId: uuid,
sellerId: uuid,
status: TradeStatus,
}
}
service TradeService {
@auth { roles: [Trader] }
#buyer
@api mark_payment_sent {
method: POST,
path: "/api/v1/trades/:id/mark-payment-sent",
> Buyer asserts fiat was sent. Idempotent if already sent.
}
}
}
}
See also
- language-spec.md — grammar and workspace
- packages.md — composition and package manager
- compilation.md — compiler pipeline
- platform.md — stack packages