Metadata-Version: 2.4
Name: sm-provision
Version: 0.1.0
Summary: Delegated, field-scoped authority for an agent store to provision a resolution binding — a binding-provisioning profile of sm-dat.
Project-URL: Homepage, https://github.com/Sharathvc23/sm-provision
Project-URL: Spec, https://github.com/Sharathvc23/sm-provision/blob/main/SPEC.md
Author-email: StellarMinds <hello@stellarminds.ai>
License-Expression: MIT
License-File: LICENSE
Keywords: ai-agents,authorization,binding,delegation,nanda,registry
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: sm-dat>=0.2.0
Provides-Extra: bridge
Requires-Dist: sm-authority>=0.1.0; extra == 'bridge'
Requires-Dist: sm-bridge>=0.4.0; extra == 'bridge'
Provides-Extra: dev
Requires-Dist: coverage>=7.0; extra == 'dev'
Requires-Dist: httpx>=0.24; extra == 'dev'
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Description-Content-Type: text/markdown

# sm-provision — delegated, field-scoped binding provisioning

**A binding-provisioning profile of [`sm-dat`](https://github.com/Sharathvc23/sm-dat).** The
signed, bounded grant a resolution-namespace **owner** gives an **agent store** to write specific
fields of the owner's **binding** in a registry — create it, repoint it, suspend it, revoke it —
and nothing else. Runtime-agnostic, vendor-neutral.

`sm-dat` answers *"was this agent allowed to **act**?"*. `sm-provision` answers the adjacent
question *"was this store allowed to **write this field of this binding**?"* — using the same
grant envelope, the same signing path, and the same three-valued verdict. It adds **no new
crypto** and requires **no change to `sm-dat`**: binding operations ride in the DAT's
`action_categories`, and the field-scope rides in `scope.stateless` under `binding_*` keys the
DAT core ignores and this profile enforces. The owner's signature covers both.

```python
from sm_provision import (Identity, sign_grant, build_binding_grant,
                          build_write_request, verify_binding_write, OP_UPDATE_TARGET)

owner, store = Identity.generate(), Identity.generate()

grant = sign_grant(owner, build_binding_grant(
    grantee_did=store.did,
    subject="john@hotmail.com",                       # human-readable locator
    subject_issuer="https://login.microsoftonline.com",
    subject_provider_id="oid:…",                      # durable anchor (recorded, not verified here)
    registry="did:web:index.example",
    allowed_ops=[OP_UPDATE_TARGET],
    allowed_fields=["agent_card_url"],                # store-managed fields only
    allowed_target_hosts=["cards.acme-store.example"],
    allowed_agent_roles=["personal-assistant"],
    not_after="2027-07-01T00:00:00Z",
    human_summary="Acme may maintain John's personal-assistant binding.",
))

req = build_write_request(op=OP_UPDATE_TARGET, subject="john@hotmail.com",
                          fields=["agent_card_url"], target_host="cards.acme-store.example",
                          agent_role="personal-assistant")

v = verify_binding_write(grant, req, "2026-07-28T12:00:00Z", store_did=store.did)
print(v.status, v.reason)      # SATISFIED ok  — or a VIOLATED/INDETERMINATE reason
```

## The invariant that defines this library

**A store can only ever be granted *store-managed* fields.** Owner-controlled fields (`subject`,
`recovery_delegates`, `transfer`, …) and registry-controlled fields (`validation_status`,
`dispute_state`, …) are **never** delegable — `build_binding_grant` rejects them at construction,
and the verifier rejects them again at write time (defence in depth). Most capability/skill/runtime
change belongs *inside the Agent Card*; the binding changes only when the discovery target,
authority, lifecycle, or provider relationship changes.

## Two-layer, fail-closed verification

1. **Authority** — `sm_dat.verify_grant`, verbatim: signature by the owner, grantee == store,
   temporal window, revocation, op-in-scope. Its `VIOLATED`/`INDETERMINATE` verdicts propagate
   unchanged — this profile never launders one into a pass.
2. **Field-scope** — right subject; only store-managed fields; only granted fields; only permitted
   target-hosts and agent-roles.

## What it deliberately does not own

Establishing that the grantor really is the owner (DAT SPEC §5.4 O1) is **out of band** — a
separate authority-evidence mechanism binds `grantor_did`/`subject` to the real owner; this
profile only records the claimed anchor. Applying the write, logging it, and resolving conflicts
between writers belong to the registry. See [SPEC.md](./SPEC.md) §1.1.

## Status

- **[SPEC.md](./SPEC.md)** — the normative draft (`provision/0.1-draft`).
- `vectors/provision/0.1/` — the deterministic conformance corpus; regenerate with
  `python vectors/_generate.py`, replay with `pytest`.
- Depends on `sm-dat` (grant envelope, signing, verification) → `sm-arp` (identity, crypto). No
  transport, no framework.

## License

MIT © 2026 StellarMinds. See [LICENSE](./LICENSE).

---

Part of the **NANDA** ecosystem · built by [StellarMinds](https://stellarminds.ai).
