#pragma once // Step 1961: OperationTaxonomy // Full domain tree with 40+ entries. classify(text) -> domain key via keyword matching. // Domains are checked most-specific first (more dots = higher priority). #include "OperationDomain.h" #include #include #include namespace whetstone { class OperationTaxonomy { public: // A matcher maps a domain key to a list of keyword sets. // A domain matches if ANY keyword set fully appears in the lowercased text. // Within a keyword set, ALL keywords must appear as substrings. struct DomainMatcher { std::string domainKey; std::vector> keywordSets; }; // Build the default taxonomy with 40+ domains across 8 top-level categories. static OperationTaxonomy buildDefault() { OperationTaxonomy t; // --- 2-dot domains (most specific, checked first) --- // serialization.*.* t.add("serialization.protobuf", "Protocol Buffers", {{"protobuf"}, {"proto buffer"}}); t.add("serialization.msgpack", "MessagePack", {{"msgpack"}, {"messagepack"}}); // compute.*.* t.add("compute.ml.training", "ML Training", {{"training", "model"}, {"backprop"}, {"gradient", "descent"}, {"train", "neural"}}); t.add("compute.ml.inference", "ML Inference", {{"inference", "model"}, {"forward pass"}, {"predict", "neural"}}); // network.*.* t.add("network.http.client", "HTTP Client", {{"http", "client"}, {"rest", "client"}, {"curl"}, {"api", "client"}, {"http request"}, {"requests"}, {"axios"}}); t.add("network.http.server", "HTTP Server", {{"http", "server"}, {"web server"}, {"rest", "server"}, {"http", "listen"}, {"api", "endpoint"}, {"api", "route"}, {"backend", "api"}, {"fastapi"}, {"express"}, {"gin"}, {"axum"}, {"spring-boot"}}); // io.*.* t.add("io.stream.audio", "Audio Stream IO", {{"audio", "stream"}, {"audio", "buffer"}, {"pcm"}}); t.add("io.stream.video", "Video Stream IO", {{"video", "stream"}, {"frame", "capture"}, {"video", "buffer"}}); // db.*.* t.add("db.query.sql", "SQL Query", {{"sql"}, {"select", "from"}, {"insert", "into"}, {"query", "table"}}); t.add("db.query.nosql", "NoSQL Query", {{"nosql"}, {"mongodb"}, {"document", "store"}, {"couchdb"}}); // --- 1-dot domains --- // serialization.* t.add("serialization.json", "JSON Serialization", {{"json"}}); t.add("serialization.binary", "Binary Serialization", {{"binary", "serial"}, {"binary", "encode"}, {"flatbuffer"}, {"capnproto"}}); t.add("serialization.xml", "XML Serialization", {{"xml"}, {"xslt"}}); t.add("serialization.csv", "CSV Serialization", {{"csv"}, {"comma", "separated"}}); t.add("serialization.yaml", "YAML Serialization", {{"yaml"}}); // compute.* t.add("compute.matrix", "Matrix Computation", {{"matrix"}, {"matmul"}, {"gemm"}, {"linear algebra"}}); t.add("compute.parallel", "Parallel Computation", {{"parallel"}, {"simd"}, {"vectorize"}}); t.add("compute.statistics", "Statistical Computation", {{"statistic"}, {"mean"}, {"variance"}, {"distribution"}}); t.add("compute.fft", "Fast Fourier Transform", {{"fft"}, {"fourier"}, {"frequency domain"}}); t.add("compute.graph", "Graph Computation", {{"graph", "algorithm"}, {"shortest path"}, {"bfs"}, {"dfs"}}); t.add("compute.sort", "Sorting", {{"sort"}, {"order", "elements"}}); t.add("compute.hash_map", "Hash Map", {{"hash map"}, {"hash table"}, {"hashmap"}, {"unordered map"}}); // network.* t.add("network.websocket", "WebSocket", {{"websocket"}, {"ws://"}, {"realtime", "socket"}, {"live", "notifications"}}); t.add("network.async", "Async Network IO", {{"async", "io"}, {"async", "network"}, {"event loop"}, {"non-blocking", "io"}}); t.add("network.grpc", "gRPC", {{"grpc"}, {"rpc", "proto"}}); t.add("network.tcp", "TCP", {{"tcp"}, {"transmission control"}}); t.add("network.udp", "UDP", {{"udp"}, {"datagram"}}); // io.* t.add("io.stream", "Stream IO", {{"stream"}}); t.add("io.file", "File IO", {{"file", "read"}, {"file", "write"}, {"filesystem"}, {"file io"}}); t.add("io.file.mmap", "Memory-Mapped IO", {{"mmap"}, {"memory map"}, {"memory mapped"}}); t.add("io.database", "Database IO", {{"database", "read"}, {"database", "write"}}); // crypto.* t.add("crypto.hash", "Cryptographic Hash", {{"sha256"}, {"sha512"}, {"sha1"}, {"md5"}, {"checksum"}, {"hash", "file"}}); t.add("crypto.symmetric", "Symmetric Encryption", {{"aes"}, {"symmetric", "encrypt"}, {"chacha20"}, {"blowfish"}}); t.add("crypto.asymmetric", "Asymmetric Encryption", {{"rsa"}, {"ecdsa"}, {"public key"}, {"private key"}}); t.add("crypto.tls", "TLS/SSL", {{"tls"}, {"ssl"}, {"certificate"}}); t.add("crypto.random", "Cryptographic Random", {{"csprng"}, {"secure random"}, {"random bytes"}, {"secure", "rand"}}); // db.* t.add("db.transaction", "Database Transaction", {{"transaction"}, {"commit"}, {"rollback"}}); t.add("db.orm", "ORM", {{"orm"}, {"object relational"}, {"entity", "mapping"}, {"data model"}, {"schema", "model"}, {"sqlalchemy"}, {"prisma"}, {"jooq"}, {"sqlx"}}); t.add("db.migration", "Database Migration", {{"migration"}, {"schema change"}, {"db upgrade"}, {"db", "migrate"}}); // auth.* t.add("auth.oauth", "OAuth", {{"oauth"}}); t.add("auth.jwt", "JWT", {{"jwt"}, {"json web token"}, {"auth", "token"}}); t.add("auth.session", "Session Auth", {{"session"}, {"cookie", "auth"}}); t.add("auth.mfa", "Multi-Factor Auth", {{"mfa"}, {"2fa"}, {"totp"}, {"two factor"}}); // storage.* t.add("storage.object", "Object Storage", {{"object storage"}, {"s3"}, {"blob storage"}}); t.add("storage.cache", "Cache Storage", {{"cache"}, {"redis"}, {"memcache"}, {"rate limit"}}); t.add("storage.queue", "Message Queue", {{"kafka"}, {"rabbitmq"}, {"message queue"}, {"message broker"}, {"job queue"}, {"background worker"}, {"queue worker"}, {"bullmq"}, {"kafka-go"}}); // validation.* t.add("validation.schema", "Schema Validation", {{"schema", "validation"}, {"validate", "input"}, {"request", "validation"}, {"type validation"}, {"runtime validation"}, {"zod"}, {"pydantic"}}); // --- 0-dot (top-level, checked last) --- t.add("serialization", "Serialization", {{"serial"}, {"marshal"}, {"encode", "data"}}); t.add("compute", "Compute", {{"compute"}, {"calculation"}}); t.add("network", "Network", {{"network"}, {"socket"}}); t.add("io", "IO", {{"file io"}, {"io stream"}}); t.add("crypto", "Cryptography", {{"crypto"}, {"encrypt"}, {"decrypt"}}); t.add("db", "Database", {{"database"}}); t.add("auth", "Authentication", {{"authenticate"}, {"authorization"}}); t.add("storage", "Storage", {{"store data"}, {"persist data"}}); // Sort matchers: more dots first, then longer key first. std::stable_sort( t.matchers_.begin(), t.matchers_.end(), [](const DomainMatcher& a, const DomainMatcher& b) { auto dots = [](const std::string& s) { return std::count(s.begin(), s.end(), '.'); }; auto da = dots(a.domainKey), db = dots(b.domainKey); if (da != db) return da > db; return a.domainKey.size() > b.domainKey.size(); }); return t; } // Classify text to a domain key. Returns "unknown" if no match. std::string classify(const std::string& text) const { std::string lower = text; std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); for (const auto& m : matchers_) { if (matches(lower, m.keywordSets)) return m.domainKey; } return "unknown"; } std::vector allDomains() const { return registry_.all(); } size_t domainCount() const { return registry_.size(); } const OperationDomainRegistry& registry() const { return registry_; } // Unique top-level category keys (domains with no dot) std::vector topLevelCategories() const { std::vector result; for (const auto& d : registry_.all()) { if (d.isTopLevel()) result.push_back(d.key); } return result; } private: OperationDomainRegistry registry_; std::vector matchers_; void add(const std::string& key, const std::string& displayName, std::vector> keywordSets) { registry_.registerDomain({key, displayName}); matchers_.push_back({key, std::move(keywordSets)}); } // Returns true if ANY keyword set fully appears in lowerText. static bool matches(const std::string& lowerText, const std::vector>& sets) { for (const auto& kwSet : sets) { bool allFound = true; for (const auto& kw : kwSet) { if (lowerText.find(kw) == std::string::npos) { allFound = false; break; } } if (allFound) return true; } return false; } }; } // namespace whetstone