Salesforce org intelligence · in build

OrgIntelYour Salesforce org, documented by the org itself.

A local command-line tool that reads a Salesforce SFDX repository and writes back a verified knowledge base: one page per component, a complete dependency graph, and an output shaped so that a language model or an MCP client can query it directly. Deterministic, incremental, and offline by construction — no cloud, no network call, nothing leaves the machine.

My own initiative Capgemini offer Python 3.12 SQLite 100 % local 0 tokens
PS C:\work> uv run orgintel run --customer customer.yaml   scan      45,672 metadata files  parse     14,256 fact sheets · 339 metadata types  graph     42,222 dependency edges  generate  14,256 Markdown pages · 24 business domains  check     0 errors · 0 warnings · 0 stale  stats     coverage 100.0 % · documented 32.0 %  html      browsable mirror + dependency viewer   docs-rag/ ready — 0 network calls, 0 bytes sent,  0 tokens spent
45,672Metadata files read
14,256Components documented
42,222Dependencies mapped
339Metadata types named
100 %Page coverage
0Network calls
Measured, not projected

One run, one reference org — a full Salesforce Contact Center demo estate — on a standard Windows 11 laptop, CPU only, with the network unplugged. Figures are what the pipeline itself reported.

01 / The problem

Nobody can describe a large org in full.
Not the documentation. Not the platform.

After ten years of delivery, a mature Salesforce estate is a system whose behaviour lives in tens of thousands of metadata files — and whose written description, if any, was accurate the week it was written.

Documentation is a claim, not a fact

A wiki page states what someone intended. The repository states what the org does. The two diverge from the first hotfix onward, and no one can tell which pages are still true.

Git is the only truth — so every sentence OrgIntel writes is derived from parsed metadata, never inferred from a naming convention that looks about right.

DriftTribal knowledgeProvenance

“What breaks if I touch this?”

“Where is this used” finds only what the platform registered. The ones that break a release are hardcoded — an API name in a formula, a queue concatenated into a SOQL string, a record type in a custom setting.

OrgIntel reads the text as well as the structure, says unresolved rather than guessing, and draws parents and children at once.

Impact analysisHardcodedDepth-N

AI assistants guess at scale

Point an assistant at 45,000 raw metadata files and it either exhausts its context window or invents an API name that sounds plausible. Retrieval needs a curated corpus, not a directory.

OrgIntel produces that corpus: progressive disclosure, stable field names, every claim traceable back to a real source path — so an answer can be checked rather than believed.

RAGHallucinationContext window
02 / What it does

Three deliverables from one command.

Point it at an SFDX repository already retrieved from the org. It reads; it never writes to Salesforce, and it never calls it.

A page per component

Objects, fields, Apex classes and triggers, Flows, Lightning Web Components, Aura bundles, Visualforce, FlexiPages, permission sets and profiles, queues, roles, Einstein Bots, Agentforce agents, prompts, named credentials — each becomes one Markdown page with its facts, its security, its relations and a link back to the exact source file.

Output is French by default, English on request, with human-written blocks that survive every regeneration byte for byte.

50+ dedicated parsersFR / EN

A dependency graph that spans the whole org

Typed edges — SOQL reads, DML writes, trigger targets, callouts, permission grants, configuration references, plain identifier references — resolved against every known component and stored in SQLite.

An interactive viewer ships with the output: one self-contained HTML file, depth-N cascade, filters on confidence and origin, no server and no external script.

Typed edgesDepth-NOffline viewer

A knowledge base an agent can read

The tree follows a file-based retrieval norm: YAML front matter, sharded indexes, a relations file, an overview, and implementation references pointing at real SFDX paths — so retrieval is navigation, not similarity search.

An optional read-only MCP server exposes the same catalogue to Claude Code, GitHub Copilot, Agentforce Vibes or any client, over standard input and output. No port, no daemon, no writer.

MCPFile-based RAGRead-only
03 / How it works

Seven idempotent stages over one SQLite catalogue.

Each stage is a command you can run on its own, each records what it did, each supports --dry-run, and each one re-run on unchanged inputs produces zero diff. That property is not a claim — it is a blocking test.

Fig. 01 — pipeline · data flowclick a stage · it walks itself
The OrgIntel pipeline An SFDX repository feeds seven stages — scan, parse, graph, generate, check, stats and quality, html — which all read and write one SQLite catalogue. The catalogue renders the docs-rag corpus, its browsable mirror, the dependency viewer and the MCP server. The seven stages are described in full in the list below this diagram. SOURCE SFDX repo force-app/** read 01 scan 45,672 files 02 parse 14,256 sheets 03 graph 42,222 edges 04 generate 14,256 pages 05 check 0 errors · gate 06 stats · quality 2 reports 07 html 1 folder read + write CATALOGUE · ONE FILE catalog.db artefacts · entities · edges · runs content hashes · lineage · decisions render OUTPUT · ON DISK docs-rag/ Markdown corpus, French docs-rag-html/ browsable mirror + search graph.html · mcp viewer + agent access 0 network calls · 0 bytes sent · 0 tokens everything above is pure Python
No model, anywhere

The seven stages are one command or seven; the catalogue is the only thing between them. Nothing in this figure crosses a network boundary and nothing in it calls a model — the whole diagram is deterministic code, which is why re-running it costs a few minutes of CPU and nothing else.

  1. Scan

    orgintel scan

    Walks the package directories and registers every metadata file: path, Metadata API type, API name, SHA-256. A file matching no known convention falls to a generic classifier that derives its type from the file suffix — and anything it still cannot name stays unknown rather than being guessed.

  2. Parse

    orgintel parse

    Turns each group of files into one fact sheet — pure deterministic extraction. XML through lxml; Apex through a documented regular-expression ruleset that strips strings and comments first, then reads class headers, method signatures, SOQL, DML, callouts and referenced identifiers. No model is involved at this layer, ever.

  3. Graph

    orgintel graph

    Cross-references identifiers across every fact sheet into a typed edge table. A name matching two components is not silently assigned: the edge is marked ambiguous and queued for a human, carrying the file it was cited in so the reviewer can verify rather than trust.

  4. Generate

    orgintel generate

    Renders the pages and the derived indexes through Jinja2, one directory per Metadata API type, mirroring the SFDX source format. Manual blocks in an existing page are extracted and re-injected byte for byte; a page whose inputs did not change is not rewritten at all.

  5. Check

    orgintel check

    Validates the output against the rules that make it trustworthy: front matter present and valid, links resolving, implementation references still on disk, no manual block lost, and a second run producing an identical tree. Errors set a non-zero exit code, so the whole thing works as a continuous-integration gate.

  6. Stats & quality

    orgintel stats · quality

    Two reports, human and machine. Stats counts components by type, coverage, the most connected hubs, orphans, and the breakdown by business domain. Quality audits the org's own documentation debt — missing descriptions, missing help text, missing security classification — ranked worst-documented domain first, and by graph degree so the debt that hurts most comes up first.

  7. HTML

    orgintel html

    Mirrors the Markdown tree into a browsable site with a landing dashboard, global client-side search, faceted filtering, hover preview cards, an entity-relationship diagram, rendered Flow diagrams, a guided first-visit tour, and a print stylesheet. One folder, no server, no content delivery network — it opens off a shared drive.

Fig. 02 — catalogue · logical modelone SQLite file, five tables
The catalogue's logical model Five tables in one SQLite file. A run writes many artefacts; artefacts are parsed into entities; entities are the source and target of typed edges; an edge that could not be resolved with certainty carries a human decision. Every row carries the content hash of what produced it. WRITTEN BY EVERY COMMAND SCAN PARSE GRAPH REVIEW Run run_id command started_at · ended_at status · dry_run inputs_hash counts (read/written) 1 · ∗ Artifact path metadata_type api_name sha256 bundle_key run_id → ∗ · 1 Entity entity_id type · api_name label · domain facts (JSON sheet) impl_refs[] inputs_hash 1 · ∗ Edge src → dst kind (soql, dml, …) confidence origin (rule) cited_in : file cited_at : line 0 · 1 Decision edge_key verdict candidates[] rule that proposed decided_by · note committed as YAML every row carries the content hash of what produced it — that is what makes the next run incremental
Five tables, no server

Five tables, no server, no vector store. Decision is the only table a human writes, and it lives in the client's own repository as YAML so a judgement made once is never asked again. Edge is where the honesty is: a reference that resolves to two candidates keeps both, with the rule that proposed them, the file it was cited in and the line inside that file.

Incremental by construction

Every artefact carries a content hash and a lineage pointer. Change one Apex class and the next run recomputes that fact sheet, the edges it touches and the handful of pages that cite it — not the org. A cold run and an incremental run are the same code path with a different work list.

04 / What it costs to run

Documenting the org costs zero tokens.
Arguing with its wiki is the part that costs.

Reverse-documentation is parsing. Every page, every edge, every report on this site comes out of deterministic Python — no prompt, no completion, no context window, nothing metered. The one job that genuinely needs a model is the one no parser can do: reading prose a human wrote and deciding whether it still matches the facts.

Fig. 03 — where the model boundary sitsleft of the line: pure code
Which half of the tool spends tokens Left of the boundary, the whole retro-documentation chain runs as deterministic code: zero tokens, zero network calls. Right of the boundary, the optional comparison between the generated facts and the client's own documentation uses a language model, which may be a local model or an API key the client supplies. PROCEDURAL · NO MODEL, EVER SFDX repo 45,672 files scan → … → html lxml · regex · Jinja2 · SQLite docs-rag/ 14,256 pages · 42,222 edges 0 tokens in · 0 tokens out 0 network calls · 0 bytes sent CPU only, on a locked-down laptop re-run it nightly, on every branch, for every client — the marginal cost is minutes, not money MODEL BOUNDARY OPT-IN · A MODEL IS INVOLVED docs-rag/ — the facts Confluence · SharePoint align & compare claim → component → verdict gap report absent · undocumented · contradicted tokens a local model — Ollama, LM Studio — or an API key you supply. Your call. cached by content: a second run over unchanged text costs nothing
Architectural, not a setting

The boundary is architectural, not a setting. The offline chain has no code path that can reach a model — that is what makes it safe to point at a regulated estate on a locked-down laptop. The comparison layer is a separate command, off by default, and it can run entirely on-premises.

Always onDeterministic

Reverse-documentation

Reading 45,672 metadata files and writing 14,256 pages is string handling. XML through a parser, Apex through a documented regular-expression ruleset, identifiers cross-referenced against a name registry, pages rendered from templates.

0tokens
per full run
  • No prompt is ever built, so no context window can overflow and no output can be hallucinated.
  • Reproducible: the same repository always yields the same tree, byte for byte.
  • Auditable: every sentence on a page maps to a source file you can open.
  • Free to repeat — nightly, per branch, per client, in continuous integration.
05 / See the output

This is what lands on the shared drive.

A working miniature of the generated front end: twenty-two fixtures instead of fourteen thousand components, but the same shapes — the tree, search over the corpus, a generated page, the dependency viewer and the documentation-debt report. Click anything. Push the depth past 2 and watch the cascade open in both directions at once. It also demonstrates itself while you read.

file:///D:/orgintel/out/acme/docs-rag-html/objects/claim-c.html
title: "Claim__c" type: reference tags: ["objet"] audience: [dev] domain: "Sinistres" updated: 2026-08-02 entity_id: "CustomObject:Claim__c" inputs_hash: "sha256:be09b6238a02568e…" impl_refs: [7 chemins SFDX] generated: true
> Auto-généré — NE PAS ÉDITER

Claim__c

Rôle

Objet personnalisé « Sinistre » (Claim__c), modèle de partage Private. 4 champs, 1 type d'enregistrement, 2 règles de validation.

Contexte métier

<!-- manual:start --> · écrit par un humain, jamais écrasé

Porte les sinistres auto déclarés par le réseau d'agences. Le flux d'affectation s'appuie sur Is_Large__c pour router vers l'équipe grands comptes.

Comportement

champtyperequisdétails
Amount__cCurrencyouiprécision 18, échelle 2
Is_Large__cFormulanonAmount__c > 10000
Policy__cLookupnon→ Policy__c
Status__cPicklistnonensemble global, restreint

Dépendances

  • ClaimService — lit l'objet (SOQL) et écrit 2 champs (DML)
  • Claim_Assignment — flux déclenché après création
  • claimList, claimSummary — composants Lightning
  • Claims_Agent — accorde lecture / création / modification

Sources

force-app/main/default/objects/Claim__c/Claim__c.object-meta.xml
force-app/main/default/objects/Claim__c/fields/Amount__c.field-meta.xml
… 5 autres chemins
Live Search, tabs, the tree, the graph and the language switch all work. The corpus is French because that is what the generator writes by default.
Fig. 04 — retrieval by navigation, not by similaritywhy an agent can read this
Progressive disclosure: how the corpus is retrieved A question enters through a sharded index or the relations file rather than a vector search. The index points at one page, the page's front matter points at its neighbours and its implementation references point back at the SFDX source, so every answer can be traced to a file on disk. Because each hop narrows the corpus, an agent reads three small files to answer a question instead of loading forty-five thousand metadata files into its context window — which is what makes the retrieval side cheap in tokens as well as accurate. a question agent, or a human ENTRY POINTS INDEX.md sharded, by type + domain RELATIONS.yaml who uses what ONE PAGE objects/claim-c.md front matter → filters relations → next hop manual block → your prose impl_refs → the source THE ANSWER quoted from the page with the page's own link to a real SFDX path nothing inferred follow-up questions walk the same edges — no re-embedding, no index rebuild NO INFRASTRUCTURE no vector store to host no embedding cost no chunk boundary to tune a wrong answer is falsifiable PROGRESSIVE DISCLOSURE · WHY THE READING SIDE IS CHEAP TOO point an agent at the repository 45,672 files it cannot hold walk the corpus instead OVERVIEW.md names 24 domains INDEX shard names the components one page answers, and cites 3 files read
Navigation, not search

Progressive disclosure is the whole design. An overview names the domains, a sharded index names the components of one domain, and a component page names its neighbours — so each hop narrows the corpus instead of widening it. An agent walks that structure the way a developer walks a repository, which is why the same corpus serves orgintel query on a terminal and an MCP client in an IDE without a second pipeline.

Progressive disclosure is also the token strategy

Generating the corpus costs nothing — that is the point of the previous section. But reading it costs whatever an agent has to load, and that is where most retrieval designs quietly become expensive: a flat corpus forces the model to pull dozens of chunks and hope the right one is among them.

Here the structure does the narrowing. Three small files answer a question that would otherwise mean holding 45,672 metadata files — or a few hundred similarity-matched fragments — in a context window. Fewer, better-chosen tokens on the way in is also a shorter, more accurate answer on the way out, and every claim in it still points at a file on disk.

06 / Non-negotiables

Six rules the tool is not allowed to break.

They are what makes the output usable in a regulated estate — and each one is enforced by a test, not by discipline.

Git is truth

Everything generated is derived from parsed metadata. Nothing is inferred from a naming convention or a plausible pattern.

Never fabricate

A fact that cannot be parsed is emitted as unknown. An ambiguous reference is marked ambiguous. A missing planner directory is reported as missing, not silently resolved.

Deterministic first, model second

Fact extraction is pure code. The one command allowed to call a language model is deliberately outside the pipeline, and off by default.

Zero diff on re-run

Stable sort order everywhere. Re-running any command on unchanged inputs must produce no diff at all — and a failing idempotence check is a blocking error.

Nothing leaves the machine

No network call anywhere in the offline chain. No service, no container, no vector database. The reference platform is a locked-down corporate Windows 11 laptop.

Client data stays out

The engine is generic and driven by one configuration file per client. Its own test suite runs on synthetic fixtures — no client metadata ever enters the tool's repository.

07 / Who it is for

Four readers, one corpus.

The same generated tree answers a developer's question and a business analyst's — because the technical facts and the business grouping are two views of one catalogue, not two documents to keep in sync.

Architects

Hubs, orphans, cycles, the real integration surface, and an audit of an estate you did not build — before you commit to a remediation plan.

Developers

Who uses this field, what this class depends on, and which permission set grants it — answered before the change, not discovered in production.

Analysts & product owners

Components grouped into business domains, a glossary for every badge and term, a user guide, and a documentation-debt report naming the worst-covered domain first.

AI agents

Four read-only tools over the catalogue — search, who-uses, dependencies, page — reachable over MCP, plus the same answers on a terminal for a human checking the agent's work.

08 / Available today

It runs, end to end, on a real org.

The offline chain is complete and validated on a full reference estate at every data-truth milestone. What follows is the state of the tool as it stands, not a roadmap.

What lands on disk

One output directory per client: the catalogue, the fact sheets, the Markdown tree, its browsable mirror, and the reports.

out/<client>/ ├── catalog.db SQLite: artefacts, entities, edges, runs ├── facts/ one JSON fact sheet per component ├── docs-rag/ the canonical corpus │ ├── OVERVIEW.md · INDEX.md · RELATIONS.yaml │ ├── AGENTS.md · glossaire.md · guide-utilisateur.md │ ├── objects/ classes/ flows/ lwc/ permissionsets/ … │ ├── stats.md · quality.md · review-queue.md │ └── graph.html self-contained dependency viewer ├── docs-rag-html/ browsable mirror + dashboard + search └── logs/
MarkdownYAML front matterSQLite

What you can run

One command for the whole chain, or any stage on its own. Every command takes --dry-run, every command logs a run record.

$ orgintel run the whole offline chain $ orgintel scan · parse · graph · generate $ orgintel check · stats · quality · html $ orgintel review accept / reject an ambiguous edge $ orgintel sf-audit security & code audit of the client org $ orgintel narrate optional business prose (off by default) $ orgintel mcp read-only MCP server, standard I/O $ orgintel query the same four tools, on a terminal
Typer CLIWindows-firstDry-run everywhere

Security, both ways

The tool audits itself on every commit — secret scanning, static analysis, dependency and supply-chain checks, with every suppression required to carry a written reason.

And it audits the client's org: orgintel sf-audit wraps Salesforce Code Analyzer, adds the checks it misses — sharing bypasses, dynamic SOQL, callouts around Named Credentials, over-broad grants — and ranks findings by severity × reachability in the graph. Advisory by design: it never blocks a build.

AdvisoryBaseline diffP0–P3

A review queue, not a black box

Every reference the tool could not resolve with certainty becomes a decision a human can make: the candidates, the rule that proposed them, the confidence, and the exact metadata file the name was cited in.

Decisions are committed as a small YAML file in the client's own repository, so a judgement made once survives every future run.

Human in the loopTraceable

Optional business prose

A separate mode writes the functional layer a fact sheet cannot: what a component is for, one chapter per business domain. The facts are injected by code — the model only writes the connective prose, and is forbidden from inventing a name, a figure or a behaviour.

It is off by default and never part of the offline chain, runs against a local model or an API key you supply, and caches by content so a second run costs nothing.

Opt-inLocal or hostedCached
09 / Where it goes

From “what exists” to “what you believe exists”.

The offline chain answers what the org contains. The next milestone answers something harder — whether the documentation your teams rely on is still true.

  1. Shipped

    The pipeline, and the truth of the graph

    End-to-end chain with incrementality and security gates; correct edges through reference packs, org snapshots, universal reference mining and a name registry; exhaustive metadata coverage down to Einstein Bots, Omni-Channel and Agentforce; the quality audit; and the whole browsable front end — dashboard, search, facets, graph viewer, entity-relationship diagram, mobile and print.

    Including provenance on every ambiguous reference: 100 % of the decisions in the review queue now name the metadata file the name was cited in, structural and mined references alike.

  2. In build

    Provenance to the line, and the last unresolved names

    The file is shipped; the line number is not, yet. A reviewer already opens the exact metadata file a disputed name came from — what is on the bench now is landing the offset inside that file, so the reviewer arrives on the statement rather than on the document.

    Alongside it, extending the standard-component reference pack: 60 % of the remaining unresolved edges point at names Salesforce ships, and resolving those takes no action from the client at all.

  3. Next

    Factual versus documented

    Ingest the client's own documentation, align each claim to a real component, and produce the gap report that matters: documented but absent, present but undocumented, contradicted by the facts — each with the evidence attached. This is where the tool stops describing an org and starts arguing with its wiki.

  4. Full mode

    The platform behind the tool

    The Lite contracts were designed so the larger architecture plugs in without rework: hybrid lexical and vector retrieval for fuzzy business questions, an entity-linked graph over documentation and tickets, release-note impact reports crossed against your own components, generated documentation published through pull requests, and telemetry that turns unanswered queries into a documentation backlog.

Status, stated plainly

OrgIntel is in build. It started as my own initiative, it is now a Capgemini offer, and it runs today on a full reference org — but it is not a product you can download, and it is not sold as one. If it is relevant to an estate you are responsible for, the conversation starts on LinkedIn.