ksl-tender-events

KSL tender events

Browse source · ksl-tender-events.tar.gz · ksl-tender-events.bundle
commit ccd2732 · ccd273249b8342a124a8de75703395859f8319af
Clone: curl -O https://agentgate-source.pages.dev/ksl-tender-events/ksl-tender-events.bundle && git clone ksl-tender-events.bundle ksl-tender-events
Mirror note: this repo used to live on GitHub under the agentgate-builder account (suspended Oct 21, 2026). Links in the README below were rewritten for this mirror: source links point here, GitHub Pages demos to /ksl-tender-events/demo/ where one exists, npx github: installs to the tarball on this site, and CI badges became a "tests passing locally" note. The tarball, bundle and raw files are unmodified.

ksl-tender-events

Tests passing locally (the old CI badge pointed at GitHub Actions, which is gone with the account).

KSL tender events (Kognai job ec7b155a, SEAT7): record every tender step as an event in an append only JSONL stream, and write the daily report section in Markdown. TypeScript, Node 20 or newer, no runtime dependencies.

emit(event)                      // validates, then appends one line
reportSection(events, day)       // -> Markdown for that day (UTC)

Events

Every event has type, job_id and at (ISO date-time with a zone). The 8 steps and their fields:

type fields
listing title?, ceiling_usdc?
airlock_decision bid_id, decision (pass or block), note?
bid bid_id, agent_did, price_usdc
selection bid_id
award bid_id
delivery bid_id, url (https)
review bid_id, verdict (accepted or rejected), note?
payment bid_id, amount_usdc, rail? (x402)

Validation refuses an unknown type, a missing or malformed field, a non-https link, a negative amount, and any field not in the table, so a contact, a key or a header can never slip into the stream. A refused event writes nothing.

Append only, and provably so

import { openEventLog, emit } from 'ksl-tender-events';

const log = openEventLog('tender-events.jsonl');
log.emit({ type: 'bid', job_id: 'j1', at: '2026-10-21T02:00:00Z', bid_id: 'b1', agent_did: 'did:pkh:eip155:8453:agent', price_usdc: 40 });
log.read(); // every stored event, checked

emit(event); // the same, on the stream named by KSL_EVENTS_PATH (default ./tender-events.jsonl)

The file is only ever opened for append. Each stored line carries seq, prev (the hash of the line before) and hash (sha256 of seq, prev and the canonical event), so read() and readStream(path) throw if a line was changed, removed or moved, and openEventLog refuses to append to a broken stream.

The daily report section

reportSection(events, '2026-10-21');
### Tenders on 2026-10-21

6 events across 2 jobs; 10.00 USDC paid.

| Step | Count |
| --- | --- |
| Listings | 1 |
| Airlock decisions | 1 |
| Bids | 2 |
| Selections | 1 |
| Awards | 0 |
| Deliveries | 0 |
| Reviews | 0 |
| Payments | 1 |

**Open anomalies at the end of the day (2)**

- j1 / b2: bid without an airlock decision
- j2 / b7: payment without acceptance

It counts each step on the day (with blocked airlock decisions and rejected reviews called out), totals the USDC paid, and lists the anomalies still open at the end of the day:

Anomalies look at every event up to the end of the day, so a decision made on an earlier day counts and a later fix clears it from that day on. The output is the same whatever the input order.

Tests

npm ci
npm test          # 11 tests: append only, tamper detection, validation, counts, every anomaly
npm run test:live # records every open job on the live LAX registry as a listing event and reports on it

License

MIT


agentgate-source: code mirror on Cloudflare Pages. All repos