@cat-factory/app 0.266.1 → 0.267.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.
@@ -0,0 +1,82 @@
1
+ import type { RunDefaultScope } from '@cat-factory/contracts'
2
+ import type { Pipeline } from '~/types/domain'
3
+ import { usePipelinesStore } from '~/stores/pipelines'
4
+ import { usePipelineErrorToast } from '~/composables/usePipelineErrorToast'
5
+
6
+ /**
7
+ * The actions a row of the saved-pipeline LIBRARY offers: archive, promote to a scope default,
8
+ * edit, clone, delete.
9
+ *
10
+ * Extracted from `PipelineBuilder.vue` so that component stays inside its (shrink-only) size
11
+ * budget. A cohesive seam rather than an arbitrary cut: every one of these takes a library row and
12
+ * nothing else, none of them touches the DRAFT chain the rest of the builder is about, and each
13
+ * reports its own failure — which is what makes them the same kind of thing.
14
+ */
15
+ export function usePipelineLibraryActions() {
16
+ const pipelines = usePipelinesStore()
17
+ const toast = useToast()
18
+ const { t } = useI18n()
19
+ const { present } = usePipelineErrorToast()
20
+ const { confirm } = useConfirm()
21
+
22
+ /** Archive / unarchive: organize the library without deleting. Works on built-ins too. */
23
+ async function toggleArchive(p: Pipeline) {
24
+ try {
25
+ if (p.archived) await pipelines.unarchive(p.id)
26
+ else await pipelines.archive(p.id)
27
+ } catch {
28
+ toast.add({ title: t('pipeline.builder.toast.updateFailed'), color: 'error' })
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Claim (or release) a pipeline as the workspace's default for one resolution scope.
34
+ *
35
+ * Both scopes are ADVANCED-tier controls in the builder, and the reason is the interface-mode rule
36
+ * rather than the feeling of the setting: a workspace that names neither runs exactly what it runs
37
+ * today (the interface-mode rung in the app, the seeded unattended rung headlessly), so hiding the
38
+ * control leaves the same default a basic-tier user would have had. What is NOT hidden is the
39
+ * resulting badge — a default somebody set has to be visible in the library at both tiers, or the
40
+ * hidden control becomes a hidden decision.
41
+ */
42
+ async function toggleDefault(p: Pipeline, scope: RunDefaultScope) {
43
+ const held = scope === 'unattended' ? p.isUnattendedDefault : p.isDefault
44
+ try {
45
+ await pipelines.setDefault(p.id, scope, !held)
46
+ } catch (error) {
47
+ present(error, 'pipeline.builder.toast.updateFailed')
48
+ }
49
+ }
50
+
51
+ /** Load a custom pipeline into the draft for in-place editing. */
52
+ function edit(p: Pipeline) {
53
+ pipelines.loadForEdit(p)
54
+ }
55
+
56
+ async function removePipeline(p: Pipeline) {
57
+ const ok = await confirm({
58
+ title: t('pipeline.builder.confirmDeletePipeline.title'),
59
+ description: t('pipeline.builder.confirmDeletePipeline.body', { name: p.name }),
60
+ variant: 'destructive',
61
+ confirmLabel: t('common.delete'),
62
+ icon: 'i-lucide-trash-2',
63
+ })
64
+ if (ok) void pipelines.removePipeline(p.id)
65
+ }
66
+
67
+ /** Clone any pipeline (incl. a read-only built-in) into an editable copy. */
68
+ async function clone(p: Pipeline) {
69
+ try {
70
+ const copy = await pipelines.clonePipeline(p.id)
71
+ toast.add({
72
+ title: t('pipeline.builder.toast.cloned', { name: p.name, copy: copy.name }),
73
+ color: 'success',
74
+ icon: 'i-lucide-copy',
75
+ })
76
+ } catch {
77
+ toast.add({ title: t('pipeline.builder.toast.cloneFailed'), color: 'error' })
78
+ }
79
+ }
80
+
81
+ return { toggleArchive, toggleDefault, edit, removePipeline, clone }
82
+ }
@@ -112,16 +112,45 @@ export function createPipelinePersistence(
112
112
  return updated
113
113
  }
114
114
 
115
- /** Set a pipeline's organizational metadata (labels / archive). Works on built-ins too. */
116
- async function organize(id: string, body: { labels?: string[]; archived?: boolean }) {
115
+ /**
116
+ * Set a pipeline's organizational metadata (labels / archive / the two default claims). Works on
117
+ * built-ins too, which is the whole reason the default claims live on this call: the rungs a
118
+ * workspace most wants as its defaults are built-in, and a built-in refuses a structural edit.
119
+ *
120
+ * Promoting one row DEMOTES another, and the response names only the winner. So the incumbent is
121
+ * released LOCALLY before the winner is upserted: a targeted edit of the two rows that changed,
122
+ * rather than a full re-read (which this store has no door for — it hydrates from the workspace
123
+ * snapshot) and rather than upserting the winner alone, which would leave two rows claiming the
124
+ * same default on screen until the next snapshot.
125
+ */
126
+ async function organize(
127
+ id: string,
128
+ body: {
129
+ labels?: string[]
130
+ archived?: boolean
131
+ isDefault?: boolean
132
+ isUnattendedDefault?: boolean
133
+ },
134
+ ) {
117
135
  const updated = await api.organizePipeline(useWorkspaceStore().requireId(), id, body)
136
+ if (body.isDefault !== undefined) releaseOtherClaims(id, 'isDefault')
137
+ if (body.isUnattendedDefault !== undefined) releaseOtherClaims(id, 'isUnattendedDefault')
118
138
  upsertPipeline(updated)
119
139
  return updated
120
140
  }
121
141
 
142
+ /** Drop `field` from every row but `id`, mirroring what the store just did server-side. */
143
+ function releaseOtherClaims(id: string, field: 'isDefault' | 'isUnattendedDefault') {
144
+ ctx.pipelines.value = ctx.pipelines.value.map((pipeline) =>
145
+ pipeline.id === id || pipeline[field] !== true ? pipeline : { ...pipeline, [field]: false },
146
+ )
147
+ }
148
+
122
149
  const archive = (id: string) => organize(id, { archived: true })
123
150
  const unarchive = (id: string) => organize(id, { archived: false })
124
151
  const setLabels = (id: string, labels: string[]) => organize(id, { labels })
152
+ const setDefault = (id: string, scope: 'interactive' | 'unattended', claimed: boolean) =>
153
+ organize(id, scope === 'unattended' ? { isUnattendedDefault: claimed } : { isDefault: claimed })
125
154
 
126
155
  return {
127
156
  saveDraft,
@@ -132,5 +161,6 @@ export function createPipelinePersistence(
132
161
  archive,
133
162
  unarchive,
134
163
  setLabels,
164
+ setDefault,
135
165
  }
136
166
  }
@@ -1,7 +1,13 @@
1
1
  import { defineStore } from 'pinia'
2
2
  import { ref } from 'vue'
3
3
  import type { Pipeline } from '~/types/domain'
4
- import type { GateConfigForm, PipelinePurpose, RetiredPipelineWire } from '@cat-factory/contracts'
4
+ import type {
5
+ GateConfigForm,
6
+ PipelinePurpose,
7
+ RetiredPipelineWire,
8
+ RunDefaultScope,
9
+ } from '@cat-factory/contracts'
10
+ import { declaredDefaultPipelineId } from '@cat-factory/contracts'
5
11
  import { useUpsertList } from '~/composables/useUpsertList'
6
12
  import { createDraftStepState, type PipelinesContext } from '~/stores/pipelines/context'
7
13
  import { createPipelineDraftActions } from '~/stores/pipelines/draftActions'
@@ -124,6 +130,23 @@ export const usePipelinesStore = defineStore('pipelines', () => {
124
130
  return pipelines.value.find((p) => p.id === id)
125
131
  }
126
132
 
133
+ /**
134
+ * The pipeline id this workspace has DECLARED as its default for a resolution scope, or undefined
135
+ * when no row claims it.
136
+ *
137
+ * The rule itself is `declaredDefaultPipelineId` in `@cat-factory/contracts`, shared with the
138
+ * engine: the SPA pre-selects on its start controls what the backend falls back to when a headless
139
+ * caller names none, and two readings of "the default" is how a Start button comes to run
140
+ * something other than what the board said it would.
141
+ *
142
+ * Undefined is a real answer, not a lookup failure, and each caller composes its own fallback with
143
+ * it: the start controls `defaultBuildPipelineId` (the interface-mode rung), the backend catalog
144
+ * order.
145
+ */
146
+ function declaredDefaultId(scope: RunDefaultScope): string | undefined {
147
+ return declaredDefaultPipelineId(pipelines.value, scope)
148
+ }
149
+
127
150
  // The draft manipulation + persistence operations, split into cohesive factories sharing the
128
151
  // state above (a size-only extraction — behaviour is identical to the former in-closure
129
152
  // functions). Persistence drives the draft-lifecycle helpers (`clearDraft`/`loadForEdit`).
@@ -173,6 +196,7 @@ export const usePipelinesStore = defineStore('pipelines', () => {
173
196
  hydrate,
174
197
  hydrateGateConfigForms,
175
198
  getPipeline,
199
+ declaredDefaultId,
176
200
  ...draftActions,
177
201
  ...persistence,
178
202
  }
@@ -611,6 +611,10 @@
611
611
  "label": "Unbeaufsichtigte Läufe ohne Wartezeit auf eine Person abschließen",
612
612
  "unattendedHint": "Wenn eine automatische Schleife aufgibt (ein Companion an seinem Überarbeitungslimit, eine Prüfung an ihrem Durchlauflimit, unbearbeitete Folgepunkte), läuft der Durchlauf nachvollziehbar weiter statt anzuhalten. Von der Pipeline angeforderte Gates wie manuelles Testen, Review und Freigabe halten den Durchlauf weiterhin an.",
613
613
  "attendedHint": "Wenn eine automatische Schleife aufgibt, hält der Durchlauf an und wartet auf eine Entscheidung. Richtig für ein Board, das jemand beobachtet; ein über die API gestarteter Durchlauf wartet unbegrenzt."
614
+ },
615
+ "autoAnswer": {
616
+ "label": "Mindestzuversicht für Auto-Antworten (%)",
617
+ "hint": "Wie sicher der Requirement Writer sein muss, damit ein unbeobachteter Lauf seinen Vorschlag übernimmt statt auf eine Person zu warten. Infrage kommen nur Befunde, die der Reviewer ohne Product Owner für beantwortbar hielt."
614
618
  }
615
619
  },
616
620
  "observabilityConnection": {
@@ -4509,7 +4513,17 @@
4509
4513
  "binaryComparison": "Kandidaten vor der Lieferung vergleichen",
4510
4514
  "binaryPerGenerator": "Kandidaten pro Integration",
4511
4515
  "binaryMultiSelect": "Mehrere behalten erlauben",
4512
- "binaryComparisonUnreachable": "Dieser Schritt kann nur einen Kandidaten pro Motiv erzeugen, es gäbe also nichts zu vergleichen und der einzige würde ungefragt behalten. Wähle eine zweite Integration oder erhöhe die Anzahl der Kandidaten pro Integration."
4516
+ "binaryComparisonUnreachable": "Dieser Schritt kann nur einen Kandidaten pro Motiv erzeugen, es gäbe also nichts zu vergleichen und der einzige würde ungefragt behalten. Wähle eine zweite Integration oder erhöhe die Anzahl der Kandidaten pro Integration.",
4517
+ "scopeDefault": {
4518
+ "interactive": "Standard in der App",
4519
+ "interactiveHint": "Was eine vom Board gestartete Aufgabe ausführt, wenn sie keine eigene Pipeline festlegt.",
4520
+ "unattended": "Standard ohne Aufsicht",
4521
+ "unattendedHint": "Was ein Lauf ohne Beobachter ausführt (API, Ticket, Zeitplan), wenn die Aufgabe keine Pipeline festlegt.",
4522
+ "claimInteractive": "Als Standard in der App festlegen",
4523
+ "releaseInteractive": "Nicht mehr Standard in der App",
4524
+ "claimUnattended": "Als Standard ohne Aufsicht festlegen",
4525
+ "releaseUnattended": "Nicht mehr Standard ohne Aufsicht"
4526
+ }
4513
4527
  },
4514
4528
  "progress": {
4515
4529
  "status": {
@@ -4794,6 +4808,17 @@
4794
4808
  "reReview": "Die Anforderungen konnten nicht erneut geprüft werden",
4795
4809
  "proceed": "Es konnte nicht fortgefahren werden",
4796
4810
  "resolveReview": "Die Prüfung konnte nicht abgeschlossen werden"
4811
+ },
4812
+ "findingClass": {
4813
+ "judgement": "Ihre Entscheidung nötig",
4814
+ "judgementHint": "Eine Geschäfts-, Produkt- oder Domänenentscheidung oder etwas, das dem Reviewer nicht mitgeteilt wurde. Nur Sie können das klären.",
4815
+ "practice": "Aus der Praxis beantwortbar",
4816
+ "practiceHint": "Durch etablierte Praxis, den bereits genutzten Stack oder den vorliegenden Kontext geklärt. Vorbefüllt zum Übernehmen oder Ändern."
4817
+ },
4818
+ "confidence": {
4819
+ "high": "Hohe Zuversicht",
4820
+ "medium": "Mittlere Zuversicht",
4821
+ "low": "Geringe Zuversicht"
4797
4822
  }
4798
4823
  },
4799
4824
  "bootstrap": {
@@ -3347,6 +3347,10 @@
3347
3347
  "label": "Finish unattended runs without waiting for a person",
3348
3348
  "unattendedHint": "When an automatic loop gives up (a companion at its rework cap, a review at its pass cap, untriaged follow-ups), the run proceeds on the record instead of parking. Gates the pipeline asks for, such as human testing, review and approval, still stop the run.",
3349
3349
  "attendedHint": "When an automatic loop gives up, the run parks and waits for someone to choose. Right for a board somebody is watching; a run started over the API waits indefinitely."
3350
+ },
3351
+ "autoAnswer": {
3352
+ "label": "Auto-answer confidence floor (%)",
3353
+ "hint": "How sure the Requirement Writer must be for an unwatched run to keep its suggested answer instead of stopping for a person. Only findings the reviewer judged answerable without a product owner are eligible."
3350
3354
  }
3351
3355
  },
3352
3356
  "observabilityConnection": {
@@ -5117,7 +5121,17 @@
5117
5121
  "binaryComparison": "Compare candidates before delivering",
5118
5122
  "binaryPerGenerator": "Candidates per integration",
5119
5123
  "binaryMultiSelect": "Allow keeping more than one",
5120
- "binaryComparisonUnreachable": "This step can only produce one candidate per subject, so nothing would be compared and the only one would be kept without asking. Select a second integration, or raise the candidates-per-integration count."
5124
+ "binaryComparisonUnreachable": "This step can only produce one candidate per subject, so nothing would be compared and the only one would be kept without asking. Select a second integration, or raise the candidates-per-integration count.",
5125
+ "scopeDefault": {
5126
+ "interactive": "In-app default",
5127
+ "interactiveHint": "What a task started from the board runs when it pins no pipeline of its own.",
5128
+ "unattended": "Unattended default",
5129
+ "unattendedHint": "What a run nobody is watching runs (the API, a ticket, a schedule) when the task pins no pipeline.",
5130
+ "claimInteractive": "Make the in-app default",
5131
+ "releaseInteractive": "Stop being the in-app default",
5132
+ "claimUnattended": "Make the unattended default",
5133
+ "releaseUnattended": "Stop being the unattended default"
5134
+ }
5121
5135
  },
5122
5136
  "progress": {
5123
5137
  "status": {
@@ -5654,6 +5668,17 @@
5654
5668
  "reReview": "Could not re-review the requirements",
5655
5669
  "proceed": "Could not proceed",
5656
5670
  "resolveReview": "Could not resolve the review"
5671
+ },
5672
+ "findingClass": {
5673
+ "judgement": "Needs your decision",
5674
+ "judgementHint": "A business, product or domain call, or something the reviewer was not told. Only you can settle these.",
5675
+ "practice": "Answerable from practice",
5676
+ "practiceHint": "Settled by established practice, the stack already in use, or the context provided. Pre-filled for you to keep or change."
5677
+ },
5678
+ "confidence": {
5679
+ "high": "High confidence",
5680
+ "medium": "Medium confidence",
5681
+ "low": "Low confidence"
5657
5682
  }
5658
5683
  },
5659
5684
  "clarity": {
@@ -3068,6 +3068,10 @@
3068
3068
  "label": "Completar las ejecuciones sin supervisión sin esperar a una persona",
3069
3069
  "unattendedHint": "Cuando un bucle automático se rinde (un companion en su límite de reintentos, una revisión en su límite de pasadas, seguimientos sin triar), la ejecución continúa dejando constancia en lugar de detenerse. Las puertas que pide la pipeline, como pruebas manuales, revisión y aprobación, siguen deteniendo la ejecución.",
3070
3070
  "attendedHint": "Cuando un bucle automático se rinde, la ejecución se detiene y espera a que alguien elija. Adecuado para un tablero que alguien está mirando; una ejecución iniciada por la API espera indefinidamente."
3071
+ },
3072
+ "autoAnswer": {
3073
+ "label": "Confianza mínima para autorrespuesta (%)",
3074
+ "hint": "Cuánta seguridad debe tener el Requirement Writer para que una ejecución sin observadores conserve su respuesta sugerida en lugar de detenerse. Solo son elegibles los hallazgos que el revisor juzgó resolubles sin un product owner."
3071
3075
  }
3072
3076
  },
3073
3077
  "observabilityConnection": {
@@ -4948,7 +4952,17 @@
4948
4952
  "binaryComparison": "Comparar candidatos antes de entregar",
4949
4953
  "binaryPerGenerator": "Candidatos por integración",
4950
4954
  "binaryMultiSelect": "Permitir conservar más de uno",
4951
- "binaryComparisonUnreachable": "Este paso solo puede producir un candidato por sujeto, así que no habría nada que comparar y el único se conservaría sin preguntar. Selecciona una segunda integración o sube el número de candidatos por integración."
4955
+ "binaryComparisonUnreachable": "Este paso solo puede producir un candidato por sujeto, así que no habría nada que comparar y el único se conservaría sin preguntar. Selecciona una segunda integración o sube el número de candidatos por integración.",
4956
+ "scopeDefault": {
4957
+ "interactive": "Predeterminada en la app",
4958
+ "interactiveHint": "Lo que ejecuta una tarea iniciada desde el tablero cuando no fija ninguna pipeline propia.",
4959
+ "unattended": "Predeterminada sin supervisión",
4960
+ "unattendedHint": "Lo que ejecuta una ejecución que nadie observa (la API, un ticket, una programación) cuando la tarea no fija pipeline.",
4961
+ "claimInteractive": "Hacer predeterminada en la app",
4962
+ "releaseInteractive": "Dejar de ser la predeterminada en la app",
4963
+ "claimUnattended": "Hacer predeterminada sin supervisión",
4964
+ "releaseUnattended": "Dejar de ser la predeterminada sin supervisión"
4965
+ }
4952
4966
  },
4953
4967
  "progress": {
4954
4968
  "status": {
@@ -5396,6 +5410,17 @@
5396
5410
  "reReview": "No se pudieron volver a revisar los requisitos",
5397
5411
  "proceed": "No se pudo continuar",
5398
5412
  "resolveReview": "No se pudo resolver la revisión"
5413
+ },
5414
+ "findingClass": {
5415
+ "judgement": "Necesita tu decisión",
5416
+ "judgementHint": "Una decisión de negocio, producto o dominio, o algo que el revisor no sabía. Solo tú puedes resolverlo.",
5417
+ "practice": "Resoluble con buenas prácticas",
5418
+ "practiceHint": "Se resuelve con la práctica establecida, el stack ya en uso o el contexto aportado. Se rellena para que lo mantengas o lo cambies."
5419
+ },
5420
+ "confidence": {
5421
+ "high": "Confianza alta",
5422
+ "medium": "Confianza media",
5423
+ "low": "Confianza baja"
5399
5424
  }
5400
5425
  },
5401
5426
  "clarity": {
@@ -3068,6 +3068,10 @@
3068
3068
  "label": "Terminer les exécutions sans surveillance sans attendre une personne",
3069
3069
  "unattendedHint": "Quand une boucle automatique abandonne (un companion à sa limite de reprises, une revue à sa limite de passes, des suivis non triés), l'exécution continue en le consignant au lieu de s'arrêter. Les points de contrôle demandés par le pipeline, comme le test humain, la revue et l'approbation, arrêtent toujours l'exécution.",
3070
3070
  "attendedHint": "Quand une boucle automatique abandonne, l'exécution s'arrête et attend un choix. Adapté à un tableau que quelqu'un surveille ; une exécution lancée via l'API attend indéfiniment."
3071
+ },
3072
+ "autoAnswer": {
3073
+ "label": "Confiance minimale pour une réponse automatique (%)",
3074
+ "hint": "Le degré de certitude que le Requirement Writer doit atteindre pour qu'un run sans surveillance conserve sa réponse suggérée au lieu de s'arrêter. Seuls les constats jugés traitables sans product owner sont éligibles."
3071
3075
  }
3072
3076
  },
3073
3077
  "observabilityConnection": {
@@ -4948,7 +4952,17 @@
4948
4952
  "binaryComparison": "Comparer les candidats avant livraison",
4949
4953
  "binaryPerGenerator": "Candidats par intégration",
4950
4954
  "binaryMultiSelect": "Autoriser à en conserver plusieurs",
4951
- "binaryComparisonUnreachable": "Cette étape ne peut produire qu’un candidat par sujet : il n’y aurait rien à comparer et le seul serait conservé sans être présenté. Sélectionnez une deuxième intégration ou augmentez le nombre de candidats par intégration."
4955
+ "binaryComparisonUnreachable": "Cette étape ne peut produire qu’un candidat par sujet : il n’y aurait rien à comparer et le seul serait conservé sans être présenté. Sélectionnez une deuxième intégration ou augmentez le nombre de candidats par intégration.",
4956
+ "scopeDefault": {
4957
+ "interactive": "Défaut dans l'application",
4958
+ "interactiveHint": "Ce qu'exécute une tâche lancée depuis le tableau lorsqu'elle ne fixe aucun pipeline.",
4959
+ "unattended": "Défaut sans surveillance",
4960
+ "unattendedHint": "Ce qu'exécute un run que personne ne surveille (API, ticket, planification) quand la tâche ne fixe aucun pipeline.",
4961
+ "claimInteractive": "Définir comme défaut dans l'application",
4962
+ "releaseInteractive": "Ne plus être le défaut dans l'application",
4963
+ "claimUnattended": "Définir comme défaut sans surveillance",
4964
+ "releaseUnattended": "Ne plus être le défaut sans surveillance"
4965
+ }
4952
4966
  },
4953
4967
  "progress": {
4954
4968
  "status": {
@@ -5396,6 +5410,17 @@
5396
5410
  "reReview": "Impossible de relire les exigences",
5397
5411
  "proceed": "Impossible de continuer",
5398
5412
  "resolveReview": "Impossible de résoudre la revue"
5413
+ },
5414
+ "findingClass": {
5415
+ "judgement": "Votre décision requise",
5416
+ "judgementHint": "Un choix métier, produit ou de domaine, ou une information que le relecteur n'avait pas. Vous seul pouvez trancher.",
5417
+ "practice": "Traitable par la pratique",
5418
+ "practiceHint": "Tranché par la pratique établie, la stack déjà utilisée ou le contexte fourni. Prérempli : gardez-le ou modifiez-le."
5419
+ },
5420
+ "confidence": {
5421
+ "high": "Confiance élevée",
5422
+ "medium": "Confiance moyenne",
5423
+ "low": "Confiance faible"
5399
5424
  }
5400
5425
  },
5401
5426
  "clarity": {
@@ -3210,6 +3210,10 @@
3210
3210
  "label": "לסיים הרצות ללא השגחה בלי להמתין לאדם",
3211
3211
  "unattendedHint": "כשלולאה אוטומטית מוותרת (קומפניון שמיצה את מכסת התיקונים, סקירה שמיצתה את מכסת המעברים, פריטי המשך שלא מוינו), ההרצה ממשיכה תוך תיעוד במקום לעצור. שערים שהצינור ביקש, כגון בדיקה אנושית, סקירה ואישור, עדיין עוצרים את ההרצה.",
3212
3212
  "attendedHint": "כשלולאה אוטומטית מוותרת, ההרצה נעצרת וממתינה שמישהו יחליט. מתאים ללוח שמישהו צופה בו; הרצה שהופעלה דרך ה-API תמתין ללא הגבלת זמן."
3213
+ },
3214
+ "autoAnswer": {
3215
+ "label": "רף ביטחון לתשובה אוטומטית (%)",
3216
+ "hint": "עד כמה Requirement Writer צריך להיות בטוח כדי שריצה בלי השגחה תשמור על התשובה המוצעת במקום לעצור לאדם. רק ממצאים שהמבקר סימן כניתנים למענה בלי בעל מוצר נכללים."
3213
3217
  }
3214
3218
  },
3215
3219
  "observabilityConnection": {
@@ -4948,7 +4952,17 @@
4948
4952
  "binaryComparison": "להשוות מועמדים לפני מסירה",
4949
4953
  "binaryPerGenerator": "מועמדים לכל אינטגרציה",
4950
4954
  "binaryMultiSelect": "לאפשר לשמור יותר מאחד",
4951
- "binaryComparisonUnreachable": "השלב הזה יכול להפיק רק מועמד אחד לכל נושא, כך שלא יהיה מה להשוות והיחיד יישמר בלי לשאול. בחרו אינטגרציה נוספת או העלו את מספר המועמדים לכל אינטגרציה."
4955
+ "binaryComparisonUnreachable": "השלב הזה יכול להפיק רק מועמד אחד לכל נושא, כך שלא יהיה מה להשוות והיחיד יישמר בלי לשאול. בחרו אינטגרציה נוספת או העלו את מספר המועמדים לכל אינטגרציה.",
4956
+ "scopeDefault": {
4957
+ "interactive": "ברירת מחדל באפליקציה",
4958
+ "interactiveHint": "מה שמריצה משימה שהופעלה מהלוח כשלא נקבע לה תהליך משלה.",
4959
+ "unattended": "ברירת מחדל ללא השגחה",
4960
+ "unattendedHint": "מה שמריץ ריצה שאף אחד לא צופה בה (ה-API, כרטיס, תזמון) כשלמשימה אין תהליך קבוע.",
4961
+ "claimInteractive": "הפוך לברירת המחדל באפליקציה",
4962
+ "releaseInteractive": "בטל כברירת מחדל באפליקציה",
4963
+ "claimUnattended": "הפוך לברירת המחדל ללא השגחה",
4964
+ "releaseUnattended": "בטל כברירת מחדל ללא השגחה"
4965
+ }
4952
4966
  },
4953
4967
  "progress": {
4954
4968
  "status": {
@@ -5396,6 +5410,17 @@
5396
5410
  "reReview": "לא ניתן לסקור מחדש את הדרישות",
5397
5411
  "proceed": "לא ניתן להמשיך",
5398
5412
  "resolveReview": "לא ניתן לפתור את הסקירה"
5413
+ },
5414
+ "findingClass": {
5415
+ "judgement": "דורש את ההחלטה שלך",
5416
+ "judgementHint": "הכרעה עסקית, מוצרית או תחומית, או מידע שלא נמסר למבקר. רק את/ה יכול/ה להכריע.",
5417
+ "practice": "ניתן לענות לפי פרקטיקה מקובלת",
5418
+ "practiceHint": "נקבע לפי פרקטיקה מקובלת, הסטאק שכבר בשימוש או ההקשר שנמסר. מולא מראש — אפשר לאשר או לשנות."
5419
+ },
5420
+ "confidence": {
5421
+ "high": "ביטחון גבוה",
5422
+ "medium": "ביטחון בינוני",
5423
+ "low": "ביטחון נמוך"
5399
5424
  }
5400
5425
  },
5401
5426
  "clarity": {
@@ -611,6 +611,10 @@
611
611
  "label": "Completare le esecuzioni non presidiate senza attendere una persona",
612
612
  "unattendedHint": "Quando un ciclo automatico si arrende (un companion al suo limite di rilavorazioni, una revisione al suo limite di passaggi, follow-up non smistati), l'esecuzione prosegue lasciandone traccia invece di fermarsi. I varchi richiesti dalla pipeline, come test manuale, revisione e approvazione, fermano comunque l'esecuzione.",
613
613
  "attendedHint": "Quando un ciclo automatico si arrende, l'esecuzione si ferma e attende una scelta. Adatto a una board che qualcuno sta guardando; un'esecuzione avviata via API attende all'infinito."
614
+ },
615
+ "autoAnswer": {
616
+ "label": "Confidenza minima per la risposta automatica (%)",
617
+ "hint": "Quanto deve essere sicuro il Requirement Writer perché un run non presidiato mantenga la risposta suggerita invece di fermarsi per una persona. Sono ammessi solo i rilievi che il revisore ha giudicato risolvibili senza un product owner."
614
618
  }
615
619
  },
616
620
  "observabilityConnection": {
@@ -4509,7 +4513,17 @@
4509
4513
  "binaryComparison": "Confronta i candidati prima di consegnare",
4510
4514
  "binaryPerGenerator": "Candidati per integrazione",
4511
4515
  "binaryMultiSelect": "Consenti di tenerne più di uno",
4512
- "binaryComparisonUnreachable": "Questo passo può produrre un solo candidato per soggetto, quindi non ci sarebbe nulla da confrontare e l’unico verrebbe tenuto senza chiedere. Seleziona una seconda integrazione oppure aumenta il numero di candidati per integrazione."
4516
+ "binaryComparisonUnreachable": "Questo passo può produrre un solo candidato per soggetto, quindi non ci sarebbe nulla da confrontare e l’unico verrebbe tenuto senza chiedere. Seleziona una seconda integrazione oppure aumenta il numero di candidati per integrazione.",
4517
+ "scopeDefault": {
4518
+ "interactive": "Predefinita nell'app",
4519
+ "interactiveHint": "Cosa esegue un task avviato dalla board quando non fissa una pipeline propria.",
4520
+ "unattended": "Predefinita non presidiata",
4521
+ "unattendedHint": "Cosa esegue un run che nessuno sta guardando (API, ticket, pianificazione) quando il task non fissa una pipeline.",
4522
+ "claimInteractive": "Rendi predefinita nell'app",
4523
+ "releaseInteractive": "Non più predefinita nell'app",
4524
+ "claimUnattended": "Rendi predefinita non presidiata",
4525
+ "releaseUnattended": "Non più predefinita non presidiata"
4526
+ }
4513
4527
  },
4514
4528
  "progress": {
4515
4529
  "status": {
@@ -4794,6 +4808,17 @@
4794
4808
  "reReview": "Impossibile rivedere di nuovo i requisiti",
4795
4809
  "proceed": "Impossibile procedere",
4796
4810
  "resolveReview": "Impossibile risolvere la revisione"
4811
+ },
4812
+ "findingClass": {
4813
+ "judgement": "Serve una tua decisione",
4814
+ "judgementHint": "Una scelta di business, prodotto o dominio, o qualcosa che il revisore non sapeva. Solo tu puoi deciderlo.",
4815
+ "practice": "Risolvibile con la prassi",
4816
+ "practiceHint": "Risolto dalla prassi consolidata, dallo stack già in uso o dal contesto fornito. Precompilato: confermalo o modificalo."
4817
+ },
4818
+ "confidence": {
4819
+ "high": "Confidenza alta",
4820
+ "medium": "Confidenza media",
4821
+ "low": "Confidenza bassa"
4797
4822
  }
4798
4823
  },
4799
4824
  "bootstrap": {
@@ -3210,6 +3210,10 @@
3210
3210
  "label": "無人実行を人の判断を待たずに完了させる",
3211
3211
  "unattendedHint": "自動ループが打ち切られたとき(コンパニオンの手戻り上限、レビューのパス上限、未仕分けのフォローアップ)、実行は停止せず記録を残して先に進みます。パイプラインが要求したゲート、たとえば人手テスト・レビュー・承認は、これまでどおり実行を止めます。",
3212
3212
  "attendedHint": "自動ループが打ち切られると、実行は停止して人の判断を待ちます。誰かが見ているボードには適していますが、API から開始した実行は無期限に待ち続けます。"
3213
+ },
3214
+ "autoAnswer": {
3215
+ "label": "自動回答の確信度しきい値 (%)",
3216
+ "hint": "無人の実行が人を待たずに提案された回答を採用するために、Requirement Writer に必要な確信度です。対象はレビュアーがプロダクトオーナー不要と判断した指摘のみです。"
3213
3217
  }
3214
3218
  },
3215
3219
  "observabilityConnection": {
@@ -4948,7 +4952,17 @@
4948
4952
  "binaryComparison": "納品前に候補を比較する",
4949
4953
  "binaryPerGenerator": "連携ごとの候補数",
4950
4954
  "binaryMultiSelect": "複数を残せるようにする",
4951
- "binaryComparisonUnreachable": "このステップは対象ごとに候補を1つしか作れないため、比較するものがなく、その1つが確認なしで採用されます。2つ目の連携を選ぶか、連携ごとの候補数を増やしてください。"
4955
+ "binaryComparisonUnreachable": "このステップは対象ごとに候補を1つしか作れないため、比較するものがなく、その1つが確認なしで採用されます。2つ目の連携を選ぶか、連携ごとの候補数を増やしてください。",
4956
+ "scopeDefault": {
4957
+ "interactive": "アプリ内の既定",
4958
+ "interactiveHint": "ボードから開始したタスクが自身のパイプラインを指定していないときに実行するもの。",
4959
+ "unattended": "無人実行の既定",
4960
+ "unattendedHint": "誰も見ていない実行(API・チケット・スケジュール)でタスクがパイプラインを指定していないときに実行するもの。",
4961
+ "claimInteractive": "アプリ内の既定にする",
4962
+ "releaseInteractive": "アプリ内の既定を解除",
4963
+ "claimUnattended": "無人実行の既定にする",
4964
+ "releaseUnattended": "無人実行の既定を解除"
4965
+ }
4952
4966
  },
4953
4967
  "progress": {
4954
4968
  "status": {
@@ -5396,6 +5410,17 @@
5396
5410
  "reReview": "要件を再レビューできませんでした",
5397
5411
  "proceed": "続行できませんでした",
5398
5412
  "resolveReview": "レビューを解決できませんでした"
5413
+ },
5414
+ "findingClass": {
5415
+ "judgement": "あなたの判断が必要",
5416
+ "judgementHint": "ビジネス・プロダクト・ドメインの判断、またはレビュアーが知らされていない情報です。あなたしか決められません。",
5417
+ "practice": "一般的な実践で回答可能",
5418
+ "practiceHint": "確立された実践、すでに使っている技術スタック、提供済みの文脈で決まります。あらかじめ入力済みで、そのままでも変更しても構いません。"
5419
+ },
5420
+ "confidence": {
5421
+ "high": "確信度: 高",
5422
+ "medium": "確信度: 中",
5423
+ "low": "確信度: 低"
5399
5424
  }
5400
5425
  },
5401
5426
  "clarity": {
@@ -3068,6 +3068,10 @@
3068
3068
  "label": "Kończ uruchomienia bez nadzoru bez czekania na człowieka",
3069
3069
  "unattendedHint": "Gdy automatyczna pętla się poddaje (companion na limicie poprawek, przegląd na limicie przebiegów, nieposegregowane zadania pochodne), uruchomienie idzie dalej z zapisem zamiast się zatrzymywać. Bramki, o które prosi pipeline, takie jak testy ręczne, przegląd i zatwierdzenie, nadal je zatrzymują.",
3070
3070
  "attendedHint": "Gdy automatyczna pętla się poddaje, uruchomienie zatrzymuje się i czeka na decyzję. Właściwe dla tablicy, którą ktoś obserwuje; uruchomienie wystartowane przez API czeka bez końca."
3071
+ },
3072
+ "autoAnswer": {
3073
+ "label": "Minimalna pewność automatycznej odpowiedzi (%)",
3074
+ "hint": "Jak pewny musi być Requirement Writer, aby nienadzorowany przebieg zachował podpowiedzianą odpowiedź zamiast zatrzymać się na człowieku. Kwalifikują się tylko uwagi uznane przez recenzenta za rozstrzygalne bez product ownera."
3071
3075
  }
3072
3076
  },
3073
3077
  "observabilityConnection": {
@@ -4948,7 +4952,17 @@
4948
4952
  "binaryComparison": "Porównaj kandydatów przed dostarczeniem",
4949
4953
  "binaryPerGenerator": "Kandydaci na integrację",
4950
4954
  "binaryMultiSelect": "Pozwól zachować więcej niż jednego",
4951
- "binaryComparisonUnreachable": "Ten krok może wytworzyć tylko jednego kandydata na temat, więc nie byłoby czego porównywać, a ten jeden zostałby zachowany bez pytania. Wybierz drugą integrację albo zwiększ liczbę kandydatów na integrację."
4955
+ "binaryComparisonUnreachable": "Ten krok może wytworzyć tylko jednego kandydata na temat, więc nie byłoby czego porównywać, a ten jeden zostałby zachowany bez pytania. Wybierz drugą integrację albo zwiększ liczbę kandydatów na integrację.",
4956
+ "scopeDefault": {
4957
+ "interactive": "Domyślny w aplikacji",
4958
+ "interactiveHint": "Co uruchamia zadanie startowane z tablicy, gdy nie wskazuje własnego procesu.",
4959
+ "unattended": "Domyślny bez nadzoru",
4960
+ "unattendedHint": "Co uruchamia przebieg, którego nikt nie obserwuje (API, zgłoszenie, harmonogram), gdy zadanie nie wskazuje procesu.",
4961
+ "claimInteractive": "Ustaw jako domyślny w aplikacji",
4962
+ "releaseInteractive": "Przestań być domyślnym w aplikacji",
4963
+ "claimUnattended": "Ustaw jako domyślny bez nadzoru",
4964
+ "releaseUnattended": "Przestań być domyślnym bez nadzoru"
4965
+ }
4952
4966
  },
4953
4967
  "progress": {
4954
4968
  "status": {
@@ -5396,6 +5410,17 @@
5396
5410
  "reReview": "Nie udało się ponownie przejrzeć wymagań",
5397
5411
  "proceed": "Nie udało się kontynuować",
5398
5412
  "resolveReview": "Nie udało się rozstrzygnąć przeglądu"
5413
+ },
5414
+ "findingClass": {
5415
+ "judgement": "Wymaga Twojej decyzji",
5416
+ "judgementHint": "Decyzja biznesowa, produktowa lub domenowa albo informacja, której recenzent nie znał. Tylko Ty możesz to rozstrzygnąć.",
5417
+ "practice": "Rozstrzygalne praktyką",
5418
+ "practiceHint": "Rozstrzygane przez utrwaloną praktykę, używany już stos technologiczny lub dostarczony kontekst. Wypełnione wstępnie — zostaw lub zmień."
5419
+ },
5420
+ "confidence": {
5421
+ "high": "Wysoka pewność",
5422
+ "medium": "Średnia pewność",
5423
+ "low": "Niska pewność"
5399
5424
  }
5400
5425
  },
5401
5426
  "clarity": {
@@ -3210,6 +3210,10 @@
3210
3210
  "label": "Gözetimsiz çalıştırmaları bir kişiyi beklemeden tamamla",
3211
3211
  "unattendedHint": "Otomatik bir döngü pes ettiğinde (yeniden çalışma sınırındaki bir companion, geçiş sınırındaki bir inceleme, ayıklanmamış takip maddeleri), çalıştırma durmak yerine kayda geçirilerek devam eder. Hattın istediği kapılar, örneğin insan testi, inceleme ve onay, çalıştırmayı yine durdurur.",
3212
3212
  "attendedHint": "Otomatik bir döngü pes ettiğinde çalıştırma durur ve birinin seçim yapmasını bekler. Birinin izlediği bir pano için doğrudur; API üzerinden başlatılan bir çalıştırma süresiz bekler."
3213
+ },
3214
+ "autoAnswer": {
3215
+ "label": "Otomatik yanıt güven eşiği (%)",
3216
+ "hint": "Gözetimsiz bir çalıştırmanın bir kişiyi beklemek yerine önerilen yanıtı kullanabilmesi için Requirement Writer’ın ne kadar emin olması gerektiği. Yalnızca inceleyicinin ürün sahibi olmadan yanıtlanabilir bulduğu bulgular uygundur."
3213
3217
  }
3214
3218
  },
3215
3219
  "observabilityConnection": {
@@ -4948,7 +4952,17 @@
4948
4952
  "binaryComparison": "Teslimden önce adayları karşılaştır",
4949
4953
  "binaryPerGenerator": "Entegrasyon başına aday",
4950
4954
  "binaryMultiSelect": "Birden fazlasını tutmaya izin ver",
4951
- "binaryComparisonUnreachable": "Bu adım her konu için yalnızca bir aday üretebilir; karşılaştırılacak bir şey olmaz ve tek aday sorulmadan tutulur. İkinci bir entegrasyon seçin ya da entegrasyon başına aday sayısını artırın."
4955
+ "binaryComparisonUnreachable": "Bu adım her konu için yalnızca bir aday üretebilir; karşılaştırılacak bir şey olmaz ve tek aday sorulmadan tutulur. İkinci bir entegrasyon seçin ya da entegrasyon başına aday sayısını artırın.",
4956
+ "scopeDefault": {
4957
+ "interactive": "Uygulama içi varsayılan",
4958
+ "interactiveHint": "Panodan başlatılan bir görev kendi hattını belirtmediğinde ne çalıştırılır.",
4959
+ "unattended": "Gözetimsiz varsayılan",
4960
+ "unattendedHint": "Kimsenin izlemediği bir çalıştırmanın (API, kayıt, zamanlama) görev hat belirtmediğinde ne çalıştıracağı.",
4961
+ "claimInteractive": "Uygulama içi varsayılan yap",
4962
+ "releaseInteractive": "Uygulama içi varsayılan olmaktan çıkar",
4963
+ "claimUnattended": "Gözetimsiz varsayılan yap",
4964
+ "releaseUnattended": "Gözetimsiz varsayılan olmaktan çıkar"
4965
+ }
4952
4966
  },
4953
4967
  "progress": {
4954
4968
  "status": {
@@ -5396,6 +5410,17 @@
5396
5410
  "reReview": "Gereksinimler yeniden incelenemedi",
5397
5411
  "proceed": "Devam edilemedi",
5398
5412
  "resolveReview": "İnceleme çözümlenemedi"
5413
+ },
5414
+ "findingClass": {
5415
+ "judgement": "Sizin kararınız gerekiyor",
5416
+ "judgementHint": "İş, ürün veya alan kararı ya da inceleyiciye söylenmemiş bir bilgi. Bunu yalnızca siz çözebilirsiniz.",
5417
+ "practice": "Yerleşik uygulamayla yanıtlanabilir",
5418
+ "practiceHint": "Yerleşik uygulama, hâlihazırda kullanılan teknoloji yığını veya verilen bağlam belirler. Önceden doldurulur; olduğu gibi bırakın ya da değiştirin."
5419
+ },
5420
+ "confidence": {
5421
+ "high": "Yüksek güven",
5422
+ "medium": "Orta güven",
5423
+ "low": "Düşük güven"
5399
5424
  }
5400
5425
  },
5401
5426
  "clarity": {