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

@stackbilt/evidence-core

v0.1.0

Published

E-E-A-T content-quality validator: Google policy-versioned gap detection for AI-generated content

Readme

@stackbilt/evidence-core

E-E-A-T content-quality validator: Google policy-versioned gap detection for AI-generated content.

Why

Post-March 2024 Google core update + November 2024 site reputation abuse update, AI-generated content without Experience / Expertise / Authoritativeness / Trustworthiness signals is buried in search. Most SEO tooling emits vague guidance ("your content needs more authority"). evidence-core emits concrete actions tied to specific Google policy versions so a creator — or a content pipeline — knows exactly what evidence is missing and what to add.

This package is the OSS core of Evidence Engine, a pre-publish content-quality gate shipped as part of Stackbilder Pro.

Install

npm install @stackbilt/evidence-core
# or
pnpm add @stackbilt/evidence-core

Quick start

import { validateEvidence } from '@stackbilt/evidence-core';

const result = await validateEvidence({
  text: 'Your draft content here...',
  author: 'Jane Doe',
  authorBio: 'Senior content strategist with 10 years...',
  lastUpdated: '2026-04-19',
  aiDisclosure: 'AI-assisted, human-reviewed',
}, {
  policyVersion: 'google_november_2024_reputation',
});

if (result.hasGaps) {
  for (const suggestion of result.suggestions) {
    console.log(`[${suggestion.priority}] ${suggestion.pillar}:`);
    for (const action of suggestion.actions) {
      console.log(`  - ${action.action}`);
      console.log(`    e.g. ${action.examples[0]}`);
    }
  }
}

Policy versions

Each preset maps to a real Google algorithm update. Pick the version that matches your content's risk surface.

| Version | When to use | |---|---| | google_baseline_2023 | Historical comparison / legacy archive re-scoring | | google_march_2024_core | Scaled content abuse + helpful content guidance; lower bar than reputation preset | | google_november_2024_reputation (default) | Reputation-sensitive verticals (YMYL, review, how-to); adds editorial-process requirements |

You can also supply a custom EvidencePolicy via options.policy.

Pillars and requirements

Experience — real-world first-hand signals

  • minCaseStudies, minOriginalVisuals, minFirstHandEvidence

Expertise — substantive, informed treatment

  • minCitations, minDataPoints, minUniqueInsights

Authoritativeness — signals of the author's or publisher's credibility

  • requiresAuthorByline, requiresAuthorBio, requiresExternalValidation, requiresEditorialProcess

Trustworthiness — transparency + source integrity

  • requiresLastUpdated, requiresAIDisclosure, requiresSourceAttribution

Evidence library schema

A JSON Schema for modeling an evidence asset library (case studies, customer quotes, original visuals, proprietary data, etc.) is exported at @stackbilt/evidence-core/schema:

import schema from '@stackbilt/evidence-core/schema' assert { type: 'json' };

The schema is a reference contract; storage is left to the consumer (D1, Postgres, flat file, etc.). The companion mergeEvidence(content, evidence) helper injects library-retrieved evidence into a draft.

Gap-fill with mergeEvidence

mergeEvidence(content, evidence) is the deterministic "inject" step of a gap-fill loop. Validate a draft, look up library assets that address the gaps, merge them into the draft, then re-draft with an LLM and re-validate. The merge itself is a pure, synchronous transformation — no LLM call, no mutation of the input, and no null coercion (absent evidence fields leave the output fields absent).

import { validateEvidence, mergeEvidence } from '@stackbilt/evidence-core';

let draft = {
  text: 'Your draft...',
  author: 'Jane Doe',
  authorBio: 'Senior content strategist with 10 years...',
};

let result = await validateEvidence(draft);
while (result.hasGaps) {
  const assets = await queryEvidenceLibrary(result.gaps); // consumer-supplied
  draft = mergeEvidence(draft, {
    caseStudies: assets.caseStudies, // [{ title, summary, url?, date? }]
    citations: assets.citations,     // [{ url, title?, publishedDate? }]
    visuals: assets.visuals,         // [{ url, alt, caption? }]
    metadata: { lastUpdated: '2026-04-19' },
  });
  draft.text = await llmRedraft(draft); // consumer-supplied
  result = await validateEvidence(draft);
}

Audit integration

The ./audit export provides audit trail hooks for validation and evidence-merge events. Records are shaped to be compatible with @stackbilt/audit-chain's writeRecord() — no production dependency, but integration point is well-defined.

Exported types

  • EvidenceAuditEvent — union of 8 event types: validation.started, validation.completed, gaps.detected, assets.merged, redraft.completed, approval.granted, publish.allowed, publish.blocked
  • EvidenceAuditRecord — audit record shape (contentId, namespace, actor, event, timestamp, chainHead)
  • ToAuditPayloadOptions — config for payload generation

Transform functions

toAuditPayload(result: ValidationResult, options: ToAuditPayloadOptions): EvidenceAuditRecord

Converts a validateEvidence() result into an audit record. Records the event type based on validation outcome (gaps detected, validation completed, etc.).

toAssetsAuditPayload(evidence: MergeableEvidence, options: ToAuditPayloadOptions): EvidenceAuditRecord

Records the assets-merge event after calling mergeEvidence().

Usage example

import { validateEvidence, mergeEvidence } from '@stackbilt/evidence-core';
import { toAuditPayload, toAssetsAuditPayload } from '@stackbilt/evidence-core/audit';
// audit-chain is optional — wire it at the app layer, not imported here
import { writeRecord, getChainHead } from '@stackbilt/audit-chain';

const contentId = 'article:uuid-12345';
const content = { text: '...', author: 'Jane Doe' };

// Validate and record the event
const result = await validateEvidence(content, { policyVersion: 'google_march_2024_core' });
const record = toAuditPayload(result, {
  contentId,
  contentHash: sha256(content.text), // optional
  actor: 'user:operator-id',         // optional, defaults to 'system:evidence-engine'
});

// Wire with audit-chain if available
const chainHead = await getChainHead(bindings, record.namespace);
await writeRecord(bindings, { ...record, chainHead });

// After merging evidence assets
const evidence = { caseStudies: [...], citations: [...] };
const mergedContent = mergeEvidence(content, evidence);
const assetsRecord = toAssetsAuditPayload(evidence, { contentId });
const updatedHead = await getChainHead(bindings, assetsRecord.namespace);
await writeRecord(bindings, { ...assetsRecord, chainHead: updatedHead });

Namespace conventions

  • Default namespace: content:{contentId} (e.g., content:article-123)
  • Multi-tenant: tenant:{tenantId}:content:{contentId} (e.g., tenant:t-456:content:article-123)
  • Override via ToAuditPayloadOptions.namespace

@stackbilt/audit-chain is a peer dependency — evidence-core has no production import on it. Consumers wire audit records into a chain at the application layer.

Heuristic scope

Pillar counters use regex patterns (case-study markers, citation links, first-hand-experience phrases, data points, etc.) — intentional design trade-off: deterministic, fast, no LLM dependency, runs in any environment including Cloudflare Workers. Consumers who want LLM-grade semantic counting should layer that on top.

License

Apache-2.0 © Stackbilt LLC. See LICENSE and NOTICE.