# Two packages, one pinned borrowing (synthetic)

Borrower `demo.handbook.payroll` computes a premium from a rate schedule it
borrows from `demo.handbook.rates`. The schedule ships in two versions;
the borrower is pinned to 1.0.0. A file registry with both versions lets
the reader replay the update. Nothing here formalizes any act.

Layout:

- `rates-1.0.0/` — the source schedule: class 1 → 0.005, class 2 → 0.012.
- `rates-1.0.1/` — the amended schedule: class 2 → 0.015 (one rule line).
- `payroll/` — the borrower, pinned to 1.0.0, with vendored `deps/`.
- `registry/` — file registry publishing both versions.

## Run

Tool `law` 0.1.0, semantics law.core/0.2 (published build):

```sh
$ law test docs/handbook/files/fixtures/reuse-payroll/payroll
law test demo.handbook.payroll: world demo.handbook.payroll, demo.handbook.rates
  ok   [demo.handbook.payroll#authored] tests/premium.lawtest / premium uses the borrowed class-2 rate
total: 1 checked, 1 passed, 0 failed, 0 not run; code 0
```

The header names the two-package world. The scene asserts class 2 and a
1,000,000 KZT payroll and expects 12000 KZT — 0.012 times the million,
where the rate is the borrowed schedule's and the arithmetic is the
borrower's.

## The pin holds

Version 1.0.1 exists in the registry and changes the borrowed rate, yet
the borrower above stays green: the pin is the `import ... version
"1.0.0"` line, the manifest entry, the lock's contentHash
(`sha256:51f4da7c…`, rates 1.0.0), and the vendored
`deps/demo.handbook.rates.lawir.json`. Nothing flows in silently.

## The update fails loudly

On a copy of `payroll/`, move the pin:

```sh
$ law update 'demo.handbook.rates@1.0.1' --registry file=../registry
file ← ../registry (--registry)
~ demo.handbook.rates 1.0.0 -> 1.0.1
changed: .law/transport.json
changed: deps/demo.handbook.rates.lawir.json
changed: law.lock
changed: law.toml
changed: package.law
$ law test .
law test demo.handbook.payroll: world demo.handbook.payroll, demo.handbook.rates
  FAIL [demo.handbook.payroll#authored] tests/premium.lawtest / premium uses the borrowed class-2 rate
        truth_status == TRUE_ONLY: in the document NEITHER
total: 1 checked, 0 passed, 1 failed, 0 not run; code 1
```

(Observed on a scratch copy; the shipped `payroll/` stays pinned to
1.0.0.) The update moves five artifacts at once — import line, manifest,
lock, vendored IR, plus the tool's own transport bookkeeping — and the
suite trips on the changed assumption: 12000 KZT no longer derives. That failure is the boundary working as designed:
the borrower notices the upstream change as a named event, not as drift.

## Boundary record

Borrowed item: class rates `class_rate/2` with inputs `risk_class/2`.

- source: `demo.handbook.rates`, pinned version 1.0.0,
  contentHash `sha256:51f4da7c9ee041e09244ea33449af619ba0b8aa3e9515dd48e2dfa2c572b521c`.
- content: two rate rules over the synthetic `RATE_SCHEDULE` source.
- provenance: synthetic schedule authored for this drill; identity checked
  by exact version plus content hash, not by title.
- assumption relied upon: class-2 rate is 0.012 per unit of payroll;
  pinned behaviorally by the 12000 KZT expectation.
- transfer mode: import of `pub` declarations (`Employer`, `risk_class`,
  `class_rate`); only `pub` names cross the boundary.
- revisit trigger: any new published version reopens this entry; the
  1.0.1 update above is the worked trigger.
