EKOS — Enterprise Knowledge Operating System

The GitHub connector, live, for the first time.
Two known gaps fixed. A third found mid-run.

No access to Salesforce, SAP, Oracle, Fabric, Snowflake, Confluence, or Jira — but this environment has a real, authenticated GitHub token. `ekos/plugins/github` was already real HTTP-calling code, just never run against the live API. This is that run: 1,600 real issues/PRs from github.com/plausible/analytics, real external documentation, real code, real cross-references — and one finding discovered only once the connector was actually running at scale, not from reading the code.

1,600 real items, live 96% collapsed into 1 identity fixed same session 1,439 real groups remain — reported, not hidden
§ 01 / two known gaps, fixed before the run
real, unedited PR bodies from the actual repo

"Migration for #3828" — no keyword, no edge, before today.

real PR bodies, sampled live — unedited
PR #3834 body: "Migration for #3828"              // no keyword
PR #6606 body: "PR #6514 changed signup tracking..." // mid-sentence
PR #6597 body: "Extracted from .../pull/6591"       // full URL

github_analyzer.rs only detected `#N` immediately after a documented GitHub auto-close keyword (`closes`, `fixes`, `resolves`) — real PR bodies in this repo overwhelmingly don't use that vocabulary. Fixed: `find_bare_issue_numbers` now catches bare `#N` too. Separately, `GitHubApiClient` issued exactly one unparameterized request — GitHub's default (30 items, newest-first) would have silently truncated a repo with ~4,600 real issues/PRs to its 30 most recent. Fixed with standard `Link`-header pagination, bounded by an explicit page cap.

Open the real transcript: 0-preflight-pr-5158.json
§ 02 / the live run
terminal — real, unedited

1,600 real issues/PRs. ~23 minutes. No mock in sight.

terminal — real, unedited
$ export EKOS_GITHUB_TOKEN=$(gh auth token)
$ export EKOS_GITHUB_OWNER=plausible EKOS_GITHUB_REPO=analytics
$ export EKOS_GITHUB_PER_PAGE=100 EKOS_GITHUB_MAX_PAGES=16
$ time ekos build
Build complete. Files observed (new): 2
Total objects in ledger: 2404
real  22m50.039s

$ ekos recover
github-analyzer complete  items=1600  edges=13580
GitHub issues/PRs analysed: 1600

The 23-minute wall clock is almost entirely the per-PR `list_files` call — ~0.5s each, sequential, no concurrency — a real, accepted cost for a one-time documented run, not engineered around. 13,580 `References` edges from 1,600 items: file-change links, closing links, and the newly-added bare-mention links, all real.

Open the real transcripts: 1-build.txt, 2-recover.txt
§ 03 / gap 3 — found live, not planned
ekos resolve — real, unedited

1,533 of 1,600 real items. One identity. Confidence 1.00.

terminal — real, unedited
35. 'plausible/analytics#5869: Reduce noise in 2FA...' (PullRequest)
    — 1533 objects merged, confidence 1.00
      • #6527: Bump fast-uri from 3.0.6 to 3.1.4 in /assets
      • #5469: remove salts logs
      • #6534: Publish tracker package 0.4.6
      • #5158: time-on-page: `imported_pages` new columns
      ...1,529 more, almost every real item fetched

Not a subtle edge case — the single largest fact about the compiled result. `Custom("Issue")`/`Custom("PullRequest")` objects are named `"{owner}/{repo}#{number}: {title}"` — every item in one repo shares the `"{owner}/{repo}#"` prefix, and unlike RFC 0060's earlier `Table` fix (a namespace only), this one also swallows the item's own number, making the shared, uninformative part proportionally dominant. Jaro-Winkler's prefix bonus inflated every pairwise comparison regardless of how different the real titles were.

Open the real transcript: 3-resolve.txt
§ 04 / fixed the same session
crates/identity/src/lib.rs — real, unedited

1,533 → 0. The catastrophic case is gone.

the fix — real, unedited
// RFC 0060's extension point, given a third case:
if matches!(&obj.kind, ObjectKind::Custom(k)
    if k == "Issue" || k == "PullRequest")
    && let Some(hash_pos) = obj.name.find('#')
    && let Some(sep_pos) = obj.name[hash_pos..].find(": ")
{
    return &obj.name[hash_pos + sep_pos + 2..];  // title only
}

Same architecture already built for `Table`'s schema-qualifier strip — just a third case, not a new mechanism. Verified: the single 1,533-object group is gone from the re-resolved output. Not a complete fix: 1,439 real merge groups remain (largest 174) — dependency-bump PRs sharing a `"Bump X from Y to Z"` template and feature-prefix conventions like `"time-on-page:"` still cluster. Same reasoning RFC 0060 already gave for not chasing a complete fix: a real design decision with estate-wide blast radius, not a scoped bugfix.

Open the real transcript: 3-resolve.txt (post-fix)
§ 05 / the honest part — the original demo PR paid the cost
ekos query object — real, unedited

#5158 was chosen as the demo before the run. It didn't survive.

terminal — real, unedited
$ ekos query object <canonical id for #5100>
Object: plausible/analytics#5100: time-on-page:
        Ingestion logic for engagement_time (PullRequest)
  Properties:
    excerpt: "The previous PR was merged into a
              dependant branch not master :facepalm:"
    // #5158's own body and migration-file evidence: gone

Even after the fix, PR #5158 ("time-on-page: `imported_pages` new columns" — this RFC's originally-chosen example) is merged into a real 16-object group of sibling "time-on-page:" PRs. The surviving identity shows only its own data — exactly RFC 0060's "surviving object swallows the rest" pattern, now confirmed on GitHub `PullRequest` objects too. Reported plainly rather than quietly swapped for a cleaner-looking example.

Open the real transcript: 9-identity-limitation-5100-vs-5158.txt
§ 06 / the working chain — a different real PR
ekos query neighbourhood — real, unedited

A real PR. A real file. One hop, live.

terminal — real, unedited
$ ekos query neighbourhood <PR #6421 id> --depth 1
Neighbourhood: 2 objects, 1 relationships

  plausible/analytics#6421: Assert how we store
  data imported from GA4 (PullRequest) [root]
  test/plausible/imported/google_analytics4_test.exs (File)

  References  #6421 → google_analytics4_test.exs

PR #6421 survived standalone — its real `References` edge to the real test file it changed is graph-traversable via `ekos query neighbourhood`, unaffected by the residual over-merge issue. This is the live, working version of "beyond Git/code": a real GitHub item connected to real code, not just co-existing in the same ledger.

Open the real transcript: 6-neighbourhood-pr-6421.txt
§ 07 / one query, four real sources
ekos query find — real, unedited

Docs. Code. A GitHub PR. One search, no hand-curation.

terminal — real, unedited
$ ekos query find "google analytics import"
31 result(s):
  google-analytics-import.html: section 10       // real docs
  lib/.../email/google_analytics_import.html.heex // real code
  google-analytics-import.html                    // real docs
  plausible/analytics#5305: GA4 import: refresh... // real PR
  ...lib/plausible/imported/google_analytics4.ex          // real code

This wasn't hand-picked to make a chain — it's what the compiled ledger returns for one ordinary search, once a real external docs page (vendored unmodified from plausible.io/docs), real code, and real GitHub items about the same feature are all in it together. A stronger demonstration than the single chain this RFC set out to build.

§ 08 / the honest scorecard
What this run found, fixed, and left open

Two gaps fixed before the run. One found live. One left honestly open.

1,600
real GitHub issues/PRs fetched live, paginated
1533→0
objects in the worst merge group, before → after the fix
1,439
real merge groups still remaining, reported not hidden
GapStatus
Bare `#N` references (no closing keyword)Fixed
Zero pagination (30-item default cap)Fixed, bounded
96% identity collapse on GitHub itemsFixed — catastrophic case eliminated
Residual smaller-scale over-merging (1,439 groups)Open — same RFC 0060 limitation, not chased further
Full-URL references, secondary rate limits, no concurrencyOpen — named explicitly, not attempted
Full writeup: devlog_63.md · RFC 0062
Try it yourself

Real repo. Real token. Nothing hidden, including the incomplete part.

terminal
$ export EKOS_GITHUB_TOKEN=$(gh auth token)
$ export EKOS_GITHUB_OWNER=<owner> EKOS_GITHUB_REPO=<repo>
$ export EKOS_GITHUB_PER_PAGE=100 EKOS_GITHUB_MAX_PAGES=10
$ ekos build && ekos recover && ekos resolve && ekos compile && ekos commit
$ ekos mcp serve --workspace .
Full workspace gateResult
cargo build/test/clippy -D warnings/fmt --checkClean — 97/97 test suites pass
Regression tests added this session10 new tests (+1 behavior-changed) across 3 crates, each built from real data
EKOS · GitHub connector, live-verified end to end · every example on this page is real output, unedited · github.com/alexeyban/EKOS