mirror of
https://github.com/piabrota/mu.git
synced 2026-11-07 06:15:59 -10:00
Make mu the company chart: the eight products, the site's logo, む, adr-verbatim
- mu is piabrota's company chart, not an umbrella, and the README header is centred. - products/ holds pirsig, alerts, ihero, gramatico, nix-os, dojo, rax and agents. The yggdrasil and asgard submodules go; our forks of them stay in the index. - PIABROTA.md follows the org as it is now: 24 public repos. - The logo is the eye that piabrota.art shows. む is drawn in pure Nix, with nix-os' pen, and checked by the flake. - .claude/skills/adr-verbatim is copied unchanged from davidondrej/cloudroom, under Apache-2.0, with credit in NOTICE.md. - The map shows the eight products, and the portfolio figure goes. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
fd1d404c4f
commit
1a0f30f9af
47 files changed
+2215
-326
No files matched your search
@@ -0,0 +1,7 @@
|
||||
# Skills
|
||||
|
||||
Agent skills this repo vendors. Refresh a skill by copying upstream again, never by editing its body.
|
||||
|
||||
| Skill | Upstream | Licence |
|
||||
| --- | --- | --- |
|
||||
| [`adr-verbatim`](adr-verbatim/SKILL.md) | [davidondrej/cloudroom](https://github.com/davidondrej/cloudroom/blob/6f6cb7fd0665624c29fa4cbbed46d0dc7b1f9f84/skills/adr-verbatim/SKILL.md), by David Ondrej, copied unchanged at `6f6cb7f` | [Apache-2.0](../../LICENSES/Apache-2.0.txt) |
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: adr-verbatim
|
||||
description: 'Record concise ADRs that preserve the user''s decisions without conversational noise. Use for "adr-verbatim", "new ADR", "document that as an ADR", "record this decision", or supplied ADR wording.'
|
||||
---
|
||||
|
||||
# ADR Verbatim
|
||||
|
||||
Preserve the user's meaning, not the conversation transcript. Record only the decision and context needed to understand it.
|
||||
|
||||
## Steps
|
||||
|
||||
1. Extract the decision the user stated or approved in the conversation. Ask only if the decision is unclear; do not require him to dictate polished wording.
|
||||
2. Use the project's established ADR location, including a previously specified repository. Do not assume the current checkout owns the ADRs. Name the file by that directory's rule (check its README or AGENTS.md); if it has none, take the next number.
|
||||
3. Write a short, clear ADR. Remove filler, emotional reactions, repetition, rhetorical questions, and instructions to the agent. Fix grammar and clarify references without changing the meaning, scope, conditions, or priorities.
|
||||
4. Check every statement against the user's decision. Remove invented requirements and unapproved agent suggestions.
|
||||
5. Show the saved path and full ADR in a code block.
|
||||
|
||||
## Format
|
||||
|
||||
Match the directory's filenames, such as `docs/adr/0042-short-slug.md` or `docs/adr/20261030-175900-short-slug.md`. Use the file's ID in the heading.
|
||||
|
||||
```markdown
|
||||
# <ID> — short title
|
||||
|
||||
Status: accepted (<decision owner>, YYYY-MM-DD)
|
||||
|
||||
<The decision in plain English.>
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- Prefer a short paragraph or list. Add sections only when they improve clarity.
|
||||
- Do not add speculative rationale, alternatives, consequences, or implementation details.
|
||||
- Use exact wording only when the user explicitly asks for an exact quote or verbatim passage.
|
||||
- A changed decision needs a new ADR. Correct an existing ADR when the user explicitly requests it, without changing unrelated history.
|
||||
+24
-6
@@ -1,9 +1,27 @@
|
||||
[submodule "products/yggdrasil"]
|
||||
path = products/yggdrasil
|
||||
url = https://github.com/piabrota/yggdrasil.git
|
||||
[submodule "products/asgard"]
|
||||
path = products/asgard
|
||||
url = https://github.com/piabrota/asgard.git
|
||||
[submodule "forks/archify"]
|
||||
path = forks/archify
|
||||
url = https://github.com/piabrota/archify.git
|
||||
[submodule "products/pirsig"]
|
||||
path = products/pirsig
|
||||
url = https://github.com/piabrota/pirsig.git
|
||||
[submodule "products/alerts"]
|
||||
path = products/alerts
|
||||
url = https://github.com/piabrota/alerts.git
|
||||
[submodule "products/ihero"]
|
||||
path = products/ihero
|
||||
url = https://github.com/piabrota/ihero.git
|
||||
[submodule "products/gramatico"]
|
||||
path = products/gramatico
|
||||
url = https://github.com/piabrota/gramatico.git
|
||||
[submodule "products/nix-os"]
|
||||
path = products/nix-os
|
||||
url = https://github.com/piabrota/nix-os.git
|
||||
[submodule "products/dojo"]
|
||||
path = products/dojo
|
||||
url = https://github.com/piabrota/dojo.git
|
||||
[submodule "products/rax"]
|
||||
path = products/rax
|
||||
url = https://github.com/piabrota/rax.git
|
||||
[submodule "products/agents"]
|
||||
path = products/agents
|
||||
url = https://github.com/piabrota/agents.git
|
||||
@@ -1,7 +1,7 @@
|
||||
# AGENTS.md: piabrota
|
||||
|
||||
piabrota is the company, an open software fabric made in Rio de Janeiro. This umbrella, `mu`, holds the
|
||||
company docs, the standards every product inherits, and the products as submodules under `products/`.
|
||||
piabrota is the company, an open software fabric made in Rio de Janeiro. This repo, `mu`, is its company
|
||||
chart: it holds the company docs, the standards every product inherits, and the eight products as submodules under `products/`.
|
||||
Read [`DOGMA.md`](DOGMA.md) first: it wins over this file. [`PIABROTA.md`](PIABROTA.md) indexes the org's
|
||||
repos. Start with `docs/README.md`.
|
||||
|
||||
@@ -37,6 +37,11 @@ loosen these.
|
||||
- Research and journal: `docs/5-research/`, `docs/6-journal/`.
|
||||
- Brand: `docs/7-branding/` (identity, voice, the naming record).
|
||||
|
||||
## Skills
|
||||
|
||||
`.claude/skills/` vendors skills ([the list and their credits](.claude/skills/README.md)). `adr-verbatim` records a decision: in this
|
||||
repo, write it as a permanent note in `brain/`, as the next section says.
|
||||
|
||||
## The brain
|
||||
|
||||
[pirsig](https://github.com/piabrota/pirsig) will manage this repo. `brain/` is its fork state, and
|
||||
@@ -60,7 +65,7 @@ you run it. If you write a reusable script, it goes here, never only in a scratc
|
||||
| --- | --- |
|
||||
| Push, open a pull request or read GitHub as `piabrota-pr-bot` | `scripts/as-bot.sh <repo> <cmd>`; `--read all` to read. The only way an agent reaches GitHub; to open a pull request, `scripts/pr-open.sh` is the default |
|
||||
| Open a pull request as `piabrota-pr-bot` and arm auto-merge on it: the default way an agent opens one. A human's approval still decides the merge; if arming fails the PR stays open and the script says why. A PR stacked on a branch other than the default one is opened without auto-merge | `scripts/pr-open.sh <repo> [gh pr create args]`, e.g. `scripts/pr-open.sh gleipnir --base main --head my-branch --title "…" --body-file body.md`. Prints the PR's URL. Never merges directly, never `--admin` |
|
||||
| Build `ygg` from the umbrella's checkouts, so a smoke or proof run never uses a stale one | `scripts/ygg-build.sh [--yggdrasil DIR] [--out FILE [--beside-path]] [--allow-behind] [--force]`. Refuses a dirty module or one behind its local `origin/main` (it fetches nothing); builds to the `ygg` first on PATH (else `$(go env GOPATH)/bin/ygg`) and writes the commits to `OUT.build.txt`; a link is followed to its target; an error if `command -v ygg` is not OUT, unless `--beside-path` (needs `--out`): a second ygg beside the one on PATH, built with its facts, and the script prints `YGG_CMD=OUT` to run it. Never overwrites a file that is not a Go binary without `--force`. The smoke and proof scripts refuse a `ygg` from PATH, or a `YGG_CMD` of one executable file, whose facts do not name odin's HEAD (`--any-ygg` skips that; a `YGG_CMD` of several words is used unchecked) |
|
||||
| Build `ygg` from this repo's checkouts, so a smoke or proof run never uses a stale one | `scripts/ygg-build.sh [--yggdrasil DIR] [--out FILE [--beside-path]] [--allow-behind] [--force]`. Refuses a dirty module or one behind its local `origin/main` (it fetches nothing); builds to the `ygg` first on PATH (else `$(go env GOPATH)/bin/ygg`) and writes the commits to `OUT.build.txt`; a link is followed to its target; an error if `command -v ygg` is not OUT, unless `--beside-path` (needs `--out`): a second ygg beside the one on PATH, built with its facts, and the script prints `YGG_CMD=OUT` to run it. Never overwrites a file that is not a Go binary without `--force`. The smoke and proof scripts refuse a `ygg` from PATH, or a `YGG_CMD` of one executable file, whose facts do not name odin's HEAD (`--any-ygg` skips that; a `YGG_CMD` of several words is used unchecked) |
|
||||
| Clean up after runs that have ended: the empty pods and leftover containers | `scripts/ygg-clean.sh --dry-run [--folder DIR] [--keep PROJECT]... [PROJECT...]`, then without `--dry-run`. Runs `ygg doctor` on each project under DIR (default `~/ygg-it`) with the config its runs used; skips a project with a live run (its lock in `/proc/locks`, or open in a process) and refuses when it cannot tell; never deletes a run, a project or an image, and never starts or stops the engine |
|
||||
| Set up and check the GPU for the engine: the NVIDIA toolkit (pinned 1.20.1) and the CDI spec in the Podman machine's distro on WSL2, repeatable after a driver update or on a new machine | `scripts/ygg-gpu.sh setup\|check [--machine NAME] [--folder DIR]`. `setup` installs only what is missing and regenerates a stale spec, then runs `check`; `check` runs the CUDA image (by digest) through `ygg-engine.sh` and prints `gpu: <name> <memory>`, or exits 3 with `missing: toolkit\|spec\|stale spec` and the fix, or 2 when the engine does not answer. Root commands go through `wsl.exe -u root`, never sudo; it never starts, stops or re-creates the machine |
|
||||
| Set up, start, stop, check and clean the local model server (llama-server and the model gate in one container, on the engine's GPU), from the operator's model list; the qwen scripts find it through it | `scripts/ygg-models.sh [--models FILE] [--folder DIR] setup [--weights DIR] [--state DIR] [--price IN:OUT[:CACHE_READ]] [--model NAME]` does the first-time setup and is safe to run again: the GPU (`ygg-gpu.sh`), the list from the example when FILE is missing (`--price` required then; folders default to `DIR/models/weights` and `DIR/models/state`), the missing `download` files (`hf`, else `uvx`), the image, start, load (the first model unless `--model`) and the chat template when it is missing. `clean [--state] [--weights]` removes the container, the network and the image, and refuses, changing nothing, while another container is on the network; `--state` the preset and allow files; `--weights` only the files the list downloads and `.cache/huggingface` under the weights folder. Also `start\|stop\|status\|load NAME\|template NAME`. FILE defaults to `${XDG_CONFIG_HOME:-~/.config}/ygg/models.yaml` and DIR (holds `factory.yaml`, which names the engine) to `~/ygg-it` (example list: `scripts/testdata/models/models.example.yaml`). `start` runs `ygg-gpu.sh check` first (a stale spec is set up again), builds the image only when its tag is missing (long, CUDA), creates the internal network when absent, writes the preset and runs the container with `127.0.0.1:<host_port>` as its only published port; `status` prints `running on <url>, loaded: <name\|none>` or exits 3; `stop` keeps the network and the image. Engine calls go through `ygg-engine.sh` |
|
||||
@@ -81,6 +86,7 @@ you run it. If you write a reusable script, it goes here, never only in a scratc
|
||||
| Check the journal against spec §10.5 and design criterion 6: front matter, sections, the index, evidence once resolved, a `factory-change` entry citing `ygg metrics --compare` | `scripts/journal-check.sh [DIR]` |
|
||||
| Scaffold a new Rust component, rendered by `minijinja-cli` | `scripts/scaffold-component.sh` |
|
||||
| Render `PIABROTA.md` from `scripts/piabrota/repos.toml`, or check that it is fresh | `scripts/piabrota-index.sh [--check]` |
|
||||
| Write the README drawings, the logo and む, from `drawings/*.nix`; `nix flake check` checks it | `scripts/drawing.sh` |
|
||||
| Draw every plot with archify, or check that the PNGs are fresh | `scripts/figure.sh draw\|check`. Sources in `docs/archify/`, PNGs in `docs/img/`, the pinned archify in `forks/archify` |
|
||||
|
||||
Only the founder runs `scripts/new-repo.sh`, `scripts/create-repo.sh`, `scripts/add-licences.sh`, `scripts/add-ci.sh`,
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -1,7 +1,7 @@
|
||||
# Notice
|
||||
|
||||
piabrota/mu started as a copy of [ouroboric-dev/ouroboric](https://github.com/ouroboric-dev/ouroboric),
|
||||
the company umbrella of Ouroboric, by Bruno Guilhermo de Barros Valério. This notice keeps that credit,
|
||||
the company repo of Ouroboric, by Bruno Guilhermo de Barros Valério. This notice keeps that credit,
|
||||
as the licences require.
|
||||
|
||||
- **What came from there:** the standards in `docs/4-ways-of-working/`, the scripts in `scripts/`,
|
||||
@@ -10,7 +10,7 @@ as the licences require.
|
||||
CC BY 4.0. See [`REUSE.toml`](REUSE.toml).
|
||||
- **What changed:** on 2026-11-01 piabrota changed the identity of the copy: names, org, bot, palette,
|
||||
charter, roadmap, budget, legal page and README. It removed Ouroboric's logos and logo prompts, and
|
||||
replaced the Go component template with a Rust one and the D2 and Mermaid diagrams with archify
|
||||
swapped the products for piabrota's own, replaced the Go component template with a Rust one and the D2 and Mermaid diagrams with archify
|
||||
figures. `git log` holds every change.
|
||||
- **What did not change:** dated records (`docs/6-journal/`, dated files in `docs/5-research/`,
|
||||
`docs/1-company/readiness/`) stay as written, under the name Ouroboric. Only their links to removed
|
||||
@@ -19,3 +19,7 @@ as the licences require.
|
||||
The names Ouroboric, Yggdrasil, Asgard and their modules are not ours. See
|
||||
[TRADEMARKS.md](TRADEMARKS.md). Ouroboric is a partner of piabrota; this notice does not say that
|
||||
Ouroboric endorses this repository.
|
||||
|
||||
`.claude/skills/adr-verbatim/` is copied unchanged from
|
||||
[davidondrej/cloudroom](https://github.com/davidondrej/cloudroom), by David Ondrej, under Apache-2.0.
|
||||
`drawings/pen.nix` comes from [piabrota/nix-os](https://github.com/piabrota/nix-os).
|
||||
+11
-13
@@ -2,18 +2,20 @@
|
||||
# PIABROTA
|
||||
|
||||
Every public repo of [piabrota](https://github.com/piabrota), an open software fabric made in Rio de
|
||||
Janeiro: 28 public repos, as of 2026-11-01. The rules
|
||||
are in [DOGMA.md](DOGMA.md). The org's 2 private repos are counted, never listed.
|
||||
Janeiro: 24 public repos, as of 2026-11-01. The rules
|
||||
are in [DOGMA.md](DOGMA.md).
|
||||
|
||||
## Umbrella
|
||||
## Company
|
||||
|
||||
| Repo | Licence | What it is |
|
||||
| --- | --- | --- |
|
||||
| [`mu`](https://github.com/piabrota/mu) | CC BY 4.0, AGPL-3.0, MPL-2.0 | The company umbrella: dogma, charter, standards, journal, brand and the scripts every project inherits. |
|
||||
| [`mu`](https://github.com/piabrota/mu) | CC BY 4.0, AGPL-3.0, MPL-2.0 | The company chart: dogma, charter, standards, journal, brand and the scripts every project inherits. |
|
||||
| [`.github`](https://github.com/piabrota/.github) | MPL-2.0 | The org's profile, with the project table, the fabric figure and the funding links. |
|
||||
|
||||
## Projects
|
||||
|
||||
The projects are the submodules under [`products/`](products/).
|
||||
|
||||
| Repo | Lane | Licence | What it is | Its place in the company |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| [`pirsig`](https://github.com/piabrota/pirsig) | think and write | MPL-2.0 | A second brain: PARA and a Zettelkasten slip-box. A Rust app with a desktop app, a REST API and the `psg` CLI, on one model layer. | Will manage this repo: `brain/` is its fork state. |
|
||||
@@ -22,7 +24,8 @@ are in [DOGMA.md](DOGMA.md). The org's 2 private repos are counted, never listed
|
||||
| [`rax`](https://github.com/piabrota/rax) | warn and host | MPL-2.0, parts Apache-2.0 | Rustic Agentic Runtime: a pure-Rust port of AX, the declarative orchestrator for agentic tasks, with AX's API. | Runs the agents' tasks on the VPS, one pod per run. |
|
||||
| [`agents`](https://github.com/piabrota/agents) | warn and host | MPL-2.0 | Small agents that watch nix-os and its VPS: deploy doctor, pull request reviewer, mentions, mirror keeper, flake annotator, feedback, health digest. | Act on GitHub as the App `piabrota-ops`, installed on nix-os only. |
|
||||
| [`nix-os`](https://github.com/piabrota/nix-os) | warn and host | MPL-2.0 | The NixOS configuration of the small VPS that serves piabrota.art. A merge to `main` is a deploy. | Hosts the site, rax, the agents and PGX. |
|
||||
| [`ihoje`](https://github.com/piabrota/ihoje) | archived | no licence file | A Rust event scraper with anime-inspired module names. Archived and no longer maintained. | None. |
|
||||
| [`ihero`](https://github.com/piabrota/ihero) | play | MPL-2.0 | A FOSS music player and game, in Rust. Coming: the repo holds only its licence. | None yet. |
|
||||
| [`dojo`](https://github.com/piabrota/dojo) | not set | MPL-2.0 | 道場. Empty so far: a licence and a title. | None yet. |
|
||||
|
||||
## Forks
|
||||
|
||||
@@ -33,9 +36,9 @@ its upstream's: no fork carries commits of its own.
|
||||
|
||||
| Repo | Upstream | Sync | Why it is here |
|
||||
| --- | --- | --- | --- |
|
||||
| [`cloudroom`](https://github.com/piabrota/cloudroom) | [`davidondrej/cloudroom`](https://github.com/davidondrej/cloudroom) | 2 behind | A platform to run many agents; this repo vendors its `adr-verbatim` skill. |
|
||||
| [`skills`](https://github.com/piabrota/skills) | [`davidondrej/skills`](https://github.com/davidondrej/skills) | even | Agent skills. |
|
||||
| [`relay`](https://github.com/piabrota/relay) | [`ronaknnathani/relay`](https://github.com/ronaknnathani/relay) | even | Skills that orchestrate coding agents on long tasks. |
|
||||
| [`rea`](https://github.com/piabrota/rea) | [`morluto/rea`](https://github.com/morluto/rea) | 761 behind | Reverse engineering with agents. |
|
||||
| [`TencentDB-Agent-Memory`](https://github.com/piabrota/TencentDB-Agent-Memory) | [`TencentCloud/TencentDB-Agent-Memory`](https://github.com/TencentCloud/TencentDB-Agent-Memory) | even | A team-level memory hub for agents. |
|
||||
| [`axon`](https://github.com/piabrota/axon) | [`danieltamas/axon`](https://github.com/danieltamas/axon) | even | Reads agent harness logs: speed, cost and output per model. |
|
||||
| [`bton`](https://github.com/piabrota/bton) | [`danieltamas/bton`](https://github.com/danieltamas/bton) | 11 behind | A team's review flow with coding agents, from the macOS menu bar. |
|
||||
@@ -52,10 +55,6 @@ its upstream's: no fork carries commits of its own.
|
||||
| Repo | Upstream | Sync | Why it is here |
|
||||
| --- | --- | --- | --- |
|
||||
| [`core`](https://github.com/piabrota/core) | [`home-assistant/core`](https://github.com/home-assistant/core) | 795 behind | Home Assistant: local home automation. |
|
||||
| [`edit`](https://github.com/piabrota/edit) | [`fmhy/edit`](https://github.com/fmhy/edit) | 7 behind | Changes to FMHY. |
|
||||
| [`prj-gd-engine`](https://github.com/piabrota/prj-gd-engine) | [`mbracali/prj-gd-engine`](https://github.com/mbracali/prj-gd-engine) | 179 behind | Re-implementations of guitar music games. |
|
||||
| [`naruto-unison`](https://github.com/piabrota/naruto-unison) | [`naruto-unison/naruto-unison`](https://github.com/naruto-unison/naruto-unison) | even | Naruto Unison, a game. |
|
||||
| [`OpenVoice`](https://github.com/piabrota/OpenVoice) | [`myshell-ai/OpenVoice`](https://github.com/myshell-ai/OpenVoice) | even | Instant voice cloning. |
|
||||
|
||||
### Runtimes and compilers
|
||||
|
||||
@@ -64,11 +63,10 @@ its upstream's: no fork carries commits of its own.
|
||||
| [`pgx`](https://github.com/piabrota/pgx) | [`pgrundev/pgx`](https://github.com/pgrundev/pgx) | even | Postgres-compatible engine in Rust; nix-os runs it for rax's store. |
|
||||
| [`rust-cuda`](https://github.com/piabrota/rust-cuda) | [`Rust-GPU/rust-cuda`](https://github.com/Rust-GPU/rust-cuda) | even | GPU code in Rust. |
|
||||
| [`lean_kernel_verify`](https://github.com/piabrota/lean_kernel_verify) | [`facebookresearch/lean_kernel_verify`](https://github.com/facebookresearch/lean_kernel_verify) | even | A compiler-based safety checker for GPU kernels, in Lean 4. |
|
||||
| [`thc`](https://github.com/piabrota/thc) | [`ekmett/thc`](https://github.com/ekmett/thc) | even | The Turbo Haskell Compiler. |
|
||||
|
||||
### The factory
|
||||
|
||||
| Repo | Upstream | Sync | Why it is here |
|
||||
| --- | --- | --- | --- |
|
||||
| [`yggdrasil`](https://github.com/piabrota/yggdrasil) | [`ouroboric-dev/yggdrasil`](https://github.com/ouroboric-dev/yggdrasil) | even | Submodule of this repo: the agentic factory. |
|
||||
| [`asgard`](https://github.com/piabrota/asgard) | [`ouroboric-dev/asgard`](https://github.com/ouroboric-dev/asgard) | even | Submodule of this repo: the kickstart realm. |
|
||||
| [`yggdrasil`](https://github.com/piabrota/yggdrasil) | [`ouroboric-dev/yggdrasil`](https://github.com/ouroboric-dev/yggdrasil) | even | The agentic factory this repo inherited its method from. |
|
||||
| [`asgard`](https://github.com/piabrota/asgard) | [`ouroboric-dev/asgard`](https://github.com/ouroboric-dev/asgard) | even | The kickstart realm of that factory. |
|
||||
@@ -1,30 +1,33 @@
|
||||
<img alt="無, mu, no thing: the kanji brushed in twelve strokes, from pirsig" src="https://raw.githubusercontent.com/piabrota/pirsig/b7dd1da2ac886845b14bb90e5d8d34976cfc95cb/docs/drawings/pirsig.svg" width="200"/>
|
||||
<!-- markdownlint-disable MD033 -->
|
||||
<div align="center">
|
||||
|
||||
<img alt="The piabrota logo, as piabrota.art shows it: an open green eye on red" src="docs/drawings/eye.svg" width="160"/>
|
||||
<img alt="む, mu, brushed in its three strokes, in pure Nix" src="docs/drawings/mu.svg" width="160"/>
|
||||
|
||||
# mu
|
||||
|
||||
無 · the piabrota umbrella · [dogma](DOGMA.md) · [repos](PIABROTA.md) · [decision models](docs/DECISION_MODELS.md) · [charter](docs/1-company/charter.md) · [licence](#licence)
|
||||
<sub>the piabrota company chart · <a href="DOGMA.md">dogma</a> · <a href="PIABROTA.md">repos</a> · <a href="docs/DECISION_MODELS.md">decision models</a> · <a href="docs/1-company/charter.md">charter</a> · <a href="#licence">licence</a></sub>
|
||||
|
||||
</div>
|
||||
|
||||
## In one minute
|
||||
|
||||
- **mu is the company umbrella of [piabrota](https://github.com/piabrota)**, an open software fabric
|
||||
- **mu is the company chart of [piabrota](https://github.com/piabrota)**, an open software fabric
|
||||
made in Rio de Janeiro. It holds the dogma, the charter, the standards, the journal and the tools
|
||||
that every piabrota project inherits.
|
||||
that every piabrota project inherits, and its eight products as submodules.
|
||||
- **[DOGMA.md](DOGMA.md) holds the ten invariants.** Agents fix every error a user or an owner reports,
|
||||
in short pull requests. Judgement is decision-oriented: evidence, a decision model, calibrated
|
||||
probabilities, rules that humans define, a verdict.
|
||||
- **[PIABROTA.md](PIABROTA.md) indexes every public repo of the org.**
|
||||
- **[pirsig](https://github.com/piabrota/pirsig) will manage this repo:** smart notes, PARA and a
|
||||
track record of high-level decisions. [`brain/`](brain/) is its fork state.
|
||||
- **mu began as a copy of Ouroboric's umbrella.** [NOTICE.md](NOTICE.md) keeps that credit.
|
||||
- **mu began as a copy of Ouroboric's company repo.** [NOTICE.md](NOTICE.md) keeps that credit.
|
||||
|
||||
## The map
|
||||
|
||||

|
||||

|
||||
|
||||
**How to read this figure.** Top to bottom, one lane per role. An arrow says what flows, and a red border marks a person or what the factory makes. The source is [`piabrota-map.json`](docs/archify/piabrota-map.json).
|
||||
|
||||
The factory's names come from Norse myth, and they are Ouroboric's; the
|
||||
[naming and mythology record](docs/7-branding/story/naming-and-mythology.md) tells the story behind each one.
|
||||
**How to read this figure.** Top to bottom, one lane per kind of work. A red border marks the people who steer. The source is [`piabrota-map.json`](docs/archify/piabrota-map.json).
|
||||
|
||||
## Contents
|
||||
|
||||
@@ -37,7 +40,7 @@ The factory's names come from Norse myth, and they are Ouroboric's; the
|
||||
| [`7-branding/`](docs/7-branding/README.md) | the piabrota identity and voice, and the naming record |
|
||||
| [`brain/`](brain/) | pirsig's fork state: PARA, smart notes, the track record |
|
||||
|
||||
The products are submodules under [`products/`](products/): clone with `--recurse-submodules`.
|
||||
The eight products are submodules under [`products/`](products/): clone with `--recurse-submodules`.
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
+8
-1
@@ -14,7 +14,14 @@ SPDX-License-Identifier = "AGPL-3.0-only"
|
||||
|
||||
# What piabrota wrote new is MPL-2.0, the org's licence.
|
||||
[[annotations]]
|
||||
path = ["DOGMA.md", "PIABROTA.md", "pirsig.toml", "brain/**", "docs/DECISION_MODELS.md", "docs/archify/**", "docs/img/**", "docs/mockups/**", "scripts/figure.sh", "scripts/minijinja-lib.sh", "scripts/piabrota-index.sh", "scripts/piabrota/**", "scripts/templates/piabrota/**", "scripts/templates/rust-component/**"]
|
||||
path = ["DOGMA.md", "PIABROTA.md", "pirsig.toml", "brain/**", "docs/DECISION_MODELS.md", "docs/drawings/**", "drawings/**", "flake.nix", "flake.lock", ".claude/skills/README.md", "scripts/drawing.sh", "docs/archify/**", "docs/img/**", "docs/mockups/**", "scripts/figure.sh", "scripts/minijinja-lib.sh", "scripts/piabrota-index.sh", "scripts/piabrota/**", "scripts/templates/piabrota/**", "scripts/templates/rust-component/**"]
|
||||
precedence = "closest"
|
||||
SPDX-FileCopyrightText = "2026 piabrota contributors"
|
||||
SPDX-License-Identifier = "MPL-2.0"
|
||||
|
||||
# adr-verbatim is copied unchanged from davidondrej/cloudroom; see .claude/skills/README.md.
|
||||
[[annotations]]
|
||||
path = [".claude/skills/adr-verbatim/**"]
|
||||
precedence = "closest"
|
||||
SPDX-FileCopyrightText = "2026 David Ondrej"
|
||||
SPDX-License-Identifier = "Apache-2.0"
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
pirsig: note
|
||||
zid: "13"
|
||||
title: "The products are piabrota's own eight"
|
||||
aliases: ["The products are piabrota's own eight"]
|
||||
kind: permanent
|
||||
tags: ["decision"]
|
||||
created: 2026-11-01T08:10:31+00:00
|
||||
updated: 2026-11-01T08:10:31+00:00
|
||||
---
|
||||
|
||||
# The products are piabrota's own eight
|
||||
|
||||
**Decided 2026-11-01.** products/ holds pirsig, alerts, ihero, gramatico, nix-os, dojo, rax and agents. Yggdrasil and Asgard stop being products; our forks of them stay.
|
||||
|
||||
**Why:** The owner set the list.
|
||||
|
||||
**Outcome:** pending.
|
||||
|
||||
Part of [[1 Decisions the track record|Decisions: the track record]].
|
||||
|
||||
@@ -6,14 +6,14 @@ aliases: ["mu takes the piabrota identity"]
|
||||
kind: permanent
|
||||
tags: ["decision"]
|
||||
created: 2026-11-01T07:14:51+00:00
|
||||
updated: 2026-11-01T07:14:51+00:00
|
||||
updated: 2026-11-01T08:02:10.995865+00:00
|
||||
---
|
||||
|
||||
# mu takes the piabrota identity
|
||||
|
||||
**Decided 2026-11-01.** This repo stops being a copy of Ouroboric's umbrella and becomes piabrota's: names, org, bot, charter, brand.
|
||||
**Decided 2026-11-01.** This repo stops being a copy of Ouroboric's company repo and becomes piabrota's company chart: names, org, bot, charter, brand.
|
||||
|
||||
**Why:** piabrota needs its own company umbrella, managed by pirsig.
|
||||
**Why:** piabrota needs its own company chart, managed by pirsig.
|
||||
|
||||
**Outcome:** pending.
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@ aliases: ["Yggdrasil's leaves stay upstream"]
|
||||
kind: permanent
|
||||
tags: ["decision"]
|
||||
created: 2026-11-01T07:14:51+00:00
|
||||
updated: 2026-11-01T07:14:51+00:00
|
||||
updated: 2026-11-01T08:10:31.266469+00:00
|
||||
---
|
||||
|
||||
# Yggdrasil's leaves stay upstream
|
||||
|
||||
**Decided 2026-11-01.** The submodules point to our forks of yggdrasil and asgard; links to the leaves stay on ouroboric-dev.
|
||||
**Decided 2026-11-01.** Links to Yggdrasil's leaves stay on ouroboric-dev.
|
||||
|
||||
**Why:** Only those two repos were forked, and they mirror upstream.
|
||||
**Why:** Only yggdrasil and asgard were forked, and they mirror upstream.
|
||||
|
||||
**Outcome:** pending.
|
||||
|
||||
|
||||
@@ -49,12 +49,12 @@ handover, `docs/` stays the source of truth.
|
||||
|
||||
## Portfolio
|
||||
|
||||
[PIABROTA.md](../../PIABROTA.md) lists every public project. The factory below came with this repo,
|
||||
from Ouroboric. Our forks of `yggdrasil` and `asgard` mirror upstream, and they stay submodules here.
|
||||
The products are pirsig, alerts, ihero, gramatico, nix-os, dojo, rax and agents, each a submodule under
|
||||
[`products/`](../../products/). [PIABROTA.md](../../PIABROTA.md) lists every public repo.
|
||||
|
||||

|
||||

|
||||
|
||||
**How to read this figure.** Top to bottom: the founder steers, Yggdrasil works, a company comes out. The company is an example. The source is [`piabrota-portfolio.json`](../archify/piabrota-portfolio.json).
|
||||
**How to read this figure.** Top to bottom, one lane per kind of work. A red border marks the people who steer. The source is [`piabrota-map.json`](../archify/piabrota-map.json).
|
||||
|
||||
## North-star measures
|
||||
|
||||
|
||||
+10
-5
@@ -11,15 +11,20 @@ style: reference
|
||||
[PIABROTA.md](../../PIABROTA.md) indexes every public repo of the [`piabrota`](https://github.com/piabrota)
|
||||
organisation. This page says how this repo's tree relates to them.
|
||||
|
||||
## Umbrellas
|
||||
## The chart and the products
|
||||
|
||||
| Repository | Kind | Role |
|
||||
| --- | --- | --- |
|
||||
| [`mu`](https://github.com/piabrota/mu) | company umbrella | this repo: dogma, charter, standards, journal, brand; the products as submodules under [`products/`](../../products/) |
|
||||
| [`yggdrasil`](https://github.com/piabrota/yggdrasil) | product umbrella | our fork of the agentic factory; it mirrors upstream |
|
||||
| [`asgard`](https://github.com/piabrota/asgard) | product umbrella | our fork of the kickstart realm; it mirrors upstream |
|
||||
| [`mu`](https://github.com/piabrota/mu) | company chart | this repo: dogma, charter, standards, journal, brand |
|
||||
| `pirsig`, `alerts`, `ihero`, `gramatico`, `nix-os`, `dojo`, `rax`, `agents` | products | submodules under [`products/`](../../products/) |
|
||||
|
||||
## Upstream repos
|
||||
## The factory
|
||||
|
||||
Our forks of [`yggdrasil`](https://github.com/piabrota/yggdrasil) and
|
||||
[`asgard`](https://github.com/piabrota/asgard) mirror upstream. They are not products of piabrota. The
|
||||
`ygg-*` scripts use clones of them beside this repo, not submodules.
|
||||
|
||||
### Upstream repos
|
||||
|
||||
Yggdrasil's leaves were not forked. They live in [`ouroboric-dev`](https://github.com/ouroboric-dev),
|
||||
and the `ygg-*` scripts build them from there, so those links stay on upstream.
|
||||
|
||||
@@ -11,11 +11,10 @@ style: direction
|
||||
This roadmap sets the order of work, not dates. Each product keeps its own detailed roadmap.
|
||||
|
||||
0. **The conversion:** this repo takes the piabrota identity, the dogma and the repo index.
|
||||
1. **The GitHub setup:** create `piabrota-pr-bot`, add the `protect-main` ruleset to `mu`, and pass
|
||||
`scripts/check-repos.sh`.
|
||||
1. **The GitHub setup:** create `piabrota-pr-bot`, add the `protect-main` ruleset to `mu`, then extend
|
||||
`scripts/check-repos.sh`, which still lists `yggdrasil` and `asgard`, to the eight products.
|
||||
2. **The handover to pirsig:** PARA, smart notes and the track record move from seed to daily use.
|
||||
3. **The decision pipeline:** try the tracked [decision models](../DECISION_MODELS.md), then write the
|
||||
decision engine's first rules.
|
||||
4. **Routines:** agents fix reported errors, on local models, Claude and Kimi.
|
||||
5. **Later:** follow [Yggdrasil's roadmap](https://github.com/piabrota/yggdrasil/blob/main/docs/1-product/roadmap.md)
|
||||
from our fork, which mirrors upstream.
|
||||
5. **The products:** ihero and dojo get their first release.
|
||||
@@ -13,7 +13,7 @@ routing and docs checks work the same everywhere.
|
||||
|
||||
## 1. Umbrella template
|
||||
|
||||
A node is one of three kinds: **company umbrellas** (for example, `mu`, or a company that
|
||||
A node is one of three kinds: **company charts or umbrellas** (for example, `mu`, or a company that
|
||||
the Asgard realm kickstarted), **product umbrellas** (for example, `yggdrasil`, a client gallery) and
|
||||
**leaves**. Company
|
||||
umbrellas use `1-company/` (charter, roadmap, legal, readiness) instead of `1-product/`, and hold the
|
||||
|
||||
@@ -8,5 +8,5 @@ The source of the piabrota identity in this repo.
|
||||
| [`voice/`](voice/README.md) | tone and copywriting rules |
|
||||
| [`story/`](story/naming-and-mythology.md) | the record of the factory's Norse names, which are Ouroboric's |
|
||||
|
||||
The piabrota logo is the green eye over the word PIABROTA, on red. It is the org's GitHub avatar, and it
|
||||
is not stored here. Ouroboric's logos were removed from this repo: see [NOTICE.md](../../NOTICE.md).
|
||||
The company logo is [`eye.svg`](../drawings/eye.svg), the mark piabrota.art shows: an open green eye on red.
|
||||
Its source is the site's code in piabrota/nix-os. Ouroboric's logos were removed from this repo: see [NOTICE.md](../../NOTICE.md).
|
||||
+4
-7
@@ -1,16 +1,13 @@
|
||||
# piabrota
|
||||
|
||||
piabrota is an open software fabric made in Rio de Janeiro. This repository, `mu`, is the company
|
||||
umbrella. Read the [dogma](../DOGMA.md) first, then the [charter](1-company/charter.md).
|
||||
chart. Read the [dogma](../DOGMA.md) first, then the [charter](1-company/charter.md).
|
||||
|
||||
## The map
|
||||
|
||||

|
||||

|
||||
|
||||
**How to read this figure.** Top to bottom, one lane per role. An arrow says what flows, and a red border marks a person or what the factory makes. The source is [`piabrota-map.json`](./archify/piabrota-map.json).
|
||||
|
||||
The factory's names come from Norse myth; the [naming and mythology record](7-branding/story/naming-and-mythology.md) tells the story behind each one, and its
|
||||
[long-term map](7-branding/story/naming-and-mythology.md#glossary) shows what comes after v0.
|
||||
**How to read this figure.** Top to bottom, one lane per kind of work. A red border marks the people who steer. The source is [`piabrota-map.json`](./archify/piabrota-map.json).
|
||||
|
||||
## Contents
|
||||
|
||||
@@ -23,7 +20,7 @@ The factory's names come from Norse myth; the [naming and mythology record](7-br
|
||||
| [`7-branding/`](7-branding/README.md) | the piabrota identity and voice, and the naming record |
|
||||
| [`DECISION_MODELS.md`](DECISION_MODELS.md) | the decision models we track, and where routines run |
|
||||
|
||||
[PIABROTA.md](../PIABROTA.md) indexes every public repo of the org. The products are submodules under
|
||||
[PIABROTA.md](../PIABROTA.md) indexes every public repo of the org. The eight products are submodules under
|
||||
[`products/`](../products/): clone with `--recurse-submodules`.
|
||||
|
||||
Dated records in `5-research/`, `6-journal/` and `1-company/readiness/` keep the name Ouroboric, as
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
piabrota-map 560
|
||||
piabrota-map 680
|
||||
piabrota-long-term-map 560
|
||||
piabrota-portfolio 430
|
||||
sdd-flow 430
|
||||
readiness-levels 300
|
||||
|
@@ -1,5 +1,4 @@
|
||||
piabrota-long-term-map db92c84d0059560a-208acba
|
||||
piabrota-map 3a7eaf62f4c9b9ff-208acba
|
||||
piabrota-portfolio ae9bc36d7f189f52-208acba
|
||||
readiness-levels 097742394b192caf-208acba
|
||||
sdd-flow 5cfa2a47d5d41f0e-208acba
|
||||
piabrota-long-term-map 6e95c7abf2355a78-208acba
|
||||
piabrota-map 5d20e923b5d1ad53-208acba
|
||||
readiness-levels 8c52751f00327775-208acba
|
||||
sdd-flow fd01389d3d214a0b-208acba
|
||||
@@ -2,7 +2,7 @@
|
||||
"schema_version": 2,
|
||||
"diagram_type": "workflow",
|
||||
"meta": {
|
||||
"title": "The map: piabrota, its factory and what it makes",
|
||||
"title": "The map: piabrota and its eight products",
|
||||
"locale": "en",
|
||||
"quality_profile": "showcase",
|
||||
"legend": {
|
||||
@@ -16,138 +16,143 @@
|
||||
"label": "Humans steer"
|
||||
},
|
||||
{
|
||||
"id": "core",
|
||||
"label": "Yggdrasil, the agentic factory"
|
||||
"id": "chart",
|
||||
"label": "The company chart"
|
||||
},
|
||||
{
|
||||
"id": "realms",
|
||||
"label": "Realms"
|
||||
"id": "think",
|
||||
"label": "Think and write"
|
||||
},
|
||||
{
|
||||
"id": "out",
|
||||
"label": "What it makes"
|
||||
"id": "host",
|
||||
"label": "Warn and host"
|
||||
},
|
||||
{
|
||||
"id": "play",
|
||||
"label": "Coming"
|
||||
}
|
||||
],
|
||||
"mainPath": [
|
||||
"founder",
|
||||
"asgard",
|
||||
"odin",
|
||||
"gleipnir"
|
||||
"owner",
|
||||
"mu",
|
||||
"pirsig"
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "founder",
|
||||
"id": "owner",
|
||||
"lane": "steer",
|
||||
"col": 1,
|
||||
"type": "external",
|
||||
"label": "Founder",
|
||||
"width": 220,
|
||||
"sublabel": "approves direction"
|
||||
"label": "Owners",
|
||||
"width": 180,
|
||||
"sublabel": "write the rules, merge"
|
||||
},
|
||||
{
|
||||
"id": "jorm",
|
||||
"lane": "core",
|
||||
"col": 0,
|
||||
"type": "backend",
|
||||
"label": "Jormungandr",
|
||||
"width": 220,
|
||||
"sublabel": "build, check, fix loop"
|
||||
},
|
||||
{
|
||||
"id": "odin",
|
||||
"lane": "core",
|
||||
"id": "mu",
|
||||
"lane": "chart",
|
||||
"col": 1,
|
||||
"type": "backend",
|
||||
"label": "Odin",
|
||||
"width": 220,
|
||||
"sublabel": "orchestrator, ygg CLI"
|
||||
},
|
||||
{
|
||||
"id": "gleipnir",
|
||||
"lane": "core",
|
||||
"col": 2,
|
||||
"type": "backend",
|
||||
"label": "Gleipnir",
|
||||
"width": 220,
|
||||
"sublabel": "harness: agents, sandbox"
|
||||
},
|
||||
{
|
||||
"id": "voluspa",
|
||||
"lane": "realms",
|
||||
"col": 0,
|
||||
"type": "database",
|
||||
"label": "Voluspa",
|
||||
"width": 220,
|
||||
"sublabel": "graph library"
|
||||
"label": "mu",
|
||||
"width": 180,
|
||||
"sublabel": "dogma, standards, brain"
|
||||
},
|
||||
{
|
||||
"id": "asgard",
|
||||
"lane": "realms",
|
||||
"id": "gramatico",
|
||||
"lane": "think",
|
||||
"col": 0,
|
||||
"type": "backend",
|
||||
"label": "gramatico",
|
||||
"width": 180,
|
||||
"sublabel": "plain pt-BR"
|
||||
},
|
||||
{
|
||||
"id": "pirsig",
|
||||
"lane": "think",
|
||||
"col": 1,
|
||||
"type": "frontend",
|
||||
"label": "Asgard realm",
|
||||
"width": 220,
|
||||
"sublabel": "kickstart"
|
||||
"label": "pirsig",
|
||||
"width": 180,
|
||||
"sublabel": "a second brain"
|
||||
},
|
||||
{
|
||||
"id": "realms",
|
||||
"lane": "realms",
|
||||
"id": "alerts",
|
||||
"lane": "host",
|
||||
"col": 0,
|
||||
"type": "backend",
|
||||
"label": "alerts",
|
||||
"width": 180,
|
||||
"sublabel": "official alerts"
|
||||
},
|
||||
{
|
||||
"id": "rax",
|
||||
"lane": "host",
|
||||
"col": 1,
|
||||
"type": "backend",
|
||||
"label": "rax",
|
||||
"width": 180,
|
||||
"sublabel": "agentic runtime"
|
||||
},
|
||||
{
|
||||
"id": "agents",
|
||||
"lane": "host",
|
||||
"col": 2,
|
||||
"type": "frontend",
|
||||
"label": "Build realms",
|
||||
"width": 220,
|
||||
"sublabel": "Midgard, Helheim"
|
||||
"type": "backend",
|
||||
"label": "agents",
|
||||
"width": 180,
|
||||
"sublabel": "watch and report"
|
||||
},
|
||||
{
|
||||
"id": "products",
|
||||
"lane": "out",
|
||||
"id": "nixos",
|
||||
"lane": "host",
|
||||
"col": 3,
|
||||
"type": "database",
|
||||
"label": "nix-os",
|
||||
"width": 180,
|
||||
"sublabel": "the VPS"
|
||||
},
|
||||
{
|
||||
"id": "ihero",
|
||||
"lane": "play",
|
||||
"col": 0,
|
||||
"type": "frontend",
|
||||
"label": "ihero",
|
||||
"width": 180,
|
||||
"sublabel": "music, coming"
|
||||
},
|
||||
{
|
||||
"id": "dojo",
|
||||
"lane": "play",
|
||||
"col": 1,
|
||||
"type": "external",
|
||||
"label": "Companies and products",
|
||||
"width": 220,
|
||||
"sublabel": "lessons feed back"
|
||||
"type": "frontend",
|
||||
"label": "dojo",
|
||||
"width": 180,
|
||||
"sublabel": "道場, empty so far"
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"id": "e1",
|
||||
"from": "founder",
|
||||
"to": "asgard",
|
||||
"label": "approves"
|
||||
"from": "owner",
|
||||
"to": "mu",
|
||||
"label": "approve"
|
||||
},
|
||||
{
|
||||
"id": "e2",
|
||||
"from": "asgard",
|
||||
"to": "odin",
|
||||
"label": "recipe, later"
|
||||
"from": "mu",
|
||||
"to": "pirsig",
|
||||
"label": "managed by"
|
||||
},
|
||||
{
|
||||
"id": "e3",
|
||||
"from": "realms",
|
||||
"to": "odin",
|
||||
"label": "recipes"
|
||||
"from": "agents",
|
||||
"to": "nixos",
|
||||
"label": "watch"
|
||||
},
|
||||
{
|
||||
"id": "e4",
|
||||
"from": "voluspa",
|
||||
"to": "odin",
|
||||
"label": "graphs"
|
||||
},
|
||||
{
|
||||
"id": "e5",
|
||||
"from": "odin",
|
||||
"to": "jorm"
|
||||
},
|
||||
{
|
||||
"id": "e6",
|
||||
"from": "odin",
|
||||
"to": "gleipnir"
|
||||
},
|
||||
{
|
||||
"id": "e7",
|
||||
"from": "realms",
|
||||
"to": "products",
|
||||
"label": "builds and verifies"
|
||||
"from": "rax",
|
||||
"to": "agents",
|
||||
"label": "runs"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
{
|
||||
"schema_version": 2,
|
||||
"diagram_type": "workflow",
|
||||
"meta": {
|
||||
"title": "The portfolio: one factory, two kinds of realm",
|
||||
"locale": "en",
|
||||
"quality_profile": "showcase",
|
||||
"legend": {
|
||||
"mode": "hidden"
|
||||
},
|
||||
"output": "piabrota-portfolio.html"
|
||||
},
|
||||
"lanes": [
|
||||
{
|
||||
"id": "steer",
|
||||
"label": "Humans steer"
|
||||
},
|
||||
{
|
||||
"id": "factory",
|
||||
"label": "Yggdrasil"
|
||||
},
|
||||
{
|
||||
"id": "out",
|
||||
"label": "A company it makes"
|
||||
}
|
||||
],
|
||||
"mainPath": [
|
||||
"founder",
|
||||
"asgard",
|
||||
"company"
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "founder",
|
||||
"lane": "steer",
|
||||
"col": 0,
|
||||
"type": "external",
|
||||
"label": "Founder",
|
||||
"width": 220,
|
||||
"sublabel": "approves direction"
|
||||
},
|
||||
{
|
||||
"id": "asgard",
|
||||
"lane": "factory",
|
||||
"col": 0,
|
||||
"type": "frontend",
|
||||
"label": "Asgard realm",
|
||||
"width": 220,
|
||||
"sublabel": "kickstart, tier 0"
|
||||
},
|
||||
{
|
||||
"id": "build",
|
||||
"lane": "factory",
|
||||
"col": 1,
|
||||
"type": "backend",
|
||||
"label": "Other realms",
|
||||
"width": 220,
|
||||
"sublabel": "web and backend in v0"
|
||||
},
|
||||
{
|
||||
"id": "company",
|
||||
"lane": "out",
|
||||
"col": 0,
|
||||
"type": "external",
|
||||
"label": "photografy",
|
||||
"width": 220,
|
||||
"sublabel": "a company"
|
||||
},
|
||||
{
|
||||
"id": "gallery",
|
||||
"lane": "out",
|
||||
"col": 1,
|
||||
"type": "frontend",
|
||||
"label": "client gallery",
|
||||
"width": 220,
|
||||
"sublabel": "a product"
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"id": "e1",
|
||||
"from": "founder",
|
||||
"to": "asgard"
|
||||
},
|
||||
{
|
||||
"id": "e2",
|
||||
"from": "asgard",
|
||||
"to": "build",
|
||||
"label": "sets direction"
|
||||
},
|
||||
{
|
||||
"id": "e3",
|
||||
"from": "asgard",
|
||||
"to": "company",
|
||||
"label": "kickstarts"
|
||||
},
|
||||
{
|
||||
"id": "e4",
|
||||
"from": "build",
|
||||
"to": "gallery",
|
||||
"label": "builds and verifies"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
# Drawings
|
||||
|
||||
## `mu.svg`
|
||||
|
||||
む (*mu*), in its three strokes, 2026. The Nix files in `drawings/` write it in two formats from one
|
||||
geometry, as [piabrota/nix-os](https://github.com/piabrota/nix-os/tree/6d636be2c4552381d6427d9b506e2a33dc3c1005/drawings) writes its own:
|
||||
|
||||
| File | What it is |
|
||||
| --- | --- |
|
||||
| `mu.svg` | The README drawing |
|
||||
| `mu.desmos.json` | The same drawing as a Desmos graph state |
|
||||
|
||||
Run `scripts/drawing.sh` to write both. `nix flake check` fails if a drawing test fails, or if the
|
||||
committed files are not its output. The pen is `drawings/pen.nix`, copied from nix-os; the strokes are
|
||||
`drawings/mu.nix`.
|
||||
|
||||
## `eye.svg`
|
||||
|
||||
The piabrota logo, the mark [piabrota.art](https://piabrota.art) shows: an open green eye on red. The site
|
||||
defines it in code (`eye` in piabrota/nix-os, `site/src/piabrota_site/parts.gleam`), so `drawings/eye.nix`
|
||||
holds the same shapes and colours. Change it in nix-os first.
|
||||
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="200" height="200" role="img" aria-label="The piabrota logo: an open green eye on red">
|
||||
<rect width="100" height="100" rx="22" fill="#BC2318"/>
|
||||
<path d="M12 50 Q50 18 88 50 Q50 82 12 50Z" fill="#F7F3EA"/>
|
||||
<circle cx="50" cy="50" r="14" fill="#2E9E4F"/>
|
||||
<circle cx="50" cy="50" r="6" fill="#0B0D12"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 383 B |
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,99 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240" width="240" height="240" role="img" aria-label="む (mu) brushed in its three strokes">
|
||||
<title>む (mu) brushed in its three strokes</title>
|
||||
<desc>Drawn from the Desmos expressions of mu.desmos.json: cubic Béziers through hand-placed points, each piece at its brush width.</desc>
|
||||
<style>.l{fill:none;stroke:#1f2328;stroke-linecap:round;stroke-linejoin:round}.d{fill:#1f2328;stroke:none}@media (prefers-color-scheme:dark){.l{stroke:#e6edf3}.d{fill:#e6edf3}}</style>
|
||||
<g class="l">
|
||||
<path d="M45.2 78.2 C45.75 78.108 46.3 77.985 46.953 77.836" stroke-width="10.78"/>
|
||||
<path d="M46.953 77.836 C47.606 77.687 48.363 77.513 49.325 77.32" stroke-width="10.34"/>
|
||||
<path d="M49.325 77.32 C50.287 77.128 51.456 76.917 52.934 76.694" stroke-width="9.9"/>
|
||||
<path d="M52.934 76.694 C54.412 76.472 56.2 76.238 58.4 76" stroke-width="9.46"/>
|
||||
<path d="M58.4 76 C60.6 75.762 63.442 75.491 66.65 75.203" stroke-width="8.965"/>
|
||||
<path d="M66.65 75.203 C69.858 74.914 73.433 74.607 77.1 74.295" stroke-width="8.415"/>
|
||||
<path d="M77.1 74.295 C80.767 73.983 84.525 73.667 88.1 73.36" stroke-width="7.865"/>
|
||||
<path d="M88.1 73.36 C91.675 73.053 95.067 72.755 98 72.48" stroke-width="7.315"/>
|
||||
<path d="M98 72.48 C100.933 72.205 103.89 71.902 106.783 71.597" stroke-width="7.15"/>
|
||||
<path d="M106.783 71.597 C109.676 71.291 112.506 70.981 115.188 70.693" stroke-width="7.37"/>
|
||||
<path d="M115.188 70.693 C117.869 70.404 120.401 70.136 122.698 69.912" stroke-width="7.59"/>
|
||||
<path d="M122.698 69.912 C124.996 69.689 127.058 69.51 128.8 69.4" stroke-width="7.81"/>
|
||||
<path d="M128.8 69.4 C130.542 69.29 131.985 69.258 133.2 69.273" stroke-width="8.305"/>
|
||||
<path d="M133.2 69.273 C134.415 69.288 135.4 69.35 136.225 69.428" stroke-width="9.075"/>
|
||||
<path d="M136.225 69.428 C137.05 69.505 137.715 69.599 138.288 69.678" stroke-width="9.845"/>
|
||||
<path d="M138.288 69.678 C138.86 69.758 139.342 69.822 139.8 69.84" stroke-width="10.615"/>
|
||||
<path d="M91.4 34.2 C91.455 34.842 91.556 35.598 91.678 36.503" stroke-width="13.035"/>
|
||||
<path d="M91.678 36.503 C91.801 37.408 91.945 38.463 92.087 39.7" stroke-width="12.705"/>
|
||||
<path d="M92.087 39.7 C92.23 40.937 92.369 42.358 92.483 43.997" stroke-width="12.375"/>
|
||||
<path d="M92.483 43.997 C92.596 45.635 92.683 47.492 92.72 49.6" stroke-width="12.045"/>
|
||||
<path d="M92.72 49.6 C92.757 51.708 92.761 54.252 92.744 57.059" stroke-width="11.66"/>
|
||||
<path d="M92.744 57.059 C92.727 59.867 92.688 62.938 92.638 66.1" stroke-width="11.22"/>
|
||||
<path d="M92.638 66.1 C92.587 69.263 92.525 72.517 92.462 75.691" stroke-width="10.78"/>
|
||||
<path d="M92.462 75.691 C92.399 78.865 92.335 81.958 92.28 84.8" stroke-width="10.34"/>
|
||||
<path d="M92.28 84.8 C92.225 87.642 92.243 90.63 92.277 93.638" stroke-width="10.065"/>
|
||||
<path d="M92.277 93.638 C92.31 96.646 92.358 99.673 92.362 102.592" stroke-width="9.955"/>
|
||||
<path d="M92.362 102.592 C92.367 105.512 92.328 108.324 92.187 110.901" stroke-width="9.845"/>
|
||||
<path d="M92.187 110.901 C92.046 113.478 91.803 115.82 91.4 117.8" stroke-width="9.735"/>
|
||||
<path d="M91.4 117.8 C90.997 119.78 90.534 121.508 89.994 123.028" stroke-width="9.515"/>
|
||||
<path d="M89.994 123.028 C89.454 124.549 88.838 125.862 88.128 127.012" stroke-width="9.185"/>
|
||||
<path d="M88.128 127.012 C87.417 128.163 86.613 129.151 85.697 130.02" stroke-width="8.855"/>
|
||||
<path d="M85.697 130.02 C84.782 130.89 83.755 131.642 82.6 132.32" stroke-width="8.525"/>
|
||||
<path d="M82.6 132.32 C81.445 132.998 79.923 133.585 78.231 134.049" stroke-width="8.195"/>
|
||||
<path d="M78.231 134.049 C76.539 134.513 74.675 134.855 72.837 135.043" stroke-width="7.865"/>
|
||||
<path d="M72.837 135.043 C71 135.23 69.187 135.265 67.595 135.115" stroke-width="7.535"/>
|
||||
<path d="M67.595 135.115 C66.004 134.965 64.633 134.63 63.68 134.08" stroke-width="7.205"/>
|
||||
<path d="M63.68 134.08 C62.727 133.53 61.883 132.567 61.184 131.371" stroke-width="6.985"/>
|
||||
<path d="M61.184 131.371 C60.485 130.175 59.931 128.745 59.555 127.26" stroke-width="6.875"/>
|
||||
<path d="M59.555 127.26 C59.179 125.775 58.982 124.235 58.998 122.819" stroke-width="6.765"/>
|
||||
<path d="M58.998 122.819 C59.014 121.403 59.243 120.11 59.72 119.12" stroke-width="6.655"/>
|
||||
<path d="M59.72 119.12 C60.197 118.13 61.068 117.062 62.188 116.023" stroke-width="6.655"/>
|
||||
<path d="M62.188 116.023 C63.309 114.984 64.679 113.973 66.155 113.098" stroke-width="6.765"/>
|
||||
<path d="M66.155 113.098 C67.631 112.222 69.212 111.482 70.754 110.983" stroke-width="6.875"/>
|
||||
<path d="M70.754 110.983 C72.297 110.485 73.8 110.228 75.12 110.32" stroke-width="6.985"/>
|
||||
<path d="M75.12 110.32 C76.44 110.412 77.911 110.815 79.427 111.451" stroke-width="7.205"/>
|
||||
<path d="M79.427 111.451 C80.943 112.087 82.504 112.955 84.003 113.978" stroke-width="7.535"/>
|
||||
<path d="M84.003 113.978 C85.501 115 86.938 116.175 88.207 117.425" stroke-width="7.865"/>
|
||||
<path d="M88.207 117.425 C89.475 118.675 90.575 120 91.4 121.32" stroke-width="8.195"/>
|
||||
<path d="M91.4 121.32 C92.225 122.64 92.835 124.102 93.291 125.675" stroke-width="8.58"/>
|
||||
<path d="M93.291 125.675 C93.747 127.249 94.049 128.933 94.26 130.698" stroke-width="9.02"/>
|
||||
<path d="M94.26 130.698 C94.471 132.462 94.59 134.307 94.679 136.201" stroke-width="9.46"/>
|
||||
<path d="M94.679 136.201 C94.769 138.095 94.828 140.038 94.92 142" stroke-width="9.9"/>
|
||||
<path d="M94.92 142 C95.012 143.962 94.897 146.065 94.693 148.249" stroke-width="10.34"/>
|
||||
<path d="M94.693 148.249 C94.489 150.433 94.196 152.698 93.93 154.98" stroke-width="10.78"/>
|
||||
<path d="M93.93 154.98 C93.664 157.263 93.426 159.563 93.332 161.821" stroke-width="11.22"/>
|
||||
<path d="M93.332 161.821 C93.238 164.078 93.288 166.292 93.6 168.4" stroke-width="11.66"/>
|
||||
<path d="M93.6 168.4 C93.912 170.508 94.274 172.708 94.728 174.914" stroke-width="11.935"/>
|
||||
<path d="M94.728 174.914 C95.181 177.12 95.727 179.331 96.405 181.463" stroke-width="12.045"/>
|
||||
<path d="M96.405 181.463 C97.083 183.594 97.895 185.645 98.88 187.53" stroke-width="12.155"/>
|
||||
<path d="M98.88 187.53 C99.865 189.415 101.025 191.133 102.4 192.6" stroke-width="12.265"/>
|
||||
<path d="M102.4 192.6 C103.775 194.067 105.402 195.419 107.213 196.639" stroke-width="12.155"/>
|
||||
<path d="M107.213 196.639 C109.023 197.859 111.017 198.948 113.125 199.888" stroke-width="11.825"/>
|
||||
<path d="M113.125 199.888 C115.233 200.827 117.456 201.618 119.725 202.242" stroke-width="11.495"/>
|
||||
<path d="M119.725 202.242 C121.994 202.867 124.308 203.325 126.6 203.6" stroke-width="11.165"/>
|
||||
<path d="M126.6 203.6 C128.892 203.875 131.435 204.013 134.094 203.995" stroke-width="10.78"/>
|
||||
<path d="M134.094 203.995 C136.752 203.978 139.525 203.806 142.275 203.463" stroke-width="10.34"/>
|
||||
<path d="M142.275 203.463 C145.025 203.119 147.752 202.603 150.319 201.898" stroke-width="9.9"/>
|
||||
<path d="M150.319 201.898 C152.885 201.194 155.292 200.3 157.4 199.2" stroke-width="9.46"/>
|
||||
<path d="M157.4 199.2 C159.508 198.1 161.516 196.702 163.412 195.092" stroke-width="9.075"/>
|
||||
<path d="M163.412 195.092 C165.309 193.482 167.094 191.66 168.758 189.713" stroke-width="8.745"/>
|
||||
<path d="M168.758 189.713 C170.421 187.765 171.964 185.691 173.374 183.577" stroke-width="8.415"/>
|
||||
<path d="M173.374 183.577 C174.785 181.463 176.063 179.308 177.2 177.2" stroke-width="8.085"/>
|
||||
<path d="M177.2 177.2 C178.337 175.092 179.441 172.479 180.442 169.689" stroke-width="7.755"/>
|
||||
<path d="M180.442 169.689 C181.442 166.899 182.338 163.931 183.058 161.113" stroke-width="7.425"/>
|
||||
<path d="M183.058 161.113 C183.777 158.294 184.32 155.624 184.615 153.43" stroke-width="7.095"/>
|
||||
<path d="M184.615 153.43 C184.909 151.235 184.955 149.517 184.68 148.6" stroke-width="6.765"/>
|
||||
<path d="M184.68 148.6 C184.405 147.683 183.534 147.569 182.346 147.93" stroke-width="6.16"/>
|
||||
<path d="M182.346 147.93 C181.158 148.291 179.652 149.127 178.108 150.112" stroke-width="5.28"/>
|
||||
<path d="M178.108 150.112 C176.563 151.098 174.979 152.232 173.635 153.189" stroke-width="4.4"/>
|
||||
<path d="M173.635 153.189 C172.291 154.146 171.187 154.925 170.6 155.2" stroke-width="3.52"/>
|
||||
<path d="M164 67.2 C164.55 67.658 165.398 68.323 166.423 69.125" stroke-width="9.185"/>
|
||||
<path d="M166.423 69.125 C167.449 69.927 168.652 70.867 169.913 71.875" stroke-width="9.955"/>
|
||||
<path d="M169.913 71.875 C171.173 72.883 172.491 73.96 173.745 75.038" stroke-width="10.725"/>
|
||||
<path d="M173.745 75.038 C175 76.115 176.192 77.192 177.2 78.2" stroke-width="11.495"/>
|
||||
<path d="M177.2 78.2 C178.208 79.208 179.24 80.308 180.259 81.448" stroke-width="12.1"/>
|
||||
<path d="M180.259 81.448 C181.279 82.589 182.288 83.769 183.25 84.938" stroke-width="12.54"/>
|
||||
<path d="M183.25 84.938 C184.213 86.106 185.129 87.264 185.966 88.358" stroke-width="12.98"/>
|
||||
<path d="M185.966 88.358 C186.802 89.452 187.558 90.483 188.2 91.4" stroke-width="13.42"/>
|
||||
<path d="M188.2 91.4 C188.842 92.317 189.392 93.233 189.867 94.116" stroke-width="12.87"/>
|
||||
<path d="M189.867 94.116 C190.343 94.998 190.744 95.846 191.088 96.625" stroke-width="11.33"/>
|
||||
<path d="M191.088 96.625 C191.431 97.404 191.718 98.115 191.964 98.722" stroke-width="9.79"/>
|
||||
<path d="M191.964 98.722 C192.21 99.329 192.417 99.833 192.6 100.2" stroke-width="8.25"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 125 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 101 KiB |
@@ -0,0 +1,63 @@
|
||||
# The README drawing, む, in pure Nix: `svg`, `desmos` and `checkSvg` are the files' text,
|
||||
# `failures` the tests that failed (lib.runTests), empty when all pass.
|
||||
{ lib }:
|
||||
let
|
||||
pen = import ./pen.nix { inherit lib; };
|
||||
mu = import ./mu.nix { inherit lib pen; };
|
||||
near = a: b: (if a < b then b - a else a - b) < 1.0e-9;
|
||||
bz = [ [ 0.0 0.0 ] [ 10.0 30.0 ] [ 40.0 (-10.0) ] [ 50.0 20.0 ] ];
|
||||
inherit (builtins) elemAt;
|
||||
first = s: elemAt s 0;
|
||||
last = s: elemAt s (builtins.length s - 1);
|
||||
stroke = elemAt mu.strokes;
|
||||
col = k: p: elemAt p k;
|
||||
in
|
||||
{
|
||||
inherit (mu.drawing) svg desmos checkSvg;
|
||||
eye = import ./eye.nix;
|
||||
|
||||
failures = lib.runTests {
|
||||
testNumbersAreShort = {
|
||||
expr = map pen.num [ 12.0 (-3.5) 0.1234 (-0.0001) ];
|
||||
expected = [ "12" "-3.5" "0.123" "0" ];
|
||||
};
|
||||
testAPolynomialReadsBack = {
|
||||
expr = let s = pen.poly [ 12.5 (-3.0) 0.0 0.25 ]; in [ s (pen.parsePoly s) ];
|
||||
expected = [ "12.5-3t+0.25t^{3}" [ 12.5 (-3.0) 0.0 0.25 ] ];
|
||||
};
|
||||
testAPartIsTheSameCurve = {
|
||||
expr = builtins.all
|
||||
(k:
|
||||
let
|
||||
s = k / 4.0;
|
||||
p = pen.at (pen.part bz 0.25 0.75) s;
|
||||
q = pen.at bz (0.5 * s + 0.25);
|
||||
in
|
||||
near (col 0 p) (col 0 q) && near (col 1 p) (col 1 q))
|
||||
(lib.range 0 4);
|
||||
expected = true;
|
||||
};
|
||||
testThePowerFormIsTheBezier = {
|
||||
# Midpoint of a cubic Bézier: (p0 + 3p1 + 3p2 + p3) / 8.
|
||||
expr = let cx = elemAt (pen.coeffs bz) 0; in
|
||||
near (pen.evalPoly cx 0.5) 25.0 && near (pen.evalPoly cx 1.0) 50.0;
|
||||
expected = true;
|
||||
};
|
||||
testMuHasItsThreeStrokesInOrder = {
|
||||
expr = [
|
||||
(builtins.length mu.strokes)
|
||||
# the second stroke starts above the first and ends below it
|
||||
(col 1 (first (stroke 1)) < col 1 (first (stroke 0)))
|
||||
(col 1 (last (stroke 1)) > col 1 (last (stroke 0)))
|
||||
# the dot sits on the right of the second stroke's start
|
||||
(col 0 (first (stroke 2)) > col 0 (first (stroke 1)))
|
||||
];
|
||||
expected = [ 3 true true true ];
|
||||
};
|
||||
# Every Desmos expression, read back from its LaTeX, stays within 0.01 of its line.
|
||||
testTheDesmosFileIsTheDrawing = {
|
||||
expr = mu.drawing.worstSquared < 0.01 * 0.01;
|
||||
expected = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
# The piabrota logo, the mark piabrota.art shows: an open green eye on red. The shapes and colours are
|
||||
# those of `eye` in piabrota/nix-os, site/src/piabrota_site/parts.gleam at 6d636be. Change it there first.
|
||||
''
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="200" height="200" role="img" aria-label="The piabrota logo: an open green eye on red">
|
||||
<rect width="100" height="100" rx="22" fill="#BC2318"/>
|
||||
<path d="M12 50 Q50 18 88 50 Q50 82 12 50Z" fill="#F7F3EA"/>
|
||||
<circle cx="50" cy="50" r="14" fill="#2E9E4F"/>
|
||||
<circle cx="50" cy="50" r="6" fill="#0B0D12"/>
|
||||
</svg>
|
||||
''
|
||||
@@ -0,0 +1,71 @@
|
||||
# The mu drawing: む (*mu*), the hiragana, brushed in its three strokes, in the standard order.
|
||||
# The shape of piabrota/nix-os' drawing: pirsig's logo is the kanji 無 and nix-os' is 无; this
|
||||
# repository writes the same sound with no meaning of its own, in kana.
|
||||
#
|
||||
# Each stroke is a brush line through hand-placed points with a width at each point: the first
|
||||
# stops firmly, the second comes down, ties its small loop on the left, runs along the bottom and
|
||||
# rises, and the third is a short falling dot.
|
||||
{ lib, pen }:
|
||||
let
|
||||
# The three strokes of む, in writing order, in a 0–100 box: [x y brush width at that point].
|
||||
strokes = [
|
||||
# 1 the short horizontal, rising a little, stopped at the end
|
||||
[
|
||||
[ 14.0 31.0 5.0 ]
|
||||
[ 20.0 30.0 4.2 ]
|
||||
[ 38.0 28.4 3.2 ]
|
||||
[ 52.0 27.0 3.6 ]
|
||||
[ 57.0 27.2 5.0 ]
|
||||
]
|
||||
# 2 down, the small loop to the left, on down, along the bottom, and up to the right
|
||||
[
|
||||
[ 35.0 11.0 6.0 ]
|
||||
[ 35.6 18.0 5.4 ]
|
||||
[ 35.4 34.0 4.6 ]
|
||||
[ 35.0 49.0 4.4 ]
|
||||
[ 31.0 55.6 3.8 ]
|
||||
[ 22.4 56.4 3.2 ]
|
||||
[ 20.6 49.6 3.0 ]
|
||||
[ 27.6 45.6 3.2 ]
|
||||
[ 35.0 50.6 3.8 ]
|
||||
[ 36.6 60.0 4.6 ]
|
||||
[ 36.0 72.0 5.4 ]
|
||||
[ 40.0 83.0 5.6 ]
|
||||
[ 51.0 88.0 5.0 ]
|
||||
[ 65.0 86.0 4.2 ]
|
||||
[ 74.0 76.0 3.6 ]
|
||||
[ 77.4 63.0 3.0 ]
|
||||
[ 71.0 66.0 1.4 ]
|
||||
]
|
||||
# 3 the short falling dot, on the upper right
|
||||
[
|
||||
[ 68.0 26.0 4.0 ]
|
||||
[ 74.0 31.0 5.4 ]
|
||||
[ 79.0 37.0 6.2 ]
|
||||
[ 81.0 41.0 3.4 ]
|
||||
]
|
||||
];
|
||||
|
||||
# The canvas, square, with the kana in its middle: the 0–100 box scaled by `scale` about its
|
||||
# point (48, 50). The widths of `strokes` are times `weight`, how heavy the brush is.
|
||||
side = 240.0;
|
||||
scale = 2.2;
|
||||
weight = 2.2;
|
||||
place = p: [
|
||||
(pen.fma (builtins.elemAt p 0 - 48.0) scale (side / 2.0))
|
||||
(pen.fma (builtins.elemAt p 1 - 50.0) scale (side / 2.0))
|
||||
];
|
||||
in
|
||||
{
|
||||
inherit strokes;
|
||||
|
||||
drawing = pen.drawing {
|
||||
w = side;
|
||||
h = side;
|
||||
label = "む (mu) brushed in its three strokes";
|
||||
desc = "Drawn from the Desmos expressions of mu.desmos.json: cubic Béziers through hand-placed points, each piece at its brush width.";
|
||||
marks = lib.concatMap
|
||||
(s: pen.brush (map place s) (map (p: builtins.elemAt p 2 * weight) s))
|
||||
strokes;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
# A pen for Desmos line art, in pure Nix: pirsig's pen (crates/pirsig-drawings, at 450e4da)
|
||||
# Copied from piabrota/nix-os (drawings/pen.nix at 6d636be), MPL-2.0.
|
||||
# ported from Rust.
|
||||
#
|
||||
# A stroke is a list of points. The pen runs a Catmull-Rom spline through them, so the line is
|
||||
# smooth and passes through every point. Each piece of the spline is a cubic Bézier, and each
|
||||
# Bézier is one Desmos parametric expression, `(a+bt+ct^2+dt^3, …)` for `0 ≤ t ≤ 1`.
|
||||
#
|
||||
# The SVG has y down and Desmos has y up: a Desmos y is `H - y` of the SVG.
|
||||
# Nix has no fused multiply-add and no square root: `fma` stands in for Rust's `mul_add`, so the
|
||||
# numbers come out as the Rust pen's did, and the check compares squared distances.
|
||||
{ lib }:
|
||||
let
|
||||
inherit (builtins) concatStringsSep elemAt floor genList length;
|
||||
|
||||
# The ink of the drawing, light and dark, as in picasso's drawings.
|
||||
ink = "#1f2328";
|
||||
inkDark = "#e6edf3";
|
||||
# The blue of the check render, the same as in piabrota/alerts, and the orange of its Desmos layer.
|
||||
blue = "#1682D4";
|
||||
orange = "#FF4F00";
|
||||
|
||||
x = p: elemAt p 0;
|
||||
y = p: elemAt p 1;
|
||||
|
||||
# Rust's f64::round, half away from zero, as an integer.
|
||||
round = v: if v < 0 then -(floor (0.5 - v)) else floor (v + 0.5);
|
||||
abs = v: if v < 0 then -v else v;
|
||||
|
||||
# a * b + c as one rounding, as Rust's f64::mul_add: the exact product as a sum of two floats
|
||||
# (Dekker's split), then a compensated sum (Ogita, Rump and Oishi, 2005). Rounding a * b first
|
||||
# moves some numbers of the drawing by 0.001.
|
||||
fma = a: b: c:
|
||||
let
|
||||
split = v:
|
||||
let t = 134217729.0 * v; hi = t - (t - v);
|
||||
in [ hi (v - hi) ];
|
||||
sa = split a;
|
||||
sb = split b;
|
||||
p = a * b;
|
||||
e = elemAt sa 0 * elemAt sb 0 - p + elemAt sa 0 * elemAt sb 1 + elemAt sa 1 * elemAt sb 0
|
||||
+ elemAt sa 1 * elemAt sb 1;
|
||||
s = p + c;
|
||||
z = s - p;
|
||||
err = p - (s - z) + (c - z);
|
||||
in
|
||||
s + (err + e);
|
||||
|
||||
# The integer `a` with its last `d` digits as decimals, after a minus sign when `neg`.
|
||||
decimals = d: neg: a:
|
||||
let p = lib.foldl' (acc: _: acc * 10) 1 (genList (_: null) d);
|
||||
in "${lib.optionalString neg "-"}${toString (a / p)}.${lib.fixedWidthNumber d (a - a / p * p)}";
|
||||
|
||||
# `v` with one decimal, as Rust's `{:.1}`: the nearest of the exact value, a tie to even.
|
||||
tenths = v:
|
||||
let
|
||||
f = floor (v * 10.0);
|
||||
r = fma v 10.0 (-f * 1.0);
|
||||
n = if r > 0.5 || (r == 0.5 && lib.mod f 2 != 0) then f + 1 else f;
|
||||
in
|
||||
decimals 1 (v < 0) (abs n);
|
||||
|
||||
# A number with at most three decimals, without trailing zeros: `12`, `-3.5`, `0.125`.
|
||||
num = v:
|
||||
let
|
||||
n = round (v * 1000.0);
|
||||
m = builtins.match "(-?[0-9]+)\\.([0-9]*[1-9])?0*" (decimals 3 (n < 0) (abs n));
|
||||
in
|
||||
if elemAt m 1 == null then elemAt m 0 else "${elemAt m 0}.${elemAt m 1}";
|
||||
|
||||
# `a+bt+ct^{2}+dt^{3}`, skipping the terms that round to zero.
|
||||
poly = c:
|
||||
num (elemAt c 0) + concatStringsSep "" (genList
|
||||
(i:
|
||||
let
|
||||
k = i + 1;
|
||||
s = num (elemAt c k);
|
||||
pow = if k == 1 then "t" else "t^{${toString k}}";
|
||||
in
|
||||
lib.optionalString (s != "0") "${lib.optionalString (!lib.hasPrefix "-" s) "+"}${s}${pow}")
|
||||
3);
|
||||
|
||||
# The power form `a + bt + ct² + dt³` of each axis of a Bézier: [[a b c d] [a b c d]].
|
||||
coeffs = bz:
|
||||
let
|
||||
f = axis:
|
||||
let
|
||||
a = axis (elemAt bz 0);
|
||||
b = axis (elemAt bz 1);
|
||||
c = axis (elemAt bz 2);
|
||||
d = axis (elemAt bz 3);
|
||||
in
|
||||
[ a (3.0 * (b - a)) (3.0 * (fma 2.0 (-b) a + c)) (fma 3.0 (b - c) (d - a)) ];
|
||||
in
|
||||
[ (f x) (f y) ];
|
||||
|
||||
# The point of a Bézier at `t`.
|
||||
at = bz: t:
|
||||
let
|
||||
u = 1.0 - t;
|
||||
f = axis:
|
||||
fma (u * u * u) (axis (elemAt bz 0)) (fma (3.0 * u * u * t) (axis (elemAt bz 1))
|
||||
(fma (3.0 * u * t * t) (axis (elemAt bz 2)) (t * t * t * axis (elemAt bz 3))));
|
||||
in
|
||||
[ (f x) (f y) ];
|
||||
|
||||
# The same curve between `t0` and `t1`, as a Bézier of its own.
|
||||
part = bz: t0: t1:
|
||||
let
|
||||
h = t1 - t0;
|
||||
# derivative at t, for the control points of the piece
|
||||
deriv = t:
|
||||
let
|
||||
u = 1.0 - t;
|
||||
g = axis:
|
||||
let
|
||||
a = axis (elemAt bz 0);
|
||||
b = axis (elemAt bz 1);
|
||||
c = axis (elemAt bz 2);
|
||||
e = axis (elemAt bz 3);
|
||||
in
|
||||
3.0 * fma (u * u) (b - a) (fma (2.0 * u * t) (c - b) (t * t * (e - c)));
|
||||
in
|
||||
[ (g x) (g y) ];
|
||||
a = at bz t0;
|
||||
b = at bz t1;
|
||||
da = deriv t0;
|
||||
db = deriv t1;
|
||||
in
|
||||
[
|
||||
a
|
||||
[ (fma (x da) (h / 3.0) (x a)) (fma (y da) (h / 3.0) (y a)) ]
|
||||
[ (fma (x db) (-h / 3.0) (x b)) (fma (y db) (-h / 3.0) (y b)) ]
|
||||
b
|
||||
];
|
||||
|
||||
# The Béziers of the open Catmull-Rom spline through `pts`, held at its ends.
|
||||
spline = pts:
|
||||
let
|
||||
n = length pts;
|
||||
get = i: elemAt pts (lib.max 0 (lib.min (n - 1) i));
|
||||
in
|
||||
genList
|
||||
(i:
|
||||
let
|
||||
p0 = get (i - 1);
|
||||
p1 = get i;
|
||||
p2 = get (i + 1);
|
||||
p3 = get (i + 2);
|
||||
in
|
||||
[
|
||||
p1
|
||||
[ (x p1 + (x p2 - x p0) / 6.0) (y p1 + (y p2 - y p0) / 6.0) ]
|
||||
[ (x p2 - (x p3 - x p1) / 6.0) (y p2 - (y p3 - y p1) / 6.0) ]
|
||||
p2
|
||||
])
|
||||
(n - 1);
|
||||
|
||||
# Pieces each segment of a brush stroke is cut into, so its width changes smoothly.
|
||||
pieces = 4;
|
||||
|
||||
# A brush stroke through `pts`: the smooth line of `spline`, whose width follows `widths` (one
|
||||
# per point) as a brush presses down and lifts. Each segment is cut into `pieces` Béziers, each
|
||||
# a mark { bezier; width; } drawn at the width of its middle.
|
||||
brush = pts: widths:
|
||||
assert length pts == length widths;
|
||||
lib.concatLists (lib.imap0
|
||||
(i: bz: genList
|
||||
(j:
|
||||
let
|
||||
t0 = j * 1.0 / pieces;
|
||||
t1 = (j + 1) * 1.0 / pieces;
|
||||
mid = (t0 + t1) / 2.0;
|
||||
w0 = elemAt widths i;
|
||||
in
|
||||
{
|
||||
bezier = part bz t0 t1;
|
||||
width = fma (elemAt widths (i + 1) - w0) mid w0;
|
||||
})
|
||||
pieces)
|
||||
(spline pts));
|
||||
|
||||
# Pretty JSON as serde_json writes it: two spaces, sorted keys, a float with its `.0`.
|
||||
json = indent: v:
|
||||
let next = indent + " ";
|
||||
in
|
||||
if builtins.isAttrs v then
|
||||
"{\n${concatStringsSep ",\n" (map (k: "${next}${builtins.toJSON k}: ${json next v.${k}}") (builtins.attrNames v))}\n${indent}}"
|
||||
else if builtins.isList v then
|
||||
"[\n${concatStringsSep ",\n" (map (e: next + json next e) v)}\n${indent}]"
|
||||
else if builtins.isFloat v then
|
||||
(if floor v == v then "${toString (floor v)}.0" else throw "json: ${toString v} is not whole")
|
||||
else builtins.toJSON v;
|
||||
|
||||
# The two coordinates of `\left(x,y\right)`, each as polynomial coefficients by power of t.
|
||||
parsePair = latex:
|
||||
let
|
||||
m = builtins.match "\\\\left\\(([^,]*),([^,]*)\\\\right\\)" latex;
|
||||
in
|
||||
if m == null then throw "cannot read ${latex}" else map parsePoly m;
|
||||
|
||||
# `12.5-3t+0.25t^{2}` → [12.5 -3 0.25 0].
|
||||
parsePoly = s:
|
||||
let
|
||||
parts = builtins.split "([+-]?[^+-]+)" s;
|
||||
read = term:
|
||||
let m = builtins.match "\\+?(-?[0-9.]+)(t(\\^\\{([0-9])})?)?" term;
|
||||
in
|
||||
if m == null then throw "cannot read the term ${term} of ${s}"
|
||||
else {
|
||||
c = builtins.fromJSON (elemAt m 0) * 1.0;
|
||||
k = if elemAt m 1 == null then 0 else if elemAt m 3 == null then 1 else lib.toInt (elemAt m 3);
|
||||
};
|
||||
terms = map (m: read (elemAt m 0)) (builtins.filter builtins.isList parts);
|
||||
in
|
||||
assert builtins.all (p: builtins.isList p || p == "") parts;
|
||||
genList (k: lib.foldl' (acc: r: if r.k == k then acc + r.c else acc) 0.0 terms) 4;
|
||||
|
||||
evalPoly = c: t: lib.foldr (v: acc: fma acc t v) 0.0 c;
|
||||
in
|
||||
{
|
||||
inherit fma num poly coeffs at part evalPoly parsePoly brush tenths;
|
||||
|
||||
# A finished drawing: its canvas `w` × `h`, its label and description, and its marks.
|
||||
drawing = { w, h, label, desc, marks }:
|
||||
let
|
||||
expressions = lib.imap1
|
||||
(i: mark:
|
||||
let
|
||||
c = coeffs mark.bezier;
|
||||
cx = elemAt c 0;
|
||||
cy = elemAt c 1;
|
||||
px = poly cx;
|
||||
py = poly ([ (h - elemAt cy 0) ] ++ map (v: -v) (lib.drop 1 cy));
|
||||
in
|
||||
{
|
||||
type = "expression";
|
||||
id = toString i;
|
||||
color = blue;
|
||||
latex = "\\left(${px},${py}\\right)";
|
||||
parametricDomain = { min = "0"; max = "1"; };
|
||||
lineWidth = num mark.width;
|
||||
})
|
||||
marks;
|
||||
|
||||
# The geometry as SVG paths, one per mark.
|
||||
shapes = map
|
||||
(mark:
|
||||
let
|
||||
b = mark.bezier;
|
||||
pt = p: "${num (x p)} ${num (y p)}";
|
||||
in
|
||||
"<path d=\"M${pt (elemAt b 0)} C${pt (elemAt b 1)} ${pt (elemAt b 2)} ${pt (elemAt b 3)}\" stroke-width=\"${num mark.width}\"/>")
|
||||
marks;
|
||||
|
||||
sw = num w;
|
||||
sh = num h;
|
||||
in
|
||||
{
|
||||
# The drawing as a Desmos graph state (`version` 11).
|
||||
desmos = json ""
|
||||
{
|
||||
version = 11;
|
||||
graph = {
|
||||
viewport = { xmin = 0; xmax = w; ymin = 0; ymax = h; };
|
||||
showGrid = false;
|
||||
showXAxis = false;
|
||||
showYAxis = false;
|
||||
};
|
||||
expressions.list = expressions;
|
||||
} + "\n";
|
||||
|
||||
# The drawing as SVG, in ink, as picasso draws: near black on light pages, near
|
||||
# white on dark ones (`prefers-color-scheme`).
|
||||
svg = ''
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${sw} ${sh}" width="${sw}" height="${sh}" role="img" aria-label="${label}">
|
||||
<title>${label}</title>
|
||||
<desc>${desc}</desc>
|
||||
<style>.l{fill:none;stroke:${ink};stroke-linecap:round;stroke-linejoin:round}.d{fill:${ink};stroke:none}@media (prefers-color-scheme:dark){.l{stroke:${inkDark}}.d{fill:${inkDark}}}</style>
|
||||
<g class="l">
|
||||
${concatStringsSep "\n " shapes}
|
||||
</g>
|
||||
</svg>
|
||||
'';
|
||||
|
||||
# The check render: the geometry in blue and, on top, each Desmos expression read back from
|
||||
# its LaTeX and sampled in orange. Where the two agree, the orange line runs inside the blue.
|
||||
checkSvg =
|
||||
let
|
||||
orangeLines = map
|
||||
(e:
|
||||
let
|
||||
f = parsePair e.latex;
|
||||
pts = genList
|
||||
(i:
|
||||
let t = i / 24.0;
|
||||
in "${tenths (evalPoly (elemAt f 0) t)},${tenths (h - evalPoly (elemAt f 1) t)}")
|
||||
25;
|
||||
lw = builtins.fromJSON e.lineWidth * 1.0;
|
||||
in
|
||||
"<polyline points=\"${concatStringsSep " " pts}\" stroke-width=\"${num (lib.min (0.4 * lw) 0.8)}\"/>")
|
||||
expressions;
|
||||
in
|
||||
''
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${sw} ${sh}" width="${sw}" height="${sh}" role="img" aria-label="${label}, with its Desmos expressions over it">
|
||||
<g fill="none" stroke="${blue}" stroke-linecap="round" stroke-linejoin="round">
|
||||
${concatStringsSep "\n " shapes}
|
||||
</g>
|
||||
<g fill="none" stroke="${orange}" stroke-linecap="round" stroke-linejoin="round">
|
||||
${concatStringsSep "\n " orangeLines}
|
||||
</g>
|
||||
</svg>
|
||||
'';
|
||||
|
||||
# The square of how far, at most, any Desmos expression strays from the line it stands for:
|
||||
# each one is read back from its LaTeX and compared with its Bézier at eleven points.
|
||||
worstSquared = lib.foldl' lib.max 0.0 (lib.zipListsWith
|
||||
(mark: e:
|
||||
let f = parsePair e.latex;
|
||||
in lib.foldl' lib.max 0.0 (genList
|
||||
(i:
|
||||
let
|
||||
t = i / 10.0;
|
||||
p = at mark.bezier t;
|
||||
dx = evalPoly (elemAt f 0) t - x p;
|
||||
dy = h - evalPoly (elemAt f 1) t - y p;
|
||||
in
|
||||
dx * dx + dy * dy)
|
||||
11))
|
||||
marks
|
||||
expressions);
|
||||
};
|
||||
}
|
||||
Generated
+27
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1793294725,
|
||||
"narHash": "sha256-loLMnbbS4KhmG2ln9EY6f0YMNCA273Yx02oWYQ9IMeE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "6f06d204d8f2d8761d9da78778745974a3216381",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-26.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
description = "mu, the piabrota company chart: its drawings, in pure Nix";
|
||||
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
|
||||
|
||||
outputs = { self, nixpkgs }:
|
||||
let
|
||||
systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ];
|
||||
each = nixpkgs.lib.genAttrs systems;
|
||||
drawing = import ./drawings { inherit (nixpkgs) lib; };
|
||||
in
|
||||
{
|
||||
# The README drawings: eye.svg, mu.svg, mu.desmos.json and mu-check.svg.
|
||||
packages = each (system:
|
||||
let pkgs = nixpkgs.legacyPackages.${system}; in {
|
||||
mu-art = pkgs.linkFarm "mu-art" [
|
||||
{ name = "eye.svg"; path = pkgs.writeText "eye.svg" drawing.eye; }
|
||||
{ name = "mu.svg"; path = pkgs.writeText "mu.svg" drawing.svg; }
|
||||
{ name = "mu.desmos.json"; path = pkgs.writeText "mu.desmos.json" drawing.desmos; }
|
||||
{ name = "mu-check.svg"; path = pkgs.writeText "mu-check.svg" drawing.checkSvg; }
|
||||
];
|
||||
});
|
||||
|
||||
# The drawing's tests pass and the committed files are its output (scripts/drawing.sh).
|
||||
checks = each (system:
|
||||
let pkgs = nixpkgs.legacyPackages.${system}; in {
|
||||
drawing = pkgs.runCommand "mu-art-check" { } ''
|
||||
${pkgs.lib.concatMapStrings (f: "echo 'failed: ${f.name}' >&2\n") drawing.failures}
|
||||
${pkgs.lib.optionalString (drawing.failures != [ ]) "exit 1"}
|
||||
art=${self.packages.${system}.mu-art}
|
||||
diff -u ${./docs/drawings/eye.svg} $art/eye.svg || { echo 'run scripts/drawing.sh' >&2; exit 1; }
|
||||
diff -u ${./docs/drawings/mu.svg} $art/mu.svg || { echo 'run scripts/drawing.sh' >&2; exit 1; }
|
||||
diff -u ${./docs/drawings/mu.desmos.json} $art/mu.desmos.json || { echo 'run scripts/drawing.sh' >&2; exit 1; }
|
||||
touch $out
|
||||
'';
|
||||
});
|
||||
};
|
||||
}
|
||||
Submodule
+1
Submodule products/agents added at 70f5b16e4b.
Submodule
+1
Submodule products/alerts added at 40d244f5e8.
Submodule products/asgard deleted from 3e614b4e7a.
Submodule
+1
Submodule products/dojo added at 5196fbb8d8.
Submodule
+1
Submodule products/gramatico added at d57371af30.
Submodule
+1
Submodule products/ihero added at ed8dfa1e90.
Submodule
+1
Submodule products/nix-os added at 6d636be2c4.
Submodule
+1
Submodule products/pirsig added at b7dd1da2ac.
Submodule
+1
Submodule products/rax added at b87c790db8.
Submodule products/yggdrasil deleted from 5802a015e7.
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
# Write the README drawings, docs/drawings/eye.svg, mu.svg and its Desmos state, from drawings/*.nix.
|
||||
# nix flake check then fails if a drawing test fails or the committed files are not this output.
|
||||
# drawing.sh
|
||||
set -euo pipefail
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
||||
art="$(nix --extra-experimental-features 'nix-command flakes' build .#mu-art --no-link --print-out-paths)"
|
||||
cat "$art/eye.svg" >docs/drawings/eye.svg
|
||||
cat "$art/mu.svg" >docs/drawings/mu.svg
|
||||
cat "$art/mu.desmos.json" >docs/drawings/mu.desmos.json
|
||||
+25
-52
@@ -2,14 +2,14 @@
|
||||
# Private repos are never listed, only counted: this repository is public.
|
||||
[meta]
|
||||
as_of = "2026-11-01"
|
||||
private_count = 2
|
||||
private_count = 0
|
||||
|
||||
[[umbrella]]
|
||||
[[chart]]
|
||||
name = "mu"
|
||||
licence = "CC BY 4.0, AGPL-3.0, MPL-2.0"
|
||||
what = "The company umbrella: dogma, charter, standards, journal, brand and the scripts every project inherits."
|
||||
what = "The company chart: dogma, charter, standards, journal, brand and the scripts every project inherits."
|
||||
|
||||
[[umbrella]]
|
||||
[[chart]]
|
||||
name = ".github"
|
||||
licence = "MPL-2.0"
|
||||
what = "The org's profile, with the project table, the fabric figure and the funding links."
|
||||
@@ -57,25 +57,39 @@ what = "The NixOS configuration of the small VPS that serves piabrota.art. A mer
|
||||
role = "Hosts the site, rax, the agents and PGX."
|
||||
|
||||
[[project]]
|
||||
name = "ihoje"
|
||||
lane = "archived"
|
||||
licence = "no licence file"
|
||||
what = "A Rust event scraper with anime-inspired module names. Archived and no longer maintained."
|
||||
role = "None."
|
||||
name = "ihero"
|
||||
lane = "play"
|
||||
licence = "MPL-2.0"
|
||||
what = "A FOSS music player and game, in Rust. Coming: the repo holds only its licence."
|
||||
role = "None yet."
|
||||
|
||||
[[project]]
|
||||
name = "dojo"
|
||||
lane = "not set"
|
||||
licence = "MPL-2.0"
|
||||
what = "道場. Empty so far: a licence and a title."
|
||||
role = "None yet."
|
||||
|
||||
[[fork]]
|
||||
name = "yggdrasil"
|
||||
upstream = "ouroboric-dev/yggdrasil"
|
||||
group = "The factory"
|
||||
sync = "even"
|
||||
why = "Submodule of this repo: the agentic factory."
|
||||
why = "The agentic factory this repo inherited its method from."
|
||||
|
||||
[[fork]]
|
||||
name = "asgard"
|
||||
upstream = "ouroboric-dev/asgard"
|
||||
group = "The factory"
|
||||
sync = "even"
|
||||
why = "Submodule of this repo: the kickstart realm."
|
||||
why = "The kickstart realm of that factory."
|
||||
|
||||
[[fork]]
|
||||
name = "cloudroom"
|
||||
upstream = "davidondrej/cloudroom"
|
||||
group = "Agents and memory"
|
||||
sync = "2 behind"
|
||||
why = "A platform to run many agents; this repo vendors its `adr-verbatim` skill."
|
||||
|
||||
[[fork]]
|
||||
name = "skills"
|
||||
@@ -91,13 +105,6 @@ group = "Agents and memory"
|
||||
sync = "even"
|
||||
why = "Skills that orchestrate coding agents on long tasks."
|
||||
|
||||
[[fork]]
|
||||
name = "rea"
|
||||
upstream = "morluto/rea"
|
||||
group = "Agents and memory"
|
||||
sync = "761 behind"
|
||||
why = "Reverse engineering with agents."
|
||||
|
||||
[[fork]]
|
||||
name = "TencentDB-Agent-Memory"
|
||||
upstream = "TencentCloud/TencentDB-Agent-Memory"
|
||||
@@ -154,13 +161,6 @@ group = "Runtimes and compilers"
|
||||
sync = "even"
|
||||
why = "A compiler-based safety checker for GPU kernels, in Lean 4."
|
||||
|
||||
[[fork]]
|
||||
name = "thc"
|
||||
upstream = "ekmett/thc"
|
||||
group = "Runtimes and compilers"
|
||||
sync = "even"
|
||||
why = "The Turbo Haskell Compiler."
|
||||
|
||||
[[fork]]
|
||||
name = "core"
|
||||
upstream = "home-assistant/core"
|
||||
@@ -168,30 +168,3 @@ group = "Other"
|
||||
sync = "795 behind"
|
||||
why = "Home Assistant: local home automation."
|
||||
|
||||
[[fork]]
|
||||
name = "edit"
|
||||
upstream = "fmhy/edit"
|
||||
group = "Other"
|
||||
sync = "7 behind"
|
||||
why = "Changes to FMHY."
|
||||
|
||||
[[fork]]
|
||||
name = "prj-gd-engine"
|
||||
upstream = "mbracali/prj-gd-engine"
|
||||
group = "Other"
|
||||
sync = "179 behind"
|
||||
why = "Re-implementations of guitar music games."
|
||||
|
||||
[[fork]]
|
||||
name = "naruto-unison"
|
||||
upstream = "naruto-unison/naruto-unison"
|
||||
group = "Other"
|
||||
sync = "even"
|
||||
why = "Naruto Unison, a game."
|
||||
|
||||
[[fork]]
|
||||
name = "OpenVoice"
|
||||
upstream = "myshell-ai/OpenVoice"
|
||||
group = "Other"
|
||||
sync = "even"
|
||||
why = "Instant voice cloning."
|
||||
@@ -2,18 +2,20 @@
|
||||
# PIABROTA
|
||||
|
||||
Every public repo of [piabrota](https://github.com/piabrota), an open software fabric made in Rio de
|
||||
Janeiro: {{ umbrella|length + project|length + fork|length }} public repos, as of {{ meta.as_of }}. The rules
|
||||
are in [DOGMA.md](DOGMA.md). The org's {{ meta.private_count }} private repos are counted, never listed.
|
||||
Janeiro: {{ chart|length + project|length + fork|length }} public repos, as of {{ meta.as_of }}. The rules
|
||||
are in [DOGMA.md](DOGMA.md).{% if meta.private_count %} The org's {{ meta.private_count }} private repos are counted, never listed.{% endif %}
|
||||
|
||||
## Umbrella
|
||||
## Company
|
||||
|
||||
| Repo | Licence | What it is |
|
||||
| --- | --- | --- |
|
||||
{% for r in umbrella -%}
|
||||
{% for r in chart -%}
|
||||
| [`{{ r.name }}`](https://github.com/piabrota/{{ r.name }}) | {{ r.licence }} | {{ r.what }} |
|
||||
{% endfor %}
|
||||
## Projects
|
||||
|
||||
The projects are the submodules under [`products/`](products/).
|
||||
|
||||
| Repo | Lane | Licence | What it is | Its place in the company |
|
||||
| --- | --- | --- | --- | --- |
|
||||
{% for r in project -%}
|
||||
|
||||
Reference in new issue
Block a user