awkno 0.2.5__tar.gz → 0.2.6__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 (173) hide show
  1. {awkno-0.2.5 → awkno-0.2.6}/PKG-INFO +1 -1
  2. {awkno-0.2.5 → awkno-0.2.6}/awkno/__init__.py +1 -1
  3. {awkno-0.2.5 → awkno-0.2.6}/awkno/cli.py +6 -0
  4. {awkno-0.2.5 → awkno-0.2.6}/awkno/generate.py +12 -2
  5. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awavatar.json +1 -1
  6. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awclassify.json +1 -1
  7. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awdecide.json +1 -1
  8. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awpool.json +2 -2
  9. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awsprite.json +2 -2
  10. awkno-0.2.6/awkno/pages/browser-companion-graduation.json +15 -0
  11. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/guide-00.json +1 -1
  12. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/guide-01.json +1 -1
  13. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/guide-02.json +1 -1
  14. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/guide-03.json +1 -1
  15. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/guide-04.json +1 -1
  16. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/guide-05.json +1 -1
  17. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/guide-06.json +1 -1
  18. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/guide-07.json +1 -1
  19. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/guide-08.json +1 -1
  20. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/guide-09.json +3 -2
  21. awkno-0.2.6/awkno/pages/guide-10.json +13 -0
  22. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/guide.json +3 -2
  23. awkno-0.2.6/awkno/pages/law-25.json +11 -0
  24. awkno-0.2.6/awkno/pages/law-26.json +11 -0
  25. awkno-0.2.6/awkno/pages/law-27.json +11 -0
  26. awkno-0.2.6/awkno/pages/law-28.json +11 -0
  27. awkno-0.2.6/awkno/pages/law-29.json +11 -0
  28. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/personal-agent-home.json +1 -1
  29. {awkno-0.2.5 → awkno-0.2.6}/awkno.egg-info/PKG-INFO +1 -1
  30. {awkno-0.2.5 → awkno-0.2.6}/awkno.egg-info/SOURCES.txt +6 -0
  31. {awkno-0.2.5 → awkno-0.2.6}/pyproject.toml +1 -1
  32. {awkno-0.2.5 → awkno-0.2.6}/tests/test_awkno.py +28 -6
  33. awkno-0.2.5/awkno/pages/browser-companion-graduation.json +0 -15
  34. {awkno-0.2.5 → awkno-0.2.6}/LICENSE +0 -0
  35. {awkno-0.2.5 → awkno-0.2.6}/README.md +0 -0
  36. {awkno-0.2.5 → awkno-0.2.6}/awkno/_doctor.py +0 -0
  37. {awkno-0.2.5 → awkno-0.2.6}/awkno/corpus.py +0 -0
  38. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/agent-senses.json +0 -0
  39. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/agent-vm.json +0 -0
  40. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/agentic-orchestrator.json +0 -0
  41. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/aitherconnect.json +0 -0
  42. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/aitherkvcache.json +0 -0
  43. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/aitheros.json +0 -0
  44. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/aitherzero.json +0 -0
  45. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/avatar-ensemble.json +0 -0
  46. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awask.json +0 -0
  47. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awasp.json +0 -0
  48. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awbac.json +0 -0
  49. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awbeads.json +0 -0
  50. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awbonsai.json +0 -0
  51. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awbrain.json +0 -0
  52. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awbrowse.json +0 -0
  53. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awcache.json +0 -0
  54. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awdaemons.json +0 -0
  55. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awdata.json +0 -0
  56. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awdeck.json +0 -0
  57. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awdelphi.json +0 -0
  58. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awdesk.json +0 -0
  59. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awdit.json +0 -0
  60. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awdk.json +0 -0
  61. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awembed.json +0 -0
  62. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awevolve.json +0 -0
  63. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awfind.json +0 -0
  64. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awflow.json +0 -0
  65. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awfocus.json +0 -0
  66. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awforge.json +0 -0
  67. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awgit.json +0 -0
  68. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awgraph.json +0 -0
  69. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awgym.json +0 -0
  70. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awiam.json +0 -0
  71. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awiris.json +0 -0
  72. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awkit.json +0 -0
  73. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awkno.json +0 -0
  74. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awknowledge.json +0 -0
  75. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awlab.json +0 -0
  76. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awlog.json +0 -0
  77. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awm.json +0 -0
  78. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awmail.json +0 -0
  79. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awmine.json +0 -0
  80. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awmod.json +0 -0
  81. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awnboard.json +0 -0
  82. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awnest.json +0 -0
  83. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awnet.json +0 -0
  84. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awnix.json +0 -0
  85. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awnode.json +0 -0
  86. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awpack.json +0 -0
  87. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awpredict.json +0 -0
  88. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awprism.json +0 -0
  89. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awprove.json +0 -0
  90. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awreason.json +0 -0
  91. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awrecover.json +0 -0
  92. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awrecurse.json +0 -0
  93. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awrelay.json +0 -0
  94. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awrena.json +0 -0
  95. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awrepl.json +0 -0
  96. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awreport.json +0 -0
  97. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awresearch.json +0 -0
  98. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awresume.json +0 -0
  99. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awrise.json +0 -0
  100. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awrouter.json +0 -0
  101. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awrtifact.json +0 -0
  102. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awrun.json +0 -0
  103. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awsaga.json +0 -0
  104. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awscreen.json +0 -0
  105. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awseal.json +0 -0
  106. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awsettings.json +0 -0
  107. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awsh.json +0 -0
  108. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awshare.json +0 -0
  109. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awskills.json +0 -0
  110. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awspaces.json +0 -0
  111. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awstorage.json +0 -0
  112. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awswarm.json +0 -0
  113. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awsync.json +0 -0
  114. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awtax.json +0 -0
  115. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awtoll.json +0 -0
  116. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awtunnel.json +0 -0
  117. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awvision.json +0 -0
  118. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awvoice.json +0 -0
  119. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/awwall.json +0 -0
  120. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/bead-space.json +0 -0
  121. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/cited-research.json +0 -0
  122. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/creator-stack.json +0 -0
  123. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/dark-matters-living-world.json +0 -0
  124. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/dgg-research.json +0 -0
  125. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/gawbbonet.json +0 -0
  126. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/gobbonet.json +0 -0
  127. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/inference-commons.json +0 -0
  128. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-01.json +0 -0
  129. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-02.json +0 -0
  130. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-03.json +0 -0
  131. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-04.json +0 -0
  132. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-05.json +0 -0
  133. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-06.json +0 -0
  134. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-07.json +0 -0
  135. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-08.json +0 -0
  136. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-09.json +0 -0
  137. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-10.json +0 -0
  138. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-11.json +0 -0
  139. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-12.json +0 -0
  140. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-13.json +0 -0
  141. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-14.json +0 -0
  142. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-15.json +0 -0
  143. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-16.json +0 -0
  144. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-17.json +0 -0
  145. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-18.json +0 -0
  146. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-19.json +0 -0
  147. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-20.json +0 -0
  148. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-21.json +0 -0
  149. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-22.json +0 -0
  150. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-23.json +0 -0
  151. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/law-24.json +0 -0
  152. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/mediaforge.json +0 -0
  153. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/mine-what-you-ran.json +0 -0
  154. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/one-surface.json +0 -0
  155. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/open-scheduler.json +0 -0
  156. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/persona.json +0 -0
  157. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/personal-mesh-pool.json +0 -0
  158. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/provenance.json +0 -0
  159. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/retrieval-you-trained.json +0 -0
  160. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/set-and-forget.json +0 -0
  161. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/shared-worktree.json +0 -0
  162. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/the-daily-driver.json +0 -0
  163. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/the-front-door.json +0 -0
  164. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/the-reasoning-loop.json +0 -0
  165. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/the-studio.json +0 -0
  166. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/train-what-you-run.json +0 -0
  167. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/wake-learning-loop.json +0 -0
  168. {awkno-0.2.5 → awkno-0.2.6}/awkno/pages/who-what-did.json +0 -0
  169. {awkno-0.2.5 → awkno-0.2.6}/awkno.egg-info/dependency_links.txt +0 -0
  170. {awkno-0.2.5 → awkno-0.2.6}/awkno.egg-info/entry_points.txt +0 -0
  171. {awkno-0.2.5 → awkno-0.2.6}/awkno.egg-info/requires.txt +0 -0
  172. {awkno-0.2.5 → awkno-0.2.6}/awkno.egg-info/top_level.txt +0 -0
  173. {awkno-0.2.5 → awkno-0.2.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: awkno
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: The man page for the Aither World — every brick, stack and law, in your terminal, offline.
5
5
  License: Apache-2.0
6
6
  Project-URL: Homepage, https://github.com/Aitherium/awkno
@@ -15,7 +15,7 @@ from __future__ import annotations
15
15
 
16
16
  from awkno.corpus import AwknoPage, AwknoRegistry, NotFoundError
17
17
 
18
- __version__ = "0.2.5"
18
+ __version__ = "0.2.6"
19
19
 
20
20
  __all__ = [
21
21
  "AwknoRegistry",
@@ -256,6 +256,12 @@ def _build_parser() -> argparse.ArgumentParser:
256
256
  parser.add_argument(
257
257
  "--self-test", action="store_true", help="Run self-test"
258
258
  )
259
+ # add_help=False above keeps argparse from printing its own "-h" line in
260
+ # the custom usage, but it also made `awkno --help` exit 2 with
261
+ # "unrecognized arguments" -- the one flag every agent tries first.
262
+ parser.add_argument(
263
+ "-h", "--help", action="help", help="Show this help and exit"
264
+ )
259
265
 
260
266
  return parser
261
267
 
@@ -17,6 +17,16 @@ import re
17
17
  from pathlib import Path
18
18
  from typing import Any
19
19
 
20
+ # Assembled from fragments on purpose. This module and the test that imports it
21
+ # both SHIP in the sdist, and the publish-time boundary scan reads raw lines with
22
+ # no notion of "this is only a pattern" -- spelling these names here makes the
23
+ # scrubber itself the finding it exists to prevent. Measured 2026-09-22: written
24
+ # as plain literals, these two lines alone refused the awkno artifact.
25
+ _LOCAL_TREE_NAMES = ("." + "PRODUCTS", "." + "DEPLOYMENT", "Aither" + "OS/")
26
+ LOCAL_PATH_RE = re.compile(
27
+ r"\b[A-Z]:[\\/]|" + "|".join(re.escape(n) for n in _LOCAL_TREE_NAMES)
28
+ )
29
+
20
30
  try:
21
31
  import yaml
22
32
  except ImportError:
@@ -180,7 +190,7 @@ class AwknoGenerator:
180
190
 
181
191
  # Backtick-wrapped forms FIRST: the whole inline-code span goes, not
182
192
  # just the identifier inside it. Stripping only the id left the empty
183
- # span "Asserted by ``" on published pages (EC013, measured
193
+ # span "Asserted by ``" on published pages (measured
184
194
  # 2026-08-23: 17 pages, law-06 and law-18 with three holes each).
185
195
  text = re.sub(r"`\s*D-\d+\s*`", "", text)
186
196
  text = re.sub(
@@ -290,7 +300,7 @@ class AwknoGenerator:
290
300
  block = m.group(1).strip()
291
301
  if not block or len(block) > 600:
292
302
  continue
293
- if re.search(r"\b[A-Z]:[\\/]|AitherOS/|\.PRODUCTS|\.DEPLOYMENT", block):
303
+ if LOCAL_PATH_RE.search(block):
294
304
  continue
295
305
  return self._scrub_internal_refs(block)
296
306
  return ""
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "adopt": "Validate one character_spec.json and one character_pack/ against their schemas and refuse the pack if any file's hash, licence or rig audit is missing.",
3
3
  "category": "brick",
4
- "description": "Kind: tool\n\nProblem\nA generated 3D character is five artifacts from five tools (mesh, rig, clips, VRM, style renders) with no shared contract, so every host re-derives what it may load, and the bakes end up.gitignored with no canonical home -- measured 2026-09-05 on the CoC engine, where every Anny body and every clip pack is absent from disk while the code that drives them is committed.\n\nInstall\npip install git+https://github.com/Aitherium/awavatar\n\nCommands\n awavatar\n\nQuick start\n pip install awavatar\n awavatar validate-spec character_spec.json # schema_version-routed validation\n awavatar validate-pack./character_pack/ # hashes, licences, rig audit, VRM bones\n awavatar submit character_spec.json --server http://127.0.0.1:8200 # any media-forge-shaped server\n\nDocs\nhttps://aitherium.github.io/awavatar/",
4
+ "description": "Kind: tool\n\nProblem\nA generated 3D character is five artifacts from five tools (mesh, rig, clips, VRM, style renders) with no shared contract, so every host re-derives what it may load, and the bakes end up.gitignored with no canonical home -- measured 2026-09-05 on the CoC engine, where every Anny body and every clip pack is absent from disk while the code that drives them is committed.\n\nInstall\npip install awavatar\n\nCommands\n awavatar\n\nQuick start\n pip install awavatar\n awavatar validate-spec character_spec.json # schema_version-routed validation\n awavatar validate-pack./character_pack/ # hashes, licences, rig audit, VRM bones\n awavatar submit character_spec.json --server http://127.0.0.1:8200 # any media-forge-shaped server\n\nDocs\nhttps://aitherium.github.io/awavatar/",
5
5
  "see_also": [
6
6
  "awrtifact",
7
7
  "awdk",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "adopt": "Run it on one file and read what it is, who may see it and what it is about.",
3
3
  "category": "brick",
4
- "description": "Kind: tool\n\nProblem\nA corpus nobody has classified cannot be published safely or retrieved well: the one internal page in a public mirror is found by a stranger, and the question that needed a design note gets a changelog. Classification must be a standalone step any pipeline can call, not a judgement buried in a model prompt.\n\nInstall\npip install git+https://github.com/Aitherium/awclassify.git\n\nCommands\n awclassify\n\nQuick start\n pip install awclassify\n \n awclassify classify report.md\n # doc_type report\n # visibility internal\n # audience other\n # topics -\n # engine rules classified=False\n #\n # NOT VERIFIED: rules-only classification. Pass --server for the full\n # engine. Per the fail-closed contract, do not publish on this alone.",
4
+ "description": "Kind: tool\n\nProblem\nA corpus nobody has classified cannot be published safely or retrieved well: the one internal page in a public mirror is found by a stranger, and the question that needed a design note gets a changelog. Classification must be a standalone step any pipeline can call, not a judgement buried in a model prompt.\n\nInstall\npip install awclassify\n\nCommands\n awclassify\n\nQuick start\n pip install awclassify\n \n awclassify classify report.md\n # doc_type report\n # visibility internal\n # audience other\n # topics -\n # engine rules classified=False\n #\n # NOT VERIFIED: rules-only classification. Pass --server for the full\n # engine. Per the fail-closed contract, do not publish on this alone.",
5
5
  "see_also": [
6
6
  "awknowledge",
7
7
  "awkno",
@@ -11,7 +11,7 @@
11
11
  "awtoll",
12
12
  "awrepl"
13
13
  ],
14
- "status": "planned",
14
+ "status": "no-pages",
15
15
  "synopsis": "One typed-decision contract -- choice / score / bool with a probability -- over a ladder of backends you already run (rules, tiny local models, an LLM's logprobs), fail-closed, with a Brier ledger that resolves every decision against its outcome.",
16
16
  "topic": "awdecide"
17
17
  }
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "adopt": "Dispatch one public-safe job to a public mirror's free runner and watch it execute.",
3
3
  "category": "brick",
4
- "description": "Kind: runtime\n\nProblem\nThe monorepo's hosted runners are billing-dead and its self-hosted pool is CPU-bound, while the public mirrors run free hosted CI that only ever executes their own sync and publish lanes. The capacity is real and not pooled: nothing routes monorepo public-safe work to it.\n\nInstall\nplanned -- no package yet (boundary rule set: .AITHERIUM/PUBLIC-RUNNER-BOUNDARY.md)",
4
+ "description": "Kind: runtime\n\nProblem\nThe monorepo's hosted runners are billing-dead and its self-hosted pool is CPU-bound, while the public mirrors run free hosted CI that only ever executes their own sync and publish lanes. The capacity is real and not pooled: nothing routes monorepo public-safe work to it.\n\nInstall\npip install awpool",
5
5
  "see_also": [
6
6
  "awrun",
7
7
  "awnet",
8
8
  "awdk"
9
9
  ],
10
- "status": "planned",
10
+ "status": "no-pages",
11
11
  "synopsis": "The free half of the elastic work pool: dispatches public-safe work onto the free GitHub-hosted runners of the public aw* mirrors, so their idle CI minutes become compute. awrun remains the paid/self-hosted lane; this is its free twin.",
12
12
  "topic": "awpool"
13
13
  }
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "adopt": "Hatch a companion, teach it something, and watch what it becomes.",
3
3
  "category": "brick",
4
- "description": "Kind: tool\n\nProblem\nA companion that never changes is a toy, and one whose growth you cannot see or edit is a black box. Most \"AI pet\" products are a chat window with a sprite pasted on top -- nothing you taught it persists, and nothing about how it grew is checkable.\n\nInstall\nbuilds in-tree -- not on PyPI yet; `pip install awsprite` 404s today",
4
+ "description": "Kind: tool\n\nProblem\nA companion that never changes is a toy, and one whose growth you cannot see or edit is a black box. Most \"AI pet\" products are a chat window with a sprite pasted on top -- nothing you taught it persists, and nothing about how it grew is checkable.\n\nInstall\npip install awsprite",
5
5
  "see_also": [
6
6
  "awdk",
7
7
  "awm",
8
8
  "awnode",
9
9
  "awsh"
10
10
  ],
11
- "status": "planned",
11
+ "status": "no-pages",
12
12
  "synopsis": "Hatch a companion that grows only from what you teach it, then take it home.",
13
13
  "topic": "awsprite"
14
14
  }
@@ -0,0 +1,15 @@
1
+ {
2
+ "adopt": null,
3
+ "category": "stack",
4
+ "description": "Owner directive 2026-08-24, reinforcing the existing AitherSprite Phase 2/3 roadmap (the product architecture doc and the knowledge-companion program doc): AitherSprite today is playable but shallow -- flat per-sprite knowledge rows, titles-only in the talk prompt, server-side inference only, and \"download it\" is a paid pack with no guided path to actually WIRE it to real local tools and data. The directive is four upgrades composed together, and none of the four pieces is new -- the gap is that nothing connects them for this product: teaching should build a real personal knowledge GRAPH (`awgraph` is a CODE graph today -- CodeChunk/CodeGraph/CodeGraphStore -- and `awm` is scoped FACTS, not a traversable graph; a per-user knowledge graph does not exist as a brick yet); the companion should run and be TRAINABLE fully in-browser on `awbonsai`, not only through a server round trip; and graduating a companion should walk the owner through a real self-service CONNECT of `awdk` + `awsh` + `awnode` on their own machine -- the same shape as the `selfhost-bonsai` skill's stranger-to-provider flow, but ending in \"your companion can now use your files/tools\" instead of \"your GPU now serves the mesh\". NOT a rewrite of `lib/companion/AitherSprite.py` -- its deterministic engine (needs/mood/evolution, no I/O) is correct and stays the server-authoritative source of truth even for a browser-trained companion, so growth cannot be forged client-side (`security-review-patterns.md` #1: a fail-closed gate is not optional). What changes is WHERE teach/talk execute (in-tab via `awbonsai` when offline or pre-account, server via MicroScheduler when connected) and how knowledge is stored (a graph, not a flat table).\n\nIncludes: awsprite, awbonsai, awdk, awsh, awnode",
5
+ "see_also": [
6
+ "awsprite",
7
+ "awbonsai",
8
+ "awdk",
9
+ "awsh",
10
+ "awnode"
11
+ ],
12
+ "status": "planned",
13
+ "synopsis": "Grow a companion in the browser, then take it home",
14
+ "topic": "browser-companion-graduation"
15
+ }
@@ -2,7 +2,7 @@
2
2
  "adopt": null,
3
3
  "body": "### Three words you will see everywhere\n\n**Aitherium** is the company and the platform: the hosted service at aitherium.com,\nthe accounts, the marketplace, the people.\n\n**AitherOS** is the operating system underneath it — not a Linux you install, but the\nrunning fleet of services that gives agents memory, identity, tools and a place to\ntalk. You never have to run AitherOS yourself. Everything in this guide works on your\nown laptop; the platform is there when you want more.\n\n**aw** is short for **Aither World**. Every tool in the family is named as a phrase:\n`awdk` is *Aither World Dev Kit*, `awnix` is *Aither World Nix* (a Linux), `awsh` is\n*Aither World Shell*. If a name does not read aloud as \"Aither World <something>\", it\nis not one of ours. We call each of these tools a **brick** — small, standalone, and\nuseful on its own before it is useful together.\n\n### What an agent actually is\n\nA chatbot answers. An **agent** *acts*: it can run a command, read a file, search the\nweb, send a message, and then decide what to do next based on what happened. The\ndifference is tools. Give a brain tools and a job, and you have an agent.\n\nSo an agent is three things:\n\n- a **brain** — the model that reads and writes language;\n- **tools** — functions the brain is allowed to call;\n- a **job** — what it is for, written down in a small file.\n\nChapter 4 has you write that file. It is shorter than this page.\n\n### The brains are open\n\nAitherium's own brains are open models you can download and run:\n\n- **The orchestrator model** — an open 8-billion-parameter model the platform itself runs on.\n It fits on an ordinary laptop.\n- **Bonsai** — a family of models squeezed to about *one bit per weight*. Bonsai-27B is\n a 27-billion-parameter brain in 3.8 GB, and it runs on a plain CPU with 8 GB of RAM.\n\n\"Open\" means the numbers that make up the model are published. You can run them\nwith no account, no network, no bill. Chapter 2 does exactly that.\n\n### How this guide works\n\nEvery chapter from here on has two columns. **Teach** (left) explains what a thing\nis and why it exists, in plain words. **Do** (right) is the exact command to type,\nwhat you should see, and what to do if you do not see it. Every chapter ends with\none command that proves you finished.\n\nYou never need a later chapter to do an earlier one. If you stop after chapter 3 you\nhave a working local brain you can talk to, and that is a fine place to stop.\n\nWHAT YOU LEARNED\n\n- An agent is a program that can take actions, not just answer.\n- A brain is the model behind it; Bonsai and our 8B orchestrator model are ours and they are open.\n- \"aw\" means Aither World - every brick name is a phrase: awdk is Aither World Dev Kit.",
4
4
  "category": "guide",
5
- "description": "Chapter 0 of 9 -- What Aitherium, AitherOS and the aw* bricks are - in plain words, before you install anything.\n\nAbout 5 minutes. Read online: https://aitherium.github.io/awknowledge/path/00-welcome.html",
5
+ "description": "Chapter 0 of 10 -- What Aitherium, AitherOS and the aw* bricks are - in plain words, before you install anything.\n\nAbout 5 minutes. Read online: https://aitherium.github.io/awknowledge/path/00-welcome.html",
6
6
  "see_also": [
7
7
  "awknowledge",
8
8
  "awdk",
@@ -2,7 +2,7 @@
2
2
  "adopt": null,
3
3
  "body": "### What you are installing\n\n**awdk** — *Aither World Dev Kit* — is one program with many verbs. Everything in\nthis guide runs through it: starting a brain (`adk quickstart-local`), chatting\n(`adk chat`), building an agent (`adk init`), installing packs (`adk install`). One\ninstall, and the rest of the chapters are verbs of the same command.\n\nThe command is called `adk`. Short for *agent dev kit*; it is the same thing.\n\n### What \"pip\" is\n\nMost of the kit is written in Python, and `pip` is Python's installer — the way\n`apt` installs on Ubuntu or the App Store installs on a phone. `pip install awdk`\ndownloads the kit from PyPI (the public Python package index) and puts `adk` on your\nPATH, which is the list of folders your terminal searches when you type a command.\n\nThat last part matters: a terminal reads PATH when it *opens*. If `adk` is \"not\nfound\" right after installing, the window you are in is simply older than the\ninstall. Open a new one.\n\n### What the wizard does\n\n`adk wizard` asks a handful of questions and writes one small config folder in your\nhome directory, `~/.aither/`. Pressing Enter accepts every default, and the defaults\nare right for this guide. It changes nothing else on your machine.\n\n### What the doctor does\n\n`adk doctor` is a list of checks, one per line, each ending in **OK**, **WARN** or\n**FAIL**. It does not guess; it tries the thing and reports. Any time something is\nodd later in the guide, this is the first command to run. A **WARN** about not being\nlogged in is expected — we do that in chapter 3, and only if you want to.\n\nDO\n\n1. $ pip install awdk\n you should see: Successfully installed awdk\n if not: If `pip` is not found, install Python from python.org first (tick 'Add to PATH'), then open a NEW terminal and try again - or use one of the two one-liners below, which install Python for you.\n2. (optional) $ curl -fsSL https://aitherium.com/install.sh | sh\n you should see: macOS / Linux only - the installer walks through Python, the kit and a first check\n if not: Skip this if `pip install awdk` already worked; it is the same kit.\n3. (optional) $ irm https://aitherium.com/install.ps1 | iex\n you should see: Windows only (PowerShell) - the same installer\n if not: Skip this if `pip install awdk` already worked.\n4. $ adk wizard\n you should see: a short questionnaire; answer with Enter to accept the defaults\n if not: If `adk` is not found, close the terminal and open a new one - the install changed your PATH and the old window does not know.\n5. $ adk doctor\n you should see: every line ends in OK (a WARN about a cloud login is fine - we have not logged in yet)\n if not: Read the first line that is not OK; it names the fix. Nothing below it matters until that one is green.\n\ndone when: $ adk doctor\n you should see: no FAIL lines\n\nWHAT YOU LEARNED\n\n- pip installs Python programs; awdk is one.\n- The wizard writes a small config in your home folder (~/.aither/). Nothing else changes.\n- `adk doctor` is the question you ask whenever something is odd: it checks, it does not guess.",
4
4
  "category": "guide",
5
- "description": "Chapter 1 of 9 -- One command puts the whole kit on your machine. Then you check it worked.\n\nAbout 10 minutes. Read online: https://aitherium.github.io/awknowledge/path/01-install-awdk.html",
5
+ "description": "Chapter 1 of 10 -- One command puts the whole kit on your machine. Then you check it worked.\n\nAbout 10 minutes. Read online: https://aitherium.github.io/awknowledge/path/01-install-awdk.html",
6
6
  "see_also": [
7
7
  "awdk",
8
8
  "guide-02"
@@ -2,7 +2,7 @@
2
2
  "adopt": null,
3
3
  "body": "### What a model is\n\nA language model is a very large file of numbers — billions of them — and a\nprogram that uses those numbers to turn text in into text out. That is the whole\nthing. When people say \"the AI\", they mean the numbers plus the program that runs\nthem. Running it is called **serving**: the program loads the file into memory and\nwaits on a port (a numbered door on your machine) for questions.\n\nThink of a vinyl record and a turntable. The record is the model; the turntable is\nthe server; the music only exists while both are together. The record is useless on\nits own, and the turntable plays whatever you put on it.\n\n### What \"8B\" means\n\n\"8B\" is eight billion numbers. Each number normally takes 16 bits, so an 8B model is\nabout 16 GB — too big for most laptops' memory. **Quantization** stores each number\nin fewer bits. At 4 bits the same model is ~4.5 GB and almost as good. At **1 bit** —\nwhich is what Bonsai does — a 27-billion-number model fits in 3.8 GB and runs on a\nplain CPU with 8 GB of RAM.\n\nFewer bits is a trade: smaller and faster, very slightly less precise. The kit picks\nthe trade that fits your machine, so you do not have to.\n\n### The open model stack\n\nTwo families of brains are Aitherium's own, and both are open:\n\n- **The orchestrator model** — the open 8-billion-parameter brain the platform itself runs\n on. This is the one `adk quickstart-local` downloads for you (an openly published\n GGUF file, quantized to fit your RAM).\n- **Bonsai** — the 1-bit family from PrismML. Bonsai-27B is the \"big brain in a tiny\n box\" option, and because 1-bit files need a special version of the server, the kit\n ships it as a container (`adk bonsai-local`, optional below).\n\nOpen means: the file is public, you can download it, and nothing about it phones\nhome. Unplug your network after this chapter — it still answers.\n\n### What `quickstart-local` does, step by step\n\nIt prints five steps as it goes:\n\n1. **Detects your hardware** — CPU or GPU, how much memory.\n2. **Picks a backend** — the program that will serve the model: plain `llama.cpp`\n on a CPU (no dependencies), Ollama if you already have it, vLLM on an NVIDIA card\n with Docker.\n3. **Installs it** and downloads a model sized for you. This is the slow step.\n4. **Verifies** it by asking the model a question and checking an answer comes back.\n A failed check fails the command — \"quickstart\" means *proven working*.\n5. **Registers** the brain with the kit, so every later chapter can find it.\n\nDO\n\n1. $ adk quickstart-local\n you should see: five numbered steps, [1/5] Detecting hardware... through [5/5], then `Config saved:` and an endpoint such as http://localhost:8200/v1\n if not: Each step prints what it is doing. If step 3 fails to download, check your disk has 6 GB free and run the same command again - the download resumes where it stopped.\n2. (optional) $ adk bonsai-local\n you should see: Starting Bonsai-27B ... and a healthy endpoint on port 8090. If the container image is not on your machine yet, it BUILDS it first from PrismML's public sources - a 3.8 GB download plus a compile, up to ~40 minutes once, seconds ever after.\n if not: This one needs Docker Desktop and the Bonsai container image. Without them, skip - the brain from the previous step is already running. Bonsai is explained on the left; you can come back for it.\n\ndone when: $ adk backend status\n you should see: Backend: llamacpp (or ollama / vllm) and Endpoint: http://localhost:... - the brain the kit will use from now on\n\nWHAT YOU LEARNED\n\n- A model is a file of numbers; the server loads it and answers requests on a port.\n- \"8B\" is eight billion of those numbers; quantization stores each in fewer bits so it fits in less memory.\n- The brain is now on YOUR machine. Unplug the network - it still answers.",
4
4
  "category": "guide",
5
- "description": "Chapter 2 of 9 -- Run an open model on your own computer, offline. Learn what \"8B\" and \"1-bit\" actually mean.\n\nAbout 20 minutes. Read online: https://aitherium.github.io/awknowledge/path/02-first-brain.html",
5
+ "description": "Chapter 2 of 10 -- Run an open model on your own computer, offline. Learn what \"8B\" and \"1-bit\" actually mean.\n\nAbout 20 minutes. Read online: https://aitherium.github.io/awknowledge/path/02-first-brain.html",
6
6
  "see_also": [
7
7
  "awdk",
8
8
  "guide-03"
@@ -2,7 +2,7 @@
2
2
  "adopt": null,
3
3
  "body": "### A prompt is a request, not a command\n\nWhen you type to a brain you are not giving an instruction a computer obeys; you\nare handing over a request it interprets. Two things follow. First, *how* you ask\nchanges what comes back — a vague question gets a vague answer, and \"explain it\nlike I have never seen a terminal\" genuinely works. Second, the brain knows only\nwhat it was given: the model file and your message. It cannot see your files,\nyour calendar, or the time unless something hands those to it. Chapter 4 is\nabout handing things to it — that is what tools are.\n\n### Two ways to talk\n\n**One question.** `adk backend test` sends a single fixed prompt to whatever brain\nthe kit is pointed at and prints the reply with the provider, the model and a\ntoken count. It is the smoke detector: if this says `Status: OK`, everything\nabove it in the stack is fine.\n\n**A conversation.** `adk start` opens a chat. Run it inside a folder and it also\nreads that folder — Python files get indexed — so you can ask \"what does this\nproject do?\" and get an answer grounded in what is actually there. The banner at\nthe top tells you which brain it found. Type `/quit` to leave.\n\n### Local or cloud is per task, not forever\n\nEverything so far runs on your machine with no account. Aitherium also hosts\nbigger brains, and `adk login` connects you to them. It is optional in this\nguide, and it stays optional: every later chapter works offline.\n\nIf you do log in, notice what does *not* happen: you never type a password into\nthe terminal. The kit prints a short code and a web address; you open the page,\ntype the code, and come back. That is a **device code** login — the same thing a\nTV does when you sign in to a streaming app — and it means the terminal never\nholds your password at all.\n\n`adk whoami` tells you which state you are in. Both answers are fine.\n\nDO\n\n1. $ adk backend test\n you should see: Provider: ..., a one-line Response: from your brain, and Status: OK\n if not: If it says FAILED, the brain from chapter 2 is not running. `adk quickstart-local` again restarts it; `adk backend status` shows what the kit expects to find.\n2. $ adk start\n you should see: a small banner - Workspace, Directory, LLM: your local brain and its address - then a `You >` prompt. Type a question; type /quit to leave.\n if not: If the LLM line names the cloud or says nothing was found, the brain is down - see the step above. Run `adk start` inside any folder; it reads that folder so it can answer questions about it.\n3. (optional) $ adk login\n you should see: a short code and a URL; open the URL, type the code, come back - Logged in as ...\n if not: Logging in is optional. It connects you to hosted brains and your workspace. Stay local if you prefer - everything in the next chapters works offline too.\n4. (optional) $ adk whoami\n you should see: your account, or Not logged in\n if not: Both answers are fine. This just tells you which you are.\n\ndone when: $ adk backend test\n you should see: Status: OK\n\nWHAT YOU LEARNED\n\n- A prompt is a request; the brain's answer depends on what it was given, which is why chapter 4 gives it tools.\n- Local vs cloud is a choice you make per task, not once: `adk backend status` shows which is current.\n- Your login is a device code you type into a web page, never a password typed into a terminal.",
4
4
  "category": "guide",
5
- "description": "Chapter 3 of 9 -- Ask your brain one question, then open a chat. Optionally connect to the cloud for the bigger brains.\n\nAbout 15 minutes. Read online: https://aitherium.github.io/awknowledge/path/03-talk-to-it.html",
5
+ "description": "Chapter 3 of 10 -- Ask your brain one question, then open a chat. Optionally connect to the cloud for the bigger brains.\n\nAbout 15 minutes. Read online: https://aitherium.github.io/awknowledge/path/03-talk-to-it.html",
6
6
  "see_also": [
7
7
  "awdk",
8
8
  "guide-04"
@@ -2,7 +2,7 @@
2
2
  "adopt": null,
3
3
  "body": "### What makes an agent an agent\n\nA brain answers. An **agent** acts. The difference is tools: functions the brain\nis allowed to call, and a loop that lets it call one, look at the result, and\ndecide what to do next. Give a brain tools and a job, and it can check the time,\nread a file, search, send a message — and *then* answer.\n\nThink of a new employee. The brain is what they know; the tools are the badge,\nthe phone and the filing cabinet; the job is the one-page description you hand\nthem on day one. Chapter 3 was a conversation with someone who has no badge.\n\n### The three files\n\n`adk init` writes a folder with three files, and they are the whole agent:\n\n- **agent.py** — the agent itself: about twenty lines that create it, give it\n one tool, and ask it a question. Read it; it is shorter than this page.\n- **config.yaml** — its settings: a name (`identity`), which brain to use\n (`llm_backend: auto` means \"whatever chapter 2 set up\"), a port, and which\n packs to load.\n- **tools.py** — your own tools. Two examples are already there.\n\n### What a tool is\n\nA tool is an ordinary function with a decorator on top:\n\n```python\n@agent.tool\ndef hello(name: str) -> str:\n \"\"\"Greet someone by name.\"\"\"\n return f\"Hello, {name}!\"\n```\n\nThe decorator registers it with the brain, and the docstring is what the brain\nreads to decide *when* to use it — so write the docstring for the brain, not for\nyou. Nothing else changes: it is still a Python function you can call yourself.\n\n### Two ways to run it\n\n**Once.** `python agent.py` creates the agent, asks it the question written at\nthe bottom of the file, prints the reply, and exits. This is how you try a change.\n\n**As a service.** `adk run` keeps the agent listening on a port so other\nprograms can talk to it — the web, other agents, and the packs in chapter 5. You\ndo not need it yet; it is here so the word \"server\" is not a surprise later.\n\nDO\n\n1. $ adk init my-agent\n you should see: Created AitherADK project at my-agent/ with three files - agent.py (your agent), config.yaml (its settings), tools.py (its custom tools) - and Next steps\n if not: If it says the folder exists and is not empty, pick another name. init never overwrites.\n2. $ cd my-agent\n you should see: your prompt now shows the my-agent folder\n if not: The next commands must run inside the folder init created.\n3. $ python agent.py\n you should see: one greeting reply, printed by your agent - agent.py asks it to say hello, and the agent has a hello tool to do it with\n if not: If it cannot reach a brain, chapter 2's brain is down: `adk backend test` tells you. If `python` is not found, try `python3`.\n4. (optional) $ adk run\n you should see: Starting AitherADK server - identity: my-agent, port: 8080 - then it keeps running; press Ctrl+C to stop\n if not: If port 8080 is busy, `adk run --port 8081`. Running as a server is how other programs (and chapter 5's packs) talk to your agent; for now the direct run above is enough.\n\ndone when: $ python agent.py\n you should see: a reply from your agent\n\nWHAT YOU LEARNED\n\n- An agent is three files - the agent, its config, its tools - and config.yaml is the job description (which brain, which packs, what port).\n- A tool is an ordinary function with a decorator; the brain decides when to call it.\n- `python agent.py` runs it once; `adk run` keeps it serving so other things can reach it.",
4
4
  "category": "guide",
5
- "description": "Chapter 4 of 9 -- An agent is a brain plus tools plus a job. You will scaffold one in three files and watch it use a tool.\n\nAbout 30 minutes. Read online: https://aitherium.github.io/awknowledge/path/04-build-an-agent.html",
5
+ "description": "Chapter 4 of 10 -- An agent is a brain plus tools plus a job. You will scaffold one in three files and watch it use a tool.\n\nAbout 30 minutes. Read online: https://aitherium.github.io/awknowledge/path/04-build-an-agent.html",
6
6
  "see_also": [
7
7
  "awdk",
8
8
  "awskills",
@@ -2,7 +2,7 @@
2
2
  "adopt": null,
3
3
  "body": "### What a pack is\n\nA **pack** is an agent you did not write. Someone — maybe Aitherium, maybe another user — built a complete agent with brain settings, tools, and a job, and published it so you can have it in one line.\n\nYou already met packs: Bonsai in chapter 2 is a pack (it comes as a container), and the \"tools\" chapter 4 talks about are tools that packs bring with them.\n\n### The pack you will try\n\nOpenClaw is a research agent — it searches the web, gathers sources, cites them, and builds a knowledge graph so you can ask follow-up questions and it remembers context across them. Research agents without your own tools are useful, but the ones with tools are agents: they can *act* (search, retrieve, synthesize) instead of just guessing.\n\n### Where packs come from\n\nRight now, packs ship inside awdk. When you `pip install awdk`, you get a bundled catalog of packs — free ones like the Orchestrator, and paid tiers like Hydra (testing and QA). The packs live inside the kit.\n\nThe **awpack** public registry is being built. When it ships, this page will change to \"go to the marketplace, browse, pick one, install\". Until then, the bundled set is what you have.\n\n### The difference between packs and skills\n\nA **skill** is smaller — one procedure. Research a question, send an email, approve a decision. Skills live in **awskills** (https://aitherium.github.io/awskills/) and are used by agents to do specific jobs. A pack is a whole agent; a skill is one thing an agent can do. Think of a pack as a person and a skill as a technique that person knows.\n\nDO\n\n1. $ adk packs\n you should see: Available Agent Packs - a short table (analyst, claude-code, code-discipline, gobbonet, hermes, openclaw) and Install with: adk install pack:<name>\n if not: An empty table means the kit did not install completely. `pip install --force-reinstall awdk` restores the bundled packs.\n2. $ adk install pack:openclaw\n you should see: Installing openclaw... then Installed to: <a folder in your home directory> and Next steps\n if not: The name must match a row from `adk packs` exactly - `pack:openclaw`, lower case.\n3. $ adk run --agents openclaw\n you should see: Starting AitherADK fleet server - agents: openclaw, port: 8080 - the pack's agent is now serving; Ctrl+C stops it\n if not: If port 8080 is busy, add --port 8081. If it says the agent is unknown, the install step did not finish - read its last line.\n\ndone when: $ adk run --agents openclaw\n you should see: Starting AitherADK fleet server - agents: openclaw\n\nWHAT YOU LEARNED\n\n- A pack is an agent in a box - brain settings, tools, skills - that installs in one command.\n- Packs ship inside awdk today; the public pack registry (awpack) is being built, and this page says so until it is not.\n- Skills are smaller than packs - one procedure each - and live in awskills.",
4
4
  "category": "guide",
5
- "description": "Chapter 5 of 9 -- Someone already built the agent you want. Find it, install it, run it - and know what is still coming.\n\nAbout 15 minutes. Read online: https://aitherium.github.io/awknowledge/path/05-agent-packs.html",
5
+ "description": "Chapter 5 of 10 -- Someone already built the agent you want. Find it, install it, run it - and know what is still coming.\n\nAbout 15 minutes. Read online: https://aitherium.github.io/awknowledge/path/05-agent-packs.html",
6
6
  "see_also": [
7
7
  "awdk",
8
8
  "awskills",
@@ -2,7 +2,7 @@
2
2
  "adopt": null,
3
3
  "body": "### How the kit picks a brain for your machine\n\nChapter 2 ran a brain on your CPU or GPU. But how did the kit know which one you had? And how big a model is safe for your RAM?\n\nThe kit **measures your hardware** — how much RAM, whether you have a GPU, whether Docker is running — and picks a model and a backend that fit. An 8B model needs at least 8 GB of RAM (or VRAM); Bonsai's 1-bit family fits in less. vLLM on NVIDIA is faster than llama.cpp on a CPU. The kit makes that choice so you do not have to know the numbers.\n\n### Model size and memory\n\nA **model** is numbers — weights. An \"8B model\" has 8 billion of them. A 4-bit quantization stores each in 4 bits instead of 32, so it fits in 8× less memory. This is why quantization exists: the same brain in a smaller space.\n\n- **The orchestrator model** is the open 8-billion-parameter brain the platform itself runs on. It is a good default.\n- **Bonsai** is the 1-bit family — Bonsai-27B is 27 billion parameters in 3.8 GB. It fits on a machine with 8 GB of RAM and runs on a CPU. It is the brain for tiny machines.\n\n### What a backend is\n\nA **backend** is the software that loads and runs a brain. llama.cpp runs models on CPUs and small GPUs. vLLM runs them on NVIDIA with high throughput. Ollama is a middle ground — easy to use, a bit slower.\n\nRegistering a backend is what lets agents anywhere reach it. A brain nobody registered is a brain nobody can call. `adk backend status` tells you which brain the kit is pointed at. `adk up` registers this machine as a service.\n\nDO\n\n1. $ adk quickstart\n you should see: hardware detected, a recommended setup for it, and a running backend\n if not: On a machine with no GPU this is the same as chapter 2 and says so. On NVIDIA it offers vLLM if Docker is present.\n2. $ adk backend status\n you should see: Backend, Endpoint and Model - the brain the kit is currently pointed at\n if not: If it says not configured, chapter 2 did not finish - run `adk quickstart-local` first.\n3. (optional) $ adk up\n you should see: your agent deployed as a service on this box, enrolled with your workspace, a heartbeat every 60 s\n if not: Needs a login (chapter 3) and Docker. Without either, `adk run` from chapter 4 is the offline equivalent.\n\ndone when: $ adk backend status\n you should see: the backend you chose, with an Endpoint that answers\n\nWHAT YOU LEARNED\n\n- Model size must fit memory; the kit measures your RAM/VRAM and picks, it does not ask you to know.\n- Our open 8B orchestrator model is the brain the platform itself runs on; Bonsai is the 1-bit family for tiny machines.\n- Registering a backend is what lets agents anywhere use it - a brain nobody registered is a brain nobody can reach.",
4
4
  "category": "guide",
5
- "description": "Chapter 6 of 9 -- CPU or GPU, laptop or rack - how the open model stack picks a model for what you have, and how a brain gets registered.\n\nAbout 30 minutes. Read online: https://aitherium.github.io/awknowledge/path/06-your-own-hardware.html",
5
+ "description": "Chapter 6 of 10 -- CPU or GPU, laptop or rack - how the open model stack picks a model for what you have, and how a brain gets registered.\n\nAbout 30 minutes. Read online: https://aitherium.github.io/awknowledge/path/06-your-own-hardware.html",
6
6
  "see_also": [
7
7
  "awdk",
8
8
  "awnode",
@@ -2,7 +2,7 @@
2
2
  "adopt": null,
3
3
  "body": "### What \"immutable\" means\n\nAn immutable Linux is one where `/usr` — the folder containing all system software — cannot be changed at runtime. A traditional computer is like a notebook: you write in it, erase things, write over them. An immutable system is like a printed book: the words never change by hand, and the only way to make a new version is to print a new book and keep the old one.\n\nEvery time your agent runs code that changes the system — installs a package, updates a config, patches a binary — that change becomes a NEW IMAGE. You can compare the two, see exactly what changed, and if something went wrong you can `bootc rollback` back to the printed book you trusted.\n\n### Cloud-init makes key-only login actually usable\n\nAn awnix machine has NO PASSWORD. Access is by SSH key only. You might think that sounds impossible — what if you lose the key? The answer is **cloud-init**: a service that runs once on first boot and injects whatever SSH keys you tell it to. On a cloud image you launched, your launch keypair arrives automatically. On bare metal you place a key yourself. Either way, nobody ever types a password, which means there is nothing to leak.\n\nTwo things must be true together or the whole idea breaks:\n- **cloud-init** must run and inject the key\n- **NOPASSWD sudo** must be enabled, so the account can administer the box without a password (the same setup `ec2-user` and `ubuntu` use)\n\n### What bootc does\n\n**bootc** — the *bootable container* system — moves a container image from `podman run` to bare metal. You build an image on your laptop, push it to a registry, and a machine boots it directly. Every boot is atomic: the system either completes or rolls back, never a partial state. An update that goes wrong is `bootc rollback`, not an afternoon of recovery.\n\n### The aw tools are preinstalled\n\nawnix ships 19 of the `aw*` tools ready to import: awgit (leases), awgraph (call graphs), awrelay (messaging), awseal (signing), and 15 others. Your agent does not have to install them — they are already there. That is the point of a base image: the guarantees are built in, and every agent on top gets them for free.\n\n### Layering an agent on top\n\nAn agent is three things:\n- The awnix base (immutable, atomic updates, built-in tools)\n- awdk — the agent runtime\n- Your skills, packs and credentials\n\nA Dockerfile that layers on top looks like:\n\n```dockerfile\nFROM awnix:latest\nRUN pip3 install --no-cache-dir awdk\n#... your packs and credentials\n```\n\nThe base is read-only. Your agent runs as a service (using the unit template in the awnix repo), and when it needs a new version, you rebuild the image and `bootc upgrade`.\n\nDO\n\n1. $ git clone https://github.com/Aitherium/awnix\n you should see: a folder named awnix with a Containerfile inside\n if not: Install git (git-scm.com) and open a new terminal.\n2. $ cd awnix\n you should see: your prompt shows the awnix folder; the build below runs here\n if not: The Containerfile is in this folder; the build must run from inside it.\n3. $ podman build -t awnix:latest -f Containerfile .\n you should see: an image named awnix:latest, built from the awnix repo you cloned\n if not: Install podman (or Docker - `docker build` works the same). Clone https://github.com/Aitherium/awnix first and run this inside it.\n4. $ podman run --rm awnix:latest awgit --version\n you should see: a version - proof the aw* tools are preinstalled in the base\n if not: If the command is not found inside the image, the build used a different Containerfile. Rebuild from the repo root.\n5. (optional) $ bootc status\n you should see: on a machine BOOTED from the image: the running image and the rollback target\n if not: Only meaningful on a box that booted from awnix (the ISO or a cloud image). Inside a container it is absent, and that is expected.\n\ndone when: $ podman run --rm awnix:latest awgit --version\n you should see: a version string\n\nWHAT YOU LEARNED\n\n- Immutable means /usr cannot change at runtime; every change is a new image you can diff and roll back.\n- No password exists on the box; keys only. NOPASSWD sudo is what makes key-only login usable.\n- Your agent layers ON TOP (FROM awnix, pip install awdk, add your pack) - the guarantees stay in the base.",
4
4
  "category": "guide",
5
- "description": "Chapter 7 of 9 -- An immutable Linux built for machines where software writes software. Your agent becomes three lines in a Dockerfile.\n\nAbout 45 minutes. Read online: https://aitherium.github.io/awknowledge/path/07-deploy-on-awnix.html",
5
+ "description": "Chapter 7 of 10 -- An immutable Linux built for machines where software writes software. Your agent becomes three lines in a Dockerfile.\n\nAbout 45 minutes. Read online: https://aitherium.github.io/awknowledge/path/07-deploy-on-awnix.html",
6
6
  "see_also": [
7
7
  "awnix",
8
8
  "awdk",
@@ -2,7 +2,7 @@
2
2
  "adopt": null,
3
3
  "body": "### Two agents, one file\n\nWhen two agents edit the same code, they can overwrite each other's work. Git tracks which *lines* changed, but it doesn't know that agent A is editing a function and agent B is reindenting it — it just sees lines moving, and when both agents commit their changes, the merge becomes a puzzle Git cannot solve alone. A **lease** stops this: before you edit a file, you claim it for a time period. If someone else holds the lease, you know to stay out; if you crash, the lease expires and the file becomes editable again.\n\n### Looking without reading everything\n\nAn agent needs to know who calls a function, what it calls, and what tests cover it — the relationships that decide which files matter to a change. A **call graph** indexes the repository by parsing it into symbols, calls, and callers, so you can answer \"who calls main\" without reading every file that matches the name. The index is built once and cached on your machine, not downloaded.\n\n### Talking through a channel\n\nAn agent that finds a bug has nowhere to tell another agent except its own transcript, which nobody reads. A **relay** is a chat channel a human can read, where agents leave findings, alerts and coordination messages in a format humans can read and agents can parse. Because the channel is durable and searchable, a decision made there is not relitigated when the next agent hits the same symptom.\n\n### Learning without re-learning\n\nMemory lets an agent record something it learned — a recipe, a decision, a measurement — so the next agent doesn't have to re-derive it. **awm** stores it in scopes so an agent's learning stays in the right context: a project-level recipe is not written to the platform, and your personal preferences do not crowd out shared ones.\n\nDO\n\n1. $ pip install awgit awgraph awrelay awm\n you should see: four packages installed\n if not: Install them one at a time to see which fails; each is independent.\n2. $ awgit lease acquire README.md\n you should see: a lease on the file, with its holder and expiry\n if not: Run it inside a git repository. A lease is about a file in a repo.\n3. $ awgraph query \"who calls main\"\n you should see: a list of callers, or 'no index yet' with the command to build one\n if not: Build the index first with the command it prints; the graph is derived from your code, not downloaded.\n4. $ awrelay send \"#general\" \"hello from the guide\" --kind note\n you should see: message delivered, with a channel and an id\n if not: awrelay needs a relay endpoint (your own, or the hosted one after chapter 3's login). The error names which is missing.\n\ndone when: $ awgit lease list\n you should see: the lease you took, still held\n\nWHAT YOU LEARNED\n\n- A lease says \"I am editing this\"; it expires, so a crashed agent cannot hold a file forever.\n- A call graph answers \"who calls this\" without reading everything.\n- Messages between agents go through a channel a human can read too - that is how decisions stop being relitigated.\n- The laws (Reference > Laws) are WHY each of these exists: every one was a real failure first.",
4
4
  "category": "guide",
5
- "description": "Chapter 8 of 9 -- Two agents editing the same code without sweeping each other's work - leases, a call graph, messaging, memory.\n\nAbout 30 minutes. Read online: https://aitherium.github.io/awknowledge/path/08-many-agents.html",
5
+ "description": "Chapter 8 of 10 -- Two agents editing the same code without sweeping each other's work - leases, a call graph, messaging, memory.\n\nAbout 30 minutes. Read online: https://aitherium.github.io/awknowledge/path/08-many-agents.html",
6
6
  "see_also": [
7
7
  "awgit",
8
8
  "awgraph",
@@ -2,9 +2,10 @@
2
2
  "adopt": null,
3
3
  "body": "### The shell's one answer\n\nA shell has exactly one response to a line it doesn't recognize: `command not found`. So every time you want to look something up — what is the hash of this commit, what does this API need, how does time work on this machine — you leave the terminal and reach for a browser, losing the directory, the environment and the session you were in. The omnibox makes that line reach an agent instead, so you stay.\n\n### It is a hook, not a new shell\n\nThis is not a new shell language. It is a **hook** that installs into your existing shell — PowerShell, bash or zsh — so your terminal stays your terminal. Your directory, your environment variables, your history, the session you are in: they are all still there. The omnibox just intercepts the moment before `command not found` and asks an agent instead.\n\n### Scripts stay silent\n\nEvery script tests whether a tool is installed by running `get-command <name>` or `which <name>`. Without a guard, every test would fire an agent request, invisibly, and those requests would be billed. So the hook fires only on lines a human types at the prompt — not on probes made from inside a script or function. A tool check returns `command not found` the normal way; your question typed at the prompt gets an answer.\n\nDO\n\n1. $ npm i -g @aitherium/awsh\n you should see: awsh and aither on your PATH\n if not: Needs Node.js (nodejs.org, LTS). Open a new terminal after installing it.\n2. $ awsh init\n you should see: 'installed in <your shell profile>' - it works in PowerShell, bash and zsh\n if not: If it says the profile is not writable, it prints the exact line to add by hand. That line is the whole feature.\n3. $ awsh doctor\n you should see: a measured miss time well under the budget it prints\n if not: A slow miss names the PATH entry causing it (usually a huge directory on PSModulePath). Remove that entry; it is costing every typo a minute.\n4. type what time is it\n you should see: an answer, where 'command not found' used to be\n if not: Open a NEW terminal - the hook installs into the profile, and the profile loads at start.\n\ndone when: $ awsh doctor\n you should see: omnibox OK\n\nWHAT YOU LEARNED\n\n- The shell has exactly one response to a line it does not know; now that line reaches an agent instead.\n- It is a shell hook (CommandNotFound), not a new shell - your terminal, your directory, your environment.\n- Probes made by scripts are ignored on purpose; only what a human types at the prompt is answered.",
4
4
  "category": "guide",
5
- "description": "Chapter 9 of 9 -- Your terminal answers you. Type a question where a command would go.\n\nAbout 10 minutes. Read online: https://aitherium.github.io/awknowledge/path/09-omnibox.html",
5
+ "description": "Chapter 9 of 10 -- Your terminal answers you. Type a question where a command would go.\n\nAbout 10 minutes. Read online: https://aitherium.github.io/awknowledge/path/09-omnibox.html",
6
6
  "see_also": [
7
- "awsh"
7
+ "awsh",
8
+ "guide-10"
8
9
  ],
9
10
  "slug": "09-omnibox",
10
11
  "status": "published",
@@ -0,0 +1,13 @@
1
+ {
2
+ "adopt": null,
3
+ "body": "### A pack is a folder\n\nIn chapter 5 you installed a pack someone else built. This chapter is the other side: you\nwrite one. A **tool pack** is an ordinary folder with three things in it:\n\n- `.toolpack.yaml` — the manifest: an id, a version, a one-line description\n- `__init__.py` — a `register(registry)` function that hands your tools to the agent\n- `tools.py` — the tools themselves, plain Python functions\n\nThe docstring and the type hints of each function ARE what the agent reads to decide when to\ncall it, so write them for the model: say what the tool returns and when it is the right one.\n\n### Your id is your namespace\n\nPack ids look like `yourname.weather`. The part before the dot is yours; names that start\nwith `aither` or `adk` belong to the platform and are refused, so a community pack can never\nshadow one the platform ships.\n\n### Four verbs, one loop\n\n`adk pack` has four author verbs, and each one answers a single question:\n\n| verb | question it answers |\n|---|---|\n| `new` | what does a working pack look like? |\n| `validate` | is the folder correct — without running any of its code? |\n| `dev` | does it load the way an agent will load it, and which tools does it expose? |\n| `build` | what exact bytes am I publishing? |\n\n`validate` never imports your code, so you can run it safely on a pack you downloaded from\na stranger. It also looks for anything shaped like an API key and reports the file and line\nwithout printing the value. `dev` is the one step that runs your code, and it says so.\n\n### Reproducible bytes\n\n`build` writes a `.tar.gz` and its sha256. The archive has sorted entries and zeroed\ntimestamps, so the same source always produces the same bytes. Anyone who rebuilds your\ntagged source gets your digest, which is how a stranger can trust a pack they did not write.\n\nDO\n\n1. $ adk pack new yourname.weather\n you should see: created <path>/yourname.weather, then the next two commands to run\n if not: If it says the id is reserved, use a namespace of your own, like your GitHub handle.\n2. $ adk pack validate yourname.weather\n you should see: OK yourname.weather 0.1.0 ... all clean\n if not: Each PKA code names the file or field to fix. Fix it and run validate again.\n3. $ adk pack dev yourname.weather\n you should see: OK yourname.weather: 1 tool(s) registered - weather_echo\n if not: 0 tools means TOOL_NAMES in __init__.py does not name the functions in tools.py.\n4. $ adk pack build yourname.weather\n you should see: built <path>/yourname.weather-0.1.0.tar.gz and a sha256\n if not: build refuses a pack that does not validate - run validate and fix what it lists.\n\ndone when: $ adk pack validate yourname.weather\n you should see: OK yourname.weather 0.1.0\n\nWHAT YOU LEARNED\n\n- A tool pack is a folder - a manifest, a register() function and plain Python tools.\n- validate never runs the pack's code; dev is the one step that does, and it loads the pack exactly as an agent will.\n- build is reproducible, so a digest you publish can be checked by anyone who rebuilds your source.",
4
+ "category": "guide",
5
+ "description": "Chapter 10 of 10 -- Write a tool pack, check it without running it, load it the way an agent will, and build bytes anyone can verify.\n\nAbout 20 minutes. Read online: https://aitherium.github.io/awknowledge/path/10-build-a-pack.html",
6
+ "see_also": [
7
+ "awdk"
8
+ ],
9
+ "slug": "10-build-a-pack",
10
+ "status": "published",
11
+ "synopsis": "Build a pack",
12
+ "topic": "guide-10"
13
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "adopt": "awkno guide 1 # start at chapter 1; `awkno open guide` for the browser",
3
- "body": "guide-00 Welcome to Aither World (~5 min)\nguide-01 Install awdk (~10 min)\nguide-02 Your first local brain (~20 min)\nguide-03 Talk to it (~15 min)\nguide-04 Build your first agent (~30 min)\nguide-05 Agent packs (~15 min)\nguide-06 Your own hardware (~30 min)\nguide-07 Deploy on awnix (~45 min)\nguide-08 Many agents, one repo (~30 min)\nguide-09 The omnibox (~10 min)",
3
+ "body": "guide-00 Welcome to Aither World (~5 min)\nguide-01 Install awdk (~10 min)\nguide-02 Your first local brain (~20 min)\nguide-03 Talk to it (~15 min)\nguide-04 Build your first agent (~30 min)\nguide-05 Agent packs (~15 min)\nguide-06 Your own hardware (~30 min)\nguide-07 Deploy on awnix (~45 min)\nguide-08 Many agents, one repo (~30 min)\nguide-09 The omnibox (~10 min)\nguide-10 Build a pack (~20 min)",
4
4
  "category": "guide",
5
5
  "description": "From \"what is an agent?\" to a terminal that answers you - one path, nothing skipped.\n\nOnline: https://aitherium.github.io/awknowledge/",
6
6
  "see_also": [
@@ -13,7 +13,8 @@
13
13
  "guide-06",
14
14
  "guide-07",
15
15
  "guide-08",
16
- "guide-09"
16
+ "guide-09",
17
+ "guide-10"
17
18
  ],
18
19
  "slug": null,
19
20
  "status": "published",
@@ -0,0 +1,11 @@
1
+ {
2
+ "adopt": null,
3
+ "body": "*Part VI · Configuration*\n\n**Fires when:** you grant an agent a permission, a sanction or a mode by writing a key into\na settings file; when a harness offers several settings layers (managed, user, project,\nlocal) and you pick the one closest to the work.\n\n## The law\n\nLayered settings are not one namespace. Each key is read from the layers the harness\nchooses for it, and a key written anywhere else is **silently ignored** — no warning, no\nerror, the file still parses, and the agent behaves exactly as if you had never written it.\n\nThe keys that matter most are the ones most likely to be scoped away: anything that widens\nwhat an agent may do. Claude Code reads its `autoMode` block **only** from user or managed\nsettings. The same block in project or local settings is dead, and it looks alive because\nit sits next to keys (permissions, hooks) that the project layer *does* honour.\n\n## The check\n\n- For every sanction-shaped key, record which layers the harness reads it from, and assert\n that the key lives in one of them. A check that parses the file is not enough — it must\n know the layer.\n- Prove it from behaviour, once: set the key, start a fresh session, and observe the\n change. A key you cannot observe taking effect is a key you have not set.\n- When a key moves layers, delete the dead copy. Two copies, one live and one ignored,\n is how the next reader edits the wrong one.",
4
+ "category": "law",
5
+ "description": "Law #25",
6
+ "see_also": null,
7
+ "slug": "a-setting-in-a-scope-nobody-reads-does-not-exist",
8
+ "status": "published",
9
+ "synopsis": "A setting in a scope nobody reads does not exist — know which layer the harness honours",
10
+ "topic": "law-25"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "adopt": null,
3
+ "body": "*Part VII · Scaling*\n\n**Fires when:** you wire a hook that runs before or after every tool call, every shell\ncommand or every prompt; when an agent session \"feels slow\" and nothing is obviously busy.\n\n## The law\n\nA hook that fires on every call is paid on every call, serially, for the life of every\nsession. Its cost is not \"small\" — it is its median latency multiplied by the number of\ncalls, and a busy agent makes thousands. Interpreter start-up and module imports dominate\nthat cost long before the hook's own logic runs.\n\nSo the shape is fixed: **decide whether the call concerns you before you import anything.**\nRead the event, match it against a cheap string or pattern test, and exit immediately on\nthe common case. Only the rare call that matches pays for the heavy path.\n\n## The check\n\n- Measure the median and the tail (p95) in milliseconds for the no-match path and the match\n path separately, on real events, and write both numbers down beside the hook.\n- Give the no-match path a budget and a test that fails when a new top-level import\n pushes it over. Imports creep; a budget nobody asserts creeps with them.\n- Several hooks on the same event are one budget, not several. Merge them behind one\n prefilter rather than paying start-up once per hook.",
4
+ "category": "law",
5
+ "description": "Law #26",
6
+ "see_also": null,
7
+ "slug": "a-hook-on-every-call-spends-a-latency-budget",
8
+ "status": "published",
9
+ "synopsis": "A hook on every call spends a latency budget — prefilter before you import",
10
+ "topic": "law-26"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "adopt": null,
3
+ "body": "*Part V · Trust*\n\n**Fires when:** you add an allow rule, an auto-approve, a trusted path or any standing\ngrant an owner has given an agent; when you cannot answer \"what is this agent allowed to do\nwithout asking?\" by reading one file.\n\n## The law\n\nEvery standing grant widens what an agent may do unobserved. If those grants are spread\nacross several files, layers and tools, no one can read the agent's real authority, review\na change to it, or revoke it in one edit — and a grant added in the wrong layer may be\nsilently dead (law 25) while the owner believes it is live.\n\nKeep the owner's sanctions in **one file, in one layer the harness honours**, owned by the\nowner. Everything else — project files, synced presets, generated configs — may reference\nit but never add to it.\n\n## The check\n\n- A checker lists every place a grant-shaped key appears and fails when one appears\n outside the sanction file.\n- The sanction file is never written by an automated sync or an agent's own edit; a change\n to it is an owner action with a visible diff.\n- Revocation is one edit. If removing a grant needs a search, the grants are scattered.",
4
+ "category": "law",
5
+ "description": "Law #27",
6
+ "see_also": null,
7
+ "slug": "one-sanction-file-never-scattered",
8
+ "status": "published",
9
+ "synopsis": "One sanction file, never scattered — the owner's grants live in one place",
10
+ "topic": "law-27"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "adopt": null,
3
+ "body": "*Part V · Trust*\n\n**Fires when:** you write a sync, an export, a mirror or a publish step that filters out\nsensitive keys, paths or content on the way out.\n\n## The law\n\nA filter that removes secrets, sanctions or machine-local state when **pushing** protects\nonly the machine it runs on. The same sync **pulling** from a shared store will happily\nwrite whatever that store holds — a hand-edited file, an older client that never filtered,\nan attacker who can write the store. The dangerous key arrives through the door you\nthought you had closed.\n\nIf a key is unsafe to send, it is unsafe to receive. Enforce the rule on both edges with\nthe same list, and make the inbound edge **refuse loudly** rather than silently drop, so a\npoisoned store is seen instead of papered over.\n\n## The check\n\n- One denylist, imported by both the push and the pull path — never two copies.\n- A test that plants each denied key in the shared store and asserts the pull refuses it,\n alongside the test that asserts the push strips it.\n- The pull's refusal names the key (never its value) and exits non-zero.",
4
+ "category": "law",
5
+ "description": "Law #28",
6
+ "see_also": null,
7
+ "slug": "a-guard-in-one-direction-is-half-a-guard",
8
+ "status": "published",
9
+ "synopsis": "A guard in one direction is half a guard — refuse inbound what you strip outbound",
10
+ "topic": "law-28"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "adopt": null,
3
+ "body": "*Part VI · Configuration*\n\n**Fires when:** you package an agent setup for another machine or another person — a\nplugin, a settings preset, a dotfiles sync, a \"set it up the way I have it\" command.\n\n## The law\n\nAn agent setup is three different things that only look like one file:\n\n| kind | what it is | how it travels |\n|---|---|---|\n| **content** | skills, rules, hooks, commands, agents | a plugin or package — files, versioned |\n| **preferences** | model, voice, notifications, UI keys | a settings preset — merged into the user layer, never overwriting |\n| **machine-local** | credentials, tokens, absolute paths, and the environment an owner's sanctions describe | **never travels** |\n\nMixing them is how a shared preset ships a token, or an owner's description of their own\nenvironment becomes every recipient's standing grant. The sanction itself is trust the\nowner gave for one machine; copying it is granting it to a stranger.\n\n## The check\n\n- The export path has a denylist for machine-local keys and a scan for secret-shaped values\n and absolute paths; it fails on a hit rather than redacting silently.\n- The import path refuses the same keys (law 28).\n- A setup command applies content and preferences, then **asks** for anything machine-local\n instead of copying it.",
4
+ "category": "law",
5
+ "description": "Law #29",
6
+ "see_also": null,
7
+ "slug": "portable-is-files-and-presets-never-credentials",
8
+ "status": "published",
9
+ "synopsis": "Portable is files and presets, never credentials — split what travels from what stays",
10
+ "topic": "law-29"
11
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "adopt": null,
3
3
  "category": "stack",
4
- "description": "Owner directive 2026-09-21, the day Meta announced Muse: the same journey has to compose HERE from bricks a stranger can install -- a desk body (awdesk) that hosts the aitherium.com Living Desktop over the real desktop and embodies an agent as an avatar; the browser body (AitherConnect) that puts the same overlay over any page; a companion (awsprite) that grows a knowledge base from what its owner teaches it, remembered in awm, built and grown with awdk packs; self-service self-hosting (awnix / awnode / awsh) so the whole thing runs on the owner's own box; device registration through a front gate (awnboard + awiam); and tunnels between those devices that the PLATFORM cannot read. Every seam was measured, not assumed: awdesk already loads aitherium.com/?mode=overlay and reuses AitherConnect's overlay-mode protocol; awdesk registers a local MCP server so awsh/adk can drive it; device enrolment lives in the garg backend (`devices.py`) and the tenant node table (`/tunnel/tenant/{t}/nodes`). What did NOT hold on 2026-09-21: every tunnel enrolment path minted the device's WireGuard private key SERVER-SIDE and `_save_peers` persisted it to the vault, so the platform could read any device's tunnel -- fixed the same day (bring-your-own public key on every enrolment endpoint, device private keys never persisted; `test_tunnel_key_custody.py`). Owner-blind device-to-device tunnels already exist and are the DEFAULT: `adk join` (awdk/adk/commands/join.py) brings the node up on the headscale tailnet (`hs.aitherium.com`, /health 200 on 2026-09-21) with a mesh key minted by Identity -- node keys are generated on the device, traffic is peer-to-peer WireGuard, and the control plane sees public keys only. The AitherTunnel hub VPN is the lane for reaching platform services and dev workspaces; it terminates at the hub by design. Still `partial` because awsprite is `planned` and mobile chat is Discord-only.\n\nIncludes: awdesk, AitherConnect, awsprite, awdk, awm, awkno, awknowledge, awnboard, awiam, awtunnel, awnet, awnode, awnix, awsh",
4
+ "description": "Owner directive 2026-09-21, the day Meta announced Muse: the same journey has to compose HERE from bricks a stranger can install -- a desk body (awdesk) that hosts the aitherium.com Living Desktop over the real desktop and embodies an agent as an avatar; the browser body (AitherConnect) that puts the same overlay over any page; a companion (awsprite) that grows a knowledge base from what its owner teaches it, remembered in awm, built and grown with awdk packs; self-service self-hosting (awnix / awnode / awsh) so the whole thing runs on the owner's own box; device registration through a front gate (awnboard + awiam); and tunnels between those devices that the PLATFORM cannot read. Every seam was measured, not assumed: awdesk already loads aitherium.com/?mode=overlay and reuses AitherConnect's overlay-mode protocol; awdesk registers a local MCP server so awsh/adk can drive it; device enrolment lives in a tenant backend (`devices.py`) and the tenant node table (`/tunnel/tenant/{t}/nodes`). What did NOT hold on 2026-09-21: every tunnel enrolment path minted the device's WireGuard private key SERVER-SIDE and `_save_peers` persisted it to the vault, so the platform could read any device's tunnel -- fixed the same day (bring-your-own public key on every enrolment endpoint, device private keys never persisted; `test_tunnel_key_custody.py`). Owner-blind device-to-device tunnels already exist and are the DEFAULT: `adk join` (awdk/adk/commands/join.py) brings the node up on the headscale tailnet (`hs.aitherium.com`, /health 200 on 2026-09-21) with a mesh key minted by Identity -- node keys are generated on the device, traffic is peer-to-peer WireGuard, and the control plane sees public keys only. The AitherTunnel hub VPN is the lane for reaching platform services and dev workspaces; it terminates at the hub by design. Still `partial` because awsprite is `planned` and mobile chat is Discord-only.\n\nIncludes: awdesk, AitherConnect, awsprite, awdk, awm, awkno, awknowledge, awnboard, awiam, awtunnel, awnet, awnode, awnix, awsh",
5
5
  "see_also": [
6
6
  "awdesk",
7
7
  "AitherConnect",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: awkno
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: The man page for the Aither World — every brick, stack and law, in your terminal, offline.
5
5
  License: Apache-2.0
6
6
  Project-URL: Homepage, https://github.com/Aitherium/awkno
@@ -117,6 +117,7 @@ awkno/pages/guide-06.json
117
117
  awkno/pages/guide-07.json
118
118
  awkno/pages/guide-08.json
119
119
  awkno/pages/guide-09.json
120
+ awkno/pages/guide-10.json
120
121
  awkno/pages/guide.json
121
122
  awkno/pages/inference-commons.json
122
123
  awkno/pages/law-01.json
@@ -143,6 +144,11 @@ awkno/pages/law-21.json
143
144
  awkno/pages/law-22.json
144
145
  awkno/pages/law-23.json
145
146
  awkno/pages/law-24.json
147
+ awkno/pages/law-25.json
148
+ awkno/pages/law-26.json
149
+ awkno/pages/law-27.json
150
+ awkno/pages/law-28.json
151
+ awkno/pages/law-29.json
146
152
  awkno/pages/mediaforge.json
147
153
  awkno/pages/mine-what-you-ran.json
148
154
  awkno/pages/one-surface.json
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "awkno"
7
- version = "0.2.5"
7
+ version = "0.2.6"
8
8
  description = "The man page for the Aither World — every brick, stack and law, in your terminal, offline."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -304,10 +304,15 @@ class TestAwknoRegistry:
304
304
  # publish-time scan of the sdist — a detector's fixture becoming
305
305
  # the thing it detects.
306
306
  needle = "aitheros" + "-"
307
- # The public release tag `aitheros-v<semver>` shares the prefix
308
- # with fleet hostnames (`aitheros-genesis`) and is the one shape a
309
- # public install line is REQUIRED to name. Strip that shape, then
310
- # anything left is a hostname and a leak.
307
+ # Public release TAGS share this prefix with fleet hostnames, and a
308
+ # tag is the one shape a public install line is REQUIRED to name.
309
+ # Strip the tag shape (prefix + "v" + semver); anything still
310
+ # carrying the prefix is a hostname and a leak.
311
+ # Keep this comment free of literals: the sdist ships this file and
312
+ # the publish-time scanners read raw lines, so a comment naming the
313
+ # thing is the same finding as code naming it. Do not name a
314
+ # hostname, a tracker id, or a scanner's own rule id here -- each of
315
+ # those took this lane red in turn on 2026-09-22.
311
316
  import re as _re
312
317
  stripped = _re.sub(needle + r"v[0-9*][0-9a-z.*-]*", "", content.lower())
313
318
  assert needle not in stripped, f"Internal hostname prefix in {topic}"
@@ -368,10 +373,27 @@ class TestBrickUsage:
368
373
  assert "https://aitherium.github.io/awnix/" in page.description
369
374
 
370
375
  def test_no_public_brick_page_leaks_a_local_path(self):
371
- import re # noqa: PLC0415
376
+ # Import the pattern rather than restating it: spelled out here it would
377
+ # ship in the sdist and become a boundary finding itself, and two copies
378
+ # would drift.
379
+ from awkno.generate import LOCAL_PATH_RE # noqa: PLC0415
372
380
 
373
381
  reg = AwknoRegistry()
374
382
  bad = [t for t in reg.list_topics()
375
383
  if reg.get(t).category == "brick"
376
- and re.search(r"\b[A-Z]:[\\/]|AitherOS/|\.PRODUCTS|\.DEPLOYMENT", reg.get(t).description)]
384
+ and LOCAL_PATH_RE.search(reg.get(t).description)]
377
385
  assert not bad, bad
386
+
387
+
388
+ class TestHelpFlag:
389
+ """`awkno --help` / `-h` print usage and exit 0 (was exit 2, add_help=False)."""
390
+
391
+ @pytest.mark.parametrize("flag", ["--help", "-h"])
392
+ def test_help_exits_zero(self, flag, capsys):
393
+ from awkno.cli import _build_parser
394
+
395
+ with pytest.raises(SystemExit) as exc:
396
+ _build_parser().parse_args([flag])
397
+ assert exc.value.code == 0
398
+ out = capsys.readouterr().out
399
+ assert "awkno [TOPIC]" in out and "--apropos" in out
@@ -1,15 +0,0 @@
1
- {
2
- "adopt": null,
3
- "category": "stack",
4
- "description": "Owner directive 2026-08-24, reinforcing the existing `.PRODUCTS/.SPRITE/` Phase 2/3 roadmap (`AitherOS/dev/prompts/aithersprite-knowledge-companion-program.md`): AitherSprite today is playable but shallow -- flat per-sprite knowledge rows, titles-only in the talk prompt, server-side inference only, and \"download it\" is a paid pack with no guided path to actually WIRE it to real local tools and data. The directive is four upgrades composed together, and none of the four pieces is new -- the gap is that nothing connects them for this product: teaching should build a real personal knowledge GRAPH (`awgraph` is a CODE graph today -- CodeChunk/CodeGraph/CodeGraphStore -- and `awm` is scoped FACTS, not a traversable graph; a per-user knowledge graph does not exist as a brick yet); the companion should run and be TRAINABLE fully in-browser on `awbonsai`, not only through a server round trip; and graduating a companion should walk the owner through a real self-service CONNECT of `awdk` + `awsh` + `awnode` on their own machine -- the same shape as the `selfhost-bonsai` skill's stranger-to-provider flow, but ending in \"your companion can now use your files/tools\" instead of \"your GPU now serves the mesh\". NOT a rewrite of `lib/companion/AitherSprite.py` -- its deterministic engine (needs/mood/evolution, no I/O) is correct and stays the server-authoritative source of truth even for a browser-trained companion, so growth cannot be forged client-side (`security-review-patterns.md` #1: a fail-closed gate is not optional). What changes is WHERE teach/talk execute (in-tab via `awbonsai` when offline or pre-account, server via MicroScheduler when connected) and how knowledge is stored (a graph, not a flat table).\n\nIncludes: awsprite, awbonsai, awdk, awsh, awnode",
5
- "see_also": [
6
- "awsprite",
7
- "awbonsai",
8
- "awdk",
9
- "awsh",
10
- "awnode"
11
- ],
12
- "status": "planned",
13
- "synopsis": "Grow a companion in the browser, then take it home",
14
- "topic": "browser-companion-graduation"
15
- }
File without changes
File without changes
File without changes
File without changes
File without changes