@mestreyoda/fabrica 0.2.22 → 0.2.24
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.
- package/ARCHITECTURE.md +137 -0
- package/README.md +1 -0
- package/defaults/fabrica/prompts/developer.md +22 -6
- package/defaults/fabrica/prompts/reviewer.md +15 -0
- package/defaults/fabrica/prompts/tester.md +9 -0
- package/dist/index.js +1569 -406
- package/package.json +2 -1
package/ARCHITECTURE.md
ADDED
|
@@ -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
|
-
|
|
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
|