<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arvind Jolly</title>
    <description>The latest articles on DEV Community by Arvind Jolly (@arvindjolly).</description>
    <link>https://dev.to/arvindjolly</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3990886%2F81a24a23-2096-44a7-bbd3-b129d26223df.png</url>
      <title>DEV Community: Arvind Jolly</title>
      <link>https://dev.to/arvindjolly</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arvindjolly"/>
    <language>en</language>
    <item>
      <title>How We Turned Geomantic Doctrine into Deterministic Software</title>
      <dc:creator>Arvind Jolly</dc:creator>
      <pubDate>Tue, 18 Aug 2026 12:27:51 +0000</pubDate>
      <link>https://dev.to/arvindjolly/how-we-turned-geomantic-doctrine-into-deterministic-software-20nf</link>
      <guid>https://dev.to/arvindjolly/how-we-turned-geomantic-doctrine-into-deterministic-software-20nf</guid>
      <description>&lt;p&gt;What happens when you take a centuries-old symbolic decision system and try to implement it as software?&lt;/p&gt;

&lt;p&gt;Not a chatbot that imitates its language.&lt;/p&gt;

&lt;p&gt;Not an AI prompt that produces something that &lt;em&gt;sounds&lt;/em&gt; traditional.&lt;/p&gt;

&lt;p&gt;A system that actually &lt;strong&gt;executes the underlying rules&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That is the engineering problem behind SAGE — the School of Ancient Geomantic Education.&lt;/p&gt;

&lt;p&gt;SAGE is building a growing portfolio of specialized decision tools based on Western Geomancy and Indian Ramal. The three newest additions are &lt;strong&gt;Temporal Engineering (Muhurta), Idea Validation (Prashna), and Venture Viability Oracle&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They are different modules for different problems, but they reveal a common architectural principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The deterministic engine calculates. The tradition constrains. AI explains.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This post looks at how that works.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with asking an LLM to "do geomancy"
&lt;/h2&gt;

&lt;p&gt;A large language model is remarkably good at producing plausible language.&lt;/p&gt;

&lt;p&gt;That is also the problem.&lt;/p&gt;

&lt;p&gt;Suppose you ask an LLM to perform a geomantic reading. It can generate figure names, describe planetary associations, interpret houses and produce a convincing narrative.&lt;/p&gt;

&lt;p&gt;But convincing is not the same as canonical.&lt;/p&gt;

&lt;p&gt;A model can accidentally mix Western geomancy with Indian Ramal. It can assign an incorrect planetary ruler to a figure. It can invent a relationship between houses. It can produce an elegant explanation of a calculation that was never actually performed.&lt;/p&gt;

&lt;p&gt;For a system like SAGE, that is unacceptable.&lt;/p&gt;

&lt;p&gt;The calculation therefore happens &lt;strong&gt;before&lt;/strong&gt; the language model enters the process.&lt;/p&gt;

&lt;p&gt;The AI receives a structured symbolic result and is instructed to interpret that result within the appropriate tradition.&lt;/p&gt;

&lt;p&gt;The distinction is fundamental.&lt;/p&gt;

&lt;h2&gt;
  
  
  The basic pipeline
&lt;/h2&gt;

&lt;p&gt;The architecture can be summarized as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Real-world question
        ↓
Use-case-specific model
        ↓
Canonical geomantic calculation
        ↓
Structured judicial evaluation
        ↓
AI synthesis
        ↓
Human-readable guidance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The three latest modules demonstrate three different implementations of that pipeline.&lt;/p&gt;

&lt;p&gt;Muhurta works backwards from a desired outcome.&lt;/p&gt;

&lt;p&gt;Prashna converts an inquiry into a deterministic chart.&lt;/p&gt;

&lt;p&gt;Venture Viability applies a Western judicial model to a proposed undertaking.&lt;/p&gt;

&lt;p&gt;The underlying principle remains the same: &lt;strong&gt;the LLM is downstream of the calculation.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Muhurta: solving the chart backwards
&lt;/h2&gt;

&lt;p&gt;Temporal Engineering is the most algorithmically unusual of the three.&lt;/p&gt;

&lt;p&gt;A normal reading starts with a chart and interprets it.&lt;/p&gt;

&lt;p&gt;An electional system asks a different question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What configuration would be desirable for the event I want to perform?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;SAGE therefore treats Muhurta as an inverse problem.&lt;/p&gt;

&lt;p&gt;The implementation defines all four-bit binary figure patterns and enumerates their combinations, producing the complete 65,536-chart possibility space.&lt;/p&gt;

&lt;p&gt;Instead of repeatedly constructing arbitrary charts, the system pre-indexes the results according to the desired H15 and H10 outcomes.&lt;/p&gt;

&lt;p&gt;That makes it possible to search for charts satisfying a particular event objective.&lt;/p&gt;

&lt;p&gt;The engine then applies additional structural filters.&lt;/p&gt;

&lt;p&gt;It checks, for example, for an antagonistic elemental relationship between the 1st and 7th houses and for specified shield-breach conditions.&lt;/p&gt;

&lt;p&gt;Only suitable candidates are retained.&lt;/p&gt;

&lt;h3&gt;
  
  
  The event itself becomes part of the model
&lt;/h3&gt;

&lt;p&gt;The system does not treat every action as equivalent.&lt;/p&gt;

&lt;p&gt;The event dictionary maps practical activities to different H10/H15 targets. Current mappings include business or project launches, housewarming, marriage, vehicle purchase, investment, travel, contract signing, professional consultation, wellness, property purchase, job changes, education, lawsuits and resignation.&lt;/p&gt;

&lt;p&gt;That creates an important software pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User describes an event
        ↓
Event classified
        ↓
Geomantic target selected
        ↓
Inverse search
        ↓
Candidate charts filtered
        ↓
Best configuration selected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user sees a simple timing tool.&lt;/p&gt;

&lt;p&gt;Underneath, the system is solving a constrained search problem across a finite symbolic state space.&lt;/p&gt;

&lt;p&gt;The resulting candidate chart provides the required first-house figure, elemental context and planetary ruler.&lt;/p&gt;

&lt;p&gt;Only then does the AI generate the natural-language explanation.&lt;/p&gt;

&lt;p&gt;The prompt itself explicitly tells the model not to expose the internal matrix terminology and instead provide a practical timing prescription, including the relevant planetary hour and elemental guidance.&lt;/p&gt;

&lt;p&gt;That is a useful general design pattern:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;keep implementation complexity inside the engine; expose the useful result through the interface.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Prashna: making an open-ended inquiry deterministic
&lt;/h2&gt;

&lt;p&gt;Prashna presents a different problem.&lt;/p&gt;

&lt;p&gt;A user can ask almost anything.&lt;/p&gt;

&lt;p&gt;How do you ensure that the same inputs lead through the same computational process?&lt;/p&gt;

&lt;p&gt;SAGE creates a deterministic canonical signature.&lt;/p&gt;

&lt;p&gt;The implementation normalizes the querent's name and event name, combines them with the supplied question, hashes the composite string and uses that result to create the seed for the Ramal chart.&lt;/p&gt;

&lt;p&gt;The important part is not the hash itself.&lt;/p&gt;

&lt;p&gt;It is the architectural separation between:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;input → deterministic symbolic state → interpretation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The chart is then evaluated through predefined judicial dimensions.&lt;/p&gt;

&lt;p&gt;The implementation extracts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1st House — querent readiness&lt;/li&gt;
&lt;li&gt;4th House — foundation and stability&lt;/li&gt;
&lt;li&gt;7th House — external factors and opposition&lt;/li&gt;
&lt;li&gt;9th House — auspiciousness&lt;/li&gt;
&lt;li&gt;10th House — public outcome and career impact&lt;/li&gt;
&lt;li&gt;11th House — realization, success and gains&lt;/li&gt;
&lt;li&gt;15th House — Judge / final verdict&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This turns a vague question into a structured diagnostic.&lt;/p&gt;

&lt;p&gt;The output is similarly structured before AI synthesis begins.&lt;/p&gt;

&lt;p&gt;For example, the system separately constructs explanations for the timing/auspiciousness dimension, readiness, foundation, success factors and final verdict.&lt;/p&gt;

&lt;p&gt;The language model then receives those computed values and is explicitly told to preserve doctrinal purity and use only the Indian Ramal figure names.&lt;/p&gt;

&lt;p&gt;Again:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;the model does not calculate the chart.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It explains the chart.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Venture Viability: same architecture, different canon
&lt;/h2&gt;

&lt;p&gt;The Venture Viability Oracle demonstrates another important software principle:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;shared architecture does not require shared doctrine.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This module is explicitly Western-exclusive and uses the Agrippan Geomantic Judicial Canon.&lt;/p&gt;

&lt;p&gt;Its input is transformed into a deterministic signature in the same general manner as Prashna, but the resulting chart is generated with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;generate_chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mothers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tradition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;western&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than the Ramal tradition.&lt;/p&gt;

&lt;p&gt;The judicial dimensions are again explicit:&lt;/p&gt;

&lt;p&gt;1st House — readiness&lt;br&gt;
4th House — foundation&lt;br&gt;
7th House — external factors&lt;br&gt;
9th House — fortune and favour&lt;br&gt;
10th House — public outcome&lt;br&gt;
11th House — gains&lt;br&gt;
15th House — Judge&lt;/p&gt;

&lt;p&gt;The synthesis layer is then given the computed Western figures, elements and planetary rulers.&lt;/p&gt;

&lt;p&gt;It is also explicitly instructed not to mix in Indian Ramal figure names.&lt;/p&gt;

&lt;p&gt;This separation is deliberate.&lt;/p&gt;

&lt;p&gt;A common software abstraction might tempt us to create one generic "geomancy" vocabulary and let the model fill in the differences.&lt;/p&gt;

&lt;p&gt;We chose the opposite approach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The architecture can be shared.&lt;br&gt;
The canon cannot be casually merged.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Why deterministic computation matters
&lt;/h2&gt;

&lt;p&gt;The word "AI" tends to make people assume that the entire system is probabilistic.&lt;/p&gt;

&lt;p&gt;That does not have to be true.&lt;/p&gt;

&lt;p&gt;In SAGE, the symbolic calculation can be deterministic even though the final narrative is generated by an AI model.&lt;/p&gt;

&lt;p&gt;That creates an interesting hybrid architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deterministic layer
    ↓
Canonical figures
    ↓
Judicial structure
    ↓
Probabilistic language layer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The deterministic portion establishes &lt;em&gt;what was calculated&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The language model determines &lt;em&gt;how that result is communicated&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That division gives us several advantages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reproducibility
&lt;/h3&gt;

&lt;p&gt;The underlying symbolic calculation follows an explicit computational pathway.&lt;/p&gt;

&lt;h3&gt;
  
  
  Doctrinal control
&lt;/h3&gt;

&lt;p&gt;Figure properties and house meanings can come from structured canonical data rather than model memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tradition separation
&lt;/h3&gt;

&lt;p&gt;Western and Ramal calculations can use distinct datasets and generation rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better AI behavior
&lt;/h3&gt;

&lt;p&gt;The model receives a constrained symbolic state rather than being asked to invent one.&lt;/p&gt;

&lt;h3&gt;
  
  
  This is particularly visible in the prompts used by the new modules, which provide the model with the computed figure, element and planetary ruler information before requesting synthesis.
&lt;/h3&gt;

&lt;h2&gt;
  
  
  The broader SAGE architecture
&lt;/h2&gt;

&lt;p&gt;These three modules are not the whole SAGE platform.&lt;/p&gt;

&lt;p&gt;They are the latest additions to a much larger and growing portfolio of specialized decision tools.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;The objective is not to build &lt;strong&gt;one giant geomantic engine&lt;/strong&gt; that tries to answer every question.&lt;/p&gt;

&lt;p&gt;It is to develop a reusable computational foundation and then build specialized modules around different categories of uncertainty.&lt;/p&gt;

&lt;p&gt;That means a use case can determine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which tradition is appropriate,&lt;/li&gt;
&lt;li&gt;which inputs matter,&lt;/li&gt;
&lt;li&gt;which houses deserve emphasis,&lt;/li&gt;
&lt;li&gt;which judicial rules apply,&lt;/li&gt;
&lt;li&gt;what constitutes the relevant outcome,&lt;/li&gt;
&lt;li&gt;and how the final result should be translated into practical guidance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The architecture therefore looks more like a platform than a single oracle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         SAGE
                          │
          ┌───────────────┼───────────────┐
          │               │               │
      Use Case A      Use Case B      Use Case C
          │               │               │
     Canon / Model    Canon / Model    Canon / Model
          │               │               │
     Deterministic    Deterministic    Deterministic
       Engine           Engine           Engine
          │               │               │
          └───────────────┼───────────────┘
                          │
                    AI Synthesis
                          │
                    User Guidance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reusable part is the infrastructure.&lt;/p&gt;

&lt;p&gt;The specialized part is the decision model.&lt;/p&gt;

&lt;p&gt;That is how an ancient symbolic system can gradually become a modern software platform.&lt;/p&gt;




&lt;h2&gt;
  
  
  The engineering lesson
&lt;/h2&gt;

&lt;p&gt;There is a broader software-engineering lesson here that goes beyond geomancy.&lt;/p&gt;

&lt;p&gt;When a system contains domain-specific rules, it can be tempting to put those rules inside an LLM prompt.&lt;/p&gt;

&lt;p&gt;That is often the fastest way to produce a demo.&lt;/p&gt;

&lt;p&gt;It is not necessarily the best way to produce a dependable system.&lt;/p&gt;

&lt;p&gt;A stronger pattern can be:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;formalize the domain → execute the rules deterministically → pass structured results to the LLM → constrain the narrative layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The same architecture could be useful in many domains where rules are explicit but explanations are naturally expressed in human language.&lt;/p&gt;

&lt;p&gt;The model becomes a &lt;strong&gt;communication layer rather than an authority on the underlying calculation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That is the distinction we are trying to preserve at SAGE.&lt;/p&gt;




&lt;h2&gt;
  
  
  The ancient system is the specification
&lt;/h2&gt;

&lt;p&gt;One of the most interesting consequences of this work is that implementation forces ambiguity into the open.&lt;/p&gt;

&lt;p&gt;A manuscript may say something that sounds perfectly clear to a human reader.&lt;/p&gt;

&lt;p&gt;A program cannot work with "something like this."&lt;/p&gt;

&lt;p&gt;The software needs to know:&lt;/p&gt;

&lt;p&gt;What is the input?&lt;/p&gt;

&lt;p&gt;What is the transformation?&lt;/p&gt;

&lt;p&gt;What are the legal states?&lt;/p&gt;

&lt;p&gt;What is the relationship between positions?&lt;/p&gt;

&lt;p&gt;What happens when a condition conflicts with another condition?&lt;/p&gt;

&lt;p&gt;Which tradition does a figure belong to?&lt;/p&gt;

&lt;p&gt;Which properties are authoritative?&lt;/p&gt;

&lt;p&gt;What constitutes an impossible configuration?&lt;/p&gt;

&lt;p&gt;In the Muhurta engine, for example, the software explicitly handles impossible H15/H10 combinations and refunds the transaction when no valid chart can satisfy the requested conditions.&lt;/p&gt;

&lt;p&gt;Encoding the doctrine therefore becomes a form of &lt;strong&gt;doctrinal clarification&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The computer is unforgiving.&lt;/p&gt;

&lt;p&gt;And that can be useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building a Silicon Oracle
&lt;/h2&gt;

&lt;p&gt;The phrase we use internally for this broader vision is the &lt;strong&gt;Silicon Oracle&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Not because silicon somehow replaces the ancient oracle.&lt;/p&gt;

&lt;p&gt;Because the computer can perform the repetitive, formal and combinatorial work that would be difficult to execute manually, while preserving the symbolic logic of the original system.&lt;/p&gt;

&lt;p&gt;The result is a new division of labor:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ancient doctrine provides the model.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Software executes the model.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI communicates the result.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And the user brings the actual decision.&lt;/p&gt;

&lt;p&gt;That last part matters.&lt;/p&gt;

&lt;p&gt;SAGE is not designed to remove human agency.&lt;/p&gt;

&lt;p&gt;The purpose of the system is to create a structured perspective around uncertainty.&lt;/p&gt;

&lt;p&gt;The final decision still belongs to the person asking the question.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where this goes next
&lt;/h2&gt;

&lt;p&gt;Muhurta, Prashna and Venture Viability are only the latest additions to SAGE.&lt;/p&gt;

&lt;p&gt;The more ambitious project is the growing portfolio itself.&lt;/p&gt;

&lt;p&gt;As additional decision categories are modeled, the same underlying principles can be reused:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;identify the decision problem,&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;select the appropriate tradition and canon,&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;encode the relevant rules,&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;generate the symbolic state deterministically,&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;evaluate it through the appropriate judicial framework,&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;and let AI turn the structured result into understandable guidance.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is the direction in which we are building SAGE.&lt;/p&gt;

&lt;p&gt;Not a chatbot that pretends to know ancient divination.&lt;/p&gt;

&lt;p&gt;Not a generic AI oracle.&lt;/p&gt;

&lt;p&gt;But a growing collection of specialized decision tools built from ancient geomantic systems and engineered for modern questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ancient systems.&lt;br&gt;
Structured logic.&lt;br&gt;
Modern engineering.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is the experiment.&lt;/p&gt;

&lt;p&gt;Explore the platform at &lt;strong&gt;&lt;a href="https://dotsofdestiny.com/" rel="noopener noreferrer"&gt;dotsofdestiny.com&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Found a Deterministic State Machine Hidden in a 1,000-Year-Old Indian Knowledge System</title>
      <dc:creator>Arvind Jolly</dc:creator>
      <pubDate>Fri, 26 Jun 2026 05:42:35 +0000</pubDate>
      <link>https://dev.to/arvindjolly/i-found-a-deterministic-state-machine-hidden-in-a-1000-year-old-indian-knowledge-system-2al5</link>
      <guid>https://dev.to/arvindjolly/i-found-a-deterministic-state-machine-hidden-in-a-1000-year-old-indian-knowledge-system-2al5</guid>
      <description>&lt;p&gt;&lt;em&gt;Sometimes the most elegant software architecture was designed centuries before software existed.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;When I began implementing &lt;strong&gt;Indian Ramal Shastra&lt;/strong&gt; (an Indian adaptation of Arabic geomancy) as a Python application, I expected to spend most of my time translating historical rules into code.&lt;/p&gt;

&lt;p&gt;Instead, I stumbled upon something I never expected.&lt;/p&gt;

&lt;p&gt;Buried inside a thousand-year-old knowledge system was what every software engineer would immediately recognize as a &lt;strong&gt;deterministic finite state machine&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Not a metaphor.&lt;/p&gt;

&lt;p&gt;An actual state machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Discovery
&lt;/h2&gt;

&lt;p&gt;One challenge in Ramal is determining the &lt;strong&gt;temporal behavior&lt;/strong&gt; of an outcome.&lt;/p&gt;

&lt;p&gt;Is an event approaching?&lt;/p&gt;

&lt;p&gt;Is it moving away?&lt;/p&gt;

&lt;p&gt;Will it remain stable?&lt;/p&gt;

&lt;p&gt;Or is it inherently unstable?&lt;/p&gt;

&lt;p&gt;Modern software engineers would probably model this using an enum.&lt;/p&gt;

&lt;p&gt;The Ramal tradition did exactly that—long before programming languages existed.&lt;/p&gt;

&lt;p&gt;Every one of its sixteen symbols belongs permanently to one of only four states.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Gati&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Enum&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;DAKHIL&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Entering&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;KHARIJ&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Exiting&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;SABIT&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Stable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;MUNQALEB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Transforming&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;Every possible input maps to exactly one state.&lt;/p&gt;

&lt;p&gt;No ambiguity.&lt;/p&gt;

&lt;p&gt;No probability.&lt;/p&gt;

&lt;p&gt;No fuzzy inference.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Static Lookup Table
&lt;/h2&gt;

&lt;p&gt;The implementation ended up looking surprisingly modern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;STATE_TABLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1211&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Gati&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DAKHIL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1121&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Gati&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KHARIJ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2222&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Gati&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SABIT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1111&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Gati&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MUNQALEB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;# ...
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The engine doesn't &lt;em&gt;calculate&lt;/em&gt; the state.&lt;/p&gt;

&lt;p&gt;It simply performs a lookup.&lt;/p&gt;

&lt;p&gt;The state is immutable because tradition already assigned it centuries ago.&lt;/p&gt;

&lt;p&gt;Once the state is known, downstream behavior becomes deterministic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Gati&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DAKHIL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;timing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1–7 days&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Gati&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KHARIJ&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;timing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2–4 weeks&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Gati&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SABIT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;timing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2–6 months&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;timing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;7–21 days&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you've written protocol handlers, parsers, workflow engines, or embedded software, this pattern probably feels familiar.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes It Interesting
&lt;/h2&gt;

&lt;p&gt;The remarkable part isn't that ancient scholars classified symbolic figures.&lt;/p&gt;

&lt;p&gt;Many traditions do that.&lt;/p&gt;

&lt;p&gt;The remarkable part is &lt;strong&gt;how&lt;/strong&gt; they classified them.&lt;/p&gt;

&lt;p&gt;The system has several properties we still value in software architecture today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deterministic&lt;/li&gt;
&lt;li&gt;Exhaustive&lt;/li&gt;
&lt;li&gt;Immutable&lt;/li&gt;
&lt;li&gt;Composable&lt;/li&gt;
&lt;li&gt;Easy to verify&lt;/li&gt;
&lt;li&gt;No undefined states&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every possible input is handled.&lt;/p&gt;

&lt;p&gt;Every input produces exactly one state.&lt;/p&gt;

&lt;p&gt;Nothing is left undefined.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond the State Machine
&lt;/h2&gt;

&lt;p&gt;While implementing the engine, I noticed something even more interesting.&lt;/p&gt;

&lt;p&gt;The four movement states aren't the only classification.&lt;/p&gt;

&lt;p&gt;Each figure also carries independent attributes describing its temperament and behavioral nature.&lt;/p&gt;

&lt;p&gt;Instead of exploding into dozens of special cases, these independent dimensions compose cleanly into what is essentially a multidimensional domain model.&lt;/p&gt;

&lt;p&gt;From a software design perspective, this is surprisingly elegant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ancient Domain-Driven Design?
&lt;/h2&gt;

&lt;p&gt;One observation kept occurring to me while writing the engine.&lt;/p&gt;

&lt;p&gt;The original practitioners obviously weren't thinking about enums, finite automata, or type systems.&lt;/p&gt;

&lt;p&gt;Yet they arrived at a structure that maps naturally onto all of them.&lt;/p&gt;

&lt;p&gt;The implementation required remarkably little interpretation because the underlying model was already highly structured.&lt;/p&gt;

&lt;p&gt;Sometimes good architecture simply transcends technology.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Wrote About It
&lt;/h2&gt;

&lt;p&gt;This isn't really an article about divination.&lt;/p&gt;

&lt;p&gt;It's an article about discovering computational thinking in an unexpected place.&lt;/p&gt;

&lt;p&gt;As developers, we're accustomed to believing that formal state modeling belongs to modern computer science.&lt;/p&gt;

&lt;p&gt;But occasionally history reminds us that people were building elegant rule-based systems long before computers existed.&lt;/p&gt;

&lt;p&gt;And that's fascinating.&lt;/p&gt;




&lt;h2&gt;
  
  
  Read the Complete Technical Breakdown
&lt;/h2&gt;

&lt;p&gt;The full article includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the complete 16-figure state table&lt;/li&gt;
&lt;li&gt;the four canonical movement states&lt;/li&gt;
&lt;li&gt;Python implementation details&lt;/li&gt;
&lt;li&gt;timing engine logic&lt;/li&gt;
&lt;li&gt;coherence scoring&lt;/li&gt;
&lt;li&gt;structural invariants&lt;/li&gt;
&lt;li&gt;why the model is effectively a deterministic finite state machine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can read the complete article here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://dotsofdestiny.com/blog-post-ramal-state-machine.html" rel="noopener noreferrer"&gt;https://dotsofdestiny.com/blog-post-ramal-state-machine.html&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm curious whether you've encountered other historical systems whose architecture resembles modern software design. I'd love to hear your examples in the comments.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>computerscience</category>
      <category>software</category>
    </item>
    <item>
      <title>Building a High-Performance Progressive Web App Without React or Next.js</title>
      <dc:creator>Arvind Jolly</dc:creator>
      <pubDate>Mon, 22 Jun 2026 11:13:19 +0000</pubDate>
      <link>https://dev.to/arvindjolly/building-an-offline-first-progressive-web-app-without-react-or-nextjs-hac</link>
      <guid>https://dev.to/arvindjolly/building-an-offline-first-progressive-web-app-without-react-or-nextjs-hac</guid>
      <description>&lt;p&gt;&lt;em&gt;Lessons learned from improving performance, caching, and user experience in a production web application.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;When we set out to build &lt;strong&gt;SAGE (School of Ancient Geomantic Education)&lt;/strong&gt;, our focus was not initially on Progressive Web Apps.&lt;/p&gt;

&lt;p&gt;SAGE combines traditional systems such as Western Geomancy and Indian Ramal Shastra with modern web technologies, educational resources, interactive calculators, and AI-assisted interpretation.&lt;/p&gt;

&lt;p&gt;As the platform evolved, performance, reliability, and user experience became increasingly important concerns.&lt;/p&gt;

&lt;p&gt;Our users access the platform from a wide variety of devices and network conditions. Some use desktop computers with fast broadband connections. Others rely on mobile networks where latency and bandwidth can vary significantly.&lt;/p&gt;

&lt;p&gt;We wanted the experience to feel fast, responsive, and dependable regardless of connection quality.&lt;/p&gt;

&lt;p&gt;That led us to explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service Workers&lt;/li&gt;
&lt;li&gt;Intelligent caching strategies&lt;/li&gt;
&lt;li&gt;Firebase Hosting optimizations&lt;/li&gt;
&lt;li&gt;Progressive Web App technologies&lt;/li&gt;
&lt;li&gt;Performance-focused UX design&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was not to create a fully offline oracle. AI-assisted readings continue to require backend services and network connectivity.&lt;/p&gt;

&lt;p&gt;Instead, the objective was to improve performance, reduce unnecessary network requests, create a more resilient user experience, and make the platform feel more like a modern application than a traditional website.&lt;/p&gt;

&lt;p&gt;This is the story of how we transformed a straightforward HTML + Firebase Hosting application into a faster, more polished Progressive Web App—without React, Next.js, or heavyweight build pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Principle: Treat the Service Worker as a Router
&lt;/h2&gt;

&lt;p&gt;Many PWA tutorials present caching strategies as isolated techniques:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cache-first&lt;/li&gt;
&lt;li&gt;Network-first&lt;/li&gt;
&lt;li&gt;Stale-while-revalidate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, a production application usually needs several of them simultaneously.&lt;/p&gt;

&lt;p&gt;The most useful mental model we found was to think of the service worker as a routing layer.&lt;/p&gt;

&lt;p&gt;Different content types receive different treatment.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Content&lt;/th&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Images, CSS, fonts, static JavaScript&lt;/td&gt;
&lt;td&gt;Cache-first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML documents&lt;/td&gt;
&lt;td&gt;Network-first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API requests&lt;/td&gt;
&lt;td&gt;Pass-through&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Configuration modules&lt;/td&gt;
&lt;td&gt;Always fresh&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The important question is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which caching strategy should I use?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The important question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which caching strategy should this particular resource use?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once we adopted that mindset, the service worker became dramatically easier to reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Public Content and Private Content Are Different Problems
&lt;/h2&gt;

&lt;p&gt;One mistake I see frequently in PWA discussions is treating all pages equally.&lt;/p&gt;

&lt;p&gt;They aren't.&lt;/p&gt;

&lt;p&gt;Some pages are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Public&lt;/li&gt;
&lt;li&gt;Anonymous&lt;/li&gt;
&lt;li&gt;Safe to cache&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Others are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User-specific&lt;/li&gt;
&lt;li&gt;Session-aware&lt;/li&gt;
&lt;li&gt;Privacy-sensitive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The boundary matters.&lt;/p&gt;

&lt;p&gt;For example, serving a stale public calculator page is usually harmless.&lt;/p&gt;

&lt;p&gt;Serving cached user-specific content to the wrong session is not.&lt;/p&gt;

&lt;p&gt;Our solution was simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Public pages can be pre-cached.&lt;/li&gt;
&lt;li&gt;Session-dependent pages are excluded from pre-caching.&lt;/li&gt;
&lt;li&gt;Sensitive content is always fetched fresh.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is a much safer offline experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Never Cache the Service Worker
&lt;/h2&gt;

&lt;p&gt;If there is one rule worth remembering, it is this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do not aggressively cache your service worker.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The service worker controls your entire update mechanism.&lt;/p&gt;

&lt;p&gt;If the browser becomes stuck with an old service worker, every future deployment becomes harder.&lt;/p&gt;

&lt;p&gt;Static assets can be immutable.&lt;/p&gt;

&lt;p&gt;The service worker cannot.&lt;/p&gt;

&lt;p&gt;Treat it as the control plane for your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build an Escape Hatch
&lt;/h2&gt;

&lt;p&gt;Eventually, every production application encounters one of these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A bad deployment&lt;/li&gt;
&lt;li&gt;Corrupted cache state&lt;/li&gt;
&lt;li&gt;An update bug&lt;/li&gt;
&lt;li&gt;A broken service worker&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When that happens, users should not need to clear browser data manually.&lt;/p&gt;

&lt;p&gt;We implemented a simple versioning mechanism that can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Detect an application version change&lt;/li&gt;
&lt;li&gt;Unregister outdated service workers&lt;/li&gt;
&lt;li&gt;Trigger a clean reload&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Think of it as an emergency recovery procedure.&lt;/p&gt;

&lt;p&gt;You may never need it.&lt;/p&gt;

&lt;p&gt;When you do need it, you'll be glad it exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why We Chose localStorage Instead of IndexedDB
&lt;/h2&gt;

&lt;p&gt;This decision often surprises developers.&lt;/p&gt;

&lt;p&gt;IndexedDB is usually presented as the "correct" storage solution for PWAs.&lt;/p&gt;

&lt;p&gt;For large datasets, that's true.&lt;/p&gt;

&lt;p&gt;For our use case, it wasn't.&lt;/p&gt;

&lt;p&gt;The application only needed to store:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Small pieces of user state&lt;/li&gt;
&lt;li&gt;Temporary workflow data&lt;/li&gt;
&lt;li&gt;Lightweight JSON payloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each payload was only a few kilobytes.&lt;/p&gt;

&lt;p&gt;The benefits of localStorage were compelling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simplicity&lt;/li&gt;
&lt;li&gt;Synchronous access&lt;/li&gt;
&lt;li&gt;No schema management&lt;/li&gt;
&lt;li&gt;Minimal implementation complexity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Could IndexedDB have worked?&lt;/p&gt;

&lt;p&gt;Absolutely.&lt;/p&gt;

&lt;p&gt;Would it have improved the user experience?&lt;/p&gt;

&lt;p&gt;Not meaningfully.&lt;/p&gt;

&lt;p&gt;Sometimes the simplest solution is the right solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Most Overlooked Performance Problem: Fonts
&lt;/h2&gt;

&lt;p&gt;Many performance discussions focus on JavaScript bundles.&lt;/p&gt;

&lt;p&gt;In our case, fonts were the bigger challenge.&lt;/p&gt;

&lt;p&gt;The application supports multiple writing systems, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Latin&lt;/li&gt;
&lt;li&gt;Devanagari&lt;/li&gt;
&lt;li&gt;Arabic&lt;/li&gt;
&lt;li&gt;Japanese&lt;/li&gt;
&lt;li&gt;Chinese&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without careful loading strategies, typography can easily become the largest source of perceived latency.&lt;/p&gt;

&lt;p&gt;Three techniques made the difference:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using &lt;code&gt;display=swap&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Adding preconnect hints&lt;/li&gt;
&lt;li&gt;Caching font resources after the first visit&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After the initial load, typography effectively became free.&lt;/p&gt;

&lt;h2&gt;
  
  
  Offline UX Is More Important Than Offline Technology
&lt;/h2&gt;

&lt;p&gt;Most developers focus on the technical side of offline support.&lt;/p&gt;

&lt;p&gt;Users don't care about your caching strategy.&lt;/p&gt;

&lt;p&gt;They care about what happens when connectivity disappears.&lt;/p&gt;

&lt;p&gt;When a page isn't available offline, users should never encounter a browser error screen.&lt;/p&gt;

&lt;p&gt;Instead, provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A branded fallback page&lt;/li&gt;
&lt;li&gt;Clear messaging&lt;/li&gt;
&lt;li&gt;A recovery path&lt;/li&gt;
&lt;li&gt;Consistent visual identity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not merely functionality.&lt;/p&gt;

&lt;p&gt;The goal is preserving trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fast Applications Need Feedback
&lt;/h2&gt;

&lt;p&gt;An unexpected challenge emerged once everything was cached.&lt;/p&gt;

&lt;p&gt;The application became extremely fast.&lt;/p&gt;

&lt;p&gt;Page transitions often completed in under 100 milliseconds.&lt;/p&gt;

&lt;p&gt;Users interpreted this as abrupt rather than responsive.&lt;/p&gt;

&lt;p&gt;The solution wasn't optimization.&lt;/p&gt;

&lt;p&gt;The solution was intentional motion.&lt;/p&gt;

&lt;p&gt;Subtle micro-interactions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entry animations&lt;/li&gt;
&lt;li&gt;State indicators&lt;/li&gt;
&lt;li&gt;Ambient visual feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;made the interface feel more polished despite adding virtually no latency.&lt;/p&gt;

&lt;p&gt;This was a reminder that perceived performance and measured performance are not always the same thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Learned
&lt;/h2&gt;

&lt;p&gt;After deploying and maintaining the application, a few principles stood out:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Service workers are routing infrastructure
&lt;/h3&gt;

&lt;p&gt;Treat them like routers rather than cache containers.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Not everything belongs in IndexedDB
&lt;/h3&gt;

&lt;p&gt;Simple state often benefits more from simplicity than scalability.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Offline experiences are UX problems first
&lt;/h3&gt;

&lt;p&gt;Caching is only the implementation detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Every PWA needs a recovery mechanism
&lt;/h3&gt;

&lt;p&gt;Eventually something will go wrong.&lt;/p&gt;

&lt;p&gt;Plan for it.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Fast interfaces still need visual feedback
&lt;/h3&gt;

&lt;p&gt;Perceived quality matters as much as measured speed.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Simplicity scales surprisingly far
&lt;/h3&gt;

&lt;p&gt;For many applications, a lightweight architecture can outperform a far more complex framework-based stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The modern web platform already provides most of the tools needed to build capable offline applications.&lt;/p&gt;

&lt;p&gt;Service Workers, Cache Storage, localStorage, and modern browser APIs are remarkably powerful when combined thoughtfully.&lt;/p&gt;

&lt;p&gt;The biggest lesson wasn't technical.&lt;/p&gt;

&lt;p&gt;It was architectural.&lt;/p&gt;

&lt;p&gt;Offline support works best when it is treated as a product requirement from the beginning rather than an enhancement added later.&lt;/p&gt;

&lt;p&gt;When that happens, the result feels less like a website and more like an application that simply happens to run on the web.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Note on Offline Functionality
&lt;/h2&gt;

&lt;p&gt;The techniques discussed in this article focus primarily on performance optimization, caching, installability, and user experience improvements.&lt;/p&gt;

&lt;p&gt;While certain assets and resources benefit from browser caching, AI-assisted readings and other server-dependent functionality continue to require network connectivity and backend processing.&lt;/p&gt;

&lt;p&gt;The goal was to build a faster and more resilient web experience rather than a fully offline application.&lt;/p&gt;




&lt;p&gt;What has been your biggest challenge building PWAs in production? I'd be interested to hear what strategies have worked (or failed) for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  About the Project
&lt;/h2&gt;

&lt;p&gt;SAGE (School of Ancient Geomantic Education) is a modern geomancy platform that combines traditional Western Geomancy and Indian Ramal Shastra with contemporary software engineering.&lt;/p&gt;

&lt;p&gt;The platform provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free geomantic calculators and educational tools&lt;/li&gt;
&lt;li&gt;Daily oracle readings&lt;/li&gt;
&lt;li&gt;Premium AI-assisted geomantic consultations&lt;/li&gt;
&lt;li&gt;Support for multiple languages&lt;/li&gt;
&lt;li&gt;Offline-capable Progressive Web App functionality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Explore the project at dotsofdestiny.com and learn more about how ancient symbolic systems can be implemented using modern web technologies.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>pwa</category>
      <category>javascript</category>
      <category>performance</category>
    </item>
    <item>
      <title>How We Modeled Conflicting Historical Knowledge Without Breaking Our Database</title>
      <dc:creator>Arvind Jolly</dc:creator>
      <pubDate>Thu, 18 Jun 2026 12:37:54 +0000</pubDate>
      <link>https://dev.to/arvindjolly/how-we-modeled-conflicting-historical-knowledge-without-breaking-our-database-4okj</link>
      <guid>https://dev.to/arvindjolly/how-we-modeled-conflicting-historical-knowledge-without-breaking-our-database-4okj</guid>
      <description>&lt;h3&gt;
  
  
  How building an AI-powered geomancy platform forced us to rethink data modeling
&lt;/h3&gt;

&lt;p&gt;Most software systems assume that there is a single source of truth.&lt;/p&gt;

&lt;p&gt;A user has one email address.&lt;/p&gt;

&lt;p&gt;A product has one price.&lt;/p&gt;

&lt;p&gt;An order has one status.&lt;/p&gt;

&lt;p&gt;Databases, APIs, and validation layers are typically designed around this assumption.&lt;/p&gt;

&lt;p&gt;But what happens when your domain contains multiple valid truths?&lt;/p&gt;

&lt;p&gt;This was a problem we encountered while building &lt;strong&gt;SAGE&lt;/strong&gt;, an AI-powered geomantic platform that supports multiple historical traditions, including Western Geomancy and Indian Ramal.&lt;/p&gt;

&lt;p&gt;Unexpectedly, the hardest challenge wasn't AI.&lt;/p&gt;

&lt;p&gt;It was data modeling.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Geomancy is built around sixteen foundational figures.&lt;/p&gt;

&lt;p&gt;Each figure carries various attributes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Element&lt;/li&gt;
&lt;li&gt;Planetary ruler&lt;/li&gt;
&lt;li&gt;Zodiac association&lt;/li&gt;
&lt;li&gt;Interpretive meanings&lt;/li&gt;
&lt;li&gt;Dignities and conditions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The complication?&lt;/p&gt;

&lt;p&gt;Different historical traditions don't always agree.&lt;/p&gt;

&lt;p&gt;For example, a figure may have one set of correspondences in a Western lineage and a different set in an Indo-Persian Ramal lineage.&lt;/p&gt;

&lt;p&gt;From a historical perspective, this is normal.&lt;/p&gt;

&lt;p&gt;From a software perspective, it creates an immediate design problem.&lt;/p&gt;

&lt;p&gt;A naïve schema might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;figures&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;planet&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;zodiac&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks fine.&lt;/p&gt;

&lt;p&gt;Until two legitimate traditions assign different values to the same figure.&lt;/p&gt;

&lt;p&gt;Now the database is asking a question that historians have debated for centuries:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which version is correct?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Wrong Solution
&lt;/h2&gt;

&lt;p&gt;Many systems solve this by choosing one authority.&lt;/p&gt;

&lt;p&gt;In effect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;One Figure
↓
One Interpretation
↓
One Truth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simplifies implementation.&lt;/p&gt;

&lt;p&gt;It also destroys historical fidelity.&lt;/p&gt;

&lt;p&gt;As soon as we hardcode one interpretation, every other lineage becomes "wrong" according to the software.&lt;/p&gt;

&lt;p&gt;That wasn't acceptable.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Shift: Truth as Context
&lt;/h2&gt;

&lt;p&gt;The breakthrough came when we stopped treating interpretations as facts.&lt;/p&gt;

&lt;p&gt;Instead, we treated them as context.&lt;/p&gt;

&lt;p&gt;The identity of a figure remains constant.&lt;/p&gt;

&lt;p&gt;Its attributes become lineage-dependent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"figure"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"puer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"binary_signature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1101"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lineages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"agrippa_western"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"element"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fire"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"planet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mars"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ramal_traditional"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"element"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"air"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"planet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mars"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the question becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What is the element of Puer
within this lineage?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What is the element of Puer?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This distinction changed the entire architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Registry Pattern
&lt;/h2&gt;

&lt;p&gt;Duplicating complete datasets for every tradition would quickly become unmaintainable.&lt;/p&gt;

&lt;p&gt;Most lineages agree on the majority of attributes.&lt;/p&gt;

&lt;p&gt;Only a small percentage differ.&lt;/p&gt;

&lt;p&gt;To solve this, we implemented a layered registry pattern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FigureRegistry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;figure_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;attribute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;lineage&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;lineage_override_exists&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;override&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;baseline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Resolution order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lineage Override
        ↓
Tradition Baseline
        ↓
Default Registry
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gave us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smaller datasets&lt;/li&gt;
&lt;li&gt;Easier maintenance&lt;/li&gt;
&lt;li&gt;Cleaner onboarding of new traditions&lt;/li&gt;
&lt;li&gt;Reduced duplication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most importantly, it allowed the system to grow without rewriting existing data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Snapshots Matter
&lt;/h2&gt;

&lt;p&gt;The next challenge was versioning.&lt;/p&gt;

&lt;p&gt;Suppose a reading is generated today.&lt;/p&gt;

&lt;p&gt;Six months later, historical research leads us to revise part of a lineage definition.&lt;/p&gt;

&lt;p&gt;Should old readings change?&lt;/p&gt;

&lt;p&gt;Absolutely not.&lt;/p&gt;

&lt;p&gt;A reading should remain reproducible forever.&lt;/p&gt;

&lt;p&gt;The solution was to store a resolved snapshot with every generated reading.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reading_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rdg_892347"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tradition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"western_agrippa"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"schema_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v1.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resolved_attributes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"puer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"element"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fire"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"planet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mars"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auditability&lt;/li&gt;
&lt;li&gt;Reproducibility&lt;/li&gt;
&lt;li&gt;Historical consistency&lt;/li&gt;
&lt;li&gt;Easier debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every reading becomes self-contained.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Broader Pattern
&lt;/h2&gt;

&lt;p&gt;Although this project involved geomancy, the underlying problem appears everywhere.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;h3&gt;
  
  
  Legal Systems
&lt;/h3&gt;

&lt;p&gt;Different jurisdictions interpret regulations differently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Medicine
&lt;/h3&gt;

&lt;p&gt;Clinical guidelines change over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finance
&lt;/h3&gt;

&lt;p&gt;Accounting standards vary across countries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Taxation
&lt;/h3&gt;

&lt;p&gt;Rules differ by region and version.&lt;/p&gt;

&lt;h3&gt;
  
  
  Historical Archives
&lt;/h3&gt;

&lt;p&gt;Sources often contradict each other.&lt;/p&gt;

&lt;p&gt;The common challenge is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Multiple valid interpretations must coexist inside a single system.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Traditional CRUD thinking doesn't solve that elegantly.&lt;/p&gt;

&lt;p&gt;Context-aware architectures do.&lt;/p&gt;




&lt;h2&gt;
  
  
  What We Learned
&lt;/h2&gt;

&lt;p&gt;The most valuable lesson wasn't about AI.&lt;/p&gt;

&lt;p&gt;It was about knowledge representation.&lt;/p&gt;

&lt;p&gt;Many domains don't contain a single source of truth.&lt;/p&gt;

&lt;p&gt;They contain multiple authoritative perspectives.&lt;/p&gt;

&lt;p&gt;The job of software architecture isn't always to eliminate disagreement.&lt;/p&gt;

&lt;p&gt;Sometimes it's to model disagreement cleanly.&lt;/p&gt;

&lt;p&gt;Once we accepted that idea, the architecture became significantly simpler.&lt;/p&gt;

&lt;p&gt;Instead of forcing competing traditions into a single schema, we designed a system that allows multiple traditions to coexist while sharing a common framework.&lt;/p&gt;

&lt;p&gt;In hindsight, that turned out to be a much more scalable solution than trying to determine which historical authority was "correct."&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;If your domain contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;competing authorities&lt;/li&gt;
&lt;li&gt;evolving standards&lt;/li&gt;
&lt;li&gt;multiple jurisdictions&lt;/li&gt;
&lt;li&gt;historical interpretations&lt;/li&gt;
&lt;li&gt;configurable business rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;you may not have a data problem.&lt;/p&gt;

&lt;p&gt;You may have a context problem.&lt;/p&gt;

&lt;p&gt;And context is often easier to model than truth.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally inspired by architectural challenges encountered while building SAGE, an AI-powered platform for Western Geomancy and Indian Ramal traditions.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;I'm the founder of SAGE (School of Ancient Geomantic Education), where we're building AI-powered systems for Western Geomancy and Indian Ramal. I write about software architecture, knowledge modeling, and the challenges of digitizing historical systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;p&gt;This article was adapted from a real architectural challenge encountered while building SAGE (School of Ancient Geomantic Education), an AI-powered platform for Western Geomancy and Indian Ramal.&lt;/p&gt;

&lt;p&gt;For the original article and additional discussion, visit:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.dotsofdestiny.com/blog-post-conflict-resolution" rel="noopener noreferrer"&gt;https://www.dotsofdestiny.com/blog-post-conflict-resolution&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also explore the broader project at:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.dotsofdestiny.com" rel="noopener noreferrer"&gt;https://www.dotsofdestiny.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>database</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
