Skip to content

Latest commit

 

History

History
20 lines (14 loc) · 10.6 KB

File metadata and controls

20 lines (14 loc) · 10.6 KB

TIMELOG — feed402

Hourly @ $60/hr, invoiced against the existing Viatika engagement. No fixed cap. One line per session. Append-only.

Format: YYYY-MM-DD | HH:MM–HH:MM | X.Xh | summary


  • 2026-04-15 | 10:30–12:00 | 1.5h | Kickoff. Drafted BRIEF.md, SPEC.md v0.0.1, CONTRACT.md. Initial scoping draft right-sized to a 10h / $600 fixed bid framing at Lanzafame's request.
  • 2026-04-15 | 13:15–13:45 | 0.5h | SPEC amendment: added §3.1 citation types (extension point) with VDS (Verified Data Session) as the first non-source type, referencing DerbyFish BHRV as the reference implementation. Zero-cost forward-compatibility hook.
  • 2026-04-18 | 13:10–13:46 | 0.6h | Session 3. Reframed billing from fixed-bid to hourly. Rewrote BRIEF.md + CONTRACT.md (author=Gian, open source, no ownership transfer). Polished SPEC.md to v0.1 (added spec + citation_types to manifest, error codes, graceful-degrade rule). Added package.json, tsconfig.json, types.ts, server.ts (Hono, 3 tiers, in-memory corpus, stub payment verification), agent.ts (discovery → 402 → paid envelope → insight tier), demo.sh, README.md. npm install + tsc --noEmit clean. End-to-end flow verified: server boots, manifest served, 402 challenge emitted, paid envelope returns with source citation + receipt, insight tier returns NL summary. Local-only, no git remote. Next: plug in real x402 facilitator verification, swap in-memory corpus for a real upstream, decide repo home.
  • 2026-04-19 | TBD | TBDh | Session 4. Bumped SPEC.md to v0.2 (backwards-compatible): added §4 optional index manifest (type, model, dim, distance, chunks, chunk_strategy, corpus_sha256, built_at) so merchants declare retrieval scheme, and §3.2 optional chunk_id + retrieval.{model, score, rank} on source citations so citations are reproducible, not just referenceable. Extended types.ts (IndexManifest, RetrievalProvenance, ChunkStrategy, IndexType, ChunkKind, SPEC_VERSION="feed402/0.2"). Updated README.md with "What's new in v0.2" section + fifth bullet in the 60-second pitch on retrieval reproducibility. All additions optional; v0.1 servers remain compliant under v0.2 per §2.3 unknown-field rule. Server not yet updated to emit v0.2 manifest (queued for next session).
  • 2026-04-21 | TBD | TBDh | Session 5. Brought server.ts to v0.2 parity: emits spec: "feed402/0.2", includes §4 index block (sparse matcher, corpus_sha256 computed at boot from CORPUS), attaches §3.2 chunk_id + retrieval.{model,score,rank} on insight-tier citations and on query-tier citations when contains substring retrieval runs (year-only structured filter correctly omits both per "providers that do not do retrieval SHOULD omit"). Added computeCorpusHash, substringScore, chunkIdOf helpers (~60 LOC). Extended sourceCitation to optionally carry retrieval provenance. Bumped agent.ts to print manifest index block and citation retrieval fields so demo.sh visibly shows v0.2 output. tsc --noEmit clean, demo passes end-to-end, wire-level manifest + all four envelope shapes (manifest, raw, query-with/without-retrieval, insight) verified via curl. Rewrote scripts/send-to-lanzafame.sh: replaced stale fixed-bid packet framing with short hourly-era resync (v0.2 summary + three steering questions: protocol direction / repo home / next burn target). Still local-only, no git remote.
  • 2026-04-21 | TBD | TBDh | Session 7 (both repos; post repo-split to gianyrox/*). Punch list #2-#6 completed end-to-end. Gateway #2 (real tx hash): refactored async-settle goroutine into settleWithTimeout (bounded 3s synchronous wait, background-continuation on timeout, extractSettleTxHash accepts transaction|txHash|tx_hash|tx and rejects success=false) so receipt.tx is now a real on-chain reference from Base, with graceful pending:<hash> fallback when the facilitator is slow. Gateway #3 (per-hit citations): new hit_parsers.go with pluggable hitParser registry keyed by route.ID — PubMed ESearch, Semantic Scholar Graph, OpenAlex /works (+ URL-tail extraction), ClinicalTrials v2. Added optional hits []feed402Hit (source_id + canonical_url + rank) on the envelope (v0.2-additive per SPEC §2.3). Capped at 10 hits per call. TS #4 (real Kruse + OpenAI): shipped 4 new files (embedder.ts — narrow interface + OpenAIEmbedder for text-embedding-3-small + MockEmbedder for offline; corpus.ts — 460-post Kruse loader with 350-word chunks / 50-word overlap + stable corpusFingerprint; index-store.ts — single-file JSON dense vector store with saveIndex/loadIndex/topK; build-index.ts — one-shot CLI npm run build-index, batches 100, backoff, ~$0.04 for full corpus). server.ts now loads dense index on boot and promotes /insight to real cosine top-5 retrieval with chunk_id + retrieval provenance in the citation, falls back to the 3-paper sparse demo when no index file exists (backwards-compat). Smoke-tested end-to-end with mock embedder on 5 posts (11 chunks): manifest §4 shows type=dense, model=mock:sha256-128, dim=128, corpus_sha256=..., /insight 402s unpaid, returns full envelope with per-hit provenance when paid. TS #6 (viem real x402): replaced stubPaymentHeader with realPaymentHeader — viem-backed EIP-3009 transferWithAuthorization signing against the USDC domain (USD Coin/v2/chainId=manifest.chain/verifyingContract=USDC, canonical addresses for base + base-sepolia baked in), 60s auth window, random 32-byte nonce, packages v2 x402 envelope ({x402Version, payload: {authorization, signature}, accepted: {scheme,network,asset,amount,payTo,maxTimeoutSeconds,extra}}); gated by FEED402_AGENT_PRIVATE_KEY env so stub remains the cold-boot default. Verified real-signing path end-to-end against reference server with a dev key. Gateway #5 (insight tier): new internal/handler/insight.go (~270 LOC) + InsightConfig on Feed402Config. Synthetic /research/insight route auto-appended to cfg.Routes on boot so manifest + x402 SDK + routeIndex see it uniformly. Extracted decodeAndVerifyPayment from handlePaymentAndProxy (now 3 lines) — shared by both paths, cleaner. Flow: verify+settle → cloneForRetrieval fills every PassThrough param + common aliases (term/query/q/search) with the question → in-process proxyToUpstream to configured retrievalRouteIdextractSnippets walks the upstream JSON pulling ≥40-char string fields (captures title/abstract/description/summary across all 4 recognized upstreams without per-upstream parsers) up to maxContextChars → summarizer (mockSummarizer default, openAISummarizer against /v1/chat/completions with anti-fabrication system prompt when OPENAI_API_KEY set) → envelope with top-hit as primary §3 citation + §3.2 retrieval provenance {model=summarizer.id()} + v0.2-additive hits array + receipt tier=insight. Added §3.2 fields (chunk_id, retrieval) to feed402CitationSource struct — gateway envelope surface now matches full SPEC §3.2 shape. 3 new Go tests (mockSummarizer determinism + empty-context fallback; extractSnippets nested-JSON walk + maxChars cap; buildInsightCitation top-hit promotion + no-hits synthetic fallback). Tally: 11 handler tests green, go build ./... + go vet clean, tsc --noEmit clean on the TS side. 6 commits total across gianyrox/x402-research-gateway and gianyrox/feed402. This closes the punch list kicked off at start of session.
  • 2026-04-21 | TBD | TBDh | Session 6 (sibling repo: ~/freelance/x402-research-gateway). Brought the production-ish Go research gateway to feed402/0.2 protocol compliance — the second live merchant, which is the actual "protocol travels" proof. Extended internal/config/config.go: added top-level Feed402Config (enabled, name, version, spec, citationPolicy, contact), per-route Feed402Tier ("raw"|"query"|"insight", validated), and RouteCitation (sourcePrefix, canonicalUrlTemplate, providerUrl, license). Fixed pre-existing loader bug: os.ExpandEnv doesn't understand bash-style ${VAR:-default} syntax (was silently nuking ${KRUSE_SEARCH_URL:-http://localhost:8765} to empty and failing validation); added expandEnvWithDefaults preprocessor (regex-based, falls through to stdlib expand for ${VAR}). Created internal/handler/feed402.go (~240 LOC): Manifest types mirroring SPEC §1+§4, envelope types mirroring SPEC §3, buildFeed402Manifest() generating discovery from config (cheapest-per-tier canonical + full routes + tier_routes aggregates), handleFeed402Manifest serving /.well-known/feed402.json (free, 60s cache), wrapFeed402Envelope wrapping upstream bodies in the §3 envelope (JSON passed as json.RawMessage, non-JSON stringified), buildCitationFor resolving per-route source_id (canonical URL template with passthrough-param substitution for id-bearing routes, synthetic prefix:query:<sha256-trunc> for search routes), placeholder pending:<hash> tx when async settle. Wired the manifest route into the chi router (only when Feed402.Enabled) + wrapped upstream responses on 2xx after successful facilitator verify; legacy error-body passthrough preserved. Tagged all 7 live routes in config/routes.yaml with tier + citation config: pubmed-search (query, public-domain), pubmed-fetch (raw, canonical template https://pubmed.ncbi.nlm.nih.gov/{id}/), semantic-scholar-search (query, CC-BY-NC-4.0), openalex-works (query, CC0), clinicaltrials-search (query, public-domain), kruse-search (query, citation-only), pubchem-compound (raw, template with {name}). Added internal/handler/feed402_test.go (~180 LOC, 5 tests all green): manifest shape + cheapest-per-tier selection, envelope shape for search tier (synthetic source_id), envelope shape for raw tier (canonical URL template substitution), non-JSON body stringification (PubMed XML case), price parsing. go build ./... clean. Live wire test: booted gateway on :8092, confirmed /.well-known/feed402.json serves the full v0.2 manifest with all 7 routes, /research/pubmed/search without payment returns proper HTTP 402 Payment Required with x402 challenge header in base64. Gateway is now the second feed402 merchant (first = the TypeScript reference at server.ts with fake in-memory corpus; second = this gateway with 7 real upstream research APIs). Two merchants = a pattern; the protocol now visibly travels.

Hour reconciliation note (2026-04-21): The logged session durations (1.5 + 0.5 + 0.6 = 2.6h through session 3) understate actual burn. Sessions 4 and 5 are intentionally logged with TBDh pending reconciliation; earlier sessions may also be under-logged. Before the next invoice roll-up into the parent Viatika engagement, backfill real hours from editor / terminal / commit timestamps and replace the TBD entries in place.