fux-engine 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. fux_engine-0.1.0/LICENSE +21 -0
  2. fux_engine-0.1.0/PKG-INFO +186 -0
  3. fux_engine-0.1.0/README.md +147 -0
  4. fux_engine-0.1.0/fux/__init__.py +6 -0
  5. fux_engine-0.1.0/fux/__main__.py +4 -0
  6. fux_engine-0.1.0/fux/assets/fux-icon.svg +61 -0
  7. fux_engine-0.1.0/fux/assets/fux-lockup.svg +69 -0
  8. fux_engine-0.1.0/fux/assets/fux-mark.svg +26 -0
  9. fux_engine-0.1.0/fux/assets/graph_boot.js +214 -0
  10. fux_engine-0.1.0/fux/assets/graph_template.html +111 -0
  11. fux_engine-0.1.0/fux/astextract.py +410 -0
  12. fux_engine-0.1.0/fux/bench.py +34 -0
  13. fux_engine-0.1.0/fux/build.py +29 -0
  14. fux_engine-0.1.0/fux/capture.py +99 -0
  15. fux_engine-0.1.0/fux/check.py +143 -0
  16. fux_engine-0.1.0/fux/cli.py +139 -0
  17. fux_engine-0.1.0/fux/clicmds.py +162 -0
  18. fux_engine-0.1.0/fux/cligraph.py +69 -0
  19. fux_engine-0.1.0/fux/cliquery.py +157 -0
  20. fux_engine-0.1.0/fux/cliutil.py +13 -0
  21. fux_engine-0.1.0/fux/community.py +50 -0
  22. fux_engine-0.1.0/fux/config.py +85 -0
  23. fux_engine-0.1.0/fux/context.py +31 -0
  24. fux_engine-0.1.0/fux/costledger.py +119 -0
  25. fux_engine-0.1.0/fux/coverage.py +43 -0
  26. fux_engine-0.1.0/fux/data/global/README.md +37 -0
  27. fux_engine-0.1.0/fux/data/global/rules/async-everywhere.md +22 -0
  28. fux_engine-0.1.0/fux/data/global/rules/doc-per-code-change.md +23 -0
  29. fux_engine-0.1.0/fux/data/global/rules/files-max-100-lines.md +20 -0
  30. fux_engine-0.1.0/fux/data/global/rules/no-secrets-in-vcs.md +21 -0
  31. fux_engine-0.1.0/fux/data/hooks/_common.sh +12 -0
  32. fux_engine-0.1.0/fux/data/hooks/post_tool_use.sh +7 -0
  33. fux_engine-0.1.0/fux/data/hooks/session_start.sh +7 -0
  34. fux_engine-0.1.0/fux/data/hooks/stop.sh +7 -0
  35. fux_engine-0.1.0/fux/data/hooks/user_prompt_submit.sh +7 -0
  36. fux_engine-0.1.0/fux/data/packs/indian-markets-tax/pack.toml +6 -0
  37. fux_engine-0.1.0/fux/data/packs/indian-markets-tax/rules/capital-gains-equity.md +22 -0
  38. fux_engine-0.1.0/fux/data/packs/indian-markets-tax/rules/market-hours-nse.md +21 -0
  39. fux_engine-0.1.0/fux/data/schema.json +48 -0
  40. fux_engine-0.1.0/fux/data/skills/adr/SKILL.md +37 -0
  41. fux_engine-0.1.0/fux/data/skills/distill/SKILL.md +66 -0
  42. fux_engine-0.1.0/fux/data/skills/fetch-rules/SKILL.md +147 -0
  43. fux_engine-0.1.0/fux/data/skills/fux/SKILL.md +154 -0
  44. fux_engine-0.1.0/fux/data/skills/plan/SKILL.md +67 -0
  45. fux_engine-0.1.0/fux/data/skills/savings/SKILL.md +56 -0
  46. fux_engine-0.1.0/fux/data/skills/trace/SKILL.md +38 -0
  47. fux_engine-0.1.0/fux/drift.py +27 -0
  48. fux_engine-0.1.0/fux/embed.py +67 -0
  49. fux_engine-0.1.0/fux/explain.py +64 -0
  50. fux_engine-0.1.0/fux/fetchrules.py +122 -0
  51. fux_engine-0.1.0/fux/findings.py +26 -0
  52. fux_engine-0.1.0/fux/fix.py +54 -0
  53. fux_engine-0.1.0/fux/fmwrite.py +46 -0
  54. fux_engine-0.1.0/fux/frontmatter.py +88 -0
  55. fux_engine-0.1.0/fux/gate.py +65 -0
  56. fux_engine-0.1.0/fux/gitutil.py +69 -0
  57. fux_engine-0.1.0/fux/globs.py +38 -0
  58. fux_engine-0.1.0/fux/governance.py +55 -0
  59. fux_engine-0.1.0/fux/graph.py +137 -0
  60. fux_engine-0.1.0/fux/graphhtml.py +14 -0
  61. fux_engine-0.1.0/fux/graphquery.py +113 -0
  62. fux_engine-0.1.0/fux/hookio.py +34 -0
  63. fux_engine-0.1.0/fux/hooks.py +99 -0
  64. fux_engine-0.1.0/fux/hybrid.py +78 -0
  65. fux_engine-0.1.0/fux/importer.py +86 -0
  66. fux_engine-0.1.0/fux/index.py +45 -0
  67. fux_engine-0.1.0/fux/initcmd.py +58 -0
  68. fux_engine-0.1.0/fux/lint.py +96 -0
  69. fux_engine-0.1.0/fux/loader.py +62 -0
  70. fux_engine-0.1.0/fux/mcpserver.py +179 -0
  71. fux_engine-0.1.0/fux/mine.py +96 -0
  72. fux_engine-0.1.0/fux/model.py +82 -0
  73. fux_engine-0.1.0/fux/narrative.py +35 -0
  74. fux_engine-0.1.0/fux/pack.py +53 -0
  75. fux_engine-0.1.0/fux/parity.py +156 -0
  76. fux_engine-0.1.0/fux/paths.py +85 -0
  77. fux_engine-0.1.0/fux/recall.py +131 -0
  78. fux_engine-0.1.0/fux/report.py +63 -0
  79. fux_engine-0.1.0/fux/savings.py +192 -0
  80. fux_engine-0.1.0/fux/scaffold.py +58 -0
  81. fux_engine-0.1.0/fux/scalars.py +32 -0
  82. fux_engine-0.1.0/fux/schema.py +54 -0
  83. fux_engine-0.1.0/fux/seal.py +142 -0
  84. fux_engine-0.1.0/fux/serve.py +77 -0
  85. fux_engine-0.1.0/fux/settings.py +52 -0
  86. fux_engine-0.1.0/fux/stats.py +132 -0
  87. fux_engine-0.1.0/fux/templates/formula.md +22 -0
  88. fux_engine-0.1.0/fux/templates/spec.md +29 -0
  89. fux_engine-0.1.0/fux/touch.py +37 -0
  90. fux_engine-0.1.0/fux/tour.py +34 -0
  91. fux_engine-0.1.0/fux/usage.py +60 -0
  92. fux_engine-0.1.0/fux/verify.py +75 -0
  93. fux_engine-0.1.0/fux/vexamples.py +144 -0
  94. fux_engine-0.1.0/fux_engine.egg-info/PKG-INFO +186 -0
  95. fux_engine-0.1.0/fux_engine.egg-info/SOURCES.txt +128 -0
  96. fux_engine-0.1.0/fux_engine.egg-info/dependency_links.txt +1 -0
  97. fux_engine-0.1.0/fux_engine.egg-info/entry_points.txt +2 -0
  98. fux_engine-0.1.0/fux_engine.egg-info/requires.txt +15 -0
  99. fux_engine-0.1.0/fux_engine.egg-info/top_level.txt +1 -0
  100. fux_engine-0.1.0/pyproject.toml +70 -0
  101. fux_engine-0.1.0/setup.cfg +4 -0
  102. fux_engine-0.1.0/tests/test_ast_backend.py +88 -0
  103. fux_engine-0.1.0/tests/test_astextract.py +71 -0
  104. fux_engine-0.1.0/tests/test_bm25f_expand.py +38 -0
  105. fux_engine-0.1.0/tests/test_capture_governance.py +90 -0
  106. fux_engine-0.1.0/tests/test_centrality.py +36 -0
  107. fux_engine-0.1.0/tests/test_check_fix.py +31 -0
  108. fux_engine-0.1.0/tests/test_costledger.py +51 -0
  109. fux_engine-0.1.0/tests/test_crossfile_calls.py +35 -0
  110. fux_engine-0.1.0/tests/test_embed_rerank.py +30 -0
  111. fux_engine-0.1.0/tests/test_examples.py +52 -0
  112. fux_engine-0.1.0/tests/test_fetch_rules.py +191 -0
  113. fux_engine-0.1.0/tests/test_frontmatter.py +49 -0
  114. fux_engine-0.1.0/tests/test_fuzz_mine.py +43 -0
  115. fux_engine-0.1.0/tests/test_globs.py +21 -0
  116. fux_engine-0.1.0/tests/test_graphhtml.py +18 -0
  117. fux_engine-0.1.0/tests/test_hybrid.py +55 -0
  118. fux_engine-0.1.0/tests/test_lint_stats_gate.py +76 -0
  119. fux_engine-0.1.0/tests/test_mcp.py +60 -0
  120. fux_engine-0.1.0/tests/test_mcp_extra.py +48 -0
  121. fux_engine-0.1.0/tests/test_pack.py +54 -0
  122. fux_engine-0.1.0/tests/test_parity_import.py +117 -0
  123. fux_engine-0.1.0/tests/test_recall_build_verify.py +64 -0
  124. fux_engine-0.1.0/tests/test_recall_eval.py +124 -0
  125. fux_engine-0.1.0/tests/test_resolution.py +37 -0
  126. fux_engine-0.1.0/tests/test_savings.py +60 -0
  127. fux_engine-0.1.0/tests/test_schema_scaffold_init.py +43 -0
  128. fux_engine-0.1.0/tests/test_seal.py +87 -0
  129. fux_engine-0.1.0/tests/test_serve_sanitize.py +60 -0
  130. fux_engine-0.1.0/tests/test_verify_hardening.py +68 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 arpit arya
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,186 @@
1
+ Metadata-Version: 2.4
2
+ Name: fux-engine
3
+ Version: 0.1.0
4
+ Summary: Fux — a portable, Claude-aware knowledge engine: rules, memory, narrative, and graph in one frontmatter substrate.
5
+ Author-email: arpit arya <arpitarya.me@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/arpitarya/fux
8
+ Project-URL: Repository, https://github.com/arpitarya/fux
9
+ Project-URL: Documentation, https://github.com/arpitarya/fux/blob/main/docs/guide.md
10
+ Project-URL: Bug Tracker, https://github.com/arpitarya/fux/issues
11
+ Keywords: knowledge,rules,graph,claude,frontmatter,llm,memory,mcp
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Software Development :: Documentation
22
+ Classifier: Topic :: Software Development :: Quality Assurance
23
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
24
+ Requires-Python: >=3.11
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Provides-Extra: embeddings
28
+ Requires-Dist: sentence-transformers>=2.2; extra == "embeddings"
29
+ Provides-Extra: ast
30
+ Requires-Dist: tree-sitter>=0.23; extra == "ast"
31
+ Requires-Dist: tree-sitter-language-pack>=0.7; extra == "ast"
32
+ Provides-Extra: pdf
33
+ Requires-Dist: pypdf>=4.0; extra == "pdf"
34
+ Provides-Extra: dev
35
+ Requires-Dist: pytest>=8; extra == "dev"
36
+ Requires-Dist: build>=1.0; extra == "dev"
37
+ Requires-Dist: twine>=5.0; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # Fux
41
+
42
+ > A portable, Claude-aware **knowledge engine**. One frontmatter substrate →
43
+ > derived **index**, **graph**, and **memory** views. `$0` deterministic
44
+ > maintenance — no mandatory LLM calls. Continuously referenced, cheaply
45
+ > maintained.
46
+
47
+ Named after *Johann Joseph Fux*, author of *Gradus ad Parnassum* (1725) — the
48
+ counterpoint treatise every composer learned the rules from. A tool that codifies
49
+ and enforces rules, named after the man who wrote *the* rulebook. Sits beside
50
+ `wagner`, `bach`, `orff`.
51
+
52
+ Fux **unifies and replaces** three things a project usually runs separately — the
53
+ structural graph (graphify), cross-session memory, and the narrative docs — and
54
+ adds the **business-rules layer** none of them held. See [docs/fux-plan.md](docs/fux-plan.md).
55
+
56
+ ## In plain words (the 5-year-old version)
57
+
58
+ Think of your code as a big LEGO city. The *reasons* things are built a certain
59
+ way — why the bridge is red, why you add the towers before the walls — usually
60
+ live only in one builder's head. When they go home, nobody remembers why.
61
+
62
+ **Fux is a notebook for those reasons.** You write each important rule down once —
63
+ *what* it is and *why* — and Fux sticks a tiny one-line list on the cover so your
64
+ helper (Claude) can flip straight to the right page instead of searching the whole
65
+ city every time. Fux also **draws a map** showing which notes belong to which
66
+ buildings, and **checks** that the notes still match the city — and it does all of
67
+ that for free, without phoning anyone for help.
68
+
69
+ So: write the *why* down once → it's found fast, stays correct, and never gets lost.
70
+
71
+ ## Why
72
+
73
+ The *why* behind a formula — why current value not invested cost, why
74
+ INR-normalize first, which cost-basis method — usually lives only as an inline
75
+ comment, invisible until someone greps for it. Fux makes that knowledge
76
+ **first-class**: one entry, authored once, served back through a tiny index (read
77
+ first) plus lazily-opened rules (read only when relevant). Lookups run ~5–10×
78
+ cheaper and more correct on every later session — and you don't have to take that
79
+ on faith: **`fux savings`** measures the multiplier from your own file sizes.
80
+
81
+ ## Install
82
+
83
+ ```bash
84
+ git clone git@github.com:arpitarya/fux.git && cd fux
85
+ ./install.sh # → ~/.claude/fux/{engine,global,packs,hooks} + /fux skill
86
+ fux --version
87
+ ```
88
+
89
+ Requires Python ≥ 3.11 (stdlib only — zero third-party dependencies).
90
+
91
+ ## Use
92
+
93
+ ```bash
94
+ cd your-project
95
+ fux init # scaffold .fux/ + wire 3 hooks + CLAUDE.md pointer
96
+ fux new formula day-pnl # scaffold a rule; fill **Rule:/Why:/Edge cases:**
97
+ fux build # regenerate INDEX.md + rules.json + graph ($0)
98
+ fux check --fix # validate; repair mechanical drift ($0)
99
+ fux why day-pnl [--history] # explain a rule (+ how its *why* evolved, via git)
100
+ fux refs src/aggregator.py # which rules govern this file
101
+ fux recall "how is day P&L computed" --hybrid # BM25F; RRF-fuse lexical+semantic+graph
102
+ fux seal --all # bind rules to an AST fingerprint of their code
103
+ fux coverage # % of important files with a governing rule
104
+ fux verify --fuzz # run invariant `check:`; boundary-fuzz for div-by-zero
105
+ fux mine # surface candidate rules latent in the code (drafts)
106
+ fux savings "how is day P&L computed" # measured token-cost win (+ cumulative ledger)
107
+ fux lint # rule *quality*: missing why / code_refs / edges
108
+ fux stats # knowledge-health dashboard + score
109
+ fux gate --install # wire a git pre-commit enforcement hook
110
+ fux mcp # serve the substrate to agents over MCP (stdio)
111
+ fux capture # queue this session's changes for `fux distill`
112
+ fux serve # local dashboard over the generated views
113
+ fux import docs/ # migrate existing markdown → narrative entries
114
+ fux parity # is it safe to retire the old graph/docs/memory?
115
+ fux tour # ordered ONBOARDING.md
116
+ ```
117
+
118
+ **Complete, example-driven guide to everything Fux does:
119
+ [docs/guide.md](docs/guide.md).** Full command reference: [docs/cli.md](docs/cli.md).
120
+ Authoring a rule: [docs/rule.guide.md](docs/rule.guide.md). Writing a spec:
121
+ [docs/spec.guide.md](docs/spec.guide.md).
122
+
123
+ ## How it works
124
+
125
+ ```
126
+ Tier 0 CLAUDE.md pointer ........ 1 line, always in context
127
+ Tier 1 .fux/out/INDEX.md ........ ~1 line/rule, read FIRST ← cheap
128
+ Tier 2 .fux/rules/<id>.md ....... opened ONLY when relevant ← lazy
129
+ Tier 3 .fux/out/{rules,graph}.json machine lookup + browsing
130
+ ```
131
+
132
+ You maintain **only** the source frontmatter. INDEX, `rules.json`, and the
133
+ interactive `graph.html` regenerate on `fux build`. Three hooks keep it live:
134
+ SessionStart injects the INDEX, PostToolUse reminds you when an edited file's rule
135
+ drifted, Stop validates before the turn ends.
136
+
137
+ The **graph** merges your rules with code symbols and call edges extracted across
138
+ **Python** (via the stdlib `ast`) and **JS/TS, Go, and Rust** (a brace-matched
139
+ heuristic by default, or **real tree-sitter ASTs** with the optional
140
+ `pip install fux-engine[ast]` extra — same schema, more accuracy, still $0 by
141
+ default), now including **cross-file** `calls` (symbol→symbol) — one navigable
142
+ map of *which rule governs which code*, with community clustering, **PageRank
143
+ centrality** (architectural chokepoints, not just raw degree), and a
144
+ `GRAPH_REPORT.md`. The interactive `graph.html` is built for review *and* agents:
145
+ node/edge-type filters, colour-by (type/community/layer/degree), focus +
146
+ neighbour highlighting, a details panel, and one-click **markdown export** of a
147
+ node's neighbourhood or the visible sub-graph.
148
+
149
+ `fux recall` is lexical **BM25F** (`$0`) by default, with opt-in **query expansion**
150
+ (glossary synonyms + 1-hop graph neighbours), an opt-in **local** re-rank, and an
151
+ opt-in **RRF hybrid** that fuses lexical ⊕ local-semantic ⊕ graph proximity (no
152
+ API); `fux verify [--fuzz]` runs a rule's invariant `check:` and worked `examples:`,
153
+ optionally boundary-fuzzing for unguarded div-by-zero. **Proof-carrying rules:**
154
+ `fux seal` binds a rule to a normalized-AST fingerprint of its code, so `fux check`
155
+ flags `unsealed` when the governed code changes *structure* (not just its mtime).
156
+ Beyond authoring, Fux **enforces and reports**: `fux lint` grades rule quality,
157
+ `fux stats` scores knowledge health, `fux gate` blocks drift at commit/CI time,
158
+ and `fux mcp` exposes the whole substrate to agents over MCP.
159
+
160
+ For cross-session memory it stays **authored, not captured**: an opt-in `capture`
161
+ hook queues *which* files changed for `fux distill` (human-confirmed) rather than
162
+ auto-summarising, and `type: memory` entries **decay** after a TTL so stale notes
163
+ stop costing context — with opt-in **usage-weighted decay** (a memory still being
164
+ recalled stays alive; an unused one decays). Every path `$0` and deterministic.
165
+
166
+ ### Layered rules (maintain once, inherit everywhere)
167
+
168
+ ```
169
+ effective ruleset = ~/.claude/fux/global/ (cross-project best practices)
170
+ ⊕ ~/.claude/fux/packs/* (opt-in shareable domain packs)
171
+ ⊕ ./.fux/rules/ (this project's domain rules)
172
+ ```
173
+
174
+ `project` overrides `pack` overrides `global`. `fux check` flags conflicts
175
+ instead of silently shadowing.
176
+
177
+ ## Guarantee
178
+
179
+ Every maintenance command is shell/AST/parse — **no LLM calls**. The only paths
180
+ that call the LLM are the `plan` / `adr` skills, and they ride the session you are
181
+ already in (no background spend). The same "$0, deterministic" promise that made
182
+ graphify trustworthy.
183
+
184
+ ## License
185
+
186
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,147 @@
1
+ # Fux
2
+
3
+ > A portable, Claude-aware **knowledge engine**. One frontmatter substrate →
4
+ > derived **index**, **graph**, and **memory** views. `$0` deterministic
5
+ > maintenance — no mandatory LLM calls. Continuously referenced, cheaply
6
+ > maintained.
7
+
8
+ Named after *Johann Joseph Fux*, author of *Gradus ad Parnassum* (1725) — the
9
+ counterpoint treatise every composer learned the rules from. A tool that codifies
10
+ and enforces rules, named after the man who wrote *the* rulebook. Sits beside
11
+ `wagner`, `bach`, `orff`.
12
+
13
+ Fux **unifies and replaces** three things a project usually runs separately — the
14
+ structural graph (graphify), cross-session memory, and the narrative docs — and
15
+ adds the **business-rules layer** none of them held. See [docs/fux-plan.md](docs/fux-plan.md).
16
+
17
+ ## In plain words (the 5-year-old version)
18
+
19
+ Think of your code as a big LEGO city. The *reasons* things are built a certain
20
+ way — why the bridge is red, why you add the towers before the walls — usually
21
+ live only in one builder's head. When they go home, nobody remembers why.
22
+
23
+ **Fux is a notebook for those reasons.** You write each important rule down once —
24
+ *what* it is and *why* — and Fux sticks a tiny one-line list on the cover so your
25
+ helper (Claude) can flip straight to the right page instead of searching the whole
26
+ city every time. Fux also **draws a map** showing which notes belong to which
27
+ buildings, and **checks** that the notes still match the city — and it does all of
28
+ that for free, without phoning anyone for help.
29
+
30
+ So: write the *why* down once → it's found fast, stays correct, and never gets lost.
31
+
32
+ ## Why
33
+
34
+ The *why* behind a formula — why current value not invested cost, why
35
+ INR-normalize first, which cost-basis method — usually lives only as an inline
36
+ comment, invisible until someone greps for it. Fux makes that knowledge
37
+ **first-class**: one entry, authored once, served back through a tiny index (read
38
+ first) plus lazily-opened rules (read only when relevant). Lookups run ~5–10×
39
+ cheaper and more correct on every later session — and you don't have to take that
40
+ on faith: **`fux savings`** measures the multiplier from your own file sizes.
41
+
42
+ ## Install
43
+
44
+ ```bash
45
+ git clone git@github.com:arpitarya/fux.git && cd fux
46
+ ./install.sh # → ~/.claude/fux/{engine,global,packs,hooks} + /fux skill
47
+ fux --version
48
+ ```
49
+
50
+ Requires Python ≥ 3.11 (stdlib only — zero third-party dependencies).
51
+
52
+ ## Use
53
+
54
+ ```bash
55
+ cd your-project
56
+ fux init # scaffold .fux/ + wire 3 hooks + CLAUDE.md pointer
57
+ fux new formula day-pnl # scaffold a rule; fill **Rule:/Why:/Edge cases:**
58
+ fux build # regenerate INDEX.md + rules.json + graph ($0)
59
+ fux check --fix # validate; repair mechanical drift ($0)
60
+ fux why day-pnl [--history] # explain a rule (+ how its *why* evolved, via git)
61
+ fux refs src/aggregator.py # which rules govern this file
62
+ fux recall "how is day P&L computed" --hybrid # BM25F; RRF-fuse lexical+semantic+graph
63
+ fux seal --all # bind rules to an AST fingerprint of their code
64
+ fux coverage # % of important files with a governing rule
65
+ fux verify --fuzz # run invariant `check:`; boundary-fuzz for div-by-zero
66
+ fux mine # surface candidate rules latent in the code (drafts)
67
+ fux savings "how is day P&L computed" # measured token-cost win (+ cumulative ledger)
68
+ fux lint # rule *quality*: missing why / code_refs / edges
69
+ fux stats # knowledge-health dashboard + score
70
+ fux gate --install # wire a git pre-commit enforcement hook
71
+ fux mcp # serve the substrate to agents over MCP (stdio)
72
+ fux capture # queue this session's changes for `fux distill`
73
+ fux serve # local dashboard over the generated views
74
+ fux import docs/ # migrate existing markdown → narrative entries
75
+ fux parity # is it safe to retire the old graph/docs/memory?
76
+ fux tour # ordered ONBOARDING.md
77
+ ```
78
+
79
+ **Complete, example-driven guide to everything Fux does:
80
+ [docs/guide.md](docs/guide.md).** Full command reference: [docs/cli.md](docs/cli.md).
81
+ Authoring a rule: [docs/rule.guide.md](docs/rule.guide.md). Writing a spec:
82
+ [docs/spec.guide.md](docs/spec.guide.md).
83
+
84
+ ## How it works
85
+
86
+ ```
87
+ Tier 0 CLAUDE.md pointer ........ 1 line, always in context
88
+ Tier 1 .fux/out/INDEX.md ........ ~1 line/rule, read FIRST ← cheap
89
+ Tier 2 .fux/rules/<id>.md ....... opened ONLY when relevant ← lazy
90
+ Tier 3 .fux/out/{rules,graph}.json machine lookup + browsing
91
+ ```
92
+
93
+ You maintain **only** the source frontmatter. INDEX, `rules.json`, and the
94
+ interactive `graph.html` regenerate on `fux build`. Three hooks keep it live:
95
+ SessionStart injects the INDEX, PostToolUse reminds you when an edited file's rule
96
+ drifted, Stop validates before the turn ends.
97
+
98
+ The **graph** merges your rules with code symbols and call edges extracted across
99
+ **Python** (via the stdlib `ast`) and **JS/TS, Go, and Rust** (a brace-matched
100
+ heuristic by default, or **real tree-sitter ASTs** with the optional
101
+ `pip install fux-engine[ast]` extra — same schema, more accuracy, still $0 by
102
+ default), now including **cross-file** `calls` (symbol→symbol) — one navigable
103
+ map of *which rule governs which code*, with community clustering, **PageRank
104
+ centrality** (architectural chokepoints, not just raw degree), and a
105
+ `GRAPH_REPORT.md`. The interactive `graph.html` is built for review *and* agents:
106
+ node/edge-type filters, colour-by (type/community/layer/degree), focus +
107
+ neighbour highlighting, a details panel, and one-click **markdown export** of a
108
+ node's neighbourhood or the visible sub-graph.
109
+
110
+ `fux recall` is lexical **BM25F** (`$0`) by default, with opt-in **query expansion**
111
+ (glossary synonyms + 1-hop graph neighbours), an opt-in **local** re-rank, and an
112
+ opt-in **RRF hybrid** that fuses lexical ⊕ local-semantic ⊕ graph proximity (no
113
+ API); `fux verify [--fuzz]` runs a rule's invariant `check:` and worked `examples:`,
114
+ optionally boundary-fuzzing for unguarded div-by-zero. **Proof-carrying rules:**
115
+ `fux seal` binds a rule to a normalized-AST fingerprint of its code, so `fux check`
116
+ flags `unsealed` when the governed code changes *structure* (not just its mtime).
117
+ Beyond authoring, Fux **enforces and reports**: `fux lint` grades rule quality,
118
+ `fux stats` scores knowledge health, `fux gate` blocks drift at commit/CI time,
119
+ and `fux mcp` exposes the whole substrate to agents over MCP.
120
+
121
+ For cross-session memory it stays **authored, not captured**: an opt-in `capture`
122
+ hook queues *which* files changed for `fux distill` (human-confirmed) rather than
123
+ auto-summarising, and `type: memory` entries **decay** after a TTL so stale notes
124
+ stop costing context — with opt-in **usage-weighted decay** (a memory still being
125
+ recalled stays alive; an unused one decays). Every path `$0` and deterministic.
126
+
127
+ ### Layered rules (maintain once, inherit everywhere)
128
+
129
+ ```
130
+ effective ruleset = ~/.claude/fux/global/ (cross-project best practices)
131
+ ⊕ ~/.claude/fux/packs/* (opt-in shareable domain packs)
132
+ ⊕ ./.fux/rules/ (this project's domain rules)
133
+ ```
134
+
135
+ `project` overrides `pack` overrides `global`. `fux check` flags conflicts
136
+ instead of silently shadowing.
137
+
138
+ ## Guarantee
139
+
140
+ Every maintenance command is shell/AST/parse — **no LLM calls**. The only paths
141
+ that call the LLM are the `plan` / `adr` skills, and they ride the session you are
142
+ already in (no background spend). The same "$0, deterministic" promise that made
143
+ graphify trustworthy.
144
+
145
+ ## License
146
+
147
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,6 @@
1
+ """Fux — a portable, Claude-aware knowledge engine.
2
+
3
+ One frontmatter substrate → derived index, graph, and memory views.
4
+ $0 deterministic maintenance; no mandatory LLM calls. See docs/fux-plan.md.
5
+ """
6
+ __version__ = "0.1.0"
@@ -0,0 +1,4 @@
1
+ from fux.cli import main
2
+
3
+ if __name__ == "__main__":
4
+ raise SystemExit(main())
@@ -0,0 +1,61 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
2
+ <defs>
3
+ <!-- tile backgrounds -->
4
+ <linearGradient id="ic-bg" x1="0" y1="0" x2=".6" y2="1">
5
+ <stop offset="0%" stop-color="#16140f"/>
6
+ <stop offset="100%" stop-color="#0a0908"/>
7
+ </linearGradient>
8
+ <radialGradient id="ic-glow" cx="50%" cy="18%" r="70%">
9
+ <stop offset="0%" stop-color="#9ed94a1a"/>
10
+ <stop offset="100%" stop-color="rgba(0,0,0,0)"/>
11
+ </radialGradient>
12
+ <linearGradient id="ic-shine" x1="0" y1="0" x2="0" y2="1">
13
+ <stop offset="0%" stop-color="rgba(255,255,255,.06)"/>
14
+ <stop offset="100%" stop-color="rgba(255,255,255,0)"/>
15
+ </linearGradient>
16
+ <!-- mark gradient -->
17
+ <linearGradient id="ic-mg" x1="0" y1="0" x2="1" y2="1">
18
+ <stop offset="0%" stop-color="#D2F58F"/>
19
+ <stop offset="55%" stop-color="#8FD13F"/>
20
+ <stop offset="100%" stop-color="#4C8A1B"/>
21
+ </linearGradient>
22
+ <clipPath id="ic-mc">
23
+ <rect x="12" y="10" width="40" height="44" rx="10"/>
24
+ </clipPath>
25
+ <filter id="ic-drop" x="-30%" y="-30%" width="160%" height="160%">
26
+ <feGaussianBlur in="SourceGraphic" stdDeviation="2.5" result="blur"/>
27
+ <feComposite in="SourceGraphic" in2="blur" operator="over"/>
28
+ </filter>
29
+ </defs>
30
+
31
+ <!-- tile base -->
32
+ <rect width="120" height="120" rx="28" fill="url(#ic-bg)" stroke="rgba(255,255,255,.08)" stroke-width="1"/>
33
+ <!-- accent glow overlay -->
34
+ <rect width="120" height="120" rx="28" fill="url(#ic-glow)"/>
35
+ <!-- top-edge shine -->
36
+ <rect width="120" height="60" rx="28" fill="url(#ic-shine)"/>
37
+
38
+ <!-- mark: size=78, centred → offset=(120-78)/2=21 -->
39
+ <svg x="21" y="21" width="78" height="78" viewBox="0 0 64 64">
40
+ <defs>
41
+ <linearGradient id="ic-mg2" x1="0" y1="0" x2="1" y2="1">
42
+ <stop offset="0%" stop-color="#D2F58F"/>
43
+ <stop offset="55%" stop-color="#8FD13F"/>
44
+ <stop offset="100%" stop-color="#4C8A1B"/>
45
+ </linearGradient>
46
+ <clipPath id="ic-mc2">
47
+ <rect x="12" y="10" width="40" height="44" rx="10"/>
48
+ </clipPath>
49
+ </defs>
50
+ <g filter="url(#ic-drop)">
51
+ <rect x="12" y="10" width="40" height="44" rx="10" fill="url(#ic-mg2)"/>
52
+ <g clip-path="url(#ic-mc2)">
53
+ <polygon points="12,10 32,10 12,30" fill="#fff" opacity=".15"/>
54
+ <polygon points="52,54 52,34 32,54" fill="#000" opacity=".17"/>
55
+ </g>
56
+ <path d="M26 10 L38 10 L38 33 L32 28 L26 33 Z" fill="#000" opacity=".26"/>
57
+ <rect x="19" y="42" width="26" height="3" rx="1.5" fill="#000" opacity=".24"/>
58
+ <rect x="19" y="48" width="17" height="3" rx="1.5" fill="#000" opacity=".24"/>
59
+ </g>
60
+ </svg>
61
+ </svg>
@@ -0,0 +1,69 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 440 110" width="440" height="110">
2
+ <defs>
3
+ <!-- background -->
4
+ <linearGradient id="lk-bg" x1="0" y1="0" x2="0" y2="1">
5
+ <stop offset="0%" stop-color="#121110"/>
6
+ <stop offset="100%" stop-color="#0a0a09"/>
7
+ </linearGradient>
8
+ <!-- vertical rule -->
9
+ <linearGradient id="lk-rule" x1="0" y1="0" x2="0" y2="1">
10
+ <stop offset="0%" stop-color="rgba(255,255,255,0)"/>
11
+ <stop offset="50%" stop-color="rgba(255,255,255,.14)"/>
12
+ <stop offset="100%" stop-color="rgba(255,255,255,0)"/>
13
+ </linearGradient>
14
+ <!-- mark gradient -->
15
+ <linearGradient id="lk-mg" x1="0" y1="0" x2="1" y2="1">
16
+ <stop offset="0%" stop-color="#D2F58F"/>
17
+ <stop offset="55%" stop-color="#8FD13F"/>
18
+ <stop offset="100%" stop-color="#4C8A1B"/>
19
+ </linearGradient>
20
+ <clipPath id="lk-mc">
21
+ <rect x="12" y="10" width="40" height="44" rx="10"/>
22
+ </clipPath>
23
+ <filter id="lk-glow" x="-40%" y="-40%" width="180%" height="180%">
24
+ <feGaussianBlur in="SourceGraphic" stdDeviation="3" result="blur"/>
25
+ <feComposite in="SourceGraphic" in2="blur" operator="over"/>
26
+ </filter>
27
+ <style>
28
+ @import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&amp;family=Space+Mono&amp;display=swap');
29
+ .lk-eyebrow { font: 8.5px 'Space Mono', 'Courier New', monospace; letter-spacing: .34em; fill: #7a756b; }
30
+ .lk-name { font: 700 30px 'Space Grotesk', 'Helvetica Neue', Arial, sans-serif; letter-spacing: .16em; fill: #f2efe9; }
31
+ .lk-role { font: 10px 'Space Mono', 'Courier New', monospace; letter-spacing: .26em; fill: #9ed94a; }
32
+ </style>
33
+ </defs>
34
+
35
+ <!-- plate -->
36
+ <rect width="440" height="110" rx="14" fill="url(#lk-bg)" stroke="rgba(255,255,255,.07)" stroke-width="1"/>
37
+
38
+ <!-- mark: 74×74, vertically centred → y=18 -->
39
+ <svg x="34" y="18" width="74" height="74" viewBox="0 0 64 64" overflow="visible">
40
+ <defs>
41
+ <linearGradient id="lk-mg2" x1="0" y1="0" x2="1" y2="1">
42
+ <stop offset="0%" stop-color="#D2F58F"/>
43
+ <stop offset="55%" stop-color="#8FD13F"/>
44
+ <stop offset="100%" stop-color="#4C8A1B"/>
45
+ </linearGradient>
46
+ <clipPath id="lk-mc2">
47
+ <rect x="12" y="10" width="40" height="44" rx="10"/>
48
+ </clipPath>
49
+ </defs>
50
+ <g filter="url(#lk-glow)">
51
+ <rect x="12" y="10" width="40" height="44" rx="10" fill="url(#lk-mg2)"/>
52
+ <g clip-path="url(#lk-mc2)">
53
+ <polygon points="12,10 32,10 12,30" fill="#fff" opacity=".15"/>
54
+ <polygon points="52,54 52,34 32,54" fill="#000" opacity=".17"/>
55
+ </g>
56
+ <path d="M26 10 L38 10 L38 33 L32 28 L26 33 Z" fill="#000" opacity=".26"/>
57
+ <rect x="19" y="42" width="26" height="3" rx="1.5" fill="#000" opacity=".24"/>
58
+ <rect x="19" y="48" width="17" height="3" rx="1.5" fill="#000" opacity=".24"/>
59
+ </g>
60
+ </svg>
61
+
62
+ <!-- vertical rule: x=130, margin 22px top+bottom → y=22..88 -->
63
+ <rect x="130" y="22" width="1" height="66" fill="url(#lk-rule)"/>
64
+
65
+ <!-- text block: x=153, centred on y=55 -->
66
+ <text x="153" y="30" class="lk-eyebrow">ALPHA FORGE</text>
67
+ <text x="153" y="68" class="lk-name">FUX</text>
68
+ <text x="153" y="88" class="lk-role">KNOWLEDGE INDEX</text>
69
+ </svg>
@@ -0,0 +1,26 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
2
+ <defs>
3
+ <linearGradient id="fux-g" x1="0" y1="0" x2="1" y2="1">
4
+ <stop offset="0%" stop-color="#D2F58F"/>
5
+ <stop offset="55%" stop-color="#8FD13F"/>
6
+ <stop offset="100%" stop-color="#4C8A1B"/>
7
+ </linearGradient>
8
+ <clipPath id="fux-c">
9
+ <rect x="12" y="10" width="40" height="44" rx="10"/>
10
+ </clipPath>
11
+ <filter id="fux-glow" x="-30%" y="-30%" width="160%" height="160%">
12
+ <feGaussianBlur in="SourceGraphic" stdDeviation="2.5" result="blur"/>
13
+ <feComposite in="SourceGraphic" in2="blur" operator="over"/>
14
+ </filter>
15
+ </defs>
16
+ <g filter="url(#fux-glow)">
17
+ <rect x="12" y="10" width="40" height="44" rx="10" fill="url(#fux-g)"/>
18
+ <g clip-path="url(#fux-c)">
19
+ <polygon points="12,10 32,10 12,30" fill="#fff" opacity=".15"/>
20
+ <polygon points="52,54 52,34 32,54" fill="#000" opacity=".17"/>
21
+ </g>
22
+ <path d="M26 10 L38 10 L38 33 L32 28 L26 33 Z" fill="#000" opacity=".26"/>
23
+ <rect x="19" y="42" width="26" height="3" rx="1.5" fill="#000" opacity=".24"/>
24
+ <rect x="19" y="48" width="17" height="3" rx="1.5" fill="#000" opacity=".24"/>
25
+ </g>
26
+ </svg>