beyondbabel 0.3.0__tar.gz → 0.4.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 (28) hide show
  1. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/PKG-INFO +37 -28
  2. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/README.md +36 -27
  3. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/bb.py +89 -20
  4. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/beyondbabel.egg-info/PKG-INFO +37 -28
  5. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/pyproject.toml +1 -1
  6. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/beyondbabel.egg-info/SOURCES.txt +0 -0
  7. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/beyondbabel.egg-info/dependency_links.txt +0 -0
  8. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/beyondbabel.egg-info/entry_points.txt +0 -0
  9. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/beyondbabel.egg-info/requires.txt +0 -0
  10. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/beyondbabel.egg-info/top_level.txt +0 -0
  11. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/setup.cfg +0 -0
  12. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_compile.py +0 -0
  13. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_edit_file.py +0 -0
  14. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_edit_new.py +0 -0
  15. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_edit_refactor.py +0 -0
  16. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_import_by_name.py +0 -0
  17. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_internals.py +0 -0
  18. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_lineage_v2.py +0 -0
  19. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_pool_refs.py +0 -0
  20. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_positional.py +0 -0
  21. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_refactor_stale.py +0 -0
  22. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_restore.py +0 -0
  23. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_scratchpad.py +0 -0
  24. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_storage.py +0 -0
  25. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_translate_file.py +0 -0
  26. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_translate_tree.py +0 -0
  27. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_undefined_names.py +0 -0
  28. {beyondbabel-0.3.0 → beyondbabel-0.4.0}/tests/test_update.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beyondbabel
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: A function pool manager for Python that enables multilingual function sharing through AST normalization
5
5
  Author: Amirouche Boubekki
6
6
  License-Expression: MIT
@@ -28,50 +28,53 @@ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
28
28
 
29
29
  ![Tests](https://github.com/amirouche/bb.py/actions/workflows/test.yml/badge.svg)
30
30
 
31
- **Nurturing a society that recognizes diversity as strength through verifiable knowledge sharing.**
31
+ **Diversity as strength, made verifiable.**
32
32
 
33
- > **Experimental**: This is research software under active development.
34
-
35
- Every programmer who thinks in Wolof, Tamil, Vietnamese, or Tamazight and codes in English pays a cognitive tax. Every variable named in a second language is a thought translated before it's expressed. This overhead is invisible to the people who don't pay it — and universal for everyone who does.
33
+ Write a function in your language; if someone else, human or machine, had the same thought, the hash will show it.
36
34
 
37
- bb.py makes that tax optional. Write functions in your language — name variables, write documentation, think natively. The tool separates what your code *does* from what you *called* things. Same logic, same hash, regardless of tongue.
38
-
39
- Content-addressing gives every function a unique fingerprint. Authorship is preserved. Lineage is traceable. Knowledge is shared without losing track of who made what.
35
+ > **Experimental**: This is research software under active development.
40
36
 
41
- ## Same logic, three languages, one hash
37
+ Convergence is detected, divergence is preserved. When two minds write the same logic, they get the same hash, and no shared language was needed to find each other. When they write different logic, they get different hashes, and both are kept. Nothing is flattened into a single English version.
42
38
 
43
39
  ```python
44
- # English
45
- def calculate_sum(first_number, second_number):
46
- """Calculate the sum of two numbers."""
47
- result = first_number + second_number
48
- return result
40
+ # Français
41
+ def additionner(premier, second):
42
+ """Additionner deux nombres."""
43
+ somme = premier + second
44
+ return somme
49
45
  ```
50
46
 
51
47
  ```python
52
- # Français
53
- def calculer_somme(premier_nombre, deuxieme_nombre):
54
- """Calculer la somme de deux nombres."""
55
- sortie = premier_nombre + deuxieme_nombre
56
- return sortie
48
+ # العربية
49
+ def اجمع(الأول, الثاني):
50
+ """اجمع عددين."""
51
+ الناتج = الأول + الثاني
52
+ return الناتج
57
53
  ```
58
54
 
59
55
  ```python
60
56
  # Español
61
- def calcular_suma(primer_numero, segundo_numero):
62
- """Calcular la suma de dos números."""
63
- resultado = primer_numero + segundo_numero
64
- return resultado
57
+ def sumar(primero, segundo):
58
+ """Sumar dos números."""
59
+ suma = primero + segundo
60
+ return suma
65
61
  ```
66
62
 
67
63
  ```bash
68
- bb init
69
- bb add example_simple.py@eng # → 9f86d0...
70
- bb add example_simple_french.py@fra # → 9f86d0... ← same hash
71
- bb add example_simple_spanish.py@spa # → 9f86d0... ← same hash again
64
+ bb add additionner.py@fra # → one hash
65
+ bb add اجمع.py@ara # → the same hash
66
+ bb add sumar.py@spa # → the same hash again
72
67
  ```
73
68
 
74
- Three languages. One identity. No one translated — they wrote originals.
69
+ Three people, or two people and a model prompted in Arabic. Nobody translated; each wrote an original. The names and the docstring stay in their own language, and the hash is computed from the logic alone.
70
+
71
+ ## Why
72
+
73
+ Students learn to code in English while thinking in their own language, and every name they choose is a thought translated before it is written. Languages in Arabic script also tend to cost more tokens on LLMs for the same meaning, a quiet tax on the people who already pay one.
74
+
75
+ The machine side is the same question seen from outside. When several LLM agents work on one problem, someone has to know whether two of them really agree, or only sound alike. A shared hash is a cheap, honest answer for the case where the logic is identical, and an honest "no" when it is not.
76
+
77
+ The project is early. Exact matching is the foundation; near-matches are still a research question (see `LIMITS.md`).
75
78
 
76
79
  ## What it enables
77
80
 
@@ -108,6 +111,12 @@ uv tool install git+https://github.com/amirouche/bb.py.git
108
111
 
109
112
  Requires Python 3.11+. No runtime dependencies.
110
113
 
114
+ ## About
115
+
116
+ Nurturing a society that recognizes diversity as strength through verifiable knowledge sharing.
117
+
118
+ Content-addressing gives every function a fingerprint. Authorship is preserved. Lineage is traceable. Knowledge is shared without losing track of who made what.
119
+
111
120
  ## Vision
112
121
 
113
122
  bb.py is a step toward Möbius — a content-addressed language where timestamps make lineage visible, and names are views into a multilingual registry. Who made what, who built on whom, who absorbed whose work without credit. The mirror doesn't prescribe norms or enforce justice. It refuses amnesia.
@@ -2,50 +2,53 @@
2
2
 
3
3
  ![Tests](https://github.com/amirouche/bb.py/actions/workflows/test.yml/badge.svg)
4
4
 
5
- **Nurturing a society that recognizes diversity as strength through verifiable knowledge sharing.**
5
+ **Diversity as strength, made verifiable.**
6
6
 
7
- > **Experimental**: This is research software under active development.
8
-
9
- Every programmer who thinks in Wolof, Tamil, Vietnamese, or Tamazight and codes in English pays a cognitive tax. Every variable named in a second language is a thought translated before it's expressed. This overhead is invisible to the people who don't pay it — and universal for everyone who does.
7
+ Write a function in your language; if someone else, human or machine, had the same thought, the hash will show it.
10
8
 
11
- bb.py makes that tax optional. Write functions in your language — name variables, write documentation, think natively. The tool separates what your code *does* from what you *called* things. Same logic, same hash, regardless of tongue.
12
-
13
- Content-addressing gives every function a unique fingerprint. Authorship is preserved. Lineage is traceable. Knowledge is shared without losing track of who made what.
9
+ > **Experimental**: This is research software under active development.
14
10
 
15
- ## Same logic, three languages, one hash
11
+ Convergence is detected, divergence is preserved. When two minds write the same logic, they get the same hash, and no shared language was needed to find each other. When they write different logic, they get different hashes, and both are kept. Nothing is flattened into a single English version.
16
12
 
17
13
  ```python
18
- # English
19
- def calculate_sum(first_number, second_number):
20
- """Calculate the sum of two numbers."""
21
- result = first_number + second_number
22
- return result
14
+ # Français
15
+ def additionner(premier, second):
16
+ """Additionner deux nombres."""
17
+ somme = premier + second
18
+ return somme
23
19
  ```
24
20
 
25
21
  ```python
26
- # Français
27
- def calculer_somme(premier_nombre, deuxieme_nombre):
28
- """Calculer la somme de deux nombres."""
29
- sortie = premier_nombre + deuxieme_nombre
30
- return sortie
22
+ # العربية
23
+ def اجمع(الأول, الثاني):
24
+ """اجمع عددين."""
25
+ الناتج = الأول + الثاني
26
+ return الناتج
31
27
  ```
32
28
 
33
29
  ```python
34
30
  # Español
35
- def calcular_suma(primer_numero, segundo_numero):
36
- """Calcular la suma de dos números."""
37
- resultado = primer_numero + segundo_numero
38
- return resultado
31
+ def sumar(primero, segundo):
32
+ """Sumar dos números."""
33
+ suma = primero + segundo
34
+ return suma
39
35
  ```
40
36
 
41
37
  ```bash
42
- bb init
43
- bb add example_simple.py@eng # → 9f86d0...
44
- bb add example_simple_french.py@fra # → 9f86d0... ← same hash
45
- bb add example_simple_spanish.py@spa # → 9f86d0... ← same hash again
38
+ bb add additionner.py@fra # → one hash
39
+ bb add اجمع.py@ara # → the same hash
40
+ bb add sumar.py@spa # → the same hash again
46
41
  ```
47
42
 
48
- Three languages. One identity. No one translated — they wrote originals.
43
+ Three people, or two people and a model prompted in Arabic. Nobody translated; each wrote an original. The names and the docstring stay in their own language, and the hash is computed from the logic alone.
44
+
45
+ ## Why
46
+
47
+ Students learn to code in English while thinking in their own language, and every name they choose is a thought translated before it is written. Languages in Arabic script also tend to cost more tokens on LLMs for the same meaning, a quiet tax on the people who already pay one.
48
+
49
+ The machine side is the same question seen from outside. When several LLM agents work on one problem, someone has to know whether two of them really agree, or only sound alike. A shared hash is a cheap, honest answer for the case where the logic is identical, and an honest "no" when it is not.
50
+
51
+ The project is early. Exact matching is the foundation; near-matches are still a research question (see `LIMITS.md`).
49
52
 
50
53
  ## What it enables
51
54
 
@@ -82,6 +85,12 @@ uv tool install git+https://github.com/amirouche/bb.py.git
82
85
 
83
86
  Requires Python 3.11+. No runtime dependencies.
84
87
 
88
+ ## About
89
+
90
+ Nurturing a society that recognizes diversity as strength through verifiable knowledge sharing.
91
+
92
+ Content-addressing gives every function a fingerprint. Authorship is preserved. Lineage is traceable. Knowledge is shared without losing track of who made what.
93
+
85
94
  ## Vision
86
95
 
87
96
  bb.py is a step toward Möbius — a content-addressed language where timestamps make lineage visible, and names are views into a multilingual registry. Who made what, who built on whom, who absorbed whose work without credit. The mirror doesn't prescribe norms or enforce justice. It refuses amnesia.
@@ -70,7 +70,10 @@ Writing functions for the pool:
70
70
  `bb edit name@lang --refactor app@lang` saves the change and updates
71
71
  everything between app and it, and lists what it rewrote (or run
72
72
  `bb update app@lang` later: it brings app and everything it uses to
73
- their current versions in one step, keeping pins).
73
+ their current versions in one step, keeping pins). An update is saved
74
+ only when the checks of what it rewrites pass, as in bb edit: one that
75
+ fails stays on its version, the rest is updated, the failure is printed
76
+ and the exit status is 1.
74
77
  - Finding functions: `bb search` alone lists every current function;
75
78
  `bb search WORDS` searches names, docs and code; `bb latest
76
79
  name@lang --hash` prints only the current hash (for scripts); `bb log`
@@ -6319,14 +6322,16 @@ def code_load_refs(tree: ast.AST, cache: Dict[str, Callable]) -> types.SimpleNam
6319
6322
  return types.SimpleNamespace(ref=loaded.__getitem__)
6320
6323
 
6321
6324
 
6322
- def code_load_normalized(func_hash: str, cache: Dict[str, Callable] = None) -> Callable:
6325
+ def code_load_normalized(func_hash: str, cache: Dict[str, Callable] = None,
6326
+ source: str = None, like: str = None) -> Callable:
6323
6327
  """
6324
6328
  Load a pool function from its normalized code, exactly as hashed.
6325
6329
 
6326
6330
  No language mapping is applied, so what runs is the code that was
6327
6331
  hashed and reviewed, whatever names a mapping displays. Each function
6328
6332
  runs in its own namespace, with its bb imports bound to their own
6329
- loaded functions.
6333
+ loaded functions. With source (and like, the function it rewrites),
6334
+ code that is not in the pool yet is loaded under func_hash.
6330
6335
 
6331
6336
  Raises:
6332
6337
  ValueError: If the function or a dependency is missing or fails to load
@@ -6336,12 +6341,16 @@ def code_load_normalized(func_hash: str, cache: Dict[str, Callable] = None) -> C
6336
6341
  if func_hash in cache:
6337
6342
  return cache[func_hash]
6338
6343
 
6339
- if code_detect_schema(func_hash) is None:
6340
- raise ValueError(f"Function not in the local pool: {func_hash}")
6341
- data = object_load(func_hash)
6342
- tree = ast.parse(data['normalized_code'])
6344
+ if source is None:
6345
+ if code_detect_schema(func_hash) is None:
6346
+ raise ValueError(f"Function not in the local pool: {func_hash}")
6347
+ data = object_load(func_hash)
6348
+ source, like = data['normalized_code'], func_hash
6349
+ else:
6350
+ data = object_load(like) # a version not saved yet, loaded like the one it rewrites
6351
+ tree = ast.parse(source)
6343
6352
  if data.get('normalization', 1) < 2:
6344
- code_restore_inner_imports(tree, func_hash)
6353
+ code_restore_inner_imports(tree, like)
6345
6354
 
6346
6355
  namespace: Dict[str, Any] = {'bb': code_load_refs(tree, cache)}
6347
6356
  body = []
@@ -6389,14 +6398,25 @@ def check_run_reviewed(func_hash: str, reviewed: set) -> Tuple[Optional[List[Tup
6389
6398
  if missing:
6390
6399
  return None, missing
6391
6400
 
6401
+ return check_run_all(func_hash, object_load_checks(func_hash)), []
6402
+
6403
+
6404
+ def check_run_all(func_hash: str, checks: List[str], source: str = None,
6405
+ like: str = None) -> List[Tuple[str, str, str]]:
6406
+ """
6407
+ Run checks against a function, already approved: results for check_report.
6408
+
6409
+ With source and like, the function is code not saved yet (see
6410
+ code_load_normalized). Callers make sure everything that runs was approved.
6411
+ """
6392
6412
  cache: Dict[str, Callable] = {}
6393
6413
  try:
6394
- implementation = code_load_normalized(func_hash, cache)
6414
+ implementation = code_load_normalized(func_hash, cache, source=source, like=like)
6395
6415
  except ValueError as e:
6396
- return [('ERROR', helper_function_label(func_hash), str(e))], []
6416
+ return [('ERROR', helper_function_label(like or func_hash), str(e))]
6397
6417
 
6398
6418
  results = []
6399
- for check_hash in object_load_checks(func_hash):
6419
+ for check_hash in checks:
6400
6420
  name = helper_function_label(check_hash)
6401
6421
  try:
6402
6422
  check = code_load_normalized(check_hash, cache)
@@ -6407,7 +6427,7 @@ def check_run_reviewed(func_hash: str, reviewed: set) -> Tuple[Optional[List[Tup
6407
6427
  results.append((status, name, detail))
6408
6428
 
6409
6429
  results.sort(key=lambda r: r[1])
6410
- return results, []
6430
+ return results
6411
6431
 
6412
6432
 
6413
6433
  def command_validate_checks(identifier: str = None, unreviewed: bool = False):
@@ -7229,7 +7249,7 @@ def command_scratchpad(identifiers: List[str], file: str, comment: str = None, t
7229
7249
  finally:
7230
7250
  shutil.rmtree(work, ignore_errors=True)
7231
7251
  if refactor:
7232
- command_update(refactor, comment)
7252
+ command_update(refactor, comment, unreviewed)
7233
7253
 
7234
7254
 
7235
7255
  def refactor_save(old_hash: str, new_hash: str, new_code: str, checks: List[str], comment: str,
@@ -7269,7 +7289,29 @@ def code_hash_rewritten(new_code: str, checks: List[str]) -> str:
7269
7289
  raise ValueError("no function in code")
7270
7290
 
7271
7291
 
7272
- def command_update(identifier: str, comment: str = None):
7292
+ def update_check_rewritten(base: str, new_hash: str, new_code: str, checks: List[str],
7293
+ unreviewed: bool = False) -> List[str]:
7294
+ """
7295
+ Run the checks of a rewrite before it is saved; the failures, one line each.
7296
+
7297
+ Like bb edit, nothing runs that you have not approved: the rewrite
7298
+ imports pool functions and so do its checks. Those not approved are
7299
+ reported as failures (bb review them), unless unreviewed.
7300
+ """
7301
+ needed = set()
7302
+ for dep in code_extract_dependencies(new_code):
7303
+ needed.update(code_resolve_dependencies(dep))
7304
+ for check_hash in checks:
7305
+ needed.update(code_resolve_dependencies(check_hash))
7306
+ missing = sorted(needed - review_approvals(list(needed)) - review_load_authored())
7307
+ if missing and not unreviewed:
7308
+ return ["not run, review first: " + ', '.join(f"bb review {h}" for h in missing)]
7309
+ results = check_run_all(new_hash, checks, source=new_code, like=base)
7310
+ return [f"{status} {name}: {detail}" if detail else f"{status} {name}"
7311
+ for status, name, detail in results if status != 'PASS']
7312
+
7313
+
7314
+ def command_update(identifier: str, comment: str = None, unreviewed: bool = False):
7273
7315
  """
7274
7316
  Bring a function and everything it uses up to date, in one step.
7275
7317
 
@@ -7282,6 +7324,12 @@ def command_update(identifier: str, comment: str = None):
7282
7324
  (written as bb.ref) are kept. A fork (several current versions) is
7283
7325
  left as it is, with a warning. One comment goes on every new version.
7284
7326
 
7327
+ Like bb edit, a rewrite is saved only when the checks of the function
7328
+ pass with the new versions it uses. One that fails is not saved: it
7329
+ stays on the version it has, its callers stay as they were, and the
7330
+ rest is updated anyway. What failed is printed, and bb update exits
7331
+ with status 1; bb edit the function to adapt it, then update again.
7332
+
7285
7333
  ```
7286
7334
  bb update app@eng -m "use the new layout everywhere"
7287
7335
  ```
@@ -7295,6 +7343,7 @@ def command_update(identifier: str, comment: str = None):
7295
7343
  comment = ""
7296
7344
  done: Dict[Tuple[str, Optional[str]], str] = {}
7297
7345
  rewritten: List[Tuple[str, str]] = []
7346
+ failed: List[Tuple[str, str, List[str]]] = []
7298
7347
 
7299
7348
  def update(func_hash: str, name: Optional[str], stack: Tuple[str, ...] = ()) -> str:
7300
7349
  """The up-to-date hash for func_hash, used by name (itself when nothing changes)."""
@@ -7323,6 +7372,11 @@ def command_update(identifier: str, comment: str = None):
7323
7372
  checks = object_load_checks(base)
7324
7373
  result = code_hash_rewritten(new_code, checks)
7325
7374
  followed = {dep: lineage_name_for(dep, lang, aliases.get(dep)) for dep in swaps}
7375
+ problems = update_check_rewritten(base, result, new_code, checks, unreviewed) if checks else []
7376
+ if problems and result != base:
7377
+ failed.append((base, result, problems))
7378
+ done[(func_hash, name)] = done[(base, name)] = base
7379
+ return base
7326
7380
 
7327
7381
  def keep(record):
7328
7382
  """Names of base that use the swapped functions by other names stay (two names, one code)."""
@@ -7339,14 +7393,27 @@ def command_update(identifier: str, comment: str = None):
7339
7393
  return result
7340
7394
 
7341
7395
  new_root = update(root, helper_identifier_name(identifier) or lineage_name_for(root, lang))
7342
- if not rewritten:
7396
+ if not rewritten and not failed:
7343
7397
  print(f"{helper_function_label(root)} is up to date: nothing to save")
7344
7398
  return
7345
- print(f"Updated {len(rewritten)} function(s), deepest first:")
7346
- for old, new in rewritten:
7347
- print(f" {helper_function_label(new)}: {old[:12]}... -> {new[:12]}...")
7348
- print("Drafts open on these functions are now stale: write them again.")
7399
+ if rewritten:
7400
+ print(f"Updated {len(rewritten)} function(s), deepest first:")
7401
+ for old, new in rewritten:
7402
+ print(f" {helper_function_label(new)}: {old[:12]}... -> {new[:12]}...")
7403
+ print("Drafts open on these functions are now stale: write them again.")
7404
+ else:
7405
+ print("Nothing updated.")
7349
7406
  print(f"Hash: {new_root}")
7407
+ if failed:
7408
+ sys.stdout.flush() # what was updated comes before what was not
7409
+ print(f"Not updated, a check failed ({len(failed)}):", file=sys.stderr)
7410
+ for old, new, problems in failed:
7411
+ print(f" {helper_function_label(old)}: {old[:12]}... stays; its update would be {new[:12]}...",
7412
+ file=sys.stderr)
7413
+ for problem in problems:
7414
+ print(f" {problem}", file=sys.stderr)
7415
+ print("Edit them to adapt (bb edit NAME@lang), then update again.", file=sys.stderr)
7416
+ sys.exit(1)
7350
7417
 
7351
7418
 
7352
7419
  def command_refactor(what_hash: str, from_hash: str, to_hash: str, at_hash: str = None, comment: str = None):
@@ -8439,6 +8506,8 @@ def _build_parser():
8439
8506
  update_parser = subparsers.add_parser('update', help='Bring a function and everything it uses up to date')
8440
8507
  update_parser.add_argument('identifier', help='Function to update (name@lang or hash)')
8441
8508
  update_parser.add_argument('--comment', '-m', default=None, help='Comment for the new versions (asked when omitted)')
8509
+ update_parser.add_argument('--dangerously-unreviewed', action='store_true',
8510
+ help='Run checks even on unreviewed functions they import')
8442
8511
 
8443
8512
  refactor_parser = subparsers.add_parser('refactor', help='Replace a dependency in a function')
8444
8513
  refactor_parser.add_argument('what', help='Function hash to modify')
@@ -8583,7 +8652,7 @@ def main():
8583
8652
  elif args.command == 'tree':
8584
8653
  command_tree(args.identifier, as_json=args.as_json)
8585
8654
  elif args.command == 'update':
8586
- command_update(args.identifier, comment=args.comment)
8655
+ command_update(args.identifier, comment=args.comment, unreviewed=args.dangerously_unreviewed)
8587
8656
  elif args.command == 'refactor':
8588
8657
  command_refactor(args.what, args.from_hash, args.to_hash, args.at_hash if hasattr(args, 'at_hash') else None,
8589
8658
  comment=args.comment)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beyondbabel
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: A function pool manager for Python that enables multilingual function sharing through AST normalization
5
5
  Author: Amirouche Boubekki
6
6
  License-Expression: MIT
@@ -28,50 +28,53 @@ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
28
28
 
29
29
  ![Tests](https://github.com/amirouche/bb.py/actions/workflows/test.yml/badge.svg)
30
30
 
31
- **Nurturing a society that recognizes diversity as strength through verifiable knowledge sharing.**
31
+ **Diversity as strength, made verifiable.**
32
32
 
33
- > **Experimental**: This is research software under active development.
34
-
35
- Every programmer who thinks in Wolof, Tamil, Vietnamese, or Tamazight and codes in English pays a cognitive tax. Every variable named in a second language is a thought translated before it's expressed. This overhead is invisible to the people who don't pay it — and universal for everyone who does.
33
+ Write a function in your language; if someone else, human or machine, had the same thought, the hash will show it.
36
34
 
37
- bb.py makes that tax optional. Write functions in your language — name variables, write documentation, think natively. The tool separates what your code *does* from what you *called* things. Same logic, same hash, regardless of tongue.
38
-
39
- Content-addressing gives every function a unique fingerprint. Authorship is preserved. Lineage is traceable. Knowledge is shared without losing track of who made what.
35
+ > **Experimental**: This is research software under active development.
40
36
 
41
- ## Same logic, three languages, one hash
37
+ Convergence is detected, divergence is preserved. When two minds write the same logic, they get the same hash, and no shared language was needed to find each other. When they write different logic, they get different hashes, and both are kept. Nothing is flattened into a single English version.
42
38
 
43
39
  ```python
44
- # English
45
- def calculate_sum(first_number, second_number):
46
- """Calculate the sum of two numbers."""
47
- result = first_number + second_number
48
- return result
40
+ # Français
41
+ def additionner(premier, second):
42
+ """Additionner deux nombres."""
43
+ somme = premier + second
44
+ return somme
49
45
  ```
50
46
 
51
47
  ```python
52
- # Français
53
- def calculer_somme(premier_nombre, deuxieme_nombre):
54
- """Calculer la somme de deux nombres."""
55
- sortie = premier_nombre + deuxieme_nombre
56
- return sortie
48
+ # العربية
49
+ def اجمع(الأول, الثاني):
50
+ """اجمع عددين."""
51
+ الناتج = الأول + الثاني
52
+ return الناتج
57
53
  ```
58
54
 
59
55
  ```python
60
56
  # Español
61
- def calcular_suma(primer_numero, segundo_numero):
62
- """Calcular la suma de dos números."""
63
- resultado = primer_numero + segundo_numero
64
- return resultado
57
+ def sumar(primero, segundo):
58
+ """Sumar dos números."""
59
+ suma = primero + segundo
60
+ return suma
65
61
  ```
66
62
 
67
63
  ```bash
68
- bb init
69
- bb add example_simple.py@eng # → 9f86d0...
70
- bb add example_simple_french.py@fra # → 9f86d0... ← same hash
71
- bb add example_simple_spanish.py@spa # → 9f86d0... ← same hash again
64
+ bb add additionner.py@fra # → one hash
65
+ bb add اجمع.py@ara # → the same hash
66
+ bb add sumar.py@spa # → the same hash again
72
67
  ```
73
68
 
74
- Three languages. One identity. No one translated — they wrote originals.
69
+ Three people, or two people and a model prompted in Arabic. Nobody translated; each wrote an original. The names and the docstring stay in their own language, and the hash is computed from the logic alone.
70
+
71
+ ## Why
72
+
73
+ Students learn to code in English while thinking in their own language, and every name they choose is a thought translated before it is written. Languages in Arabic script also tend to cost more tokens on LLMs for the same meaning, a quiet tax on the people who already pay one.
74
+
75
+ The machine side is the same question seen from outside. When several LLM agents work on one problem, someone has to know whether two of them really agree, or only sound alike. A shared hash is a cheap, honest answer for the case where the logic is identical, and an honest "no" when it is not.
76
+
77
+ The project is early. Exact matching is the foundation; near-matches are still a research question (see `LIMITS.md`).
75
78
 
76
79
  ## What it enables
77
80
 
@@ -108,6 +111,12 @@ uv tool install git+https://github.com/amirouche/bb.py.git
108
111
 
109
112
  Requires Python 3.11+. No runtime dependencies.
110
113
 
114
+ ## About
115
+
116
+ Nurturing a society that recognizes diversity as strength through verifiable knowledge sharing.
117
+
118
+ Content-addressing gives every function a fingerprint. Authorship is preserved. Lineage is traceable. Knowledge is shared without losing track of who made what.
119
+
111
120
  ## Vision
112
121
 
113
122
  bb.py is a step toward Möbius — a content-addressed language where timestamps make lineage visible, and names are views into a multilingual registry. Who made what, who built on whom, who absorbed whose work without credit. The mirror doesn't prescribe norms or enforce justice. It refuses amnesia.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "beyondbabel"
7
- version = "0.3.0"
7
+ version = "0.4.0"
8
8
  description = "A function pool manager for Python that enables multilingual function sharing through AST normalization"
9
9
  readme = "README.md"
10
10
  license = "MIT"
File without changes