npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@clossys/giver

v0.1.8

Published

The giver role: did this person get what they asked for, or a reason, or a human — and everything we owed them, on time? Dependency-free machinery for a consumer's own delivery records: a runtime verdict that is a ternary (delivered/refused/handed off, ne

Readme

@clossys/giver

Everything about what you get — what you asked for, and what we owe you.

The question this role answers, and no other role does:

Did this person get what they asked for, or a reason, or a human — and everything we owed them, on time?

Ships the schema and the checkers; every consumer authors its own values.

The loop this closes

What is permitted and what is owed are the setpoints. Delivering, refusing or handing off is the act. Delivery proofs and placement records are the observation. Comparison against the declared service level and the declared window is the check. Re-sending, escalating and recording lateness are the correction.

A request answered and never joined to a record of what the person actually got has no observation and no comparison. It is an open loop, and closing it is the reason this package exists.

The defect this exists to repay

A send path in this workspace reads its policy collaborator like this:

const policy = (await config.policy?.(message)) ?? { outcome: "allow" };

An optional collaborator defaulting to a positive outcome. A host that wires nothing sends everything to everyone, and nothing errors — the absence of a signal is indistinguishable from a passing one. Two rules follow here, and both are structural rather than advisory.

1. No collaborator is optional, and no absence has a positive default. Every field decideOutcome needs is required. "Nothing is owed" is written owed: null; "no human is free" is written { available: false, namedReason }. There is no ?. and no ?? anywhere in the decision path, and src/collaborators.check.ts fails the build if a single ? is ever added to the input type.

2. Neither collapse is expressible. An indeterminate read cannot become a delivery, because every DeliveryBasis variant is a positive, named reason to send — there is no variant meaning "we could not tell". It also cannot become a bare refusal, because every VerdictRefusalGrounds variant is either the person's own standing decision or a hand-off that could not be placed, and the second carries the hand-off record with it.

The second collapse is the more dangerous one, and it is the reason the type is shaped that way rather than merely documented. Rounding "could not decide" down to "refuse" looks like discipline: the refusal metrics stay healthy while real requests are quietly dropped and nobody is ever handed the thing that needed a person.

The verdict is a ternary

delivered / refused / handed off. Never a binary. A binary cannot tell a request given to a person apart from a request that went nowhere.

Hand-off is the only outcome that requires a human. If no human is available, the outcome is a refusal with a named reason, recorded as a hand-off that could not be placed — never a delivery. The hand-off record does not evaporate into the refusal: handoffRecordFor returns it, the placement gate reads it, and it is reported as raised and never picked up.

The inverted rule

On a standing refusal, this package refuses — except for something we owe, which it must still send, with the send recorded against the denial.

That precedence rule lives in decideOutcome and nowhere else. An obligation is owed regardless of what the standing record says; that is what distinguishes it from anything else we might send. When a refusal is on record the send still happens and the basis becomes owed-against-standing-refusal, carrying the policy version and date of the refusal it overrode. The refusal is not overwritten and not ignored — it travels with the send, which is the only form in which "we sent this to someone who told us not to" is auditable afterwards.

The butler seam is a document, not an import

Whether a person has a standing instruction on file is owned by the butler role. This package does not import it, does not depend on it, and does not restate its evaluation logic. It reads a document:

  • a declared filename — STANDING_DECISIONS_DOCUMENT_FILENAME, exported from ./record, currently standing-decisions.json, relative to whatever directory the consumer nominates;
  • a declared schema — StandingDecisionDocument, a schemaVersion, a producedAt, and a list of { subjectId, topic, status, ... } entries whose four statuses (granted, denied, absent, stale) mirror what the producing role reports;
  • and JSON in between.

That choice costs something, so here is why it is worth it. An import would couple the send path to another package's release cadence and make "the standing answer could not be determined" an exception rather than a value. The document seam makes the failure mode explicit instead: a file that is missing, unparseable, or does not validate becomes unreadableStandingDecision(reason) — a first-class read with status "unreadable" that decideOutcome routes to a person. There is no code path from an unreadable document to a delivery, and no way to write one.

import { readStandingDecision, unreadableStandingDecision, validateStandingDecisionDocument } from "@clossys/giver/record";

A document announcing a schemaVersion this reader does not know is refused, not read optimistically. Two independently-maintained copies of a vocabulary agree only by luck, so the seam declares what it agreed on.

The keeper seam is a document owned here

The grounds retained behind a refusal remain a giver record, because this is the role that requires them. keeper does not duplicate or import that record; its visibility gate reads the versioned JSON document at RETAINED_GROUNDS_DOCUMENT_FILENAME (retained-grounds.json, relative to the consumer-nominated directory). Each ground carries the opaque subjectId of the person the decision concerns, which lets a disclosure route be checked without putting the grounds into keeper's holding store.

RetainedGroundsDocument, RETAINED_GROUNDS_SCHEMA_VERSION, and validateRetainedGroundsDocument are exported from ./record. An unknown version or a ground with no subject is unreadable, never silently visible.

Install

npm install @clossys/giver

This package is published to https://registry.npmjs.org with public access; installing it requires no authentication.

import { checkObligationDischarge, decideOutcome } from "@clossys/giver";

Timely semantic closure rate

Independent consumer evidence shows the position's owned metric meets its setpoint over the declared review cadence. The owned metric is timely semantic closure rate, computed by assessTimelySemanticClosureRate(). An empty evaluated set is indeterminate, never a perfect rate of 1. checkHandoffPlacement, checkGrounding, and checkObligationDischarge remain the gates they are; none of them is this combined rate. This package does not measure consumer evidence and does not close the loop. A green run of this package's tests is not a close.

import { assessTimelySemanticClosureRate } from "@clossys/giver";

const report = assessTimelySemanticClosureRate(input);
giver-rate-check assessment.json

The command prints JSON and exits 0 for satisfied, 1 for violated, and 2 for indeterminate, unreadable, or invalid input.

This package declares that command as its first-day assessment surface in its own manifest:

"foundry": { "assessment": { "bin": "giver-rate-check", "invocation": "single-json-input" } }

Onboarding discovers that declaration from the installed manifest and never infers a surface. giver-check remains the three-gate CLI and is not the assessment surface. Giver is not a required first-day role; Advisor remains the only required first-day assessment.

The three gates

All three are reachable from one installed bin, giver-check, dispatched on the first argument matching a gate name exactly. The charter assessment is a second mapped bin, giver-rate-check, and is not a fourth gate on this dispatcher.

giver-check handoff-placement ./handoffs.json ./placements.json --at 2026-08-22T12:00:00.000Z
giver-check grounding ./answers.json ./retained-grounds.json
giver-check obligation-discharge ./obligations.json ./proofs.json --at 2026-08-22T12:00:00.000Z

handoff-placement

Every hand-off has a placement record inside its declared service level. It fails on a hand-off whose service level elapsed with no placement at all, on one picked up after that level had already elapsed, on a placement timestamped before the hand-off it answers, on a placement naming a hand-off outside the set being checked, and on a hand-off raised after the instant the run claims to check at.

A raised hand-off nobody picked up is a finding, not silence. That is the whole gate. This particular failure produces no error, no alert and no record anywhere else: a person was told someone would get back to them, and the queue simply never emptied.

A hand-off still inside its own declared service level is counted and reported as awaiting, never as a finding — and if nothing in the set has come due, the gate exits 2 rather than reporting a pass it never earned.

grounding

Every delivered answer cites a source, and every refusal retains its grounds. It joins citations to the grounds the consumer says it still holds, rather than trusting that a citation exists — a reference to material that has since been dropped reads exactly like a good citation right up until someone asks to see it. It fails on a delivery citing nothing, on a delivery or a refusal citing material no longer retained, and on a refusal that retained no grounds at all.

The refusal half is the half people forget. A person may ask why they were refused and contest it, which is only possible if the grounds were retained rather than merely computed. An outcome recorded without its reasons is a decision nobody, including its author, can revisit.

A handed-off answer is not judged here. It has neither delivered nor refused anything; whether it was picked up is the first gate's question.

obligation-discharge

Every fired obligation has delivery proof timestamped inside its window. It fails when the window closed with no proof at all, when every recorded send against it failed, when a delivery landed outside the window, and on a proof naming an obligation outside the set being checked.

An attempt is not a delivery. A weaker tool checks that a send was attempted and passes on a record whose own state says the send failed — the dispatcher this package repays resolves its promise on failure, and its own documentation says plainly that a resolved promise is not a success. Counting attempts reports a clean run while nobody was told. This gate reads the observed state of each proof: "failed" is a breach, "unknown" is unprovable, and only "delivered" inside the declared window discharges anything. Three recorded attempts that all failed are three proofs and zero deliveries.

A send whose outcome was never observed makes the obligation unprovable, which exits 2 — not 0, and not 1. On a mixed run, where one obligation breached and another was never observed, the gate reports the indeterminate reason and exits 2 while still printing the breach it did find: the exit code describes the completeness of the answer, the printed findings are the answer so far.

Exit codes

| Code | Meaning | | --- | --- | | 0 | Ran against a non-empty record set and found nothing. | | 1 | Ran and found at least one real violation. | | 2 | Could not run: a missing, unreadable, unparseable or schema-invalid record store; an empty record set; a set in which nothing has come due; an outcome that could not be established; a required declared value that was not supplied; or no gate selected at all. |

2 is not a variant of failure. "I checked and it is fine" and "I never checked" are different answers, and a gate that reports the second as the first is worse than no gate.

A bare giver-check with no subcommand exits 2, not 0. Nothing was selected, so nothing was checked, and a CI step with a dropped argument must go red rather than green on the strength of having examined nothing. An explicitly requested --help is the one exception, and exits 0, because asking for help is a run that did exactly what was asked.

--at is required on the two gates that compare against a deadline, and has no default. A gate that read its own clock could never be replayed, and whether a record is late would depend on when someone happened to look.

API

Everything below is exported from the package root.

Deciding

| Export | What it does | | --- | --- | | decideOutcome | The one decision. Returns the ternary verdict, and resolves the precedence rule between a standing refusal and a thing we owe. Takes the actor and the subject as separate fields. | | evaluateObligation | Evaluates one obligation against every proof recorded for it. Returns discharged, breached, or unprovable. |

The gates, as pure functions

| Export | What it does | | --- | --- | | checkHandoffPlacement | Gate 1, over hand-offs, placements, and the instant to judge at. | | checkGrounding | Gate 2, over answers and the grounds the consumer still retains. | | checkObligationDischarge | Gate 3, over obligations, delivery proofs, and the instant to judge at. | | assessTimelySemanticClosureRate | Charter close metric. Returns TimelySemanticClosureRateAssessment from consumer-supplied independent observations. Not any one of the three gates. | | TimelySemanticClosureRateAssessment, TimelySemanticClosureRateFinding, TimelySemanticClosureRateState | Its result shape |

Validators and guards

| Export | What it does | | --- | --- | | validateHandoffRecord | Validates one untyped hand-off. | | validateHandoffRecords | Validates an untyped array of them. | | validatePlacementRecords | Validates an untyped array of placement records. | | validateAnswerRecord | Validates one untyped answer, including its ternary outcome. | | validateAnswerRecords | Validates an untyped array of them. | | validateRetainedGrounds | Validates an untyped array of retained grounds. | | validateObligationRecord | Validates one untyped obligation. | | validateObligationRecords | Validates an untyped array of them. | | validateDeliveryProofs | Validates an untyped array of delivery proofs. | | isHandoffRecord | Boolean guard over validateHandoffRecord. | | isAnswerRecord | Boolean guard over validateAnswerRecord. | | isObligationRecord | Boolean guard over validateObligationRecord. |

Vocabularies

VERDICT_KINDS, ANSWER_OUTCOME_KINDS, HANDOFF_REASONS, DELIVERY_STATES, STANDING_READ_STATUSES, INDETERMINATE_STANDING_STATUSES and INDETERMINATE_DISCHARGE_FINDING_KINDS are the closed lists a caller validating untyped input, or deriving an exit code, needs.

Types

The record types are HandoffRecord, HandoffSla, HandoffReason, PlacementRecord, AnswerRecord, AnswerOutcome, GroundCitation, RetainedGround, ObligationRecord, ObligationWindow, DeliveryProof, DeliveryState, PolicyVersion and StandingRead.

The decision types are OutcomeInputs, OwedObligation, HumanAvailability, GroundsReadiness, Verdict, DeliveryBasis, VerdictRefusalGrounds, UnplacedHandoff, ObligationStatus and ObligationBreachReason.

Each gate returns its own result type — HandoffPlacementResult, GroundingResult, ObligationDischargeResult — carrying findings typed as HandoffPlacementFinding, GroundingFinding and ObligationDischargeFinding, whose kinds are HandoffPlacementFindingKind, GroundingFindingKind and ObligationDischargeFindingKind, and whose non-clean outcomes are named by HandoffPlacementFailureReason, GroundingFailureReason and ObligationDischargeFailureReason.

Validation surfaces ValidationIssue, ValidationResult and Validator.

The ./record subpath

Two things live here, and they are the same idea from both ends.

The document seams described above: STANDING_DECISIONS_DOCUMENT_FILENAME, STANDING_DECISIONS_SCHEMA_VERSION, STANDING_DECISION_STATUSES, validateStandingDecisionDocument, readStandingDecision, and unreadableStandingDecision. A subject with no entry reads absent, which is indeterminate and routes to a person — never a grant, and never a refusal either. "Nobody ever asked them" and "they said no" stay different answers all the way through. The same subpath exports RETAINED_GROUNDS_DOCUMENT_FILENAME, RETAINED_GROUNDS_SCHEMA_VERSION, RetainedGroundsDocument, and validateRetainedGroundsDocument for the person-facing grounds register that keeper reads without importing this package.

The emitters: answerRecordFor and handoffRecordFor turn one verdict into exactly the records the gates read back. They exist so the decision and the evidence of it cannot drift apart — a consumer hand-writing its own records could record a delivery for a verdict that refused, and nothing downstream would ever know. handoffRecordFor returns a record for a hand-off that was placed and for a refusal that could not place one, which is what keeps an unanswered person from becoming a clean row.

Requirements

Node 20 or newer. Zero runtime dependencies.

What this package is not

  • It carries no obligation, no register, no category, no service level, no window and no jurisdiction logic. Every one of those is a value, and values belong in each consumer's own repository — the consumer declares its own obligation register.
  • It makes no claim of legal compliance. It is record machinery, not advice.
  • It holds no content. No record here carries the text of a request, an answer, a refusal, or a message; grounds are referenced by opaque id and proofs by an opaque transport reference. A gate can run over a whole record set with no person-attributable content passing through it, and no such record is ever written into this repository.
  • subjectId and actorId are opaque host-owned references. Neither ever carries an email address, a name, a phone number, an address, or an IP, and they are separate identifiers in every signature — an actor answering on a person's behalf and the person themselves must stay distinguishable.

Licence

MIT. See LICENSE.