You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-`apps/server/src/git/Layers/GitManager.ts` — `runStackedAction` resolves `jiraTickets` once via `JiraContextCollector` and threads them into `runFeatureBranchStep` / `runCommitStep` / `runPrStep`
178
+
-`apps/server/src/jira/Services/JiraContextCollector.ts` + `Layers/JiraContextCollector.ts` — Effect service that walks `thread.messages`, extracts `<jira_context>` blocks, then **filters by `thread.implementingJiraTicketKeys`** so only classified tickets reach the auxiliary generators. Falls back to all mentions when classification hasn't run yet.
179
+
-`apps/server/src/jira/threadJiraContext.ts` — `collectThreadJiraContexts` with token budgets + dedup
180
+
-`apps/server/src/orchestration/Layers/ProviderCommandReactor.ts` — `maybeClassifyAndPersistImplementingJiraTickets` runs at first turn before branch-rename / title-gen, persists result via `thread.meta.update`
-`packages/contracts/src/git.ts` — `threadId?: ThreadId` on `GitRunStackedActionInput`
183
+
-`packages/contracts/src/orchestration.ts` — `implementingJiraTicketKeys: Schema.Array(JiraIssueKey)` on `OrchestrationThread` + `OrchestrationThreadShell`; same field optional on `ThreadMetaUpdateCommand` / `ThreadMetaUpdatedPayload`
184
+
-`apps/server/src/orchestration/{decider,projector}.ts` + `Layers/{ProjectionPipeline,ProjectionSnapshotQuery}.ts` — projection plumbing for the new field
-`apps/server/src/persistence/Migrations/031_ProjectionThreadsImplementingJiraTicketKeys.ts` + `Migrations.ts` — adds `implementing_jira_ticket_keys_json TEXT NOT NULL DEFAULT '[]'` to `projection_threads`
-`apps/web/src/components/GitActionsJiraChips.tsx` — chip beside the git-actions group reads `thread.implementingJiraTicketKeys`; tooltip explains the classification semantics
189
+
-`apps/web/src/components/GitActionsControl.tsx` — passes `activeServerThread?.implementingJiraTicketKeys` to the chip; passes `activeThreadRef.threadId` on `runStackedAction` mutation
190
+
-`apps/web/src/lib/gitReactQuery.ts` — `gitRunStackedActionMutationOptions` accepts and forwards `threadId`
191
+
192
+
For enterprise users who live in Jira + GitLab/GitHub. The flow:
193
+
194
+
1. User `@jira:`-mentions tickets in any user message. Composer serializes them into a trailing `<jira_context>...</jira_context>` block per message (existing infra).
195
+
2.**First-turn classifier** runs on the server via the configured text-generation model. Input: the user's message text + every mentioned ticket. Output: the subset of ticket keys the user is **actively implementing** (vs. mentioned for context / reference / pattern-matching). Even a single mentioned ticket goes through the classifier — a lone reference ticket (e.g. "fix this the same way we fixed `@jira:OTHER-99`") must not leak into the branch/commit/PR.
196
+
3. Result is persisted as `thread.implementingJiraTicketKeys` via the existing `thread.meta-updated` event path. Survives reconnects, server restarts, and app reopens.
197
+
4.**Branch:** the worktree-rename produces `marcode/PROJECT-111-<short-name>` (or `marcode/PROJECT-111-PROJECT-222-<short-name>` for multi-ticket implementations). Commit-time feature-branch flow wraps to `feature/PROJECT-111-…`.
198
+
5.**Commit messages:** Jira tickets are passed to the prompt as **CONTEXT ONLY**. The model uses ticket descriptions to inform the body's "why" but is explicitly forbidden from including the ticket key in the subject or body — no `Refs:` trailer, no `[KEY]` prefix, no parenthesized suffix. Commit messages read naturally on their own.
199
+
6.**PR/MR titles:** the implemented ticket key is **mandatory and visible**. The model picks placement (bracketed prefix, parenthesized suffix, or interpolated scope) — non-negotiable that the key appears.
200
+
7.**PR/MR bodies:** Jira description informs `## Summary`'s "why". No `## Tickets` sidecar section, no `Refs:` trailer — the title already carries the key.
201
+
8.**UI chip** (`GitActionsJiraChips`) sits beside the Commit / Push / MR action button and shows the classified implementing keys (primary + `+N` for additional tickets, hover popover lists all). Reads from `thread.implementingJiraTicketKeys` directly — server is the source of truth, web is read-only feedback.
202
+
203
+
### Trust boundary (Critical)
204
+
205
+
The contract change is **only `threadId?: ThreadId`** on `GitRunStackedActionInput`. The client never ships ticket descriptions back to the server. The server re-derives Jira context from stored message text via `JiraContextCollector` and applies the classified-keys filter. Avoids prompt-injection vector and parser drift.
206
+
207
+
When merging upstream, **reject** any change that:
208
+
209
+
- Adds a `jiraTickets[]` payload field to `GitRunStackedActionInput`.
210
+
- Drops the `threadId` field or stops the web from passing it.
211
+
- Inlines Jira context parsing into web — keep it in `@marcode/shared/jiraContext` so server + web stay aligned.
212
+
- Removes the `withDecodingDefault([])` on `OrchestrationThread.implementingJiraTicketKeys` / `OrchestrationThreadShell.implementingJiraTicketKeys` (breaks decoding of pre-feature DB rows).
213
+
- Drops migration `031_ProjectionThreadsImplementingJiraTicketKeys` from `Migrations.ts`.
214
+
215
+
### Resilience
216
+
217
+
`JiraContextCollector` wraps the read pipeline in `Effect.catchCause` — any failure (read-model miss, parse error, OAuth-expired Jira upstream) degrades silently to `[]`. The classifier itself is wrapped the same way and falls back to `mentionedTickets` (no filtering) when classification fails. Commit/PR actions are never blocked by the Jira layer.
218
+
219
+
The classifier prompt defaults to **excluding** ambiguous tickets — better to omit a key from artifacts than engrave a reference ticket the user never intended to implement. The model output is filtered through `filterToAllowedKeys` so the model can't invent a key.
220
+
221
+
---
222
+
167
223
## Theme System
168
224
169
225
**Commit:**`4e52e0e9` (and `fc042b23`)
@@ -316,6 +372,7 @@ After any upstream merge, verify each feature still works:
316
372
-[ ] All rich tool display cards
317
373
-[ ] GitLab MR support + dynamic PR/MR labels
318
374
-[ ] Jira OAuth + board selection + task chips
375
+
-[ ] Jira ticket engraving — first-turn classifier persists `implementingJiraTicketKeys`; branch/PR title carry the key; commit messages stay clean (no `Refs:` trailer, no `[KEY]` prefix); chip beside git-actions reads `thread.implementingJiraTicketKeys`; migration `031` adds the column; `@marcode/shared/jiraContext` hosts the shared parser
0 commit comments