Why: The HotpathPolicy and SalienceEngine are the central source of truth for the Williams Bound architecture. Every subsequent module (ingest, query, hierarchy, Daydreamer) depends on them. Implementing these first ensures the bound is enforced from day one rather than retrofitted.
P0-F1: Implement core/HotpathPolicy.ts
computeCapacity(graphMass: number): number — H(t) = ⌈c · √(t · log₂(1+t))⌉
computeSalience(hebbianIn: number, recency: number, queryHits: number, weights?: SalienceWeights): number — σ = α·H_in + β·R + γ·Q
deriveTierQuotas(capacity: number, quotaRatios?: TierQuotaRatios): TierQuotas — allocate H(t) across shelf/volume/book/page tiers
deriveCommunityQuotas(tierBudget: number, communitySizes: number[]): number[] — proportional with min(1) guarantee
Export a frozen DEFAULT_HOTPATH_POLICY object containing all constants: c = 0.5, α = 0.5, β = 0.3, γ = 0.2, q_s = 0.10, q_v = 0.20, q_b = 0.20, q_p = 0.50
Keep strictly separate from core/ModelDefaults.ts (policy-derived ≠ model-derived)
P0-F2: Add HotpathPolicy test coverage (tests/HotpathPolicy.test.ts)
H(t) grows sublinearly: verify H(10_000) / 10_000 < H(1_000) / 1_000
H(t) is monotonically non-decreasing over a representative range: verify H(t+1) >= H(t) for each t in [0, 1, 2, 10, 100, 1_000, 10_000, 100_000]
H(t) is a finite integer ≥ 1 for edge inputs: t = 0, t = 1, t = Number.MAX_SAFE_INTEGER; result must never be NaN, Infinity, or < 1
Derived tier-quota counts sum exactly to capacity: deriveTierQuotas(cap).shelf + .volume + .book + .page === cap for cap in [1, 10, 100, 1_000]
Community quota counts sum exactly to tier_budget: sum(deriveCommunityQuotas(budget, sizes)) === budget for representative (budget, sizes) inputs including edge cases (budget = 0, empty sizes array, budget < sizes.length)
Community quotas never produce NaN, Infinity, or negative values for any valid input, including sizes with a single community or all equal sizes
Salience is deterministic for same inputs
Salience clamps output to a finite number: never NaN or Infinity for extreme weight or hit-count values
P0-F3: Extend core/types.ts
Add PageActivity interface: { pageId: Hash; queryHitCount: number; lastQueryAt: string; communityId?: string }
Add HotpathEntry interface: { entityId: Hash; tier: 'shelf' | 'volume' | 'book' | 'page'; salience: number; communityId?: string }
Add TierQuotas type: { shelf: number; volume: number; book: number; page: number }
Add hotpath method signatures to MetadataStore interface:
putHotpathEntry(entry: HotpathEntry): Promise<void>
getHotpathEntries(tier?: HotpathEntry['tier']): Promise<HotpathEntry[]>
evictWeakest(tier: HotpathEntry['tier'], communityId?: string): Promise<void>
getResidentCount(): Promise<number>
putPageActivity(activity: PageActivity): Promise<void>
getPageActivity(pageId: Hash): Promise<PageActivity | undefined>
P0-F4: Extend storage/IndexedDbMetadataStore.ts
Add hotpath_index object store keyed by entityId; secondary index by tier
Add page_activity object store keyed by pageId
Implement all six new MetadataStore hotpath methods
Extend tests/Persistence.test.ts with hotpath store tests:
put/get/evict cycle for HotpathEntry
put/get for PageActivity
getResidentCount returns correct value after multiple puts
Exit Criteria: HotpathPolicy module passes all tests; types.ts has hotpath interfaces; IndexedDB hotpath stores are implemented and tested.
Why: The HotpathPolicy and SalienceEngine are the central source of truth for the Williams Bound architecture. Every subsequent module (ingest, query, hierarchy, Daydreamer) depends on them. Implementing these first ensures the bound is enforced from day one rather than retrofitted.
P0-F1: Implement
core/HotpathPolicy.tscomputeCapacity(graphMass: number): number— H(t) = ⌈c · √(t · log₂(1+t))⌉computeSalience(hebbianIn: number, recency: number, queryHits: number, weights?: SalienceWeights): number— σ = α·H_in + β·R + γ·QderiveTierQuotas(capacity: number, quotaRatios?: TierQuotaRatios): TierQuotas— allocate H(t) across shelf/volume/book/page tiersderiveCommunityQuotas(tierBudget: number, communitySizes: number[]): number[]— proportional with min(1) guaranteeDEFAULT_HOTPATH_POLICYobject containing all constants:c = 0.5,α = 0.5,β = 0.3,γ = 0.2,q_s = 0.10,q_v = 0.20,q_b = 0.20,q_p = 0.50core/ModelDefaults.ts(policy-derived ≠ model-derived)P0-F2: Add HotpathPolicy test coverage (
tests/HotpathPolicy.test.ts)H(10_000) / 10_000 < H(1_000) / 1_000H(t+1) >= H(t)for eachtin[0, 1, 2, 10, 100, 1_000, 10_000, 100_000]t = 0,t = 1,t = Number.MAX_SAFE_INTEGER; result must never beNaN,Infinity, or< 1deriveTierQuotas(cap).shelf + .volume + .book + .page === capforcapin[1, 10, 100, 1_000]tier_budget:sum(deriveCommunityQuotas(budget, sizes)) === budgetfor representative(budget, sizes)inputs including edge cases (budget = 0, emptysizesarray,budget < sizes.length)NaN,Infinity, or negative values for any valid input, includingsizeswith a single community or all equal sizesNaNorInfinityfor extreme weight or hit-count valuesP0-F3: Extend
core/types.tsPageActivityinterface:{ pageId: Hash; queryHitCount: number; lastQueryAt: string; communityId?: string }HotpathEntryinterface:{ entityId: Hash; tier: 'shelf' | 'volume' | 'book' | 'page'; salience: number; communityId?: string }TierQuotastype:{ shelf: number; volume: number; book: number; page: number }MetadataStoreinterface:putHotpathEntry(entry: HotpathEntry): Promise<void>getHotpathEntries(tier?: HotpathEntry['tier']): Promise<HotpathEntry[]>evictWeakest(tier: HotpathEntry['tier'], communityId?: string): Promise<void>getResidentCount(): Promise<number>putPageActivity(activity: PageActivity): Promise<void>getPageActivity(pageId: Hash): Promise<PageActivity | undefined>P0-F4: Extend
storage/IndexedDbMetadataStore.tshotpath_indexobject store keyed byentityId; secondary index bytierpage_activityobject store keyed bypageIdMetadataStorehotpath methodstests/Persistence.test.tswith hotpath store tests:HotpathEntryPageActivitygetResidentCountreturns correct value after multiple putsExit Criteria:
HotpathPolicymodule passes all tests;types.tshas hotpath interfaces; IndexedDB hotpath stores are implemented and tested.