# Author a company in HSX

HSX is the textual company language. An author declares the business choices
that determine money movement. The compiler checks those choices and lowers
them to HSX-JSON, a Business Frame, and then UDL. Do not hand-author the
generated lifecycle or ledger choreography.

## Program shape

One `.hsx` file contains a flat list of declarations in any order. Forward
references are legal.

```hsx
program photo_booth "Photo booth rentals"

import { held_payment } from "settlement"

party renter: person
party company: business

asset booth: good { title_transfer: off_platform }

settlement booking = held_payment {
  payer: renter
  payee: company
  amount: bookingFee: money(SAR)
  release: port confirm_delivery
  on_cancel(funded) { renter: 100% }
}

port confirm_delivery {
  allowed: [company]
  shape { boothId: id(booth) deliveredOn: date }
}
```

The file declares exactly one `program`. Its name uses `snake_case`. Import
every settlement brick from the only module, `"settlement"`, before using it.

A `party` is a `person` or `business`. An `asset` is `access`, `claim`, `good`,
`service`, or `ticket`. `title_transfer` says whether the asset changes hands
on or off platform. It does not move money.

A `settlement` instance becomes a published business noun. Its name becomes
the noun id. The brick determines the noun's states, verbs, accounts, holds,
transfers, exits, and conservation checks.

A `port` is a typed decision owned by the tenant's backend. `allowed` names
the parties that may decide. Its optional `shape` accepts `text`, `date`,
`id(<asset>)`, and `money(<CUR>)` fields. A port decides whether an already
proved money path fires. It does not choose an arbitrary amount or invent a
new path.

Names for programs, declarations, and meters use `snake_case`. Stored fields
use `camelCase`. Currency uses a three-letter uppercase code. Percentages are
exact to one basis point and never round during compilation.

## The 17 settlement bricks

Use a brick from this closed set. Compose bricks when one business flow needs
more than one money relationship.

| Brick                      | Contract                                                                                            |
| -------------------------- | --------------------------------------------------------------------------------------------------- |
| `advance`                  | Disburse now, then repay from one declared hold release or one finite schedule.                     |
| `captured_payment`         | Reserve once, capture strict partial slices, settle the remainder, or void it.                      |
| `conditional_disbursement` | Pay one externally approved amount under a stored parent cap.                                       |
| `credit_facility`          | Hold reusable or non-reusable draw capacity while a referenced scheduled obligation owns repayment. |
| `deposit`                  | Reserve on the payer, then post the whole amount to the holder or void it back.                     |
| `funding_round`            | Cap committed money and contributor count, then collect or refund each commitment whole.            |
| `held_payment`             | Hold the payer's amount in escrow until a port releases it or a declared exit drains it.            |
| `instant_transfer`         | Transfer straight from payer to payee without custody.                                              |
| `metered`                  | Charge one committed per-unit rate on each usage event until the period closes.                     |
| `pooled_split`             | Pool one period total and pay fixed percentage shares on a stored date.                             |
| `premium_forward`          | Hold a premium, bind the policy through a port, then forward once minus commission.                 |
| `recurring_collection`     | Add mandate evidence and explicit attempts to a scheduled obligation. It never retries implicitly.  |
| `rotating_pool`            | Fix members, contribution, due anchors, and payout order before activation.                         |
| `scheduled`                | Partition one total across a finite number of stored-date anchors.                                  |
| `settlement_batch`         | Freeze capture lineage and signed adjustments, calculate net, then instruct one payout.             |
| `swap`                     | Let exactly two parties fund one escrow and release or unwind the exchange as one lifecycle.        |
| `weighted_distribution`    | Freeze evidence-backed weights and allocate with deterministic largest remainder.                   |

Do not hand-roll settlement choreography. If the 17 bricks cannot express a
money graph, the platform team must add one brick with its proof.

## Money laws

- Money fields hold integer minor units paired with one currency. Do not use
  decimal JSON numbers for amounts.
- All percentage splits use integer basis points. Lowering computes each piece
  with floor division and assigns the remainder to a declared recipient or the
  first piece.
- Every split emits a partition check. Create admission proves all pieces sum
  exactly to the total before any money moves.
- A payer-side fee rides on top and never enters custody. A payee-side fee is
  carved from the released amount.
- Schedules have a literal finite count. Lowering emits one idempotent verb per
  anchor.
- A held balance must drain on every reachable exit. The compiler refuses a
  program that can strand value.
- Decision ports choose when a proved route runs. They do not calculate money.
- The lowered noun may use only the seven UDL kernel instructions described in
  [udl.md](udl.md).

## `derived_amount`

Any settlement may declare one machine-computed on-top amount:

```hsx
derived_amount {
  field: platformAmount
  source: transferAmount
  rule: 2.5%
  bearer: payer
}
```

`field` and `source` use `camelCase`. `source` must be a stored money field on
the same settlement. `bearer` must name a declared party. `rule` must be above
0% and below 100%.

At create admission, the runtime computes
`floor(source * basisPoints / 10000)` with `BigInt`. It rejects a zero result.
The derived target is absent from public create input, so a caller cannot
supply or replace it. Lowering adds a create-time transfer from `bearer` to
`platform`. Version 1 refuses fixed and tiered rules. `advance.fee` remains a
separate credit term.

## Compile and check

Use the published `@hyperscale0/hsx` command:

```bash
bunx @hyperscale0/hsx check company.hsx --strict
bunx @hyperscale0/hsx build company.hsx --out company.hsx.json
```

`check` prints diagnostics and no artifact. `build` writes the HSX-JSON
document and Business Frame. Exit `0` means accepted, `1` means the compiler
refused the program, and `2` means the invocation or file failed. Diagnostics
carry source line, column, severity, and stage. Do not match diagnostic text as
a stable code.

## Evolution

Treat a live company as a versioned program. Additive changes can add a noun,
verb, optional field, state, transition, or settlement instance after the
product version increases. A changed money shape on a live flow needs a new
flow and a retire, drain, then remove migration. Removal, rename, a tighter
lifecycle, or an in-place money change is destructive and must fail.

Compile the candidate, validate its UDL, and compare it with the last live UDL
before minting a new Build. Read [udl.md](udl.md) for the exact append-only
rules.

## Source of truth

The compiler wins over this guide. Check the published `@hyperscale0/hsx`
package and its language reference (open/hsx/docs/reference.md in this tree),
especially when a brick parameter changes before 1.0.
