143 lines
4.1 KiB
Markdown
143 lines
4.1 KiB
Markdown
Here’s a concrete enforcement logic plan for `nip verify` to **validate `.npk` license manifests** — especially for ACUL compliance — and **reject invalid or incomplete packages** with clear diagnostics:
|
||
|
||
---
|
||
|
||
## ✅ Enforcement Logic: `nip verify` (ACUL-Aware)
|
||
|
||
### 🔍 **1. Manifest Detection**
|
||
|
||
On `nip verify`, check for a license manifest (`license.yaml` or `license.json`) inside the `.npk` archive or alongside the `fragment.npk.yaml` file.
|
||
|
||
Fail early if not found:
|
||
|
||
```bash
|
||
✖ [license] No license manifest detected. Expected `license.yaml` or `license.json`.
|
||
```
|
||
|
||
---
|
||
|
||
### 📑 **2. Required Fields Check**
|
||
|
||
For `ACUL` type, enforce presence of these keys:
|
||
|
||
| Key | Required? | Type |
|
||
| ----------------------- | --------- | ------------------------------------------- |
|
||
| `license.type` | ✅ | string |
|
||
| `license.version` | ✅ | string |
|
||
| `foundation_membership` | ✅ | string (enum: Bronze, Silver, Gold, Custom) |
|
||
| `attribution` | ✅ | bool |
|
||
| `npk_logs` | ✅ | bool |
|
||
| `reproducible_build` | ✅ | bool |
|
||
| `license_file` | ✅ | string (filename must exist in `.npk`) |
|
||
| `website` | ⚠️ (warn) | string |
|
||
|
||
Fail if missing:
|
||
|
||
```bash
|
||
✖ [license] Invalid ACUL manifest: missing required field `foundation_membership`
|
||
```
|
||
|
||
---
|
||
|
||
### 🔐 **3. Membership Tier Validation**
|
||
|
||
Optional (if server available): ping a public or internal `https://nexus.foundation/api/check-membership/<vendor>/<level>` endpoint to validate the licensee’s status.
|
||
|
||
If offline, emit warning only:
|
||
|
||
```bash
|
||
⚠ [license] Cannot validate foundation membership tier (offline mode).
|
||
```
|
||
|
||
If invalid:
|
||
|
||
```bash
|
||
✖ [license] Foundation membership `Copper` is not recognized. Must be Bronze, Silver, or Gold.
|
||
```
|
||
|
||
---
|
||
|
||
### 📦 **4. Runtime Reproducibility Proof**
|
||
|
||
If `npk_logs: true` and `reproducible_build: true`, enforce that:
|
||
|
||
* A `build.log` file exists
|
||
* A `manifest.yaml` or `.npk.hash` file is present with SHA256 checksums
|
||
|
||
Fail otherwise:
|
||
|
||
```bash
|
||
✖ [reproducibility] Missing reproducibility log `build.log`
|
||
✖ [reproducibility] No manifest or hash file found (`manifest.yaml` or `.npk.hash`)
|
||
```
|
||
|
||
---
|
||
|
||
### 📁 **5. License File Validation**
|
||
|
||
Ensure the declared `license_file` exists and matches expected name:
|
||
|
||
```bash
|
||
✖ [license] Declared license file `LICENSE-ACUL.txt` not found in package.
|
||
```
|
||
|
||
If content hash enforcement is needed (future version), validate SHA256 of license file.
|
||
|
||
---
|
||
|
||
## 🧪 Example `nip verify` Output (Success)
|
||
|
||
```bash
|
||
✓ [license] Valid ACUL manifest detected (v1.0)
|
||
✓ [license] Foundation membership: Silver
|
||
✓ [attribution] Attribution: OK
|
||
✓ [reproducibility] build.log found
|
||
✓ [manifest] manifest.yaml found with checksums
|
||
✓ [license_file] LICENSE-ACUL.txt present and valid
|
||
|
||
✔ Verification successful: package `anomaly-core.npk` is ACUL-compliant.
|
||
```
|
||
|
||
---
|
||
|
||
## 🔧 Optional `nip.conf` Flags
|
||
|
||
```yaml
|
||
nip:
|
||
require_license_manifest: true
|
||
require_reproducibility_for_acul: true
|
||
accepted_membership_tiers:
|
||
- Bronze
|
||
- Silver
|
||
- Gold
|
||
enforce_license_file_presence: true
|
||
```
|
||
|
||
---
|
||
|
||
## 📦 Integration into `nip` CLI
|
||
|
||
```nim
|
||
# pseudocode in Nim-style
|
||
|
||
proc verifyLicense(pkg: NpkPackage): Result =
|
||
if not pkg.has("license.yaml") and not pkg.has("license.json"):
|
||
return err("No license manifest found")
|
||
|
||
let lic = parseLicense(pkg)
|
||
if lic.type == "ACUL":
|
||
if lic.foundation_membership notin ["Bronze", "Silver", "Gold"]:
|
||
return err("Invalid membership level")
|
||
if not lic.npk_logs or not lic.reproducible_build:
|
||
return err("ACUL requires reproducibility + logs")
|
||
if not pkg.has(lic.license_file):
|
||
return err("License file missing: " & lic.license_file)
|
||
|
||
return ok()
|
||
|
||
```
|
||
|
||
---
|
||
|
||
Do you want this as a ready-to-drop `verify_license.nim` module for the `nip` tool?
|