Show HN: Open-Source Alternative to TypeSafe.ai A developer released an open-source template for building deterministic models with structured reasoning, positioning it as an alternative to TypeSafe.ai. The template runs JavaScript rule functions through a forward-chaining symbolic inference engine locally on Node.js with no LLM at inference time, and pairs with an agent that orchestrates a feedback loop between LLM fact extraction and deterministic rule evaluation, returning FACT_NEEDED with a fact's schema rather than guessing when facts are ambiguous. The repo includes a model knowledge base template and a symbolic-kb skill in .claude/skills/symbolic-kb/ designed to run as an Agent Skills standard skill across opencode, Claude Code, and Codex. A self-contained template for building a deterministic model with structured reasoning. Rules are JavaScript functions executed by a forward-chaining symboling inference engine locally with Node.js — no LLM is used at inference time. To interact with unstructured inputs, an agent can be used to orchestrate a feedback loop between LLM fact extraction and deterministic rule evaluation, refusing to guess when facts are ambiguous. This repo contains a model knowledge base template clone it, use the skill to modify .kb/ , ship and the symbolic-kb skill in .claude/skills/symbolic-kb/ , which includes instructions for maintaining the knowledge base and the symbolic reasoning engine. This skill is designed to run as an Agent Skills https://agentskills.io standard skill opencode, Claude Code, Codex . A common practical example is where the deterministic code is responsible for making a decision, whereas LLM handles extraction of simple facts from the source unstructured data a source document, a set of facts/state that need to be extracted from the text etc . The decision-making then runs until an answer can be determined: 1. The agent picks the rule that answers your question, and extracts the facts it can see in the document/state. 2. It runs the engine. If a fact is missing, the engine returns FACT NEEDED with that fact's schema — never a guess. 3. The agent goes back to the document for that specific fact using the schema's type and description , adds it, and re-runs. 4. Repeat until COMPLETED , then the agent answers with the reasoning tree attached. In an opencode, Claude Code, or Codex session in this repo, ask: Here's a contract: "Acme LLC and Beta Inc. agree to a 12-month non-compete. Signed by A. Smith for Acme and J. Doe for Beta." Is it valid according to the 'symbolic-kb' skill? The agent extracts contract.hasNonCompete , contract.signedByPartyA , contract.signedByPartyB from the text, runs the inference, and answers with the reasoning tree — the same one the command-line example below prints. If a fact isn't in the document e.g., one signature is missing , the engine stops at FACT NEEDED for that fact and the agent says so rather than guessing: ● Skill symbolic-kb Successfully loaded skill Searched for 1 pattern, ran 3 shell commands Yes — valid, according to the contract.isValid rule. Reasoning trace: - contract.hasNonCompete = true 12-month non-compete clause is present - contract.signedByPartyA = true A. Smith signed for Acme - contract.signedByPartyB = true J. Doe signed for Beta - → contract.isSignedByBothParties = true both signatures present - → contract.isValid = true has non-compete AND signed by both parties For a document on disk, point the agent at the file attach it or give its path and ask the same question. For structured inputs, the same engine can be called programmatically without an LLM or an agent: 1. Query with a missing fact — the engine recurses into contract.isSignedByBothParties, finds contract.signedByPartyB missing, and stops rules load at runtime, no build step echo '{"fact":"contract.isValid","facts":{"contract.hasNonCompete":true,"contract.signedByPartyA":true}}' \ | node .claude/skills/symbolic-kb/scripts/run inference.mjs --kb-dir .kb \ | node .claude/skills/symbolic-kb/scripts/print tree.mjs ▶ Inferring contract.isValid — Is the contract valid? contract.hasNonCompete = true known ▶ Inferring contract.isSignedByBothParties — Is the contract signed by both parties? contract.signedByPartyA = true known ✗ contract.signedByPartyB is missing boolean — Whether party B signed the contract ✗ inference stopped due to contract.signedByPartyB missing ✗ inference stopped due to contract.signedByPartyB missing 2. Provide all facts — inference recurses and completes echo '{"fact":"contract.isValid","facts":{"contract.hasNonCompete":true,"contract.signedByPartyA":true,"contract.signedByPartyB":true}}' \ | node .claude/skills/symbolic-kb/scripts/run inference.mjs --kb-dir .kb \ | node .claude/skills/symbolic-kb/scripts/print tree.mjs ▶ Inferring contract.isValid — Is the contract valid? Rule: A contract is valid if it has a non-compete clause and is signed by both parties contract.hasNonCompete = true known ▶ Inferring contract.isSignedByBothParties — Is the contract signed by both parties? Rule: A contract is signed by both parties if party A and party B both signed contract.signedByPartyA = true known contract.signedByPartyB = true known ✓ inferred contract.isSignedByBothParties = true ✓ inferred contract.isValid = true A FACT NEEDED response is the engine refusing to guess — supply the missing fact and re-run, or have an agent extract it from your document see the Quick start above . To add or change rules, describe them in natural language; the agent translates your description to first-order logic, writes the rule file, updates manifest.json question, condition, dependencies , and lints the schemas. Usage example in this repo: Show me the knowledge base in this project Prints explanation of the existing rules in the knowledge base Add a rule: a contract is binding if it is valid and has been filed with the county. The agent updates the knowledge base with the additional rule. Re-run the query example to see how the updated tree executes. Modern agents can use the skill to automatically build entire reasoning knowledge base from a set of a few examples , reverse-engineering them into a decision-making model. For example: Redo this knowledge base to implement logic behind writing the emails. Use relevant skill to remove all existing rules, analyse the following examples and write rules that would produce all information needed to write a welcome email from the inputs: a set of emails and when each email was sent The agent would then analyze a few email examples provided and reverse-engineer how each was written and how decisions about varying the examples were made based on the input variables, producing a deterministic model capable of making decisions and writing an email brief from those input variables. .kb/ manifest.json Rule metadata: question, condition, dependencies schema rules/