feat(0.x): pluggable knowledge sources + freshness + change detection#7
Merged
Merged
Conversation
…tion Static knowledge ships information rot — FTC non-compete rule vacated by Ryan LLC v. FTC (2024), Beverly-Killea → RULLCA, DTSA section confusion. This adds the primitives that bridge "live authority" to "eval re-runs": - `KnowledgeSource` contract (`src/sources/types.ts`): pluggable `fetch(opts) → KnowledgeFragment[]`. Every fragment carries canonical URL, source-attested timestamp, jurisdiction tag, `verifiable` flag, and `dimensionHints`. - Three shipped sources: - `cornell-lii.ts` — federal US Code + Wex from law.cornell.edu - `irs-publications.ts` — IRS index + named publications + revenue procedures - `state-sos.ts` — generic adapter (state config + URL pattern + selector) - `politeFetch`: 1 req/sec/host throttle, polite UA, on-disk content cache, block-page heuristic (verifiable=false rather than throwing). - `KnowledgeFreshnessStore`: per-(workspaceId, sourceId) last-refresh tracker, filesystem adapter + D1 adapter scaffold. Per-tenant isolation by keying. - `detectChanges(prev, next)`: added/removed/modified diff, each change carries `affectedDimensions` so an eval scheduler knows which campaigns to re-run when an authority shifts. DX bar = agent-eval 0.24.0: - biome.json + `pnpm lint`/`pnpm format` - `noUncheckedIndexedAccess: true` - @stable/@experimental JSDoc tags on every public re-export - README "Pluggable Knowledge Sources" worked example - CI workflow (lint + typecheck + test + build) - pnpm `minimumReleaseAge` block Tests: 69 total, 64 pure-unit (vitest) + 5 live (gated on AGENT_KNOWLEDGE_RUN_NETWORK_TESTS=1, skip with a warning rather than fail on rate-limit). Each test names the bug class it defends against. Verified against real Cornell LII (18 USC § 1836 + Wex restraint_of_trade), IRS publications index + p15, and CA SOS forms page on 2026-05-14.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Static knowledge bundles ship information rot — FTC non-compete rule vacated by Ryan LLC v. FTC (2024), CA Beverly-Killea → RULLCA, DTSA § 1836 confusion. Today every consumer of
@tangle-network/agent-knowledgehas to hand-roll its own ingestion against external authorities. This PR ships the primitives that close the loop: live authority → fragment snapshot → freshness state → change detection → eval re-runs tagged by the exact dimensions that moved.Scope
KnowledgeSourcecontract (src/sources/types.ts)```ts
interface KnowledgeSource {
id: string
name: string
description: string
fetch(opts: FetchOpts): Promise<KnowledgeFragment[]>
}
```
Every
KnowledgeFragmentcarries: canonical URL, source-attested timestamp (Last-Modified → Date → fetch time), jurisdiction tag,verifiableflag (false on 4xx / captcha / parse miss — consumers MUST refuse to promoteverifiable: falsecontent), anddimensionHints(which eval dimensions a change here should re-score, e.g.jurisdictional_accuracy,citation_hygiene,tax_compliance).Three shipped sources
createCornellLiiSourcejurisdictional_accuracy,citation_hygienecreateIrsPublicationsSourcetax_compliance,regulatory_currency,citation_hygienecreateStateSosSourcejurisdictional_accuracy,corporate_formation,citation_hygieneKnowledgeFreshnessStore(src/freshness.ts)last() / mark() / stale() / list(), keyed by(workspaceId, sourceId). Per-tenant isolation enforced by keying — no global mutable state. Filesystem adapter ships in-package;createD1FreshnessStoreStub(adapter)anchors the D1 / Postgres shape for production.detectChanges(prev, next)(src/changes.ts)Diffs two fragment snapshots. Each
KnowledgeChangecarriesaffectedDimensions— the eval scheduler reads this set to re-run only the campaigns tagged with those dimensions. Unverifiable fragments are filtered before diffing (otherwise a captcha snapshot vs a real one would falsely fire every fragment asremoved).Polite HTTP fetcher (
src/sources/http.ts)1 req/sec/host throttle, polite UA, disk cache keyed by URL hash, block-page heuristic on 200 responses, never throws on network/HTTP failure — returns
verifiable: falsewith reason.Worked example: Cornell LII → eval cron re-runs
createCornellLiiSourcereturns aKnowledgeFragmenttaggeddimensionHints: ['jurisdictional_accuracy'].detectChanges(prev, next)emits{ kind: 'modified', fragmentId: 'wex:...', affectedDimensions: ['jurisdictional_accuracy'], diff: { before, after } }.affectedDimensions, schedules ONLY thejurisdictional_accuracycampaigns to re-run. No global re-eval, no eval rot.DX bar parity with agent-eval 0.24.0
biome.json+pnpm lint/pnpm formatnoUncheckedIndexedAccess: true@stable/@experimentalJSDoc tags on every public re-export.github/workflows/ci.ymlruns lint + typecheck + test + build on every PRpnpm.minimumReleaseAge: 4320(supply-chain hardening)Tests (69 total)
Each test names the bug class it defends against.
tests/sources-types.test.ts(15) — factory id stability, htmlToText entity decoding, block-page heuristictests/http-cache.test.ts(11) — verifiable=true/false matrix, disk cache write/read, TTL expiry, host throttle ≥900ms gap, network-error pathtests/sources-mocked.test.ts(10) — Cornell / IRS / SOS parsers against HTML snippets that match live structure (verified 2026-05-14)tests/freshness.test.ts(7) — TTL math, workspace isolation, concurrent writes serialise, D1 stub round-triptests/changes.test.ts(9) — added/removed/modified, dimension union dedup,filterDimensionsnarrowing, unverifiable-fragment drop, duplicate-id warningtests/sources-live.test.ts(5) — real HTTP against Cornell LII (DTSA + Wex restraint_of_trade), IRS (index + p15), CA SOS, 30s timeout, skip-with-warning on rate-limit. Gated onAGENT_KNOWLEDGE_RUN_NETWORK_TESTS=1.Test plan
pnpm typecheckcleanpnpm lintclean (0 errors)pnpm test— 64 unit pass, 5 live skipped without env flagAGENT_KNOWLEDGE_RUN_NETWORK_TESTS=1 pnpm test— 69/69 passpnpm buildcleanverifiable: true