diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..9dc7687 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,263 @@ +# AGENTS.md — instructions for AI coding/operations agents + +Machine-facing operating instructions for this repository. Every command and +behavior below was executed against committed fixtures at this commit. No +marketing language, no aspirational capability. + +**Hard rule: do not invent commands, flags, interfaces, endpoints, or maturity +claims that are not listed here.** If a capability you need is not documented in +this file, it does not exist in this repository. Report that as a limitation +rather than improvising a substitute or assuming an undocumented interface. + +--- + +## 1. What AuthContract is + +AuthContract turns an institutional rule into a canonical, digest-bound artifact, +evaluates a proposed action against that rule together with runtime facts, and +issues a decision receipt whose every bound value can be independently +recomputed from the raw inputs. + +Implemented chain: + +``` +contract artifact + → canonical identity (RFC 8785 JCS + SHA-256) and sibling digest binding + → deterministic projection into a declared action domain + → runtime fact admission (issuer / trust basis / freshness / evidence binding) + → action check against the projection + → ALLOW or REFUSE + → decision receipt (on ALLOW only) + → independent receipt verification from raw inputs +``` + +## 2. Current maturity + +Experimental reference implementation, **TRL 4**. Implemented, tested, and +benchmarked against **one synthetic banking specimen family**. + +**Automated natural-language source-to-rule comparison is NOT implemented end to +end.** It is the project's target capability. Worked examples in `README.md` +below the `# How it works — the full model` divider describe target behavior, not +current behavior. Do not represent it as working. + +## 3. Requirements + +- Python **>= 3.10** (`pyproject.toml: requires-python = ">=3.10"`). CI tests 3.10 and 3.12. +- `git`. +- No credentials, services, or network beyond clone and dependency install. + +## 4. Installation + +```bash +git clone https://github.com/veraxis-protocol/AuthContract.git +cd AuthContract +python3 -m venv .venv && source .venv/bin/activate +pip install -e ".[test]" +``` + +Verify: `pytest -q` → `342 passed`. + +**Not on PyPI.** `pip install authcontract` will not work. Install from source only. + +## 5. Supported CLI commands + +Exactly six. Any other subcommand does not exist. + +| Command | Purpose | +|---|---| +| `authcontract verify ` | Verify one rule artifact's canonical identity | +| `authcontract project ` | Project a rule into its declared runtime action domain | +| `authcontract check-action ` | Check an action against the declared domain | +| `authcontract git-gate ` | Check a CI result against the version that would actually merge | +| `authcontract run-specimen --execution-result ` | Full end-to-end check; issues a receipt on PASS | +| `authcontract verify-receipt ` | Recompute the receipt bindings from raw inputs and compare | + +`--execution-result` accepts exactly: `NOT_EXECUTED`, `SIMULATED_SUCCESS`, `SIMULATED_FAILURE`. + +All commands emit **single-line JSON on stdout**. + +## 6. Canonical successful end-to-end command + +```bash +authcontract run-specimen \ + fixtures/banking_payment_specimen.json \ + fixtures/actions/send_payment_valid.json \ + fixtures/runtime/facts_valid.json \ + --execution-result SIMULATED_SUCCESS +``` + +Expect `"status": "PASS"`, `"decision": "ALLOW"`, `"reason_code": "OK"`, a +`receipt` object with 10 bound fields, and **exit code 0**. + +## 7. Canonical refusal commands + +Undeclared action → `RUN_UNCLASSIFIED_ACTION`: + +```bash +authcontract run-specimen \ + fixtures/banking_payment_specimen.json \ + fixtures/actions/send_payment_unknown_action_type.json \ + fixtures/runtime/facts_valid.json \ + --execution-result SIMULATED_SUCCESS +``` + +Stale runtime fact → `RUN_FACT_STALE`: + +```bash +authcontract run-specimen \ + fixtures/banking_payment_specimen.json \ + fixtures/actions/send_payment_valid.json \ + fixtures/runtime/facts_stale.json \ + --execution-result SIMULATED_SUCCESS +``` + +Both return `"status": "REFUSED"` and **exit code 1**. **No receipt is issued on +refusal.** A refusal is correct, expected behavior — do not treat it as a failure +to be worked around, and do not retry with altered inputs to force an ALLOW. + +## 8. Receipt verification + +```bash +authcontract verify-receipt \ + fixtures/runtime/receipt_valid.json \ + fixtures/banking_payment_specimen.json \ + fixtures/actions/send_payment_valid.json \ + fixtures/runtime/facts_valid.json +``` + +Expect `"status": "PASS"`, `"reason_code": "OK"`, exit `0`. This recomputes every +bound value from raw inputs and trusts no field in the receipt. + +`verify-receipt` requires the **receipt object itself**, not the full +`run-specimen` wrapper. Extract it first: + +```bash +authcontract run-specimen ... > /tmp/full.json +python3 -c "import json; json.dump(json.load(open('/tmp/full.json'))['receipt'], open('/tmp/receipt.json','w'))" +``` + +Passing the wrapper returns `VEIP_RECEIPT_MALFORMED`. + +## 9. Exit-code semantics + +| Exit | Meaning | +|---|---| +| `0` | PASS / ALLOW | +| `1` | REFUSED, or an error condition | + +Branch on the JSON `status` and `reason_code` fields rather than parsing prose. + +## 10. Reason codes + +`reason_code` is a **machine-facing identifier** in the current implementation; +`OK` on success. Branch on it rather than on prose — within the currently +documented and tested interface it is the intended programmatic signal. + +**Cross-version stability is not guaranteed.** This repository establishes no +versioned public-interface commitment that reason codes remain unchanged across +future releases; no such versioning or pinning mechanism exists yet. Treat the +set below as accurate for this commit, and re-check it if you upgrade. Do not +represent these codes as a stable API contract. + +`message` (present on refusal) is human-readable and **not** contractual at any +version — do not parse it. + +Codes observed in the implementation, by family: + +- **Artifact/identity:** `AC_DIGEST`, `AC_DIGEST_SCOPE`, `AC_INVALID_JSON`, `AC_INVALID_STRUCTURE`, `AC_IO_ERROR`, `AC_INTERNAL_ERROR` +- **Projection/action:** `RUN_UNCLASSIFIED_ACTION`, `RUN_DOMAIN_ESCAPE`, `RUN_INACTIVE_CONTRACT`, `CONTRACT_SCOPE_CONFLICT` +- **Runtime facts:** `RUN_FACT_STALE`, `RUN_FACT_INADMISSIBLE`, `RUN_FACT_IDENTITY_MISMATCH`, `RUN_FACT_EVIDENCE_MISMATCH`, `RUN_FACT_UNATTESTED`, `RUN_FACT_SELF_ASSERTED`, `RUN_FACT_TRUST_BASIS`, `RUN_FACT_REPRESENTATION`, `RUN_FACT_FUTURE_TIMESTAMP`, `RUN_FACT_TIME_UNVERIFIABLE`, `RUN_FACT_TYPE_UNSUPPORTED`, `RUN_FACT_CORROBORATION_MISSING`, `RUN_FACT_CONTRACT_INVALID` +- **Orchestration/receipt:** `VEIP_REFUSED`, `VEIP_MALFORMED_INPUT`, `VEIP_MISSING_ACTIVATION_ID`, `VEIP_INVALID_EXECUTION_RESULT`, `VEIP_FACT_BUNDLE_INCOMPLETE`, `VEIP_RECEIPT_MALFORMED`, `VEIP_RECEIPT_MISMATCH` +- **Git gate:** `GIT_FAIL`, `GIT_ERROR`, `GIT_UNRESOLVED`, `GIT_NEUTRAL_CONCLUSION`, `GIT_MERGE_RESULT_UNVERIFIED`, `GIT_GATE_REFUSAL` + +## 11. Python library integration + +```python +import json +from authcontract.veip import run_specimen, verify_receipt + +artifact = json.load(open("fixtures/banking_payment_specimen.json")) +action = json.load(open("fixtures/actions/send_payment_valid.json")) +facts = json.load(open("fixtures/runtime/facts_valid.json")) + +result = run_specimen(artifact, action, facts, execution_result="SIMULATED_SUCCESS") +# result.decision -> "ALLOW"; result.reason_code -> "OK" + +if result.decision == "ALLOW": + check = verify_receipt(result.receipt, artifact, action, facts) + # check.status -> "PASS" +``` + +`run_specimen` returns a `RunResult` (`decision`, `reason_code`, `message`, +`receipt`). `verify_receipt` returns a `VerifyResult` (`status`, `reason_code`, +`message`). + +**Refusals are return values, not exceptions.** `run_specimen` does not raise on +an ordinary refusal. Check `.decision` / `.status`; do not wrap these calls in +try/except expecting refusal to surface as an exception. + +Other useful entry points: `authcontract.digest` (`contract_digest`, +`verify_artifact`, `canonical_bytes`), `authcontract.projection` (`project`, +`check_action`, `projection_digest`). + +## 12. GitHub merge-gate workflow + +`.github/workflows/authcontract-gate.yml` exists and runs `authcontract git-gate` +on `pull_request` events. It re-resolves the base ref live and proves the +evaluated commit contains both base and PR head. + +**The workflow's presence does NOT mean GitHub requires it.** Whether a check is +*enforced* — whether branch protection blocks a merge on failure — is separate +repository configuration (branch protection / rulesets), not workflow content. +Do not report the gate as an enforced required status check. If you need to know +what is actually required to merge, read the repository's branch-protection +settings directly. + +## 13. Interfaces that do NOT exist + +Do not attempt these, and do not report them as available: + +- **No PyPI package.** Source install only. +- **No HTTP or gRPC service.** No server, no endpoint, no daemon. In-process library and CLI only. +- **No persistence layer.** Stateless over in-memory inputs. Receipts are not stored for you. +- **No multi-contract registry.** One artifact per invocation; no cross-contract selection or resolution. +- **No replay protection.** Replayed identical requests produce identical receipts — that is determinism, not protection. No nonce, sequence, or single-use semantics. +- **No concurrency or distribution layer.** +- **No telemetry.** +- **No authentication, identity, or PKI subsystem** of production grade. + +## 14. Claim ceiling + +This repository establishes **only** what its measurements demonstrate, bounded +to one synthetic banking specimen family on a single machine and process. It does +**not** establish: production readiness; regulatory or legal correctness; +universal source-to-rule derivation; arbitrary-domain compatibility; security +certification; distributed scalability; formal proof; or comparative superiority +over any other system. + +Do not soften, omit, or paraphrase this ceiling when summarizing the project. + +## 15. Licensing + +**No license is declared.** No `LICENSE` file exists and `pyproject.toml` +declares no license field, so default copyright applies and no usage rights are +granted. Treat this as source-available for evaluation and reading. **Do not +describe it as open source**, and do not assume redistribution or derivative +rights. Direct licensing questions to the repository owner. + +## 16. Prohibition on invention + +If asked to do something this repository does not support: + +1. State plainly that the capability does not exist here. +2. Cite the relevant section above. +3. Do **not** fabricate a command, flag, endpoint, config key, or package name. +4. Do **not** infer capability from the roadmap, from target-behavior examples, + or from the presence of a workflow file. +5. Do **not** weaken or bypass a refusal to produce a desired outcome. + +Further reading: [`README.md`](README.md) · measured evidence +[`docs/BENCHMARKS.md`](docs/BENCHMARKS.md) · maturity +[`docs/TRL-ASSESSMENT.md`](docs/TRL-ASSESSMENT.md) · planned work +[`docs/ROADMAP.md`](docs/ROADMAP.md). diff --git a/README.md b/README.md index 85b18d3..da20f99 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ Note that **no receipt is issued on refusal** — a refused decision never produ |---|---| | `status` | `PASS` or `REFUSED` — the outcome of the check | | `decision` | `ALLOW` on a permitted action; absent on refusal | -| `reason_code` | Stable machine-facing identifier (e.g. `RUN_FACT_STALE`). Safe to branch on | +| `reason_code` | Machine-facing identifier (e.g. `RUN_FACT_STALE`). Branch on this rather than on prose — but see the note below on cross-version stability | | `message` | Human-readable explanation of a refusal | | `contract_digest` | Canonical identity (RFC 8785 JCS + SHA-256) of the rule that applied | | `projection_digest` | Identity of the action domain the rule was projected into | @@ -170,6 +170,8 @@ Every digest is recomputable from raw inputs. That is what makes the receipt che Exit codes: `0` pass · `1` refusal. +**On `reason_code` stability.** Reason codes are the intended programmatic signal within the currently documented and tested interface, and are accurate for this commit. This repository does **not** yet establish a versioned public-interface commitment that they remain unchanged across future releases — no versioning or pinning mechanism exists. Re-check them if you upgrade, and do not treat them as a frozen API contract. `message` is human-readable and is not contractual at any version. + --- ## How to integrate it today @@ -263,6 +265,30 @@ Measured evidence and its limits: [`docs/BENCHMARKS.md`](docs/BENCHMARKS.md) · | Understand the terminology | [`docs/DEVELOPER-LANGUAGE.md`](docs/DEVELOPER-LANGUAGE.md) | | See how this compares to other systems | [`docs/SOTA.md`](docs/SOTA.md) | | Understand the full conceptual model | keep reading below | +| Use AuthContract from an AI coding agent | [`AGENTS.md`](AGENTS.md) | + +--- + +## Getting help, reporting problems, and commercial use + +| | | +|---|---| +| **Found a bug, or a claim that doesn't hold?** | Open a [GitHub issue](https://github.com/veraxis-protocol/AuthContract/issues). Reproduction steps against the committed fixtures are the most useful thing you can include. | +| **Benchmark didn't reproduce?** | Include your OS, Python version, and the `benchmarks/results/` JSON your run produced — the harness records the DUT and harness SHAs it verified. | +| **Commercial or institutional use** | [veraxis.io](https://veraxis.io) | + +**Contributions.** There is no contribution process established yet, and no +contributor licence or review policy exists. Issues are the reliable path today. +If you are considering a substantive contribution, open an issue first so it +isn't wasted effort. + +**A note on scope of support.** This is an experimental reference implementation +maintained as research and engineering evidence. There is no support commitment, +response-time expectation, or maintenance guarantee attached to it. + +If the clean-room run above was useful to you, a GitHub star helps other +engineers evaluating this space find it — entirely optional, and only if it +actually earned one. --- --- diff --git a/docs/AGENT-USABILITY.md b/docs/AGENT-USABILITY.md new file mode 100644 index 0000000..f30f327 --- /dev/null +++ b/docs/AGENT-USABILITY.md @@ -0,0 +1,110 @@ +# Agent usability test record (AC-037) + +Clean-room test of this repository from the perspective of an AI coding / +operations agent, using **only** repository files: `README.md`, `AGENTS.md`, and +the executable interfaces. No hidden coaching, no undocumented commands. + +**This document records observations. It does not certify CURRENT-SDLC Gate F** — +that adjudication belongs to the Engineering Lead. + +## Test conditions + +| | | +|---|---| +| Method | Fresh `git clone` into an empty directory, checkout of the candidate commit | +| Candidate commit | `7e7f28d6d8ba8d94cd42d8f3ff4989bf637068d6` | +| Environment | Linux x86_64, Python 3.11.15, git 2.43.0 | +| Instructions used | `AGENTS.md` and `README.md` only | +| Prior knowledge assumed | None | + +Every command below was executed. Results are pasted from real output. + +--- + +## Criterion matrix + +| # | Criterion | Result | Evidence | +|---|---|---|---| +| A | Determine what AuthContract currently does | **PASS** | `AGENTS.md` §1 states the implemented chain in seven steps; §2 states TRL 4 and that automated natural-language source-to-rule comparison is **not** implemented end to end. | +| B | Install it | **PASS** | `AGENTS.md` §4 commands ran verbatim. `pytest -q` → **342 passed**. | +| C | Execute the successful E2E path | **PASS** | §6 command → `status PASS`, `decision ALLOW`, `reason_code OK`, receipt with **10** bound fields, **exit 0**. | +| D | Intentionally produce REFUSED | **PASS** | §7 command 1 → `REFUSED` / `RUN_UNCLASSIFIED_ACTION`, exit 1. Command 2 → `REFUSED` / `RUN_FACT_STALE`, exit 1. Both confirmed `receipt` absent, matching the documented "no receipt is issued on refusal". | +| E | Verify a receipt | **PASS** | §8 command on the committed fixture → `PASS` / `OK`, exit 0. The documented extraction step also verified: extracting `.receipt` from the wrapper → `PASS` / `OK`. | +| F | Interpret PASS/REFUSED and `reason_code` | **PASS** | §9 exit-code table and §10 reason-code families match observed output. Codes in §10 were extracted from source, not recalled. | +| G | Invoke it from Python | **PASS** | §11 example run verbatim → `decision ALLOW reason OK`, then `status PASS OK`. The documented "refusals are return values, not exceptions" claim was tested directly: a stale-fact run returned `REFUSED` / `RUN_FACT_STALE` with **no exception raised**. | +| H | Determine which interfaces do NOT exist | **PASS** | §13 claims tested rather than assumed: `authcontract.server`, `.api`, `.http`, `.registry`, `.db` all raise `ModuleNotFoundError`. `authcontract --help` lists exactly the six documented subcommands and no others. | +| I | Recognize that workflow presence ≠ enforced branch protection | **PASS** | §12 states the distinction explicitly and instructs the agent not to report the gate as enforced. Independently corroborated: `authcontract-gate.yml` is `on: pull_request` only. | +| J | Recognize the claim ceiling | **PASS** | §14 states the ceiling and instructs against softening it. §15 states no license is declared and instructs against describing the project as open source. | + +**Totals: 10 PASS · 0 FAIL · 0 NOT EVALUATED.** + +--- + +## Verified negative behavior + +A usability claim is only worth as much as its failure modes, so these were +executed rather than asserted: + +- **Wrapper passed to `verify-receipt`.** `AGENTS.md` §8 warns that passing + `run-specimen`'s full JSON wrapper instead of the extracted receipt object + returns `VEIP_RECEIPT_MALFORMED`. Confirmed exactly: + `VEIP_RECEIPT_MALFORMED: receipt missing required field(s): ['activation_id', 'admission_digest', 'contract_digest', 'decision_time', 'exact_action_digest', 'execution_result', 'projection_digest', 'receipt_digest', 'runtime_fact_set_digest']`, exit 1. + This is the same defect the AC-028 clean-room run originally uncovered; it is + now documented before an agent can hit it. +- **No receipt on refusal.** Both refusal paths were checked for a `receipt` + key. Absent in both. +- **Unsupported modules.** Five plausible module names an agent might guess were + imported and all failed, confirming §13 rather than trusting it. + +--- + +## Observations and limitations + +1. **`AGENTS.md` is the only agent surface.** No prior `AGENTS.md`, + `CONTRIBUTING.md`, skill file, or machine-readable usage guidance existed, so + this is additive rather than duplicative. A separate reusable skill file was + **deliberately not added** — see the decision note below. + +2. **The reason-code list is descriptive, not a stability contract.** §10 lists + codes extracted from the implementation at this commit. Nothing in the + repository pins them as a versioned public interface, so an agent should + branch on them but should not assume they are frozen across versions. This is + a gap in the repository, not in `AGENTS.md`. + +3. **Refusal semantics are the most likely agent failure mode.** An agent + optimizing for a successful exit code could plausibly retry a refusal with + altered inputs until it gets `ALLOW`. `AGENTS.md` §7 and §16 explicitly + prohibit this, but the prohibition is instructional — nothing mechanically + prevents it. + +4. **Not tested: an actual third-party agent.** This record was produced by the + same executor that wrote `AGENTS.md`. That is a real limitation on its + evidentiary weight — it demonstrates the instructions are *accurate and + executable*, not that an independent agent *would* follow them. Independent + agent reproduction remains absent, consistent with the TRL 4 assessment in + [`docs/TRL-ASSESSMENT.md`](TRL-ASSESSMENT.md). + +--- + +## Decision: no separate skill file + +AC-037 Phase 2 permits an optional reusable agent skill. **One was not added.** + +`AGENTS.md` already carries the full install → run → refuse → verify → interpret +sequence with real commands and real outputs. A separate skill file would either +duplicate it — creating two surfaces that can drift apart, which is precisely the +class of defect AC-036S corrected in `README.md` — or would have to invent +tool-specific automation scaffolding that does not exist in this repository. + +Recorded explicitly so the omission is understood as a decision rather than an +oversight. + +--- + +## Claim ceiling + +This record establishes only that the documented agent-facing instructions are +accurate and executable at this commit, for one synthetic banking specimen +family, on one machine. It establishes no production readiness, no regulatory or +legal correctness, no arbitrary-domain compatibility, no security certification, +and no independent validation.