-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy path.fabrika.jsonc
More file actions
155 lines (144 loc) · 8.69 KB
/
Copy path.fabrika.jsonc
File metadata and controls
155 lines (144 loc) · 8.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
{
// Binds this file to its JSON Schema so an editor autocompletes keys and reds a typo or a
// wrong-typed value while you type, instead of at fabrika runtime. The schema is generated from
// the config-key fragments by `fabrika config schema --write` — never hand-edited (#6488).
"$schema": "./.fabrika.schema.json",
// Who may clear one extra repair round on a PR (`fabrika build clear`). Founder-ruled 2026-08-18
// on #5959: the grant-author set is repo configuration, not a compiled-in "founder" concept —
// GitHub usernames and teams, both `@`-prefixed as GitHub writes them. In phoenix it is the
// three founder accounts. One grant buys exactly one round.
// The governed roots — declared verbatim per the shipped default (config/keys/governed-roots.ts):
// phoenix's four roots plus this file. Declared explicitly 2026-08-26 after the two-derivations
// mismatch (#4730-class) parked PRs #7085/#7114: ship gate raises governance from raw paths
// (#5036) while review scope/post dropped the namespace absent this declaration — the gate
// demanded what the reviewer verb could not emit.
"governedRoots": [".decisions/", ".claude/", ".github/", "claude-plugins/", ".fabrika.jsonc"],
"capClearAuthors": ["@usirin", "@notusirin", "@cansirin"],
// The names that resolve only in this repository, which fabrika's own shipped text may not
// carry (`fabrika guard portability-guard check`). The shipped default is the empty list and
// turns nothing off — the guard's four other rules never read this key. phoenix names its org,
// its repo, its products and the one app directory its skills used to point at.
"portability": {
"repoNames": ["phoenix", "kamp-us", "Tuval", "sözlük", "apps/web"]
},
// How many issue lanes a driver may hold at once — the number the founder drove this weekend, now
// enforced at the boot instead of remembered (#8264). A seat is an active lane whose issue carries
// a live `lane claim`; an active lane nobody claims is idle and counts for nothing (#8484).
// `lane open` and `lane emit` refuse past it with nothing written; there is no override flag, so
// raising this line is the only way past.
"laneConcurrencyCap": 2,
// Who may declare a campaign or flip its lifecycle state (`fabrika campaign open` / `campaign
// state`). It narrows the repo's collaborator ACL and never replaces it: an entry here still
// needs `write` or above on the repo (ADR 0294). Founder-declared 2026-08-20 on #6811 — the
// shipped default is empty, which refuses every declaration, so phoenix names the founder.
"campaignAuthors": ["@usirin"],
// Docs whose subject IS path hygiene: they must spell the forbidden path shapes out, so
// `fabrika build check --surface prose` skips its leak scan on them. Repo-relative path
// suffixes, matched by suffix the way `fabrika guard leak-guard scan` matches its own
// self-exempt list (#5687). This is phoenix's second declaration of one policy, and it is the
// MARKDOWN half: the gate also self-exempts shell and TypeScript files the prose surface never
// scans. The two are held equal by a test, not by this comment —
// `packages/fabrika-cli/src/guard/leak.golden.test.ts` reds when either side moves (ADR 0251).
// A repo without these docs declares an empty list, or no key at all, and nothing is exempt.
"docLeakExempt": [
"/CLAUDE.md",
"/agents/triager.md",
"/packages/leak-guard/README.md",
"/skills/report/SKILL.md",
"/skills/review-doc/SKILL.md",
"/skills/triage/SKILL.md"
],
// NOTHING READS THIS KEY. A §CP read that fails is the caller's exit 11 in every repo, and a
// proven-absent CODEOWNERS is the `unknown` hold — the founder reverted the per-repo policy on
// #5631, back to ADR 0220 §4. The strict value is kept declared so this repo cannot drift if the
// key is ever wired up again; what becomes of the key itself is the founder's to rule.
"unreadableCodeowners": "refuse",
// The repo's own commands that compile and lint its code. `fabrika build check --surface code`
// runs each one in the lane's tree, and both script names here are phoenix's own —
// `typecheck:affected` and `lint:worktree`. Nothing is compiled into the CLI, so a repo
// declaring nothing gets a named refusal rather than these two commands (#6015).
//
// `typecheck:affected` is `TURBO_SCM_BASE=origin/main turbo run typecheck --affected`: the
// packages this branch changed plus their dependents, measured from the MERGE-BASE of
// `origin/main` and HEAD. The cache carries the rest, and turbo shares one `.turbo/cache` across
// every linked worktree of this clone, so a lane that touched one package pays for one package.
// The base lives in the script rather than here because a validator is argv with no environment,
// and `--affected` takes its base from `TURBO_SCM_BASE` (defaulting to a LOCAL `main`, which in a
// lane worktree lags the remote) — the same script backs the pre-push hook, so one base serves
// both.
//
// Two things this deliberately does not do. There is no cache-bypass flag: turbo 2.10.3's `run`
// reference defines it as ignoring cached artifacts and re-executing all tasks, so it recompiled
// every package on every check, every `lane integrate` and every repair round — for a
// cache-poisoning risk nothing here ever recorded, and which `ci.yml`'s own bare `pnpm typecheck`
// never took (#8275). And it does not use `--filter=...[origin/main]`, which diffs against the
// ref itself rather than the merge-base and so selects every package on any branch behind main
// (#8273 review round 1). A checkout too shallow to hold a merge base degrades to every package,
// the fail-safe direction.
"codeValidators": [
{ "command": ["pnpm", "typecheck:affected"] },
{ "command": ["pnpm", "lint:worktree"] }
],
// The install that reconciles a tree with the lockfile it carries. `fabrika lane integrate` runs
// it in the epic run's assembly worktree after a clean child merge and before the validators
// above, so they compile against the merged lockfile rather than the install the worktree was
// placed with (#7188). `--frozen-lockfile` is pnpm's fail-closed flag: an install that cannot
// honor the merged lockfile refuses instead of rewriting it, and the integration reads that as
// a FAIL.
"dependencyReconciler": { "command": ["pnpm", "install", "--frozen-lockfile"] },
// The runnable apps this repo renders, one row per app (ADR 0345) — the list `review scope` /
// `ship scope` raise the `ui` class from and `ui render` boots. `prefix` is the source root whose
// changed files raise that class: `web` and `web-lab` share `apps/web/src/` because they are two
// mounts over one app. Ported from the retired `design-harness.json` (#7369); no row declares a
// port, because a fixed port is not a per-worktree resource (#7992).
"uiSurfaces": [
{
"name": "web",
"prefix": "apps/web/src/",
"mount": "/",
"command": "[ -f apps/web/.env ] || cp apps/web/.env.example apps/web/.env; export PHOENIX_SPA_PORT={{port}} PHOENIX_WORKER_PORT={{port:worker}}; pnpm --filter @kampus/web dev:worker 1>&2 & pnpm --filter @kampus/web dev 1>&2",
"readyPath": "/api/health"
},
{
"name": "web-lab",
"prefix": "apps/web/src/",
"mount": "/lab",
"command": "PHOENIX_SPA_PORT={{port}} pnpm --filter @kampus/web dev 1>&2",
"readyPath": "/"
},
{
"name": "tuval-chat",
"prefix": "apps/tuval/src/",
"mount": "/tuval/chat",
"basePath": "/",
"command": "pnpm --filter @kampus/tuval proof:chat --port {{port}} --strictPort 1>&2",
"readyPath": "/"
},
{
"name": "tuval-pi-window",
"prefix": "apps/tuval/src/",
"mount": "/tuval/pi-window",
"basePath": "/",
"command": "pnpm --filter @kampus/tuval proof:pi-window --port {{port}} --strictPort 1>&2",
"readyPath": "/"
},
{
"name": "tuval-pi-vertical",
"prefix": "apps/tuval/src/",
"mount": "/tuval/pi-vertical",
"basePath": "/",
"command": "pnpm --filter @kampus/tuval proof:pi-vertical --page-port {{port}} --strict-port 1>&2",
"readyPath": "/"
}
],
// The repo's own commands that machine-read `.github/workflows/**`. `fabrika build check
// --surface workflows` runs each one over a workflows-touching diff, on top of `actionlint` when
// the tree has one (#5991), and `reads` names the exact workflow files that command opens — the
// only thing that tells the verb WHICH changed workflow a passing run actually covers.
//
// Phoenix declares none, and the empty list is the ruling rather than a gap: founder ruling on
// #5991, 2026-08-18 — the surface stands on `actionlint` alone. So a local tree without
// `actionlint` opens no workflow file and `--surface workflows` refuses `11`, UNKNOWN — never
// green — and `ci.yml`'s own jobs stay the deciding authority on these files.
"workflowValidators": []
}