个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Free, model-optional reliability control plane for AI agent handoffs - finds the first broken handoff, blocks unapproved tools, prepares the smallest safe retry. Deterministic English rules, or a dynamic semantic judge.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Catch the first broken handoff in your multi-agent run — before the next agent acts on it.
A free, model-optional reliability control plane for AI agent handoffs.
Multi-agent systems play telephone. One agent hedges, the next asserts; a
draft-only instruction disappears; $5k quietly becomes $50k — and by the
time the final answer looks wrong, you no longer know which handoff broke
it. Final-answer evals judge the output. LineageGuard judges the chain.查看完整 README ↗Catch the first broken handoff in your multi-agent run — before the next agent acts on it.
Open the live demo · npm package · Framework integrations
A free, model-optional reliability control plane for AI agent handoffs.
Multi-agent systems play telephone. One agent hedges, the next asserts; a
draft-only instruction disappears; $5k quietly becomes $50k — and by the
time the final answer looks wrong, you no longer know which handoff broke
it. Final-answer evals judge the output. LineageGuard judges the chain.
It records what each agent received and produced, finds the first handoff where evidence, meaning, or authority changed, shows the downstream blast radius, and prepares the smallest safe retry. It doesn't just observe — it blocks unsafe handoffs and unapproved tool calls before they execute.
No model API, account, database, analytics service, or paid service is required for deterministic local analysis. The built-in lexical rules cover English; dynamic semantic analysis is available through a host-provided judge.
| Surface | What it does |
|---|---|
| 🚦 Runtime supervisor | Resumable session that blocks unsafe handoffs before downstream agents run |
| 🔐 Tool registry | Host-owned tools with scoped one-time approvals and idempotency |
| 🕸️ DAG analyzers | Chain and branch/merge analysis with per-parent claim projection |
| 📡 OTLP adapter | Dependency-free OTLP/JSON ingestion for OpenTelemetry GenAI spans |
| 🔬 Forensic workspace | Visual replay UI plus a framework-neutral HTTP/JSON gate |
0.9.0 closes the 2026-10-05 audit and the completion plan in
docs/COMPLETION.md. The detector now catches a hedge,
quantifier or contraction that is silently dropped and no longer blocks
contractions, between X and Y, currency words, the month May or a tense
change. Approval tokens are fingerprinted after trimming, restore() accepts
only its documented options, handoffs over the trace limits return a blocked
decision, the semantic judge has a timeout, and dense graph payloads are
bounded. The workspace accepts pasted JSON. Releases publish only from main
and prereleases go to the next dist-tag. See
CHANGELOG.md for the full list.
0.8.0 repairs tenant authentication, approval/input integrity, concurrent handoffs, snapshot safety, numeric canonicalization, graph contamination, and import/report validation. See AUDIT.md for reproductions and verification results and CHANGELOG.md for compatibility notes. Some verdicts and malformed-input responses change, so review the notes below before upgrading.
Signed numeric changes and exact decimal conversions are now checked, range signals carry units on both endpoints, and every blocking graph branch is included in contamination. Graph ties use ID order, not inferred chronology. Returned reports and decisions are defensive copies. Await each agent/handoff; overlapping operations are rejected. Take snapshots only after operations settle. Tool inputs are copied before approval, and a session change invalidates pending authorization. Custom built-in subclasses (including Node Buffer) must be converted to plain values such as a private, non-shared Uint8Array. Some special-value fingerprints change; reissue affected approvals and do not rewrite persisted idempotency hashes to force a match.
After installing lineageguard, save this as quickstart.mjs and run
node quickstart.mjs on Node.js 20 or newer:
import { LineageGuardSession } from "lineageguard";
const guard = new LineageGuardSession()
.recordSource("Budget", "The budget is $5k.");
const decision = guard.inspectHandoff(
"writer", "Writer", "The budget is $50,000.",
);
console.log(decision.status); // blocked
console.log(guard.isFrozen()); // true
Use the packed audit build when verifying unreleased changes. The tarball test executes this quickstart from both READMEs against the packed package.
Every run passes through seven visible modules:
$5k vs $5,000, 500mg vs
0.5g, 2026-07-24 vs July 24, 2026, and "three customers" vs
"3 customers" — canonicalize to the same claim and do not
trigger a warning; a changed value behind the same rewrites still does.A trace written mostly in a script the meaning and authority families cannot read raises a visible low-severity coverage signal instead of pretending to be clean.
The interface exposes the exact rules and evidence. Its rule-family agreement is not presented as a probability or a made-up model confidence score.
Truth-Decay Replay lets a reviewer play the run one handoff at a time. The first transition where a structured claim changes turns red; later stages become the visible blast radius. The resulting Mutation Receipt contains a stable run fingerprint, first break, signal types, evidence, and human verdicts.
Try the public, local-first workspace at lineageguard.ugrp44group.chatgpt.site. Trace analysis happens in the browser; the hosted evaluation API stays disabled unless a deployer explicitly configures tenant authentication.
Prerequisite: Node.js 22.13 or newer.
pnpm install
pnpm dev
Open the local URL printed in the terminal. The repository includes planted clinical, customer-support, and clean-chain examples.
To embed the SDK in another TypeScript or JavaScript agent runtime:
pnpm add lineageguard
import { LineageGuardSession } from "lineageguard";
const guard = new LineageGuardSession({
runName: "Customer support run",
guardrail: "Draft only. Do not contact the customer.",
blockAtOrAbove: "medium",
approvalVerifier: approvalService.verify,
tools: [
{
name: "send-email",
action: "Send customer response",
sideEffect: true,
execute: emailProvider.send,
},
],
}).recordSource("Customer request", sourceText);
const result = await guard.runSequence(agents, applicationContext);
if (result.status === "blocked") {
showHumanReview(result.report.recovery);
guard.resetToLastVerified();
}
Agents receive the restricted registered-tool client. The host owns the implementation and side-effect classification:
await tools.execute("send-email", email, {
approval: {
token: humanApproval.token,
approvedBy: humanApproval.reviewer,
},
idempotencyKey: `send:${messageId}`,
});
The callback is never called when policy denies the tool, the approval is
missing or invalid, the token was already consumed, or the idempotency key was
used for another operation. Give the session a toolExecutionStore (the same
kind of store as checkpoint()) to keep that true across a crash: the consumed
token and the pending key are saved before the tool runs, so a resumed session
refuses to run the same approved call again.
Persist a session through any durable adapter:
await guard.checkpoint(snapshotStore);
const resumed = await LineageGuardSession.resume(
snapshotStore,
guard.sessionId,
{ approvalVerifier: approvalService.verify, tools },
);
Run the dependency-free reference workflows:
pnpm demo:agent
pnpm demo:otel
pnpm demo:semantic
The first demo attempts to send an email, LineageGuard blocks the tool before
execution, and the final count remains Emails actually sent: 0.
See docs/agent-runtime-integration.md for the interception contract, or docs/framework-integrations.md for concise OpenAI Agents SDK and LangGraph examples.
The deterministic families cannot catch a paraphrase that flips meaning
without touching a number, hedge word, negation, or protected action. The
runtime SDK therefore accepts an optional asynchronous semanticJudge —
typically an LLM call — that reviews each proposed handoff before the
deterministic gate:
const guard = new LineageGuardSession({
analysisMode: "semantic",
semanticJudge: async ({ from, proposedOutput }) => {
const verdict = await llmReview(from.text, proposedOutput);
return verdict.changed
? [{ severity: verdict.severity, title: verdict.title, explanation: verdict.reason }]
: null;
},
});
analysisMode has three values:
"deterministic": offline English lexical and numeric rules only."hybrid": deterministic rules plus the dynamic semantic judge."semantic": judge-only handoff decisions, with no lexical fallback.Hybrid is the recommended production mode: the model handles nuanced meaning, while stable numeric and authority checks remain reproducible. Semantic-only mode is available when fully dynamic behavior matters more than repeatability, but it requires a model or semantic service and inherits that provider's latency, cost, variability, and failure modes.
Judge findings are merged into the report as inspectable meaning-family
issues and persist through snapshots. If the judge itself fails, the handoff
fails closed by default (semanticJudgeFailureMode: "warn" downgrades that to
a visible low-severity note). The judge is raced against
semanticJudgeTimeoutMs (default 30 000 ms) and receives an AbortSignal; a
timeout follows semanticJudgeFailureMode. Handoffs over the trace limits (50
stages, 500 000 characters per stage, 1.5 M in total) are blocked, not thrown.
The core stays dependency-free: no judge, no model call. Run the executable
demo with pnpm demo:semantic.
Existing orchestration loops should call await guard.inspectHandoffAsync(...)
to include the semantic judge. The synchronous inspectHandoff(...) method is
kept for deterministic-only, latency-sensitive paths.
Analysis modes currently apply to the live LineageGuardSession runtime. The
synchronous chain/DAG builders, OTLP adapter, browser workspace, and HTTP gate
remain deterministic; a host can run a semantic reviewer around those edges or
convert the workflow to the session runtime when dynamic decisions are needed.
Use LineageGuardGraphRun for parallel roots, branches, and merge nodes:
const report = new LineageGuardGraphRun()
.recordRoot("facts", "Facts", facts)
.recordRoot("policy", "Policy", policy)
.recordHandoff(
"merge",
"Merge agent",
mergedOutput,
["facts", "policy"],
{
facts: factsClaimInMergedOutput,
policy: policyClaimInMergedOutput,
},
)
.finalize();
Per-parent claim projections prevent a merge from comparing unrelated documents as though they were one linear rewrite.
The dependency-free OTLP adapter accepts the standard OTLP/JSON
resourceSpans -> scopeSpans -> spans shape. It reads
gen_ai.input.messages and gen_ai.output.messages, understands structured
OTLP AnyValue content, follows parent spans and same-trace links, and converts
the selected trace to the same validated DAG used everywhere else:
import { runOtlpReliabilityPipeline } from "lineageguard/otel";
const report = runOtlpReliabilityPipeline(otlpJson, {
traceId,
guardrail: "Preserve uncertainty. Approval before publishing.",
});
if (report.firstBlockingEdgeId) {
stopWorkflow(report.recovery);
}
Root model spans must contain gen_ai.input.messages,
lineageguard.source, or an explicit sourceText option. The adapter fails
closed rather than treating a model output as authoritative evidence. GenAI
content attributes can contain sensitive data; keep collection and retention
under the host system's privacy policy.
For Python, Go, Java, or a separate agent service, submit the accumulated trace before handing the proposed output to the next agent:
POST /api/evaluate
The response contains decision: "allow" | "block", the blocking transition
or graph edge, and a recovery packet. Chain payloads use schema 1.0; graph
payloads use schema 1.1. The endpoint is stateless and uses the same engine.
Loopback requests work without credentials only when NODE_ENV=development;
with no credentials configured, any other request is refused with 503. Hosted access requires either
an explicitly trusted workspace-authenticated user header
(LINEAGEGUARD_TRUST_WORKSPACE_IDENTITY=true behind a header-sanitizing
dispatcher) or LINEAGEGUARD_API_KEYS_JSON plus x-lineageguard-tenant and a
bearer token. LINEAGEGUARD_RATE_LIMIT_PER_MINUTE sets a per-isolate
(per-worker) safety valve, not a quota: each isolate counts requests
independently, so the effective ceiling scales with the number of workers.
Wrong credentials are limited separately: after 10 failed attempts in a
minute for one caller and tenant id, further attempts get 429 until the
window ends.
Tool execution should still be wrapped locally in the host process: once an opaque framework has already executed a tool, no external monitor can undo it.
The workspace accepts either a direct stages array or an ordered events
array:
{
"schemaVersion": "1.0",
"runName": "Support handoff",
"guardrail": "Draft only. Do not send.",
"events": [
{
"sequence": 0,
"type": "source",
"agentId": "source",
"agentName": "Customer request",
"content": "Prepare a refund email draft."
},
{
"sequence": 1,
"type": "handoff",
"agentId": "action-agent",
"agentName": "Action agent",
"content": "The refund email was sent."
}
]
}
See docs/trace-contract.md for validation rules.
pnpm run verify
pnpm run verify is the core of the release gate used by GitHub Actions. It
performs lint, type checks, detector/runtime/OTLP tests, a production build,
rendered API checks, the curated regression evaluation, the executable demos,
and a real tarball install in an isolated consumer project. CI additionally
runs pnpm audit:security and imports the packed SDK on Node.js 20, and the
publish workflow additionally runs scripts/verify-release-tag.mjs, requires
the tagged commit to be on main, and repeats the Node.js 20 import.
Individual commands:
pnpm test:engine
pnpm typecheck
pnpm test:sdk-package
pnpm test:sdk-tarball
pnpm eval:check
pnpm build
pnpm test:render
The current curated-regression-v2 set contains 86 cases at the medium
threshold: 63 deliberately small positive and negative English cases, including
equivalence rewrites that must stay clean (contractions, between X and Y,
currency words, the month May) and structural mutations that must block
(including a hedge, quantifier or negation that is silently dropped from a
restated claim); 3 authority-precision cases (a third-party subject and a gated
passive stay clean, "I sent the email" blocks); and 20 independent multi-stage
handoffs (indep-*, research → writer → editor → publisher) that are not
unit-test fixtures. Two independent cases are tagged knownFailure and document
real limitations (a scheduling date added by the publisher, and "nothing has
been sent" not read as a negation); they count toward the metrics but do not
fail the gate, which is the 0.9 minimums below.
| Metric | Result |
|---|---|
| Precision | 95.6% |
| Recall | 100% |
| Specificity | 95.3% |
| Expected-signal coverage | 100% |
| False-positive rate | 4.7% |
These are regression-set results at the medium threshold, not a claim about unseen production traffic. Add real anonymized traces as integrations expose new language and policy patterns.
The public package is lineageguard.
It has no runtime dependencies and exports the main SDK plus runtime,
graph, otel, analysis, and pipeline subpaths. The package lifecycle compiles declarations before every
pack, and publishing runs the complete repository release gate.
The repository pins pnpm 11.9.0, disables implicit peer installation, declares
the required Webpack peer explicitly, allowlists only the three required native
build packages, explicitly disables unused Sharp installation, and commits the
regenerated lockfile. A fresh
pnpm install --frozen-lockfile is therefore the supported installation path.
See docs/releasing.md for maintainer release steps and
docs/COMPLETION.md for the closed definition of done.
The application is stateless and Cloudflare-compatible. A deployment exposes:
GET /api/health
POST /api/evaluate
The health response declares the product version, deterministic local analysis,
whether a paid API is required, and the supported capabilities. The project
contains .openai/hosting.json for deployment through Sites, but no hosted
service is required for local use.
| Concern | Answer |
|---|---|
| API cost | $0 in deterministic mode; judge-provider pricing in hybrid/semantic mode |
| Network during analysis | None in deterministic mode; judge-defined in hybrid/semantic mode |
| Storage | Trace input stays in React state; nothing is written to a server |
| Import | JSON files are parsed locally and limited to 2 MB in the UI |
| Export | Reports, recovery packets, and JSON are generated locally |
Installing the open-source development dependencies may use the network. That is separate from analyzing a trace.
LineageGuard is a smoke detector, not a truth machine. It catches explicit
structural mutations but can miss subtle paraphrases, sarcasm, and a false
claim that remains unchanged. It can also warn on a harmless rewrite. The
built-in meaning and authority lexicons cover English. The coverage heuristic
flags a stage, or the guardrail, with at least 8 letters when fewer than 30% are
in its Latin-script range, or when at least 6 words contain fewer than 8%
common English function words; it does not identify every unsupported language
or short phrase. Numeric checks still run. Use a semantic judge or domain rule for broader language review.
Number canonicalization interprets bare k and currency-prefixed m/b
magnitudes, complete dates, and common metric units; ambiguous partial forms
stay literal. Domain teams can add inspectable CustomLineageRule extensions
without replacing the baseline engine.
Human confirmation is therefore part of the product, not hidden in fine print. Do not use the current rules as a replacement for source verification, compliance review, medical judgment, or safety approval.
The live LineageGuardSession remains a serial state machine even though DAG
analysis is supported. Snapshot durability, distributed locks, globally
coordinated quotas, authenticated approval issuance, and preventing code from
bypassing the registered tool boundary remain host responsibilities.
resetToLastVerified() does not authenticate a reviewer. It restores the
checkpoint and clears the local freeze. The host must enforce the recovery
packet's approval instructions before reset or downstream release.
app/
LineageGuard.tsx Interactive control plane
lineageguard/ Workspace controller hook
api/health/route.ts Deployment health contract
api/evaluate/route.ts Framework-neutral handoff gate
lib/
analysis.ts Dependency-free mutation detector
graph.ts DAG validation, analysis, and recovery
fingerprint.ts Canonical SHA-256 run fingerprints
api-security.ts Tenant auth and per-isolate quotas
pipeline.ts Seven-module reliability pipeline and recovery
trace-schema.ts Generic JSON validation and normalization
sdk/
index.ts Runtime instrumentation API
runtime.ts Public entry for the runtime/ supervisor
runtime/ Session (agents, handoffs, recovery), tool gate, snapshots
graph.ts DAG builder API
otel.ts OTLP/JSON GenAI trace adapter
package.json Publishable lineageguard manifest
evals/
cases.ts Curated positive and negative regression cases
run.ts Measured release threshold
examples/
guarded-agent-runtime.ts Executable non-web integration
otel-ingestion.ts Executable OTLP integration
semantic-judge.ts Executable optional-judge integration
docs/
agent-runtime-integration.md Runtime interception guide
releasing.md Maintainer release checklist
trace-contract.md Framework-independent trace contract
tests/
analysis.test.ts Detection behavior
pipeline.test.ts Graph, modules, and recovery behavior
sdk.test.ts Runtime SDK behavior
runtime.test.ts Live blocking, tool enforcement, semantic judge
trace-schema.test.ts Import validation
rendered-html.test.mjs Production render and health smoke tests
The design boundaries and runtime flow are documented in ARCHITECTURE.md.