yay-layer 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONSTITUTION.md +55 -0
- package/LICENSE +21 -0
- package/README.md +383 -0
- package/bin/yay.js +3550 -0
- package/package.json +55 -0
- package/src/adopt.js +181 -0
- package/src/adversary.js +119 -0
- package/src/analyze.js +270 -0
- package/src/assurance.js +122 -0
- package/src/attest.js +216 -0
- package/src/capability.js +59 -0
- package/src/constitution.js +162 -0
- package/src/coverage.js +77 -0
- package/src/crypto.js +78 -0
- package/src/dashboard.js +463 -0
- package/src/durable.js +152 -0
- package/src/e2e.js +67 -0
- package/src/extract.js +179 -0
- package/src/foundation.js +143 -0
- package/src/gate.js +252 -0
- package/src/grants.js +249 -0
- package/src/history.js +77 -0
- package/src/ids.js +40 -0
- package/src/manifest.js +303 -0
- package/src/map.js +1742 -0
- package/src/mutate.js +192 -0
- package/src/objects.js +31 -0
- package/src/phone.js +188 -0
- package/src/plan.js +141 -0
- package/src/policy.js +0 -0
- package/src/predicate.js +143 -0
- package/src/prove.js +876 -0
- package/src/ratify.js +28 -0
- package/src/record.js +30 -0
- package/src/reverify.js +212 -0
- package/src/roster.js +117 -0
- package/src/signer-page.js +603 -0
- package/src/specdiff.js +69 -0
- package/src/tags.js +67 -0
- package/src/testrun.js +41 -0
- package/src/util.js +234 -0
- package/src/vendor/recovery.js +217 -0
- package/src/vendor/tweetnacl.min.js +1 -0
- package/src/verify.js +560 -0
- package/standard/STANDARD.md +135 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# YayLayer Standard v0.1
|
|
2
|
+
|
|
3
|
+
*A protocol for provable, signed AI code.*
|
|
4
|
+
|
|
5
|
+
> YayLayer is a building permit for AI-written code: approved blueprints first, an inspector who checks the build matches them, and you can't move in until it passes.
|
|
6
|
+
|
|
7
|
+
This document is the source of truth every tool derives from — the extractor, the verifier, the signer, the map, and the AI [Constitution](../CONSTITUTION.md). Status: **draft**. Where the reference implementation only partially covers a section, it is marked **MVP** / **roadmap**.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. Core model
|
|
12
|
+
|
|
13
|
+
- **YayLayer** — the protocol/system as a whole.
|
|
14
|
+
- **Cell** — one sealed unit of meaning, at any order. Flat id, prefix `C-` (e.g. `C-040`). A "module" is *not* a separate type — it is simply a Cell that declares `contains`. (Convention: give container Cells a high range, e.g. `C-900+`.)
|
|
15
|
+
- **Policy** — a cross-cutting rule that ranges over many Cells (prefix `P-`).
|
|
16
|
+
- **Coverage is total; granularity is meaning-level.** Every line of code lives inside some Cell; a Cell is the smallest chunk with a purpose you can state in one `intent:` sentence. Private helpers are governed by their Cell's spec, not separately specced.
|
|
17
|
+
|
|
18
|
+
## 2. The marker grammar
|
|
19
|
+
|
|
20
|
+
A Cell's spec lives in comments between two unique markers, so a parser can find it and a human can read it:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
//∷YAY⟨C-040⟩ v1
|
|
24
|
+
// <field>: <value>
|
|
25
|
+
// ...
|
|
26
|
+
//∷YAY-END⟨C-040⟩
|
|
27
|
+
<the code the spec governs>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- `∷YAY⟨id⟩` opens; `∷YAY-END⟨id⟩` closes. `YAY` means "this is YayLayer"; the id names the Cell.
|
|
31
|
+
- The comment lead may be `//` or `#` (language-dependent). Ids match `[A-Za-z0-9._-]+`.
|
|
32
|
+
- A continuation line (a comment line with no `key:`) appends to the previous field.
|
|
33
|
+
|
|
34
|
+
## 3. Spec fields
|
|
35
|
+
|
|
36
|
+
Two tracks. **Machine fields** are checkable and can earn Green. `intent:` is human prose, judged by an AI reviewer that is **downgrade-only** — it can lower a color but never lift a Cell to Green.
|
|
37
|
+
|
|
38
|
+
| Field | Track | Meaning |
|
|
39
|
+
|-------|-------|---------|
|
|
40
|
+
| `unit` | machine | the function/component/route this Cell governs |
|
|
41
|
+
| `lang` | machine | language (picks the adapter) |
|
|
42
|
+
| `intent` | human | one plain sentence; vague ⇒ capped at Yellow |
|
|
43
|
+
| `in` / `out` | machine | typed shape of inputs / result |
|
|
44
|
+
| `pure` | machine | `yes` ⇒ no side effects (verified) |
|
|
45
|
+
| `ensures` | machine | behavioural promise (property-tested — roadmap) |
|
|
46
|
+
| `throws` | machine | declared error paths |
|
|
47
|
+
| `effects` | machine | declared side effects (undeclared ⇒ Red/Yellow) |
|
|
48
|
+
| `contains` | machine | child Cell ids (makes this a module) |
|
|
49
|
+
| `feeds` | machine | consumer Cell ids (builds the flow graph) |
|
|
50
|
+
|
|
51
|
+
## 4. The seal
|
|
52
|
+
|
|
53
|
+
`specHash = sha256(normalized spec block)`. **You sign the spec, not the code** — so refactors pass freely; only a changed *promise* re-prompts you. (Optional **code-pin**, off by default, makes a Cell's seal also cover a code hash so any edit re-prompts you — reserved for crown-jewel Cells; human-enabled only.)
|
|
54
|
+
|
|
55
|
+
Signatures are **ed25519**. A seal is a signature over the canonical bytes of an *approval*:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{ "id":"A-0007", "project":"…", "prev":"A-0006", "nonce":"…",
|
|
59
|
+
"at":"…", "signer":"alice",
|
|
60
|
+
"brief": { "text":"Add pause/resume to the game loop and persist the high score between sessions.",
|
|
61
|
+
"orderedBy":"human (AI-drafted, human-approved)" },
|
|
62
|
+
"items": { "C-040":"<specHash>", … } }
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
One signature covers a whole change-set (`items` may hold one Cell or a hundred). When the change-set carries a **brief** (§5), its text is part of these signed bytes — so the human's intent is attributed and tamper-evident, cryptographically bound to the exact Cells and hashes approved. The lock (`.yaylayer/lock.json`) is an append-only chain (`prev`), and both it and the roster (`config.json`, holding **public** keys) are committed. Private keys never are.
|
|
66
|
+
|
|
67
|
+
## 5. Briefs
|
|
68
|
+
|
|
69
|
+
Cell `intent:` is bottom-up and local; it doesn't record **what the human actually ordered**. A **Brief** is that top-down layer: a short prose statement of the human's intent for a change-set, drafted by the AI, edited and approved by the human, and signed as part of the approval (§4).
|
|
70
|
+
|
|
71
|
+
- **Shape.** A brief has an optional short `title` (a headline — like a commit subject) and `text` (the human's intent, one short paragraph), and covers the exact Cell set + spec-hashes of its approval. The title is signed with the rest, and is the scannable headline in the ledger / clouds / phone. It is date-stamped (`at`) and attributed (`signer`) by the seal it rides in. Briefs form an append-only log across approvals — the project's plain-English history of what was commissioned, when, by whom.
|
|
72
|
+
- **AI drafts, human owns.** The AI writes the brief as its best understanding of the request — *fine-tuned, not the human's verbatim words* — and the human refines it **in the loop with the AI before it is presented**, not on the phone. This is deliberate: the Brief drives its Cells, so a wording change may warrant a spec change, and only the AI can move the Cells with it. At signing the human's moves are **Accept** or **Send back** (with an optional note); a send-back returns the whole change-set to the AI to reconcile Brief + specs together. An unedited-but-accepted brief is still the human's, because they signed it.
|
|
73
|
+
- **Intent lane, never verification.** A brief is prose: like `intent:`, it is human/AI-judged and **can never earn or lift a color to Green**. It describes and attributes; it does not prove anything. Machine fields still do all verification. This keeps briefs clear of "false green."
|
|
74
|
+
- **Scope-bound, so it can't drift.** Because the brief is signed together with its `items` (Cell ids + spec-hashes), the ledger can always show "Brief M covered C-011, C-030 at these hashes." Editing a covered Cell later puts it visibly outside the brief's approved scope (Unsigned), rather than silently riding an old brief.
|
|
75
|
+
- **Tagged from a project pool.** A project may define a small tag vocabulary (`yay tags` — six starter sets, or your own). When present, every Brief is tagged with **1–3** tags from the pool, carried in `brief.tags` and signed with it (attributed + tamper-evident). Tags are a *view* for sorting the history by concern over time — never a gate, never a color. Keep a Brief single-concern; the AI advises splitting a request that mixes unrelated tags into separate Briefs.
|
|
76
|
+
- **Default, not optional.** A brief is **required by default** on every approval — the AI must draft one, and `yay sign` prompts a human for it if omitted. The only escape is an explicit `--no-brief` for a trivial re-sign (e.g. re-approving after a pure refactor). Briefs feed the System Plan and the decision log; they are a *view* and an *attribution record*, not a gate.
|
|
77
|
+
|
|
78
|
+
*(MVP: `yay sign --brief "…"` attaches the brief to the approval; the phone approve screen shows it read-only with **Accept & sign** / **Send back**; the seal in `lock.json` is tamper-evident via the signature. A send-back returns `{rejected, reason, tags?}` to the AI's `yay sign` output so it can reconcile and re-present. The map has a **Briefs** view (list, grouped-by-tag, and a Cloud view — a card per tag), a **Tags** vocabulary tab, and `yay briefs` in the terminal.)*
|
|
79
|
+
|
|
80
|
+
## 6. Colors — two axes
|
|
81
|
+
|
|
82
|
+
State combines **VERIFY** (does code match spec?) and **TRUST** (who approved the spec?):
|
|
83
|
+
|
|
84
|
+
- **GREEN** — signed *and* code proven to match the spec.
|
|
85
|
+
- **YELLOW** — signed and matching, but flagged (prose-only spec, undeclared effect, unproven claim, broken edge).
|
|
86
|
+
- **RED** — signed but code ≠ spec (missing unit, purity violated, mismatch), or a tampered signature.
|
|
87
|
+
- **UNSIGNED** — no valid seal covers the current spec.
|
|
88
|
+
- **PINK** — code with **no formal specification at all** (untracked, never described or signed). Total coverage is mandatory, so PINK is the most dangerous state and **blocks the gate** like Red/Unsigned. Untagged code is never silently ignored. *(Detected via a real parser (`@babel/parser`) for **JS, TypeScript, JSX, TSX** — every named unit at any depth: functions, object/class methods, arrow-props — plus top-level imperative code. Unparseable files degrade to file-level grouping.)*
|
|
89
|
+
- **Delegated** (trust overlay) — approved under an Autopilot grant, not personally reviewed; green-on-verify is possible but marked, and sits in the ratification queue.
|
|
90
|
+
|
|
91
|
+
A container Cell's color **rolls up** to the worst of its descendants.
|
|
92
|
+
|
|
93
|
+
## 7. Verification tiers
|
|
94
|
+
|
|
95
|
+
1. **Static** — spec well-formed; `unit` exists; declared `pure`/`effects` hold. *(A real AST parser (`@babel/parser`, covering JS/TS/JSX/TSX) discovers units and extracts exact bodies; effect analysis is still signal-based. Deeper analysis is roadmap.)*
|
|
96
|
+
2. **Dynamic** — property tests generated from `ensures`, run with fresh seeds; graded by **mutation testing** (low score caps at Yellow). *(Roadmap.)*
|
|
97
|
+
3. **Semantic** — AI judge of `intent`, downgrade-only.
|
|
98
|
+
|
|
99
|
+
**Test independence** comes from *isolation*, not a second model: tests are generated from the spec (deterministically or by a code-blind agent), never from the implementation.
|
|
100
|
+
|
|
101
|
+
## 8. Higher-order — flow & Policies
|
|
102
|
+
|
|
103
|
+
- **Flow:** at every `feeds` edge, `producer.out ⊨ consumer.in`. A Red Cell taints everything downstream. *(MVP checks edges resolve; contract-compat is roadmap.)*
|
|
104
|
+
- **Policies** — first-class signed rules over matched Cells. *Shipped:* the **signing policy** (§11) — owner-signed "who must sign what" rules (path / tag / module → required signer), enforced as a for-all-matched-Cells gate. *Roadmap:* richer checkable flavors — **mandate / prohibit / grant** with an `intent` + a checkable rule (grant carries an inherited effect declaration so minimality stays clean); the concern's mechanism stays a normal Cell the Policy points at.
|
|
105
|
+
|
|
106
|
+
## 9. Integrity & approval
|
|
107
|
+
|
|
108
|
+
- The private key lives only on the owner's phone (Face ID); pair once via QR, then an **encrypted push channel**. The rendezvous server is **untrusted** — relays hashes + timestamps, never sees code.
|
|
109
|
+
- **Nonce** per request kills replay; `prev` chains history (tamper-evident); verify **recomputes hashes from the real files**.
|
|
110
|
+
- **Enforcement:** a local git hook is fast feedback only. The real gate is **CI + branch protection** running `yay verify --strict` — Red/Unsigned fails the check and the merge is blocked. Build/deploy verify is the solo fallback. *(MVP: `yay verify --strict` exit code; local keystore stands in for the phone signer.)*
|
|
111
|
+
- **Key recovery:** back up as a 24-word mnemonic + passphrase, plus a second enrolled key. Lost phone → restore the same key → no re-seal. "Re-seal" (new trust root) is a rare one-signature fallback.
|
|
112
|
+
|
|
113
|
+
## 10. Autopilot (delegated execution)
|
|
114
|
+
|
|
115
|
+
A **delegation grant** — signed once on the phone (Face ID), scoped and time/count-boxed. Within it the AI approves in-scope Cells (delegated) with **no further phone contact** (the grant is the authorization; verify checks it). Sensitive/code-pinned Cells are excluded. Everything delegated is stamped `Delegated` and queued for **ratification**. Stop early with a signed **revocation**, honored at the CI gate. *(Shipped: `yay grant --for … --count …`, `yay ratify`, `yay grant list|revoke`.)*
|
|
116
|
+
|
|
117
|
+
## 11. Teams
|
|
118
|
+
|
|
119
|
+
Each person holds their own key; a signed **roster** maps keys → names, so every seal attributes to a *named* human. Optional **role-based rights** and **M-of-N multi-sig** for sensitive Cells. Adding a signer is a privileged, signed (owner) action. Merges union per-Cell seals; the CI gate re-proves the merged whole and catches logical merge conflicts git can't. *(Shipped: the signed, hash-chained roster; owner/signer roles; `yay enroll` / `yay invite` / `yay revoke` / `yay reroot`; and signer routing (below). M-of-N multi-sig and automated merge re-proving are roadmap.)*
|
|
120
|
+
|
|
121
|
+
**Signing policy.** A project may declare, in an owner-signed policy (derived from the roster, so it is tamper-evident), that Cells matched by path glob, spec tag / `sensitive`, or module **must** be signed by a named person. The gate holds any matching Cell Red until that specific signer seals it. Neutral by default — with no policy every signer is equal.
|
|
122
|
+
|
|
123
|
+
**Routing (signer inbox).** Each signer has a deterministic **inbox channel** — a public hash of their public key. A request can be *addressed* to one person by sealing it (an anonymous X25519 sealed box, from their existing ed25519 key — no extra key) to that inbox; only they can open it, and it appears only on their on-duty phone (`yay inbox`), never anyone else's. Addressing is **fire-and-return**: `yay sign --name "<Name>"` seals the request, returns a request id, and leaves the Cells Unsigned (gate-blocked) until that person approves asynchronously; `yay sign --check` collects the sealed reply (the reply rides back under a per-request symmetric key the requester keeps). The relay only ever stores opaque ciphertext.
|
|
124
|
+
|
|
125
|
+
## 12. Language reach
|
|
126
|
+
|
|
127
|
+
Adapter order: **JS/TS first** (covers JS, TS, React, Node, Next) → **HTML/CSS** (structural Green) → **Python** → **Rust, then Solidity (deferred)**. A language without its full adapter runs "structural-lite" and caps at Yellow.
|
|
128
|
+
|
|
129
|
+
## 13. Adopt (retrofit)
|
|
130
|
+
|
|
131
|
+
`yay adopt` derives *descriptive* draft specs from existing code → the human **prunes** them prescriptive → signs → code that overreaches the pruned spec goes Red → the AI refactors to match. Coverage is reported honestly (uncovered = Pink, never faked). *(AST-based for JS: scaffolds a draft block over every named unit at any depth, with a purity guess. Deriving `intent` prose from behaviour needs an LLM — roadmap.)*
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
*Reference implementation: this repo. See [README](../README.md) for what's built vs planned.*
|