@magnusekdahl/parallix 1.0.0

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.
Files changed (123) hide show
  1. package/CHANGELOG.md +140 -0
  2. package/LICENSE +661 -0
  3. package/README.md +196 -0
  4. package/config/agents.json +25 -0
  5. package/config/agents.local.json.template +8 -0
  6. package/config/state-map.json +4 -0
  7. package/config/state-map.json.template +31 -0
  8. package/config/workflow.config.schema.json +98 -0
  9. package/data/.gitkeep +0 -0
  10. package/docs/adr/0031-ai-agent-instruction-boundary-and-command-floor.md +114 -0
  11. package/docs/adr/0032-mission-refinement-state-and-usage-budget-signals.md +135 -0
  12. package/docs/adr/0034-module-and-skill-invocation-model.md +202 -0
  13. package/docs/adr/0036-mission-sizing-and-dependency-wave-heuristics.md +79 -0
  14. package/docs/adr/0037-ai-workflow-coordination-architecture.md +162 -0
  15. package/docs/adr/0041-integration-pipeline-gates.md +165 -0
  16. package/docs/adr/0042-workflow-cli-color-rendering-approach.md +106 -0
  17. package/docs/adr/0043-git-target-resolution-strategy.md +185 -0
  18. package/docs/adr/0044-workflow-distribution-model.md +277 -0
  19. package/docs/adr/0045-parallax-branch-model.md +182 -0
  20. package/docs/adr/0046-npm-publish-process-and-security.md +138 -0
  21. package/docs/adr/index.md +20 -0
  22. package/docs/agents.md +212 -0
  23. package/docs/authority-reference.md +298 -0
  24. package/docs/forgejo-setup.md +31 -0
  25. package/docs/migration/extraction.md +61 -0
  26. package/docs/migration/task-classification.md +36 -0
  27. package/docs/operator-setup.md +76 -0
  28. package/docs/readme-rewrite-benchmark.md +188 -0
  29. package/docs/use-cases.md +105 -0
  30. package/examples/README.md +62 -0
  31. package/examples/run-enterprise-tarball-workflow-smoke.sh +257 -0
  32. package/examples/run-verify-env-smoke.sh +40 -0
  33. package/index.js +250 -0
  34. package/lib/README.md +13 -0
  35. package/lib/agents/agents.js +867 -0
  36. package/lib/agents/claude-telemetry.js +233 -0
  37. package/lib/agents/claude.js +139 -0
  38. package/lib/agents/codex-telemetry.js +202 -0
  39. package/lib/agents/codex.js +219 -0
  40. package/lib/agents/limit-hit.js +252 -0
  41. package/lib/agents/mistral-telemetry.js +44 -0
  42. package/lib/agents/mistral.js +68 -0
  43. package/lib/agents/opencode-export.js +110 -0
  44. package/lib/agents/opencode-telemetry.js +356 -0
  45. package/lib/agents/opencode.js +218 -0
  46. package/lib/agents/stage-telemetry.js +37 -0
  47. package/lib/commands/active.js +625 -0
  48. package/lib/commands/checkpoint.js +76 -0
  49. package/lib/commands/config.js +39 -0
  50. package/lib/commands/coverage-gate.js +358 -0
  51. package/lib/commands/diff.js +119 -0
  52. package/lib/commands/draft.js +854 -0
  53. package/lib/commands/handoff.js +501 -0
  54. package/lib/commands/integrate.js +1528 -0
  55. package/lib/commands/mission-start.js +246 -0
  56. package/lib/commands/rebase.js +597 -0
  57. package/lib/commands/repair-handoff.js +227 -0
  58. package/lib/commands/resolve-conflict.js +109 -0
  59. package/lib/commands/review.js +13 -0
  60. package/lib/commands/setup-review.js +13 -0
  61. package/lib/commands/setup.js +3 -0
  62. package/lib/commands/stats-backfill.js +395 -0
  63. package/lib/commands/stats.js +1601 -0
  64. package/lib/commands/status.js +183 -0
  65. package/lib/commands/verify.js +1 -0
  66. package/lib/core/fmt.js +202 -0
  67. package/lib/core/git.js +73 -0
  68. package/lib/core/gitignore.js +110 -0
  69. package/lib/core/mission-utils.js +1017 -0
  70. package/lib/core/persistent-data-migration.js +201 -0
  71. package/lib/core/product-config.js +508 -0
  72. package/lib/core/runtime-matrix.js +82 -0
  73. package/lib/core/spawn-tee.js +173 -0
  74. package/lib/core/state-map.js +89 -0
  75. package/lib/core/storage.js +165 -0
  76. package/lib/core/verification.js +149 -0
  77. package/lib/index.js +77 -0
  78. package/lib/review/rebase.js +163 -0
  79. package/lib/review/review-adapter.js +135 -0
  80. package/lib/review/review-artifacts.js +619 -0
  81. package/lib/review/review-commands.js +1375 -0
  82. package/lib/review/review-events.js +1007 -0
  83. package/lib/review/review-loop.js +1004 -0
  84. package/lib/review/review-polling.js +141 -0
  85. package/lib/review/review-prompts.js +212 -0
  86. package/lib/review/review-state.js +280 -0
  87. package/lib/review/review.js +96 -0
  88. package/lib/tools/backlog.js +680 -0
  89. package/lib/tools/forgejo.js +1585 -0
  90. package/lib/tools/gatekeeper.js +106 -0
  91. package/lib/tools/sessions.js +74 -0
  92. package/lib/tools/setup-review.js +1053 -0
  93. package/package.json +56 -0
  94. package/prompts/act-on-review-verbose.md +20 -0
  95. package/prompts/act-on-review.md +22 -0
  96. package/prompts/draft.md +20 -0
  97. package/prompts/execute.md +24 -0
  98. package/prompts/portfolio.md +30 -0
  99. package/prompts/review-verbose.md +20 -0
  100. package/prompts/review.md +17 -0
  101. package/px.js +236 -0
  102. package/templates/AGENTS-snippet.md +14 -0
  103. package/templates/AGENTS.md.template +34 -0
  104. package/templates/CLAUDE.md.template +27 -0
  105. package/templates/CODEX.md.template +38 -0
  106. package/templates/MISTRAL.md.template +24 -0
  107. package/templates/claude-commands/act-on-review.md +3 -0
  108. package/templates/claude-commands/area-review.md +3 -0
  109. package/templates/claude-commands/draft.md +6 -0
  110. package/templates/claude-commands/execute.md +6 -0
  111. package/templates/claude-commands/integrate.md +4 -0
  112. package/templates/claude-commands/portfolio.md +5 -0
  113. package/templates/claude-commands/review.md +4 -0
  114. package/templates/codex/config.toml +6 -0
  115. package/templates/mission-scaffold.md +39 -0
  116. package/templates/vibe/skills/act-on-review/SKILL.md +16 -0
  117. package/templates/vibe/skills/area-review/SKILL.md +16 -0
  118. package/templates/vibe/skills/draft/SKILL.md +16 -0
  119. package/templates/vibe/skills/execute/SKILL.md +16 -0
  120. package/templates/vibe/skills/integrate/SKILL.md +16 -0
  121. package/templates/vibe/skills/portfolio/SKILL.md +21 -0
  122. package/templates/vibe/skills/review/SKILL.md +16 -0
  123. package/tools/setup-forgejo-docker.sh +84 -0
@@ -0,0 +1,106 @@
1
+ # ADR 0042: Workflow CLI Color Rendering Approach
2
+
3
+ Status: Proposed
4
+ Date: 2026-05-23
5
+
6
+ ## Context
7
+
8
+ The workflow CLI (`workflow/lib/fmt.js`) uses hand-rolled ANSI escape codes for terminal coloring. The current `useColor()` function has a bug: lines 53–58 are unreachable dead code after an unconditional return on line 52, meaning the CI, COLORTERM, and isTTY fallback checks never execute. This has caused intermittent "sometimes colors, sometimes not" behavior (task-1132).
9
+
10
+ The workflow CLI's zero-dependency philosophy (Node.js built-ins only, no npm packages) constrains the solution space: adding `chalk`, `picocolors`, or `ink` would violate this principle.
11
+
12
+ Node.js v21.7+ ships `util.styleText(format, text)`, which:
13
+ - Handles `NO_COLOR`, `FORCE_COLOR`, `TERM=dumb`, and stream TTY detection automatically
14
+ - Supports all the color names the workflow already uses: `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, `bold`, `dim`
15
+ - Maps `gray`/`grey` to `\x1b[90m` — the exact code the workflow currently calls "dim"
16
+ - Uses proper per-format close codes (e.g., `\x1b[39m` for colors, `\x1b[22m` for bold) instead of a blanket `\x1b[0m` reset, enabling correct nesting
17
+ - Supports compound formats via array: `util.styleText(['bold', 'red'], text)`
18
+
19
+ This project runs Node v24.15.0; `util.styleText` is fully stable.
20
+
21
+ The Gemini CLI (`google-gemini/gemini-cli`) was examined as a reference point. Its CLI package uses `chalk` v4 + `ink` (React for terminals) + `ink-gradient` + `ink-spinner` + `ansi-escapes` — a heavy stack suited for rich interactive UIs. The core package uses no color library at all; it delegates rendering entirely to the CLI layer. The relevant takeaway is not the specific libraries, but the pattern: **use the platform's native capabilities for color detection rather than reimplementing it**.
22
+
23
+ ## Decision
24
+
25
+ Replace the hand-rolled ANSI palette and `useColor()` function in `workflow/lib/fmt.js` with Node.js built-in `util.styleText()`.
26
+
27
+ ## Decision matrix
28
+
29
+ | Option | Summary | Benefits | Risks / Costs | Fit to constraints | Decision |
30
+ |--------|---------|----------|---------------|--------------------|----------|
31
+ | A: `util.styleText` | Node.js built-in color API | Zero deps; auto color detection handles NO_COLOR/FORCE_COLOR/TERM/TTY correctly; proper close codes enable nesting; maintained by Node core | Tests must update expected ANSI close codes (`\x1b[0m` → `\x1b[39m` etc.); requires Node ≥21.7 (project already on v24) | Perfect — maintains zero-dep philosophy | **Accept** |
32
+ | B: `chalk` v4 | Most popular Node color lib | Battle-tested, rich API, CJS compatible | Adds npm dependency + `supports-color` transitive dep; violates zero-dep constraint | Poor — introduces external dependency | Reject |
33
+ | C: `picocolors` | Ultra-light color lib (~3KB) | Tiny, fast, CJS, auto detection | Still an npm dependency; basic API | Poor — still a dependency | Reject |
34
+ | D: Fix hand-rolled | Patch `useColor()` dead code | Minimal change, keeps existing API | Reinvents color detection that Node.js already provides; fragile; more code to maintain | Acceptable but inferior | Reject |
35
+ | E: Ink (Gemini CLI style) | React for terminals | Powerful interactive components | Massive dep tree (react, ink, chalk); CJS incompatible; complete overkill for batch CLI output | Very poor — wrong tool | Reject |
36
+
37
+ ## Consequences
38
+
39
+ ### Positive consequences
40
+
41
+ - **Color detection is correct by default.** `util.styleText` handles NO_COLOR, FORCE_COLOR, TERM=dumb, and stream TTY detection without any custom logic. The entire `useColor()` function and `_colorCache` can be removed.
42
+ - **Proper ANSI nesting.** Per-format close codes (`\x1b[39m` for color, `\x1b[22m` for bold) replace blanket `\x1b[0m` resets, so `bold(green(text))` works correctly.
43
+ - **Zero new dependencies.** Stays within the workflow's Node-built-ins-only constraint.
44
+ - **Reduced maintenance surface.** The `colors` object (raw escape codes), `useColor()`, `_colorCache`, and `resetColorCache()` are replaced by a single stdlib call.
45
+ - **Compound styling.** `util.styleText(['bold', 'cyan'], text)` replaces manual escape concatenation.
46
+
47
+ ### Negative consequences
48
+
49
+ - **Test assertions change.** Tests that assert specific ANSI sequences (e.g., `\x1b[32m[PASS]\x1b[0m`) must update to the new close codes (`\x1b[32m[PASS]\x1b[39m`). The `stripAnsi` regex also needs to cover close codes like `\x1b[22m`, `\x1b[39m` (it already does — the existing regex `\x1B\[[0-9;]*m` matches these).
50
+ - **Minimum Node version floor rises to 21.7.** Not a practical concern (project is on v24), but worth documenting.
51
+ - **Semantic rename: `dim()` → `gray()`.** The current `dim()` function uses `\x1b[90m` (bright black / gray), not the ANSI dim modifier (`\x1b[2m`). With `util.styleText`, the correct format name is `'gray'`. Callers of `fmt.dim()` should be audited — if they mean "gray text", the function should be renamed; if they mean "actually dim", it should use `'dim'`.
52
+
53
+ ## Alternatives considered
54
+
55
+ ### chalk v4 (CJS)
56
+
57
+ Positive:
58
+ - Proven in production across thousands of projects
59
+ - Clean chainable API (`chalk.bold.red(text)`)
60
+ - Solid color detection via `supports-color`
61
+
62
+ Negative:
63
+ - Adds an npm dependency to a zero-dependency package
64
+ - `supports-color` as a transitive dep introduces another moving part
65
+ - Unnecessary now that Node.js provides the same capability built-in
66
+
67
+ ### picocolors
68
+
69
+ Positive:
70
+ - ~3KB, extremely fast
71
+ - CJS compatible, drop-in simple API
72
+
73
+ Negative:
74
+ - Still an external dependency
75
+ - Basic API (no nesting, no compound styles)
76
+ - Less well-maintained than Node core
77
+
78
+ ### Keep hand-rolled, fix the dead-code bug
79
+
80
+ Positive:
81
+ - Smallest diff
82
+ - No behavior change in close codes
83
+
84
+ Negative:
85
+ - Re-implements color detection that Node.js already handles correctly
86
+ - The `_colorCache` pattern is fragile (requires `resetColorCache()` in tests)
87
+ - More surface area to maintain and get wrong again
88
+
89
+ ### Ink (React for terminals)
90
+
91
+ Positive:
92
+ - Extremely powerful for interactive UIs (spinners, layouts, live updates)
93
+ - Component model scales to complex interfaces
94
+
95
+ Negative:
96
+ - Massive dependency tree (react, ink, chalk, and dozens of transitive deps)
97
+ - ESM-only in recent versions; CJS fork exists but is unofficial
98
+ - Total architectural overkill for batch status output and tables
99
+ - Would require rewriting the entire fmt.js layer as React components
100
+
101
+ ## Links
102
+
103
+ - [Node.js `util.styleText` docs](https://nodejs.org/api/util.html#utilstyletextformat-text-options)
104
+ - [NO_COLOR standard](https://no-color.org/)
105
+ - [Gemini CLI package.json](https://github.com/google-gemini/gemini-cli/blob/main/packages/cli/package.json)
106
+ - [task-1132: workflow coloring in terminal is unstable](../missions/2026/task-1132/MISSION.md)
@@ -0,0 +1,185 @@
1
+ # ADR 0043: Git target resolution strategy for workflow branch operations
2
+
3
+ Status: Proposed
4
+ Date: 2026-05-24
5
+
6
+ ## Context
7
+
8
+ `node workflow rebase` and `node workflow integrate` must reason about the same primary-branch target or they can compute different merge bases for the same mission branch. That drift is active in the current repo state: local `main` is at `7f0db085c`, while the local remote-tracking ref `review/main` is still at `f6318aa6f`, so the local branch is one commit ahead of the Forgejo-tracking copy.
9
+
10
+ Before this change, `workflow/lib/rebase.js` fetched `review/<primary>` but then rebased the mission branch onto `review/<primary>`. `workflow/lib/integrate.js`, by contrast, performs integration decisions from the local primary checkout. The result is a split-brain workflow:
11
+
12
+ - Rebase can move a mission branch onto stale Forgejo state.
13
+ - Integrate can then compare or merge against newer local state.
14
+ - The same mission can therefore produce different ancestry answers between rebase and integrate, including "unrelated histories" failures during later integration steps.
15
+
16
+ Forgejo PRs are remote objects, so Forgejo itself cannot literally target an unpublished local branch. The actual decision is therefore two separate questions:
17
+
18
+ 1. Which git ref is authoritative for local branch-to-branch ancestry decisions inside the workflow CLI?
19
+ 2. How should the workflow keep Forgejo's remote `main` aligned enough that PR diffs and review UI reflect the same baseline?
20
+
21
+ ## Decision
22
+
23
+ Adopt a **local-first git target resolution rule** for workflow branch operations:
24
+
25
+ - Fetch `review/<primary>` when the workflow needs to refresh remote visibility.
26
+ - Use the local primary branch ref (`main` or `master`, via `getPrimaryBranch()`) as the authoritative target for `git rebase`, merge-base reasoning, and manual recovery instructions executed inside a local worktree.
27
+
28
+ ## Invariants
29
+
30
+ Invariant 1: Any workflow command that performs a local branch-to-branch ancestry operation MUST target the local primary branch ref, not `review/<primary>`.
31
+
32
+ Invariant 2: Fetching `review/<primary>` MAY refresh remote state, but fetch success MUST NOT change the authoritative rebase or merge-base target away from the local primary branch.
33
+
34
+ Invariant 3: User-facing workflow instructions for manual recovery MUST name the same local primary branch target that the automated workflow path uses.
35
+
36
+ Invariant 4: Tests for workflow branch operations MUST encode the local-primary-target rule so remote-tracking refs cannot silently re-enter rebase-target expectations.
37
+
38
+ ## Options considered
39
+
40
+ | Option | Branch authority | Publication surface | Human diff viewer | Review-round state owner | Benefits | Risks / Costs | Decision |
41
+ |--------|------------------|---------------------|-------------------|--------------------------|----------|---------------|----------|
42
+ | A | Local `main` | Forgejo-hosted repo | Forgejo PR UI | Workflow + repo artifacts | Preserves trunk-based worktree flow; keeps the current local-first PR UI; cleanly separates ancestry authority from publication; smallest migration cost | Workflow must implement explicit round semantics because Forgejo does not appear to provide strong per-revision reviewed-state tracking on its own | **Current baseline, but under-specified** |
43
+ | B | Local `main` | Forgejo-hosted repo | Forgejo PR UI | Forgejo comments/status only | Minimal new implementation; preserves current tooling | Leaves the known review-round gap unresolved; repeated review cycles still depend on comment discipline and rereading large PRs | Reject |
44
+ | A2 | Local `main` | Forgejo-hosted repo | Forgejo PR UI | Workflow as authoritative PR-handling owner; Forgejo mirrors workflow outcomes | Keeps the current Forgejo setup unchanged; lets workflow own round number, current side, disposition, and comment governance explicitly; resolves the known round-state gap without changing branch authority | Requires new workflow infrastructure and a transition period where workflow authority is introduced while Forgejo remains the published mirror | **Preferred implementation path** |
45
+ | C | Local `main` | GitHub mirror | Reviewable on top of GitHub PRs | Reviewable | Strongest documented revision-aware PR review surface; per-file/per-revision reviewed state; better handling of rebases and round-to-round diffs | Requires external-hosted mirror and GitHub coupling; moves away from the repo's current local-first review appliance model | Acceptable alternative if Forgejo + workflow-native rounds proves insufficient |
46
+ | D | Local `main` | GitHub mirror | Graphite on top of GitHub PRs | Graphite | Strong PR version comparison and reviewer workflow; explicit "hide reviewed changes" flow; likely better than vanilla PR UI for iterative review | GitHub-only; pushes the repo toward Graphite's stacked-review/product model; more product coupling than "viewer only" | Acceptable alternative if the repo wants stronger product-managed review rounds without leaving PRs |
47
+ | E | Local `main` | GitLab-hosted repo | GitLab merge request UI | GitLab MR versions | Built-in MR diff versions on each push; stronger built-in iteration model than baseline Forgejo/Gitea PRs | Platform migration cost; replaces a working local review surface; not clearly better than Reviewable for revision-aware review | Acceptable but lower-priority alternative |
48
+ | F | Hosted review repo | Gerrit-hosted repo | Gerrit UI | Gerrit patch sets | First-class patch-set review rounds and patch-set-to-patch-set diffs; strongest web-native review-round model in the research set | Requires workflow redesign around Gerrit semantics; changes branch/publication authority assumptions materially; larger migration than a viewer augmentation | Reject for this mission; candidate only for a deliberate review-system redesign |
49
+ | G | Local Git repo / patch series | Patch/email + Patchwork + `b4` | Patchwork web UI plus `b4` local tools | Patch series revisions | Most Git-native explicit round model; strong revision semantics via v1/v2/range-diff | Major cultural/tooling shift away from PR review; weaker fit if the repo wants a central visual PR surface | Reject for this repo's current operating style |
50
+ | H | Local `main` | None or minimal publication | Local tools only (`delta`, `difftastic`, scripts) | Workflow + local artifacts | Maximum authority clarity; no hosted-surface coupling; useful fallback if all hosted surfaces prove too weak | Loses centralized review UI and PR-status visibility; raises human coordination cost relative to current Forgejo workflow | Keep as fallback, not preferred primary model |
51
+ | I | `review/<primary>` or other hosted ref | Forgejo-hosted repo | Any | Any | Remote-tracking branch is explicit and visible | Diverges from local integration target; stale remote state can produce incorrect ancestry and "unrelated histories" errors | Reject |
52
+ | J | Conditional target (local only when remote lags) | Mixed | Mixed | Mixed | Attempts to preserve some remote-first behavior while avoiding obvious drift | Adds branching logic and ambiguity; still leaves the workflow without one invariant ancestry source | Reject |
53
+
54
+ ### Option notes
55
+
56
+ - **Option A** intentionally splits responsibility:
57
+ - local `main` remains the ancestry authority for `rebase`, merge-base reasoning, and integration preflight
58
+ - Forgejo remains the hosted publication/review surface
59
+ - workflow-owned state carries round number, current phase (`implementer` vs `reviewer`), and round-resolution summary
60
+ - **Option A2** is the concrete hardening of the current baseline:
61
+ - workflow becomes the authoritative owner of PR round handling
62
+ - Forgejo remains unchanged as the mirrored review surface
63
+ - workflow publishes mirrored outcomes to Forgejo rather than reading Forgejo as the authority for PR-round state
64
+ - the follow-up task tree for this path is `TASK-1143`, `TASK-1143.01`, `TASK-1143.02`, `TASK-1143.03`, `TASK-1143.04`, and `TASK-1143.05`
65
+ - **Option B** is the status-quo review model after the `rebase` fix. It is included because it is the cheapest path, but the repo already has evidence that comment-only round tracking is too weak for multi-round review ergonomics.
66
+ - **Options C/D/E** are "better hosted diff/review layers while keeping local branch authority." They should be compared on review-round quality, operational complexity, and whether the repo is willing to leave the current local-first review appliance model.
67
+ - **Options F/G** are "change the review model itself," not just the viewer.
68
+
69
+ ## Consequences
70
+
71
+ ### Positive
72
+
73
+ - Rebase and integrate use the same branch target for local ancestry operations.
74
+ - Manual recovery instructions become consistent with the automated path.
75
+ - Future regressions are easier to spot because the rule is explicit and testable.
76
+
77
+ ### Negative
78
+
79
+ - Existing tests that hardcode `review/master` or `review/main` as the rebase target must be updated.
80
+ - Forgejo PR views can still lag behind local `main` until humans or later workflow steps push updated state to the remote.
81
+
82
+ ## Alternatives and evidence
83
+
84
+ The active divergence data in this mission is already enough to reject the remote-tracking target as the workflow authority:
85
+
86
+ - Local `main`: `7f0db085c`
87
+ - `review/main`: `f6318aa6f`
88
+ - Divergence: local primary is 1 commit ahead
89
+
90
+ Option D was corrected during ADR review to mean: do not use `review/main` as a workflow authority at all; instead, keep Forgejo PRs based on Forgejo `main`, and sync that Forgejo `main` from the local `main` checkout before PR creation.
91
+
92
+ That model matches the existing implementation shape:
93
+
94
+ - `workflow/lib/forgejo.js:createPr()` resolves `primaryBranch`, calls `syncPrimaryBaseline()`, and creates the PR with `base: primaryBranch`.
95
+ - `syncPrimaryBaseline()` pushes local `main` to Forgejo `main` before PR creation, so the Forgejo review surface is refreshed from the local baseline.
96
+
97
+ Option D is therefore compatible with this ADR, but only as a review-surface rule. It does not replace the ancestry decision in Option A because:
98
+
99
+ - A PR base in Forgejo is still a remote branch, never an unpublished local commit.
100
+ - Local rebase and merge-base calculations must still rely on the local primary branch because they run before, during, or independently of remote sync.
101
+ - A failed sync can make the PR surface stale again, but it must not be allowed to change the local ancestry authority.
102
+
103
+ The resulting split of responsibility is deliberate:
104
+
105
+ - Local `main` is the authority for ancestry.
106
+ - Forgejo `main` is the published review baseline that should be synchronized from local `main` before PR creation or refresh.
107
+
108
+ ### Source-backed review-surface comparison
109
+
110
+ This mission widened from "what should `rebase` target?" to "what combination of review surface, diff viewer, and round-state owner best fits the repo's trunk-based, worktree-heavy workflow?"
111
+
112
+ #### Forgejo / Gitea PR UI
113
+
114
+ Official docs show standard pull-request review capabilities: branch-based PRs, line comments, reviewer assignment, approvals / request changes, and reviewing a single commit inside a larger PR.
115
+
116
+ Inference: Forgejo is a capable **human diff viewer** and publication surface. The docs reviewed here do not show first-class per-revision reviewed-state tracking comparable to Reviewable, Gerrit patch sets, or GitLab MR diff versions. That makes it a good viewer but a weak sole owner of multi-round review state.
117
+
118
+ #### Reviewable
119
+
120
+ Official docs describe revision-aware review mechanics beyond standard PR UIs:
121
+
122
+ - diff any two revisions
123
+ - hide or ignore rebase-only / whitespace-only changes
124
+ - map comments across revisions
125
+ - track who reviewed which revision of each file
126
+
127
+ Inference: Reviewable is the strongest researched candidate if the repo wants a **PR-based review layer that natively owns revision-aware round tracking**.
128
+
129
+ #### Graphite
130
+
131
+ Official docs describe PR versions, explicit version-to-version comparison, and "hide reviewed changes" workflows for updates pushed after an earlier review.
132
+
133
+ Inference: Graphite is a strong candidate if the repo wants a more product-managed PR-round experience than Forgejo, but it comes with stronger workflow/product coupling than a pure viewer swap.
134
+
135
+ #### GitLab merge request versions
136
+
137
+ Official docs state that each push to an MR branch creates a new diff version and that versions can be compared.
138
+
139
+ Inference: GitLab has better built-in revision slicing than baseline Forgejo/Gitea PRs, but the migration cost is materially higher than retaining Forgejo and filling the round-state gap in workflow.
140
+
141
+ #### Gerrit patch sets
142
+
143
+ Official docs make patch sets first-class review-round objects and support comparing one patch set against another.
144
+
145
+ Inference: Gerrit is the strongest **web-native review-round model**, but adopting it would be a workflow redesign, not a diff-viewer improvement.
146
+
147
+ #### Patchwork + `b4`
148
+
149
+ Official docs show explicit patch-series state, revision tracking, delegates/action-required states, and local reviewer tooling with range-diff and "waiting on new revision" support.
150
+
151
+ Inference: this is the strongest **Git-native** review-round model but a major cultural and tooling shift away from PR-centric review.
152
+
153
+ #### Local diff tools: `delta` and `difftastic`
154
+
155
+ Both are valuable, but they solve a different problem:
156
+
157
+ - `delta` improves readability of line-based diffs
158
+ - `difftastic` improves structural/semantic readability
159
+
160
+ Inference: they are excellent complements to any review model and remain useful as local fallback tools, but they do not themselves solve hosted review-round state.
161
+
162
+ ### Comparative conclusion
163
+
164
+ The current evidence supports three distinct conclusions:
165
+
166
+ 1. **Local `main` should remain the ancestry authority.** No researched hosted diff/review layer changes the fact that local rebase and merge-base calculations must not depend on a stale hosted tracking ref.
167
+ 2. **Forgejo remains viable as a human diff viewer.** The repo's current dissatisfaction is not with raw diff readability but with round-state semantics.
168
+ 3. **The missing capability is review-round ownership.** The preferred path is therefore Option A2: keep the current Forgejo setup as the viewer/publication surface, but move PR-handling authority into workflow so workflow owns round number, active side, disposition, and comment governance. Stronger external products (Reviewable, Graphite, GitLab, Gerrit) remain valid alternatives if that workflow-owned state proves too custom or too weak in practice.
169
+
170
+ ### Follow-up path
171
+
172
+ This ADR does not attempt to implement the new PR-handling authority model inside the current mission. The selected follow-up path is the workflow-owned authority task tree created from this mission:
173
+
174
+ - `TASK-1143` — workflow-owned PR handling authority with Forgejo as mirrored review surface
175
+ - `TASK-1143.01` — workflow PR authority model and round-state transitions
176
+ - `TASK-1143.02` — workflow comment governance and mirrored PR comment contract
177
+ - `TASK-1143.03` — workflow-to-Forgejo mirror contract for PR state publication
178
+ - `TASK-1143.04` — workflow command to launch the primary local diff tool for branch-vs-main review
179
+ - `TASK-1143.05` — transition plan from Forgejo-led PR history to workflow-owned PR authority
180
+
181
+ ## Links
182
+
183
+ - `workflow/lib/rebase.js`
184
+ - `workflow/lib/integrate.js`
185
+ - `docs/missions/2026/task-1140/MISSION.md`
@@ -0,0 +1,277 @@
1
+ # ADR 0044: Workflow Distribution Model for parallix
2
+
3
+ Status: Accepted
4
+ Date: 2026-06-02
5
+ Last updated: 2026-06-22 (task-1331 — public distribution stance locked)
6
+
7
+ ## 2026-06-22 Update: Public distribution stance (task-1331)
8
+
9
+ parallix was pushed to public GitHub on 2026-06-22. This ADR is moved from
10
+ `Proposed` to `Accepted` with one concrete near-term public distribution stance,
11
+ so the public repo has a single authoritative answer for contributors and
12
+ operators. The original Context/Decision/analysis below is preserved as the
13
+ reasoning that produced this stance.
14
+
15
+ **Accepted near-term model: local npm tarball, globally installed `px` CLI — no
16
+ registry publish.** This is Alternative A (external runner / package boundary)
17
+ realized as the simplest credible delivery for a freshly public repo:
18
+
19
+ - The published package name is the scoped `@magnusekdahl/parallix`, resolving the
20
+ `px` namespace risk (this ADR, "`px` Namespace Risk", items 1–4). The unscoped
21
+ `px` / `parallix` npm names are not relied upon.
22
+ - Acquisition is `npm pack` from this repo followed by a single global
23
+ `npm install -g <tarball>` (a user-writable `--prefix` is supported for
24
+ no-sudo installs). Reinstall replaces rather than accumulates runtimes.
25
+ - `node parallix <command>` (source run) remains the compatibility baseline and
26
+ the local-development path; the tarball install is the same code with a
27
+ versioned global `px`.
28
+ - `package.json` reflects this: `"private": false`, `"name": "@magnusekdahl/parallix"`,
29
+ `bin.px`, and a `files` allowlist. The operator-facing install/invoke/source-dev
30
+ story lives in `README.md` ("Public distribution (canonical packaging and
31
+ install)").
32
+
33
+ **Still deferred (not accepted by this stance):** publishing to the public npm
34
+ registry or any registry, standalone single-file binaries, Homebrew, Docker, and
35
+ CI/release automation or signing. The enterprise no-source-copied artifact path
36
+ (acceptance gate 6) and the per-command logging/dry-run audit (gate 7) remain
37
+ open follow-up work; the accepted stance is the manual local-tarball path that is
38
+ proven by the existing `px.js` runner, `files` allowlist, and Node test suite,
39
+ not those still-open enterprise gates.
40
+
41
+ ## Context
42
+
43
+ parallix (`workflow/`) is a Node.js CLI that coordinates AI-assisted software missions through the full lifecycle: `draft → active → review → integrate → done`. It lives as raw, uncompiled source in the WrGroceries monorepo at `workflow/` — no bundlers, no transpilation, no publish step. This was chosen deliberately in ADR 0037 to preserve the fastest possible developer iteration: `node workflow <command>` works immediately with zero setup.
44
+
45
+ Since then, parallix (the workflow tool) has grown beyond WrGroceries use:
46
+
47
+ 1. **WrGroceries inner-loop** (current): `node workflow` runs directly from source in the monorepo root. Zero friction.
48
+ 2. **EM task repository**: The operator maintains a separate repository for EM-only tasks. Copying `workflow/` there is feasible but creates implicit drift — there is no version boundary, no way to say "which revision am I running?", and no automated way to get updates.
49
+ 3. **Enterprise locked-down repositories**: The operator wants to demonstrate and test parallix in enterprise repos where committing custom Node.js code is prohibited. Enterprise IT policy does not allow unreviewed source code in product repositories. parallix's current architecture requires the code to live *inside* the target repository to function, which is incompatible with this constraint.
50
+ 4. **Public publishing**: The operator wants to share parallix publicly. A directory of Node files without a package manifest, CLI entry point, semantic versioning, changelog, or distribution mechanism is not credible as a public tool from an EM facing senior/staff engineers.
51
+
52
+ The current model optimizes for use case 1 at the expense of 2, 3, and 4. The `workflow/package.json` exists but is marked `"private": true`, has no `bin` field, no exports map, no dependencies beyond one optional devDependency (`sonarqube-scanner`), and one entry point (`index.js`). The `workflow/lib/` directory contains 44 modules across these domains:
53
+
54
+ - **Command handlers** (one per `node workflow <command>`): `mission-start.js`, `draft.js`, `active.js`, `status.js`, `checkpoint.js`, `review.js`, `handoff.js`, `integrate.js`, `resolve-conflict.js`, `rebase.js`, `diff.js`, `stats.js`, `verification.js`, `coverage-gate.js`
55
+ - **Core infrastructure**: `git.js`, `fmt.js`, `spawn-tee.js`, `gatekeeper.js`
56
+ - **Agent adapters**: `codex.js`, `claude.js`, `gemini.js`, `glm.js`, `opencode.js`, `mistral.js`
57
+ - **State/config**: `state-map.js`, `backlog.js`, `product-config.js`, `forgejo.js`, `agents.js`, `sessions.js`
58
+ - **Review subsystem**: `review-state.js`, `review-polling.js`, `review-events.js`, `review-loop.js`, `review-artifacts.js`, `review-commands.js`, `review-prompts.js`
59
+ - **Utility**: `mission-utils.js`, `repair-handoff.js`, `limit-hit.js`, `runtime-matrix.js`, `stats-backback.js`
60
+
61
+ The `workflow/config/` directory holds `state-map.json` (virtual-to-actual state mappings) and `agents.json` (agent family eligibility). The `workflow/data/` directory holds `stats.csv` (mission history). These are all repo-relative paths assumed to exist at fixed locations beneath the `workflow/` directory root.
62
+
63
+ There is no existing target-repository resolution mechanism that lets parallix operate from outside the host repository. Some modules read and write repo state through paths rooted in the current `workflow/` checkout, while normal JavaScript imports such as `require('./lib/...')` resolve tool code relative to the runtime. Those are different path classes and must not be collapsed into one rule during extraction.
64
+
65
+ ## Decision
66
+
67
+ **Adopt parallix productization with `px` as the intended short external binary name, while separating the workflow runtime from target-repository state. Do not lock subcommands, flag names, config schema, install location, or enterprise distribution mechanism in this ADR.**
68
+
69
+ The current `workflow/` directory remains the source of truth until extraction work proves a safer boundary. Future phases must first classify every path the workflow touches as one of:
70
+
71
+ - **Tool-owned assets**: code, prompts, built-in config, tests, and release metadata that travel with parallix.
72
+ - **Target-repository state**: `AGENTS.md`, mission docs, backlog tasks, review events, git branches/worktrees, verification scripts, and any repo-local policy files.
73
+ - **Operator-local state**: credentials, agent launcher commands, sessions, caches, and workstation-specific settings.
74
+
75
+ Only after that classification is proven by tests may implementation work introduce a package boundary or new invocation surface.
76
+
77
+ ### Candidate consumption modes
78
+
79
+ These modes describe use cases to validate, not an installation contract:
80
+
81
+ | Mode | Candidate delivery mechanism | Target repo needs workflow source? | Use case | Required proof before adoption |
82
+ |------|------------------------------|-----------------------------------|----------|--------------------------------|
83
+ | WrGroceries local | Existing `node workflow <cmd>` from source | Existing repo-owned source | Current inner-loop development | Existing behavior remains byte-for-byte or semantically equivalent where output includes expected runtime data |
84
+ | Local external runner | A checked-out or locally linked parallix runtime outside the target repo | No copied `workflow/` in target repo | EM repo and cross-repo dogfooding | Commands operate on an explicit target repo without assuming sibling directories or a fixed OS path |
85
+ | Package artifact | npm package, tarball, or another Node-compatible artifact | No copied `workflow/` in target repo | Broader reuse and version pinning | Artifact contents, install/run process, and update path are proven in temporary directories |
86
+ | Enterprise artifact | To be determined after enterprise constraints are known | No copied workflow source | Locked-down demos | Human-reviewed feasibility note covering allowed runtimes, network policy, source-review expectations, and artifact handling |
87
+ | Standalone binary | Future option only | No copied workflow source | Environments without Node/npm | Separate ADR or task after package boundary is stable |
88
+
89
+ ### Interface Boundary
90
+
91
+ ADR 0044 accepts `px` as the intended short binary name for external distribution because the product is being renamed and prepared for external visibility. It does **not** define the `px` subcommand list, flag names, help text, or repo-selection syntax. The accepted interface requirements are:
92
+
93
+ 1. The existing `node workflow <command>` interface continues to work in WrGroceries during extraction.
94
+ 2. Any `px` interface beyond the binary name must be proposed by implementation evidence, documented in its own task, and tested against at least one temporary target repo.
95
+ 3. Target repository selection must be explicit and OS-neutral. It may use CWD, an absolute path, a relative path, or config discovery, but it must not assume sibling worktree names, home-directory layouts, package manager globals, or platform-specific install directories.
96
+ 4. Existing command behavior is the compatibility baseline. New ergonomics such as `doctor`, `init`, aliases, or dry-run modes are product features, not ADR commitments.
97
+
98
+ ### `px` Namespace Risk
99
+
100
+ `px` is a good product-aligned short name, but it is not globally unique. Current/historical public uses include:
101
+
102
+ - `@ae-studio/px`, a JavaScript package-manager command wrapper that installs a `px` binary and advertises invocations such as `px dev` and `px install`.
103
+ - PX Systems, a parallel/cloud execution tool centered on a `px` CLI with commands such as `px cluster up` and `px job submit`.
104
+ - `@posix/px`, an older npm script-shell package that exposes `px` / `px.cmd`.
105
+ - `px`, an older npm package for PC-Axis parsing, which occupies the unscoped npm package name even though it is not primarily a modern CLI.
106
+
107
+ The practical risk is local PATH collision, not conceptual naming failure. parallix can still use `px` if follow-up packaging work proves:
108
+
109
+ 1. The published package name is scoped, for example `@magnusekdahl/parallix`, rather than relying on the unscoped `px` package name.
110
+ 2. Install is a single global install (`npm install -g <tarball>`) that replaces on reinstall rather than accumulating runtimes, and is never blind: `px --version` identifies the executing `px.js` path, operators check for a pre-existing `px` on PATH (item 4), and a user-writable prefix (`npm config set prefix`) can control the location. (Resolved by TASK-1236; see `parallix/README.md`.)
111
+ 3. `px` startup/help output clearly identifies parallix so accidental collisions are obvious.
112
+ 4. Enterprise and dogfood validation check whether `px` is already present on PATH and document the selected invocation form.
113
+
114
+ ### Configuration and State Boundary
115
+
116
+ ADR 0044 does **not** define `parallix.config.json`, presets, adapter schemas, or config merge order.
117
+
118
+ Before a config file is added, follow-up work must produce a configuration inventory that answers:
119
+
120
+ 1. Which current files are tool defaults (`workflow/config/state-map.json`, `workflow/config/agents.json`, prompts, command metadata).
121
+ 2. Which files are target-repo state (`docs/missions/*`, `backlog/tasks/*`, `review-events/*`, verification scripts, repo instructions).
122
+ 3. Which values are operator-local and must not be committed (agent commands, tokens, local session paths, caches).
123
+ 4. Which values truly need repo-local override, with examples from actual WrGroceries and EM usage.
124
+
125
+ Any eventual config contract must be minimal, evidence-based, and treated as a product API with migration and compatibility tests.
126
+
127
+ ### Package Boundary
128
+
129
+ The package layout is intentionally unresolved. A future phase may keep the current `workflow/` shape, introduce subpackages, or use another layout, provided it proves:
130
+
131
+ 1. `workflow/index.js` or an equivalent compatibility shim preserves existing `node workflow` behavior.
132
+ 2. Tool-owned assets resolve relative to the installed/runtime location.
133
+ 3. Target-repository state resolves relative to the selected target repo.
134
+ 4. Operator-local state stays outside committed target-repo artifacts.
135
+ 5. Tests cover path resolution from at least one temporary target repo that is not the parallix source tree.
136
+
137
+ ### Architecture boundary
138
+
139
+ ```
140
+ ┌─────────────────────────────────────────────────────┐
141
+ │ Target Repository │
142
+ │ (any git repo: WrGroceries, EM repo, enterprise) │
143
+ │ │
144
+ │ optional config ← only after proven needed │
145
+ │ docs/missions/ ← mission artifacts │
146
+ │ backlog/tasks/ ← backlog tasks │
147
+ │ AGENTS.md ← repo rules │
148
+ │ .git/ ← git data │
149
+ │ │
150
+ │ no copied workflow source for enterprise use │
151
+ └──────────────────────┬──────────────────────────────┘
152
+ │ explicit target-repo selection
153
+
154
+ ┌─────────────────────────────────────────────────────┐
155
+ │ parallix runtime │
156
+ │ │
157
+ │ package, checkout, or other proven artifact │
158
+ │ px — intended external binary │
159
+ │ lib/ — command implementations │
160
+ │ draft.js, active.js, review.js, etc. │
161
+ │ git.js, forgejo.js, agents.js │
162
+ │ codex.js, claude.js, gemini.js, opencode.js │
163
+ │ config/ — tool defaults │
164
+ │ data/ — tool-owned data, if any │
165
+ └─────────────────────────────────────────────────────┘
166
+ ```
167
+
168
+ ## Enterprise Safety Model
169
+
170
+ parallix is designed for use in enterprise environments where source code hygiene is mandatory:
171
+
172
+ - **No workflow source copied into enterprise target repos**: Enterprise use requires parallix to run from outside the target product repository. Vendored source may remain a separate non-enterprise distribution mode, but it does not satisfy the enterprise safety model.
173
+ - **No assumed install directory or operating system layout**: Enterprise docs must describe inputs and constraints, not hard-coded paths. Validation must use temporary directories and paths supplied at runtime.
174
+ - **Artifact claims require proof**: A `.tgz`, npm package, or binary is not assumed enterprise-safe. Each artifact must be inspectable, hashable, and tested for install/run behavior before it is documented as supported.
175
+ - **No secrets in repo config**: Credentials, tokens, local agent launcher commands, and session state remain operator-local. If config is later introduced, it must not require secrets in committed files.
176
+ - **Dry-run and logging are requirements to evaluate, not assumed existing features**: Enterprise-facing tasks must inventory which commands already support preview behavior and add explicit support only where implementation and tests prove it.
177
+ - **Explicit logging boundary required**: parallix's logging must be audited before enterprise use. The required outcome is that logs do not expose git secrets, credentials, local agent command contents, or sensitive prompt material.
178
+
179
+ ## Decision matrix
180
+
181
+ | Option | WrGroceries loop | EM repo | Enterprise demo | Public credible | Source coupling | Ops cost | Decision |
182
+ |--------|-----------------|---------|-----------------|-----------------|-----------------|----------|----------|
183
+ | **A: External runner/package boundary** | Fast if compatibility shim stays | Clean if target-state boundary is proven | Possible but unproven until constraints are known | High if versioned and documented | Low — parallix tool and target repos are separate | Medium — packaging, release process, compatibility work | **Accept** |
184
+ | B: Copy/export script | Fast (is source) | Feasible but drift | Prohibits — source must be copied in | Low — no version boundary, no install mechanism | High — hidden forks across repos | Low — copy a directory | Reject as primary |
185
+ | C: Git submodule/subtree | Fast (is source) | Versioned but inline | Prohibits — source lives in target repo | Low — Git dependency, not a standard package | Medium — submodule ref is versioned code in target | Low-Medium | Accept only for non-enterprise repos that explicitly allow vendored source |
186
+ | D: Keep embedded (current) | Fastest (zero setup) | Drift-prone copy required | Prohibits — must commit source | Very low — no package, no CLI, no versioning | Maximum | Zero | Reject — status quo is the problem |
187
+ | E: Single binary (packaged) | Slower iteration (rebuild needed) | Clean | Best — no node/npm dependency | High — standalone executable | Low — separated | High — bundling, rebuild cycle, debuggability | Keep as future extension, not primary |
188
+
189
+ ### Alternative analysis
190
+
191
+ **Alternative A (external runner/package boundary)**: Separate the parallix runtime from target-repo state and make versioning possible. npm packaging may be the eventual delivery path because the current workflow is Node-based and already has `workflow/package.json`. The ADR accepts `px` as the intended external binary name, but does not prescribe subcommands, flags, config schema, tarball installation flow, or filesystem layout. Those details must be proven by follow-up implementation tasks.
192
+
193
+ **Alternative B (copy/export with `w.sh` script in target)**: The operator currently solves the EM repo use case by copying `workflow/` into a second repository. This works but creates the well-known software distribution problems: no version tracking, no way to update downstream consumers, silent drift when the source repository's workflow changes. The `w.sh` shell wrapper helps with context switching between repos but does not address distribution. This is a pragmatic migration bridge but not the target architecture.
194
+
195
+ **Alternative C (git submodule)**: A submodule keeps `workflow/` as a versioned external reference. The consuming repo does not own the source but still contains it on disk. This solves versioning for non-enterprise repos that explicitly allow vendored tooling, but it fails the enterprise requirement because workflow source materializes inside the target repository. It also adds Git operational complexity (submodule init/update, fixed commits) that is unnecessary for the primary productization path.
196
+
197
+ **Alternative D (keep embedded — current model)**: The existing model. Works perfectly for use case 1 and nothing else. The `workflow/` directory is the thing being evaluated — it is the constraint, not the solution.
198
+
199
+ **Alternative E (standalone binary)**: Tools like `pkg` or `nexe` can produce a single executable. Useful for enterprise demos where the target machine has no Node.js installed. However, packaging adds a build step that breaks the current zero-friction inner loop, and single-executable Node has debugging limitations. This is a good future extension for enterprise air-gapped demos, not the right primary model.
200
+
201
+ ### Why Node package artifacts remain the leading candidate over standalone binary
202
+
203
+ The distinction between Option A and E in the matrix above is delivery mechanism. Option A first proves a runtime/target-repo boundary for the existing Node workflow. A Node package artifact is the leading candidate after that proof because it fits the current implementation, but this ADR does not accept npm, tarball, or any specific install flow as the final distribution contract. Option E (standalone binary) is retained as a future enterprise extension.
204
+
205
+ The reason a Node package artifact is preferred over a standalone binary for the **first proof path** is:
206
+
207
+ 1. **Inner-loop speed**: The existing source-run mode preserves the current zero-compilation loop while the boundary is proven. A binary would need rebuilds.
208
+ 2. **Debuggability**: Source-level debugging of Node modules is well-supported. Standalone binaries obscure stack traces and source maps.
209
+ 3. **Ecosystem alignment**: The workflow already has `package.json`, depends only on Node builtins, and has no external npm dependencies to vendor. The expected packaging cost is lower than a standalone binary, but the exact package metadata and layout remain follow-up proof work.
210
+ 4. **Ecosystem familiarity**: npm packages, changelogs, and semantic versioning are standard expectations for public Node tools. A custom binary format has none of those conventions.
211
+
212
+ ## Consequences
213
+
214
+ ### Positive
215
+
216
+ - **WrGroceries keeps fast inner-loop**: `node workflow <cmd>` remains the compatibility baseline. No rebuild step is required until a later task proves an alternative.
217
+ - **EM repo usage can become clean**: No copying once the target-state boundary is proven. The same verified runtime can operate on a selected repo and respect that repo's backlog, missions, and AGENTS.md.
218
+ - **Enterprise demos get a credible path**: The design no longer requires copying workflow source into a target repo. Actual artifact acceptability remains to be proven with enterprise constraints.
219
+ - **Public publishing becomes credible after proof**: Semantic versioning, changelog, package metadata, and tests are standard expectations for a tool at this scope.
220
+ - **Version pinning**: A package or artifact can prove exactly which revision ran and eliminate silent copy drift.
221
+ - **Senior/staff credibility**: Versioned tooling with ADRs, changelogs, and test suites is recognized as professional-grade. The "my personal scripts" narrative is replaced by an explicit target-repo boundary backed by evidence.
222
+ - **Multi-repo consistency becomes possible**: Once package/artifact distribution is proven, repositories can run the same versioned runtime instead of divergent copies.
223
+
224
+ ### Negative
225
+
226
+ - **Initial extraction cost**: The 44 modules in `workflow/lib/` must be audited and may need reorganization. Cross-module imports and `__dirname`-relative paths need classification before they can be changed safely.
227
+ - **Release discipline required**: Every change to the workflow after extraction needs a version bump (or at least clear development-version tracking). The current model has no such overhead.
228
+ - **External-runner setup for WrGroceries**: If a later task introduces workspace linking, a local package, or another external runner, that setup must be documented and tested. It is not assumed by this ADR.
229
+ - **Agent adapter coupling**: Each agent adapter (`codex.js`, `claude.js`, `gemini.js`, `glm.js`, `opencode.js`, `mistral.js`) currently resolves commands from environment variables or `agents.json`. Follow-up work must preserve the operator-local command protocol before adding repo-level overrides.
230
+ - **Config migration is unproven**: The existing `workflow/config/state-map.json` and `agents.json` may remain tool defaults, become target-repo state, or be split. A new schema is not accepted until a task proves the need.
231
+ - **Tests need adaptation**: The 44 lib modules reference each other and `workflow/` filesystem paths. Tests must be restructured to prove both source-tree and external-target execution.
232
+
233
+ ## Alternatives considered
234
+
235
+ ### Keep embedded (current model)
236
+
237
+ Positive: Zero-friction inner loop. No packaging overhead. Everything works out of the box.
238
+ Negative: As documented in Context, creates friction for EM repo (task 2), enterprise demos (task 3), and public publishing (task 4). Each additional repository multiplies the copy-drift problem. The ChatGPT research in the backlog task identified the embedded model as "good for one repo, poor as a reusable EM/developer tool."
239
+ Assessment: Retain as the compatibility baseline while the external boundary is proven. Do not require workspace linking until an implementation task demonstrates it is the right local development shape.
240
+
241
+ ### Shell wrapper + env-based config extraction
242
+
243
+ Positive: No build step, no package boundary, no npm. Wrap `workflow/` with a shell script that sets environment variables for parallix to read, pointing it at a target repo path.
244
+ Negative: The workflow's modules use `__dirname` directly (not environment variables). Every module would need refactoring to respect env-based paths. The approach is essentially reimplementing the config/CLI layer that Option A provides as a first-class feature. The environment variable protocol would be undocumented unless treated as a formal spec.
245
+ Assessment: A valid interim step for EM repo usage if full extraction takes too long. Any environment-variable or config resolution pattern must be documented as a product API before consumers depend on it.
246
+
247
+ ### Docker container
248
+
249
+ Positive: Isolates parallix from the target repo's environment. No npm, no Node installation required on the target machine. Container image can include everything.
250
+ Negative: Docker is overkill for a pure Node CLI. Container image size, build time, and runtime overhead are not justified by the problem scope. Docker-in-Docker may be blocked in enterprise environments anyway (the same environments where we want parallix).
251
+ Assessment: Not worth the cost for this problem domain unless enterprise constraints require it. A tarball may be simpler than Docker, but it is still an artifact containing files that must be reviewed and tested before being called enterprise-safe.
252
+
253
+ ### Git worktree-based distribution
254
+
255
+ Positive: Leverages existing worktree infrastructure. parallix lives in one worktree, commands run from it targeting sibling worktrees.
256
+ Negative: Worktrees are a repository-level mechanism, not a distribution mechanism. They require the workflow source to exist in *some* worktree, which does not solve the enterprise constraint (some enterprise repo may not allow any worktrees, or parallix may need to run against a repo on a machine without write access).
257
+ Assessment: parallix already uses worktrees as its mission orchestration mechanism (ADR 0037). This ADR is about how parallix *code itself* reaches target repos, not how it orchestrates them. Worktrees remain an internal implementation detail.
258
+
259
+ ## Acceptance Gates for `Status: Accepted`
260
+
261
+ ADR 0044 can move from `Proposed` to `Accepted` only after follow-up work proves:
262
+
263
+ 1. A committed path inventory classifies tool-owned assets, target-repository state, and operator-local state across the current `workflow/` runtime.
264
+ 2. `node workflow <cmd>` remains compatible for WrGroceries after any boundary refactor.
265
+ 3. A `px` proof slice runs against at least one temporary target repo without relying on fixed OS paths, sibling directory names, package-manager globals, or copied workflow source.
266
+ 4. The config/state decision is settled: either no repo config is needed yet, or a minimal schema is documented with migration and compatibility tests.
267
+ 5. The chosen local artifact/dogfood path is tested from caller-supplied temporary paths and its contents exclude operator-local state.
268
+ 6. Enterprise distribution has a constraints matrix and either a supported no-source-copied artifact path with proof or an explicit defer/no-go decision.
269
+ 7. Logging and dry-run/preview behavior are inventoried command-by-command before any enterprise safety claim is made.
270
+
271
+ ## Links
272
+
273
+ - ADR 0037: AI Workflow Coordination Architecture — established the `workflow/` directory as the repo's coordination CLI
274
+ - ADR 0041: Integration-time pipeline gates — the `node workflow integrate` command that operates on target repos
275
+ - ADR 0042: Workflow CLI Color Rendering Approach — the `fmt.js` module that the new package will reorganize
276
+ - ADR 0043: Git target resolution strategy — shows the workflow already has repo-target reasoning, but only for the host repo
277
+ - backlog task-1229: Adopt an ADR and create missions for productification of workflow