@mestreyoda/fabrica 0.2.22 → 0.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,137 @@
1
+ # Architecture
2
+
3
+ ## Core shape
4
+
5
+ Fabrica is implemented as a local OpenClaw plugin with the local repository as
6
+ its source of truth.
7
+
8
+ Main areas:
9
+
10
+ - `lib/intake`
11
+ Intake, target resolution, impact analysis, task creation and triage.
12
+ - `lib/github`
13
+ GitHub App auth, webhook ingestion, event store, PR binding, quality gate and
14
+ governance.
15
+ - `lib/services`
16
+ Pipeline, heartbeat, queue scans and workflow execution helpers.
17
+ - `lib/machines`
18
+ `FabricaRunMachine` and `LifecycleMachine` for explicit state transitions.
19
+ - `lib/observability`
20
+ Pino logging, correlation context and OpenTelemetry spans.
21
+ - `lib/dispatch`
22
+ DM bootstrap, Telegram topic routing, worker notifications and attachment hooks.
23
+ - `lib/telegram`
24
+ Telegram config resolution and topic creation services.
25
+ - `defaults`
26
+ Packaged assets and workflow defaults that ship with the plugin.
27
+ - `genesis`
28
+ Packaged runtime assets still used by the plugin during the migration away
29
+ from older shell-driven flows.
30
+
31
+ ## Runtime model
32
+
33
+ Large/xlarge work can be represented as a parent coordination issue plus child
34
+ execution issues.
35
+
36
+ Canonical runtime fields live in `project.issueRuntime[issueId]`:
37
+
38
+ - `parentIssueId`
39
+ - `childIssueIds`
40
+ - `dependencyIssueIds`
41
+ - `decompositionMode`
42
+ - `decompositionStatus`
43
+ - `completedChildIssueIds`
44
+ - `blockedChildIssueIds`
45
+ - `maxParallelChildren`
46
+
47
+ Operational rules:
48
+
49
+ - parent issues are coordinator-only and do not enter normal developer execution
50
+ - child issues can enter the normal queue with their own level labels and PR flow
51
+ - dependency-linked children stay blocked until predecessor execution is complete
52
+ - sibling execution is capped by `maxParallelChildren`
53
+ - parent rollups are refreshed from child runtime and can auto-close when the
54
+ family is complete
55
+
56
+ ## Environment gate
57
+
58
+ `lib/test-env` provisions the shared toolchain and the project environment
59
+ before dispatching workers in `developer` or `tester` mode.
60
+
61
+ State model:
62
+
63
+ `pending -> provisioning -> ready | failed`
64
+
65
+ Environment contracts are versioned per family using `{family}@v1`
66
+ (for example `python@v1` and `node@v1`).
67
+
68
+ Operational rules:
69
+
70
+ - Python uses a shared toolchain in `~/.openclaw/toolchains/python`
71
+ - Python project environments are materialized locally as `.venv`
72
+ - Existing Node repos require a reproducible lockfile before real work starts
73
+ - Failure backoff is 60 seconds
74
+ - A provisioning state older than 10 minutes is treated as stale and retried
75
+ - `dryRun: true` skips environment provisioning entirely and stays side-effect free
76
+
77
+ ## Telegram routing model
78
+
79
+ New project intake is DM-first. The Fabrica bot accepts a new-project request in
80
+ Telegram DM, asks for missing essentials there if needed, and only creates the
81
+ project topic when the intake is ready to register. For greenfield projects,
82
+ repo provisioning now happens in the TS intake path before registration and
83
+ issue creation.
84
+
85
+ The canonic route identity for Telegram-backed projects is:
86
+
87
+ `channel=telegram + channelId + messageThreadId`
88
+
89
+ This avoids collisions between multiple projects inside the same Telegram forum
90
+ group. After registration:
91
+
92
+ - the project topic becomes the primary route for project messages
93
+ - follow-ups inside that topic resolve the exact project
94
+ - worker notifications and project lifecycle updates publish back to that topic
95
+ - ops alerts stay in the separate ops group
96
+
97
+ The hot path for GitHub is:
98
+
99
+ `webhook -> event store -> FabricaRun -> Quality Gate -> artifactOfRecord -> done`
100
+
101
+ Important invariants:
102
+
103
+ - a cycle never closes with an open canonical PR
104
+ - `Done` requires `artifactOfRecord`
105
+ - duplicate GitHub deliveries must not duplicate effects
106
+ - force-push updates the canonical binding instead of spawning duplicate runs
107
+
108
+ ## Installation model
109
+
110
+ Fabrica is distributed as a self-contained OpenClaw plugin package.
111
+
112
+ The supported operator path is:
113
+
114
+ ```bash
115
+ openclaw plugins install @mestreyoda/fabrica
116
+ ```
117
+
118
+ The installed extension must be loadable in isolation. Fabrica may depend on
119
+ OpenClaw only through the plugin host ABI and runtime objects passed by the
120
+ host. It must not require manual symlinks, local `npm install`, or host-global
121
+ module resolution to load.
122
+
123
+ External credentials and routes such as GitHub auth, Telegram chat IDs, and
124
+ webhook secrets are operational configuration, not installation dependencies.
125
+ Fabrica's `doctor` and `setup` flows guide and validate that operational
126
+ configuration where applicable.
127
+
128
+ ## Operational notes
129
+
130
+ - Gateway runtime is managed by the OpenClaw systemd service.
131
+ - GitHub webhook ingress is protected by GitHub signature validation inside the
132
+ plugin; the route itself must remain reachable without gateway bearer auth.
133
+ - GitHub App and webhook credentials are expected to come from the Fabrica
134
+ plugin config (`openclaw.json`) using direct values and credential file paths;
135
+ legacy env-based fields remain only as compatibility fallback.
136
+ - Structured logs and OpenTelemetry spans are emitted by the plugin itself.
137
+ - Security validation lives in `openclaw fabrica doctor security --json`.
package/README.md CHANGED
@@ -43,6 +43,7 @@ The heartbeat ticks every 60 seconds. On each tick, Fabrica alternates between a
43
43
  - **Pluggable AI workers** — each role (developer, reviewer, tester, architect) maps to a configurable model and level
44
44
  - **Polling-first GitHub integration** — uses `gh` CLI for all GitHub operations; no webhook infrastructure or GitHub App required
45
45
  - **Telegram bootstrap** (optional) — describe a new project via DM; Fabrica asks clarifying questions and provisions the repo automatically
46
+ - **Parent/child large-work orchestration** — large initiatives can become one coordinator issue plus execution-ready child issues with dependency-aware scheduling and automatic parent rollups
46
47
  - **Stack-aware environment gate** — developer and tester dispatch only start after the project stack environment is provisioned and marked ready
47
48
  - **Lifecycle-driven worker completion** — reviewer, developer, tester, and architect completion resolve from agent lifecycle plus canonical result lines, not from fragile tool availability assumptions
48
49
  - **Detailed event timeline** — project topics receive explicit worker start, completion, review, rejection, and recovery events with cycle-aware dedupe
@@ -29,18 +29,18 @@ Read the comments carefully — they often contain clarifications, decisions, or
29
29
  ```bash
30
30
  # Example: task message says Repo: /home/ubuntu/git/acme/myproject
31
31
  REPO_ROOT="/absolute/path/from-task-message"
32
- cd "$REPO_ROOT"
33
32
  BRANCH="feature/<issue-id>-<slug>"
34
33
  WORKTREE="${REPO_ROOT}.worktrees/${BRANCH}"
35
- if git worktree list --porcelain | grep -Fq "worktree ${WORKTREE}"; then
34
+ mkdir -p "$(dirname "$WORKTREE")"
35
+ if git -C "$REPO_ROOT" worktree list --porcelain | grep -Fq "worktree ${WORKTREE}"; then
36
36
  cd "$WORKTREE"
37
37
  else
38
- git worktree add "$WORKTREE" -b "$BRANCH"
38
+ git -C "$REPO_ROOT" worktree add "$WORKTREE" -b "$BRANCH"
39
39
  cd "$WORKTREE"
40
40
  fi
41
41
  ```
42
42
 
43
- The `.worktrees/` directory sits NEXT TO the repo folder (not inside it). This keeps the main checkout clean for the orchestrator and other workers. If the assigned worktree already exists from a previous task on the same branch, verify it's clean and reuse it.
43
+ The `.worktrees/` directory sits NEXT TO the repo folder (not inside it). This keeps the main checkout clean for the orchestrator and other workers. Never improvise with `./.worktrees`, `${REPO_ROOT}/.worktrees`, or any other in-repo worktree path. If the assigned worktree already exists from a previous task on the same branch, verify it's clean and reuse it.
44
44
 
45
45
  Never create or implement the project under `~/.openclaw/workspace/<slug>` unless the task message explicitly says that directory is the canonical repo path. If the repo already contains scaffolded files, do not re-initialize the project with `npm init`, `uv init`, `cargo init`, or a second skeleton generator — keep the existing stack and modify the scaffold inside the assigned worktree. Once you are in the assigned worktree, stay there for the rest of the task and do not switch back to the main checkout.
46
46
 
@@ -51,6 +51,15 @@ Never create or implement the project under `~/.openclaw/workspace/<slug>` unles
51
51
  - Follow existing code patterns and conventions in the project
52
52
  - Run tests/linting if the project has them configured
53
53
 
54
+ ### Technical Quality Bar
55
+
56
+ - Prefer the most idiomatic, well-supported solution for the project's stack instead of inventing custom infrastructure.
57
+ - Match the project archetype: API projects need strong boundary validation and error handling; CLI projects need excellent help/exit-code UX; UI projects need clear loading/error states.
58
+ - Choose mature libraries/functions that simplify the codebase and improve reliability. Do not add a dependency when the standard stack already solves the problem cleanly.
59
+ - Keep the implementation simple and cohesive. Avoid overengineering, speculative abstractions, and generic frameworks for a narrow problem.
60
+ - Optimize for maintainability first, then performance where the task actually needs it. Remove obvious inefficiencies in hot paths, repeated I/O, wasteful queries, and duplicated work.
61
+ - If the request is security-sensitive (auth, permissions, secrets, payments, personal data), treat correctness and safe defaults as mandatory, not optional polish.
62
+
54
63
  ### Structure & Hygiene
55
64
 
56
65
  - **No monolith files.** If a single file exceeds ~200 lines or mixes concerns (routes, business logic, templates), split into focused modules.
@@ -82,7 +91,8 @@ Conventional commits: `feat:`, `fix:`, `chore:`, `refactor:`, `test:`, `docs:`
82
91
  - **NEVER** include host-system paths outside the repository (e.g., `/home/*/`, `~/.openclaw/`)
83
92
  - **NEVER** include raw output of commands not explicitly listed in this template
84
93
 
85
- Use `gh pr create` with the template below. Do NOT deviate from this format:
94
+ Use `gh pr create` with the template below. Do NOT deviate from this format.
95
+ Create the PR with the base body only first — do NOT try to embed multiline `## QA Evidence`, code fences, or raw `scripts/qa.sh` output directly inside the `gh pr create --body "..."` command. That content must be added only by the separate QA Evidence PATCH workflow below.
86
96
 
87
97
  ```bash
88
98
  gh pr create --base "$BASE_BRANCH" \
@@ -106,6 +116,7 @@ Addresses issue #<issue-id>.
106
116
  **Do NOT use closing keywords** in the description (no "Closes #X", "Fixes #X"). Use "Addresses issue #X" instead — Fabrica manages issue lifecycle.
107
117
 
108
118
  **Do NOT invent ad-hoc sections** beyond Summary, Changes, and Security Checklist. The only additional section allowed in the PR body is the canonical `## QA Evidence` section updated in place by the QA workflow below.
119
+ **Never place `## QA Evidence` directly in the initial `gh pr create --body` text.** Create the PR first, then update that section via the dedicated PATCH flow below.
109
120
 
110
121
  ### Handling PR Feedback (changes requested / To Improve)
111
122
 
@@ -130,10 +141,15 @@ When your task message includes a **PR Feedback** section, it means a reviewer r
130
141
 
131
142
  ### QA Evidence (MANDATORY)
132
143
 
133
- After implementing (or after addressing reviewer feedback), run `scripts/qa.sh` in the worktree. The QA script is expected to bootstrap project-local test dependencies when needed; do not rely on a shared host-level venv or globally preinstalled project packages. Then **replace the PR description body's existing `## QA Evidence` section** with fresh sanitized output (never append a second section):
144
+ After implementing (or after addressing reviewer feedback), run `scripts/qa.sh` in the worktree. The QA script is expected to bootstrap project-local test dependencies when needed; do not rely on a shared host-level venv or globally preinstalled project packages. Then **replace the PR description body's existing `## QA Evidence` section** with fresh sanitized output (never append a second section).
145
+ Do this as a second step after PR creation — not inline in `gh pr create` — because multiline QA output, code fences, and shell quoting frequently corrupt the initial PR creation command:
146
+
147
+ **Do NOT weaken, replace, or bypass the canonical `scripts/qa.sh` contract just to make the task pass.** Preserve the five canonical gates (`lint`, `types`, `security`, `tests`, `coverage`) and fix the product code or project setup instead. Ad-hoc scenario scripts, one-off smoke tests, or custom gate names do not satisfy Fabrica's QA Evidence validator.
134
148
 
135
149
  ```bash
136
150
  # Get current PR body, replace QA Evidence, update
151
+ # IMPORTANT: keep this as a separate PATCH step after `gh pr create` succeeds.
152
+ # Never paste multiline QA output directly into the `gh pr create --body` command.
137
153
  PR_NUM=$(gh pr list --head "$BRANCH" --json number -q '.[0].number')
138
154
  QA_RAW=$(bash scripts/qa.sh 2>&1); QA_EXIT=$?
139
155
  # MANDATORY: sanitize before embedding in PR — strip lines with tokens/keys/env vars/host paths
@@ -91,8 +91,23 @@ Do **not** treat the task envelope (`Repo:`, `Project:`, `Channel:`, branch hint
91
91
 
92
92
  - Read the PR diff carefully
93
93
  - Check the code against the review checklist
94
+ - Reject work that solves the wrong problem, uses an obviously poor approach for the stack, or adds unnecessary complexity
94
95
  - Output your decision in the format described in **Completing Your Task** below
95
96
 
97
+ ## Technical Review Bar
98
+
99
+ Your job is not to ask whether the code merely works. Your job is to decide whether it is good enough to represent Fabrica-quality delivery.
100
+
101
+ Reject when you find any of these:
102
+ - a solution that technically works but does not faithfully match the issue's requested behavior or constraints
103
+ - a weak stack fit (wrong library choice, brittle custom infrastructure, or avoiding a mature standard tool without reason)
104
+ - unnecessary complexity, speculative abstraction, or architecture inflation for a narrow task
105
+ - poor maintainability (unclear module boundaries, duplicated logic, confusing names, or hidden side effects)
106
+ - avoidable performance mistakes in likely hot paths or repeated I/O/query work
107
+ - security-sensitive code treated as optional polish instead of a correctness requirement
108
+
109
+ When you approve, it means you checked fidelity, technical approach, maintainability, and risk — not only style.
110
+
96
111
  ## Conventions
97
112
 
98
113
  - **Do NOT use closing keywords in PR/MR descriptions** (no "Closes #X", "Fixes #X", "Resolves #X"). Use "As described in issue #X" or "Addresses issue #X". Fabrica manages issue state — auto-closing bypasses the review lifecycle.
@@ -75,6 +75,15 @@ For each AC in the issue:
75
75
  - If an AC is ambiguous, note what you checked and mark CONDITIONAL
76
76
  - **Every single AC must be verified** — do not skip any
77
77
 
78
+ ### Quality & Evidence Bar
79
+
80
+ - Your job is to produce evidence proportional to the project archetype, not a superficial green check.
81
+ - For API work, verify request/response behavior, validation, and key failure paths.
82
+ - For CLI work, verify help output, exit codes, invalid-argument handling, and the main happy path.
83
+ - For UI work, verify the main flow plus loading/error behavior when applicable.
84
+ - For security-sensitive work (auth, permissions, secrets, payments, personal data), treat missing negative tests or weak evidence as a real failure, not a nit.
85
+ - If the implementation technically runs but the evidence is too weak to trust the result, prefer `Test result: FAIL` or `Test result: REFINE` over a false PASS.
86
+
78
87
  ### 4. Check for regressions
79
88
 
80
89
  - Run the full test suite if available