EKOS — Enterprise Knowledge Operating System

How TSD works,
read from its binaries.

A retail barcode terminal and its desktop exchange server, known to EKOS only as a bin/Release folder of compiled .NET assemblies: no source code, no documentation, no developers to ask. This deck explains how the whole system works. Every claim traces to a metadata token in a specific binary.

12 assemblies ekos build · recover · compile · commit 888 types · 8,327 methods · 10,956 call edges ekos_binary_explain · ekos_impact this deck
§ 01 / what it is
The system in one slide

A handheld that scans, and a desktop that feeds it.

The handheld window is titled “Data Collection Terminal”. Store staff use it for price checks, stock-taking, receiving trucks and boxes, and returns. The desktop app, “TSD Exchange Server”, loads the product catalogue and documents onto it and pulls the scans back.

  • HandheldTSDClient.exe, .NET Compact Framework 2.0 on Windows CE. 117 types, 1,189 methods.
  • DesktopTSDServer.exe, Windows Forms tray app. 59 types, 817 methods.
  • DevicesVendor SDK wrappers under namespace Calib: barcode reader, Bluetooth, buzzer/vibrator.
  • UpstreamProducts carry a NavCode, shown as “Navision code”. The ERP is most likely Dynamics NAV (reading).
§ 02 / architecture
No network. No database server.

Everything moves as files through the ActiveSync cradle.

upstream
text files
windows-1251
desktop
TSDServer
DataLoaderClass
FamilTsdDB
.db · .col
.idx · .idf
ActiveSync
RAPI file copy
handheld
TSDClient
ActionsClass
results
scannedbarcodes
register

Zero database I/O

Across all 12 binaries, EKOS found no call into any database provider. The typed TableAdapters call FamilTsdDB's Fill/Write, an in-house indexed file store.

One code base, two exes

The handheld declares its classes in namespace TSDServer. Both executables compile the same DataSets and the same storage engine.

evidence 174 I/O boundaries, 0 of kind database · RAPI.BeginCopyFileToDevice / CopyFileFromDevice in TSDServer.exe 0x06000011 / 0x06000025
§ 03 / the daily cycle
Seven steps, all compiled call paths

Import, upload, scan, download, publish.

#WhereWhat happensMethod
1desktopOperator imports the product or document file; parsing runs on a background threadAutoLoadProduct · LoadFile
2desktopwindows-1251 text is parsed (fixed-width or delimited) into FamilTsdDB; bad barcodes are skippedBeginImport
3desktop → deviceCatalogue-age check, old files deleted on the device, new ones copied over RAPI (device clock is synced on connect)button2_Click
4deviceSettings.xml loaded (with built-in defaults), numbered menu shown, scanner startedProgram.Main · BeginScan
5deviceEvery scan updates the table and is journaled to disk at once, via change eventsWriteDbTxt
6device → desktopScanned files copied back over RAPIdownloadBtn_Click
7desktopResults written and archived as {name}_{yyyyMMddhhmmss}.txt; terminal wiped if configuredUploadResults · DeleteOldDB
batch mode TSDServer.exe /c runs steps 1–2 unattended with a 900,000 ms timeout per file; every import's status is emailed (subject “Data load status”)
§ 04 / the handheld
MainForm — button captions (translated from Russian)

A numbered keypad menu, seven workflows.

evidence captions: string constants of MainForm 0x0200001D · forms: constructors called by MenuEvents 0x0600013C · key ↔ form pairing: reading
§ 05 / workflows
What each screen enforces — its own messages

The rules live in the messages the code can show.

Receiving

“This is a foreign box!”
“Box already accepted!”
“Waybill is not for this store!”
“Accepted {0} of {1} boxes”

Stock-taking and notes

“Scan the new count sheet barcode”
“Count already exists!”
“Barcode {0}: wrong address!”
“Item already received: {0} of {1}”

Price check and returns

“This item is part of a return”
“No returns found”
“Box {0} already closed”
F1 / F2 print label · F4 documents

evidence string literals of IncomeForm, TtnForm, InventarForm, ViewProductForm.DoAction 0x0600004B, ReturnForm, ActionsClass.CloseReturnBoxAction 0x060001B1
§ 06 / one scan
Trigger to disk, following resolved Calls edges

Anatomy of a single scan.

reader thread
ScanClass.start
SysWaitForEvent
screen
OnScanned
SearchBarcode
rules · cc 38
ViewProductForm
.DoAction
dispatch
ActionsClass
.InvokeAction
record
AddScannedRow
RowChanged
WriteDbTxt
journal + register
  • ReaderOBROpen via OBReadLibNet; waits on "OBRScanningEvent" with a 2000 ms timeout.
  • Journal8 fields, |-separated, UTF-8, flushed per change, so a battery loss loses nothing.
  • Blast radiusekos_impact: 29 methods (14 direct, deepest 4 hops away) write scan records through AddScannedRow.
  • HotspotnavCodeTB_KeyDown (cc 42) and DoAction (cc 38) are the most complex methods in the system.
§ 07 / action engine
The back office decides what the terminal does

Behaviour ships as data, inside each document row.

Each DocsTbl row carries LabelCode, MusicCode, VibroCode and Priority. On a scan, the action handler plays SOUND_{MusicCode}.def on the buzzer and VIBRO_{VibroCode}.def on the vibrator. It can also print LABEL_{n}.DEF to the Bluetooth printer, after filling <GOODS_ATTRIBUTE_x>, <DOCS_ATTRIBUTE_x>, <SCAN_ATTRIBUTE_x> and <SYSTEMDATE>.

evidence PlaySound 0x0600016F · PlayVibro 0x06000172 · PrintLabel 0x06000174 · ReplaceAttr 0x06000178 (constants 60/62 = < >)
TSDUtils.ActionCode — 24 members · ekos_neighborhood
NoAction  Returns  Reprice  Remove
InventoryGlobal  InventoryLocal  QuickHelp
IncomeBox  BoxIncomes  SimpleIncome  CloseIncome
Cars  CarsBoxes  BoxWProducts  StrangeBox
BoxReturns  ReturnBoxWProducts  CloseBoxReturns
ReturnsTTN  ReturnInInventory  CloseInventar
AlreadyAccepted  NotFound  DocNotFound
// labels: REPRICING, TRANSFER,
// QUICK HELP, Deliveries (waybill), …
§ 08 / data
Typed DataSets, recovered from their accessors

Four tables carry the whole business.

TableColumnsRole
ProductsTblBarcode · NavCode · Article · ProductName · Country · Structure · OldPrice · NewPrice · Message (+ MarketPrice · Message2 · AcceptDefect on the client)catalogue
DocsTblDocId · DocType · NavCode · DocumentDate · Quantity · Priority · LabelCode · MusicCode · VibroCode · Text1–3plan + per-document behaviour
ScannedBarcodesBarcode · DocId · DocType · PlanQuanity · FactQuantity · ScannedDate · TerminalId · Prioritythe day's result
TypedSettings19 terminal settings: printer MAC and COM port, storage path, templates, permissions…Settings.xml
observed in the release folder
# terminal journal (8 fields)          scannedbarcodes.txt1
6600000000001|6600000000001|8|0|02.01.2003|0|0|0
# desktop export (7 fields)             scannedbarcodes.txt
2900655000005|02: 15.06.11|2|1|29.06.2011|1|0
§ 09 / what the graph found
Things you only see with the call graph

Dead code, dead settings, missing files.

6 of 19 settings are never read

Including VibarationOn/ScanSoundNotifyOn and the SQL CE products.sdf connection string. Their getters have no incoming Calls edge.

An unreachable screen

ReturnBoxForm (11 methods, a near-copy of IncomeForm) is never constructed. GetDeviceID is never called either, so TerminalID comes from the settings file.

Label templates are absent

PrintLabel reads LABEL_{n}.DEF, and none is in the folder. Three DLLs that no binary depends on (Imager, MoFlink, ControlsLib) ship anyway.

Three builds side by side

TSDClient.exe, TSDClient - Copy.exe and TSDClient.ex_ differ in type count. The folder alone cannot tell which one is deployed.

§ 10 / how EKOS knows
Provenance, and its limits

Structural facts are certain. Conditions are not reconstructed.

  • ReadNames, signatures, resolved calls, string and numeric constants, branch counts, fields. Read in-process from IL and metadata; the binaries are never executed.
  • TracedEvery fact carries its ECMA-335 token and the binary's SHA-256.
  • Queriedekos_binary_explain over all 931 types; ekos_impact, ekos_neighborhood, ekos_dependents, ekos_state.
  • Not knownThe exact predicate behind each of DoAction's 33 branches; enum numeric values; import column widths (runtime settings).
  • Not readNative MCSSLib.dll (ARM), the .pdb and the .zip.
  • Not usedThe opt-in LLM business-rule reconstruction. Every "reading" in the documentation is a stated join of compiled facts.
side effect this analysis found and fixed four defects in EKOS's .NET recovery; before them the call graph above was empty (0 of 36,107 calls resolved). See devlog_190.
Reproduce it

Point EKOS at a release folder. Ask it anything.

# compile the binaries into a ledger
ekos init && ekos build && ekos recover
ekos resolve --force && ekos compile && ekos commit
# deterministic docs, then ask through MCP
ekos docs generate --layout curated
ekos mcp serve --workspace .   # ekos_binary_explain · ekos_impact

Full documentation (18 sections) · raw ekos_binary_explain output · EKOS-generated reports