Releases: razukc/writmint
v0.2.0 — capability/permission vocabulary split + manifest hardening
A breaking release. Splits the public-API vocabulary into an outer identity layer (the capability — the manifest as a unit of governance) and an inner permission layer (the individual grants the manifest declares). Adds manifest hardening that runs at submit-time so an agent gets a structured rejection before approval, not after.
Locked tagline: Writmint is a verifier for capabilities an author can't author past.
Breaking changes
Outer identity layer renamed: feature → capability
| v0.1 | v0.2 |
|---|---|
FeatureManifest |
CapabilityManifest |
MemoryFeatureStore |
MemoryCapabilityStore |
FeatureStore interface |
CapabilityStore |
FeatureRecord |
CapabilityRecord |
FeatureStatus |
CapabilityStatus |
ApproveInput.featureId |
ApproveInput.capabilityId |
AuditEvent.featureId / featureVersionHash |
AuditEvent.capabilityId / capabilityVersionHash |
AuditEventKind value feature_emit |
capability_emit (and capability_call / capability_denied) |
error code approval.unknown_feature |
approval.unknown_capability |
src/feature-manifest.ts |
src/capability-manifest.ts |
Inner permission layer renamed: capabilities[] → permissions[]
| v0.1 | v0.2 |
|---|---|
CapabilityManifest.capabilities[] |
permissions[] |
ActionManifest.capabilities[] |
permissions[] |
CapabilityError class |
PermissionError |
broker envelope field capabilityId (inner) |
permissionId |
AuditTransport.emit({capabilityId,…}) |
AuditTransport.emit({permissionId,…}) |
createFeatureCapabilityRegistry() |
createPermissionRegistry() |
src/capabilities.ts |
src/permissions.ts |
capability.* error codes |
permission.* (same suffixes) |
manifest.capabilities.type validator code |
manifest.permissions.type |
action.capability_ref.type / .unknown |
action.permission_ref.type / .unknown |
The outer capabilityId on AuditEvent is manifest identity; the inner permissionId (also on AuditEvent, and on the broker emit envelope) is the specific permission entry the event came through. Both fields ride on every event.
Hash shift
hashManifest() is unchanged in algorithm, but every shipped manifest will produce a different versionHash under v0.2 because the renamed object keys (permissions[], etc.) are part of the canonical hash input. Re-submit and re-approve any manifest carried over from v0.1.
Added
hardenManifest()(src/capability-manifest.ts) — runs after structural validation. Five rules:permission.reason.too_short— reason ≥ 5 words.action.description.too_short— description ≥ 5 words.permission.network.host_wildcard— no*in any host.permission.storage.scope_wildcard— no*in any scope.permission.reason.no_action_ref(warning) — every permission's reason should mention an action that references it.
ApprovalLifecycle.submit()now runs hardening and throwsApprovalErroron the first hardening error. New return shapeSubmitResultextendsCapabilityRecordwithwarnings: ManifestWarning[].- 13 new tests covering each rule + wiring. Total: 737 → 750.
- README rewritten around a show-by-failing opener.
Changed
fixtures/suspicious-transaction-triage/manifest.ts— everypermission.reasonnow opens with "Used by<action.id>…"; fixture passes hardening with 0 errors, 0 warnings.
Migration for any v0.1 consumer
- Update import names per the two tables above.
- Rename
capabilities→permissionsin every manifest object (outer and inside actions). - Re-submit and re-approve every manifest (hash shift).
- Lengthen any
reasonor actiondescriptionshorter than 5 words; remove any wildcard hosts/scopes; consider adding the referencing action id to each reason to clear the no-action-ref warning.
Notes
- Pre-stable. Public API surface may change before v1.0.
- Requires Node ≥ 22.
- 750 tests / 48 files. All 24 demo phases pass.
v0.1.0 — initial release
Initial release. Five pillars + the canonical triage demo.
Added
- Feature Manifest (
src/feature-manifest.ts) — typed, declarative contract describing a feature's id, version, capabilities, config schema, and actions. - Capabilities (
src/capabilities.ts) — broker-mediated boundary for network, storage, UI, clock, and audit. A feature only sees what its manifest declared; undeclared access throws a structuredCapabilityError. - Structured errors (
src/errors.ts) — every error carries{code, where, expected, actual, fixHint}for deterministic recovery by automated callers. - Replay (
src/replay.ts) — record execution at the transport seam and replay deterministically with strict-ordered divergence detection. - Approval lifecycle + audit (
src/approval.ts) —draft → submitted → approved → active → revoked, SHA-256-bound to manifest content, audit-emitted with manifest-declared redaction. - Canonical demo (
fixtures/suspicious-transaction-triage/) — analyst triage flow exercising all five pillars across phases A–H, including chaos-transport failure-path correctness in phase H. - 737 tests across
tests/{unit,integration,property}. npm run demochains all four demo entry points (demo:smoke,demo:approval,demo:replay,demo:e2e).- License: Apache-2.0 with explicit patent grant.
SECURITY.mdfor private vulnerability reports.CONTRIBUTING.mdfor issue/PR shape.
Notes
- Pre-stable. Public API surface may change before v1.0.
- Requires Node ≥ 22.
Install
npm install writmint
📦 npm: https://www.npmjs.com/package/writmint