Skip to content

Releases: razukc/writmint

v0.2.0 — capability/permission vocabulary split + manifest hardening

15 May 12:16
de9b27a

Choose a tag to compare

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 throws ApprovalError on the first hardening error. New return shape SubmitResult extends CapabilityRecord with warnings: 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 — every permission.reason now opens with "Used by <action.id>…"; fixture passes hardening with 0 errors, 0 warnings.

Migration for any v0.1 consumer

  1. Update import names per the two tables above.
  2. Rename capabilitiespermissions in every manifest object (outer and inside actions).
  3. Re-submit and re-approve every manifest (hash shift).
  4. Lengthen any reason or action description shorter 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

01 May 18:47

Choose a tag to compare

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 structured CapabilityError.
  • 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 demo chains all four demo entry points (demo:smoke, demo:approval, demo:replay, demo:e2e).
  • License: Apache-2.0 with explicit patent grant.
  • SECURITY.md for private vulnerability reports.
  • CONTRIBUTING.md for 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