5.2 KiB
The Mize software factory framework.
goal: make clean/sane, configurable, extensible, maintanable, human-comprehendable, debuggable, tracable, pluggable, well-architectured, ... software usuing agentic engineering.
@./docs/general-agent-guide.md
Overview
Mize is built around the parts architecture which allows you to compose anc configure functionality modularly. Each part is a self-contained unit that:
- can store and manage its own state
- can expose methods to other parts
- Registers itself with the Mize instance
- Defines configuration options
- define UI components (called presenters)
Parts are the primary way to build any new software using this framework.
conditions when to stop and check back in with the human (IMPORTANT).
- dealing with/adding dependencies on system libraries or packages is also something to stop for and ask the user how to do it.
- in case it takes too long finding smth or figuring smth out. stop and ask the user. (goal is not to do stuff as autonomous as possible)
- Stop on architectural dead-ends. If something does not work out architecture-wise — e.g. one part needs to notify another of a state change, but there is no elegant existing mechanism (
method/opt/has_part/ listeners / etc.) — do not invent a hacky workaround and push on. Stop, describe the gap and the options you see, and ask the user how to proceed.
some other notes
-
Prefer expanding an existing part over creating a new one when it fits — but ask user before expanding.
-
when developing a new part. present it's config options and methods to the human first.
When turning a design / whole application into parts, follow Splitting an app into parts.
Splitting an app into parts
A part is a named capability with its own config namespace and callable surface — not a technical layer (UI/API/DB) and not a folder dump of screens.
When turning a design document or whole application into parts:
- One capability, one part — Group requirements that share one job and vocabulary (login/tokens, inbox, hub shell). That cluster becomes one part id (
auth.client,mme,sci.inbox). - Config namespace = part boundary — Settings that naturally sit under one prefix (
auth.client.issuer, …) belong to that part. Two unrelated prefixes → two parts. - Methods are the public API — Expose capability-shaped methods (
login,set_login_state), not “whatever the dashboard clicked.” CLI and other parts should call the samemethods viadyn_call/ generated bindings — don’t use CLIrunas the only inter-part API. - Product / UI shells are thin — Dashboards own layout and presentation. Domain work stays in capability parts. Optional UI notify via
has_part("…")+dyn_callso headless/CLI still works. - Split on replaceability or reuse — Would you swap the IdP but keep the hub? Second app needs login without the hub? Keep that capability separate. Only this screen will ever use X? Keep X in the shell until a second consumer appears.
- Don’t split only by layer — Avoid default
foo.ui+foo.logic. Preferfoo(capability) + optional shell. Shared widgets can be a library (e.g.dioxus-components) until they need mize opts/methods. - Hard vs soft dependency — Hard: cannot run without the other (load order / deps). Soft: “if UI is loaded, push URL/code.” Soft deps must not break headless use.
- Lifecycle is a boundary smell — Background refresh, blocking window, long device poll with different lifetimes often means the domain side should be its own part with clear methods.
- Start coarse; split on friction — Prefer fewer parts from a design doc. Split when a second consumer appears, config namespaces diverge, or you need to enable one capability without another.
- Before coding, present a part table — For each proposed part:
id, one-sentence responsibility,opts,methods, hard deps, soft notifies. Present that to the human first (same rule as presenting config options and methods).
UI work
For any UI work:
- Use Dioxus (desktop unless the user says otherwise).
- Build with
parts/mize.ui/dioxus-components— reuse existing components (Button,Prompt,Control, …) and extend that library when something reusable is missing; don’t invent a parallel widget set. - Prefer inlined CSS via
OnceStyle/ isolated style components (see that crate). Do not putdocument::Styleinside components that re-render often; don’t bring backasset!/ css-modules for these components unless the user asks. - Don’t block the Dioxus UI thread on long part work (login flows, etc.): background thread / async + part
methods updating shared state the UI reads.
unless specified diferently any mize UI uses the PPC color pallete (derived from the PPC Logo: https://wiki.ppc.social/PPC-Logo):
Token Light mode Dark mode
Background #F7F8F4 #171D18
Surface #FFFFFF #242D25
Surface secondary #EFF2EA #2C362D
Primary text #20251C #F2F4EA
Secondary text #66705E #AAB5A4
Border #DFE4D9 #3A463A
Primary accent #FEC251 #D7E47D
Accent text #79500F #D7E47D
Success #526F32 #B9D987
Info #376777 #B9E4EB
Warning #A66B13 #FFD77F
Danger #B94D42 #FF9B8E