@cat-factory/app 0.267.0 → 0.268.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.
- package/app/components/layout/AccountRiskPolicySettings.vue +120 -0
- package/app/components/settings/AccountSettingsPanel.vue +17 -2
- package/app/components/settings/RiskPolicyCreateForm.vue +164 -0
- package/app/components/settings/RiskPolicyEditorRow.vue +315 -0
- package/app/components/settings/RiskPolicyInheritedRow.vue +69 -0
- package/app/components/settings/RiskPolicyPanel.vue +176 -603
- package/app/composables/api/presets.ts +50 -13
- package/app/composables/usePipelineErrorToast.ts +11 -0
- package/app/composables/useRiskPolicyHealth.ts +14 -1
- package/app/composables/useRunStart.spec.ts +9 -5
- package/app/stores/riskPolicies.ts +123 -13
- package/app/types/merge.ts +5 -0
- package/app/utils/riskPolicy.spec.ts +28 -0
- package/app/utils/riskPolicy.ts +24 -1
- package/app/utils/riskPolicyDraft.ts +203 -0
- package/i18n/locales/de.json +45 -4
- package/i18n/locales/en.json +45 -4
- package/i18n/locales/es.json +45 -4
- package/i18n/locales/fr.json +45 -4
- package/i18n/locales/he.json +45 -4
- package/i18n/locales/it.json +45 -4
- package/i18n/locales/ja.json +45 -4
- package/i18n/locales/pl.json +45 -4
- package/i18n/locales/tr.json +45 -4
- package/i18n/locales/uk.json +45 -4
- package/package.json +2 -2
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import type { StepGating } from '@cat-factory/contracts'
|
|
2
|
+
import type {
|
|
3
|
+
ClassRulesByRole,
|
|
4
|
+
DryRunRoles,
|
|
5
|
+
MergeClassRules,
|
|
6
|
+
RequirementConcernLevel,
|
|
7
|
+
RiskPolicy,
|
|
8
|
+
SubmissionClassesByRole,
|
|
9
|
+
UpdateRiskPolicyInput,
|
|
10
|
+
} from '~/types/merge'
|
|
11
|
+
import type { RiskPolicyAxis } from '~/utils/riskPolicy'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The editable form state behind one risk policy, and the conversions either side of it.
|
|
15
|
+
*
|
|
16
|
+
* Extracted out of the settings panel because the SAME form now serves two tiers (a board's own
|
|
17
|
+
* policies and an account's, ADR 0055) plus the create row, and three copies of "percentages are
|
|
18
|
+
* edited 0..100 and stored 0..1" is three chances for one of them to drift by a factor of a hundred.
|
|
19
|
+
*/
|
|
20
|
+
export interface RiskPolicyDraft {
|
|
21
|
+
name: string
|
|
22
|
+
maxComplexity: number
|
|
23
|
+
maxRisk: number
|
|
24
|
+
maxImpact: number
|
|
25
|
+
ciMaxAttempts: number
|
|
26
|
+
maxRequirementIterations: number
|
|
27
|
+
maxRequirementConcernAllowed: RequirementConcernLevel
|
|
28
|
+
autoMergeEnabled: boolean
|
|
29
|
+
/**
|
|
30
|
+
* Whether a run under this policy answers the parks its own automatic loops raise when they give
|
|
31
|
+
* up, rather than stopping for a person. Edited as a switch because the vocabulary is two-valued
|
|
32
|
+
* and the OFF state is the historical behaviour.
|
|
33
|
+
*/
|
|
34
|
+
unattended: boolean
|
|
35
|
+
/**
|
|
36
|
+
* The confidence floor an unattended run's auto-answered requirements finding must clear, as a
|
|
37
|
+
* PERCENT (like the numbers above). Only read while `unattended` is on.
|
|
38
|
+
*/
|
|
39
|
+
minAutoAnswerConfidence: number
|
|
40
|
+
/**
|
|
41
|
+
* Per-change-class auto-merge rules. An OMITTED class means "use the score ceilings above", so
|
|
42
|
+
* `{}` is the identity.
|
|
43
|
+
*/
|
|
44
|
+
classRules: MergeClassRules
|
|
45
|
+
/**
|
|
46
|
+
* The ROLE layer over those rules: per-role narrowing (narrow-only, so `{}` is the identity) and
|
|
47
|
+
* the roles whose runs are sandboxed. Both replace the stored value wholesale on save, which is
|
|
48
|
+
* why clearing one in the editor is a plain omission.
|
|
49
|
+
*/
|
|
50
|
+
classRulesByRole: ClassRulesByRole
|
|
51
|
+
dryRunRoles: DryRunRoles
|
|
52
|
+
/**
|
|
53
|
+
* Which classes each role may LAND at all. A role with no entry is unrestricted, so `{}` is the
|
|
54
|
+
* identity; an entry with no classes is the different policy that the role lands nothing.
|
|
55
|
+
*/
|
|
56
|
+
submissionClassesByRole: SubmissionClassesByRole
|
|
57
|
+
/** Implementation-fork decision gating (edited 0..100, stored 0..1); disabled ⇒ off in `auto`. */
|
|
58
|
+
forkEnabled: boolean
|
|
59
|
+
forkMinComplexity: number
|
|
60
|
+
forkMinRisk: number
|
|
61
|
+
forkMinImpact: number
|
|
62
|
+
forkOnMissing: 'run' | 'skip'
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Which draft field carries each axis's fork FLOOR: the same three axes as the auto-merge ceilings,
|
|
67
|
+
* read as "how big an estimate has to be before the coder stops to propose implementations". Shares
|
|
68
|
+
* the axis order but not the fields, and is exhaustive over the union so adding an axis fails the
|
|
69
|
+
* typecheck rather than silently rendering two.
|
|
70
|
+
*/
|
|
71
|
+
export const FORK_FLOOR_FIELD: Record<
|
|
72
|
+
RiskPolicyAxis,
|
|
73
|
+
'forkMinRisk' | 'forkMinImpact' | 'forkMinComplexity'
|
|
74
|
+
> = {
|
|
75
|
+
risk: 'forkMinRisk',
|
|
76
|
+
impact: 'forkMinImpact',
|
|
77
|
+
complexity: 'forkMinComplexity',
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** A stored policy → the form state, percentages scaled up for editing. */
|
|
81
|
+
export function toRiskPolicyDraft(p: RiskPolicy): RiskPolicyDraft {
|
|
82
|
+
return {
|
|
83
|
+
name: p.name,
|
|
84
|
+
maxComplexity: Math.round(p.maxComplexity * 100),
|
|
85
|
+
maxRisk: Math.round(p.maxRisk * 100),
|
|
86
|
+
maxImpact: Math.round(p.maxImpact * 100),
|
|
87
|
+
ciMaxAttempts: p.ciMaxAttempts,
|
|
88
|
+
maxRequirementIterations: p.maxRequirementIterations,
|
|
89
|
+
maxRequirementConcernAllowed: p.maxRequirementConcernAllowed,
|
|
90
|
+
autoMergeEnabled: p.autoMergeEnabled,
|
|
91
|
+
unattended: p.autonomy === 'unattended',
|
|
92
|
+
minAutoAnswerConfidence: Math.round(p.minAutoAnswerConfidence * 100),
|
|
93
|
+
classRules: { ...p.classRules },
|
|
94
|
+
classRulesByRole: { ...p.classRulesByRole },
|
|
95
|
+
dryRunRoles: [...p.dryRunRoles],
|
|
96
|
+
submissionClassesByRole: { ...p.submissionClassesByRole },
|
|
97
|
+
forkEnabled: p.forkDecision?.enabled ?? false,
|
|
98
|
+
forkMinComplexity: Math.round((p.forkDecision?.minComplexity ?? 0.5) * 100),
|
|
99
|
+
forkMinRisk: Math.round((p.forkDecision?.minRisk ?? 0.4) * 100),
|
|
100
|
+
forkMinImpact: Math.round((p.forkDecision?.minImpact ?? 0.4) * 100),
|
|
101
|
+
forkOnMissing: p.forkDecision?.onMissingEstimate ?? 'run',
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** The blank draft a create form opens on: the shipped defaults, and never a granted licence. */
|
|
106
|
+
export function blankRiskPolicyDraft(): RiskPolicyDraft {
|
|
107
|
+
return {
|
|
108
|
+
name: '',
|
|
109
|
+
maxComplexity: 50,
|
|
110
|
+
maxRisk: 40,
|
|
111
|
+
maxImpact: 50,
|
|
112
|
+
ciMaxAttempts: 10,
|
|
113
|
+
maxRequirementIterations: 6,
|
|
114
|
+
maxRequirementConcernAllowed: 'none',
|
|
115
|
+
autoMergeEnabled: true,
|
|
116
|
+
// A new policy parks on its own caps, matching every built-in but the unattended default: a
|
|
117
|
+
// licence to answer them is a posture somebody grants, never one a blank form assumes.
|
|
118
|
+
unattended: false,
|
|
119
|
+
minAutoAnswerConfidence: 80,
|
|
120
|
+
// The create row authors the numbers only. Class and role rules start at their identity and are
|
|
121
|
+
// edited on the saved policy, where each rule can be shown beside the base rule (and the track
|
|
122
|
+
// record) it narrows — neither reads as anything on a policy that does not exist yet.
|
|
123
|
+
classRules: {},
|
|
124
|
+
classRulesByRole: {},
|
|
125
|
+
dryRunRoles: [],
|
|
126
|
+
submissionClassesByRole: {},
|
|
127
|
+
forkEnabled: false,
|
|
128
|
+
forkMinComplexity: 50,
|
|
129
|
+
forkMinRisk: 40,
|
|
130
|
+
forkMinImpact: 40,
|
|
131
|
+
forkOnMissing: 'run',
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** The `StepGating` payload for the fork-decision gate from a draft. */
|
|
136
|
+
export function forkGatingFromDraft(d: RiskPolicyDraft): StepGating {
|
|
137
|
+
return {
|
|
138
|
+
enabled: d.forkEnabled,
|
|
139
|
+
minComplexity: d.forkMinComplexity / 100,
|
|
140
|
+
minRisk: d.forkMinRisk / 100,
|
|
141
|
+
minImpact: d.forkMinImpact / 100,
|
|
142
|
+
onMissingEstimate: d.forkOnMissing,
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The form state → the PATCH body, percentages scaled back down.
|
|
148
|
+
*
|
|
149
|
+
* Every role/class map is submitted whole on every save, which is what makes clearing one entry a
|
|
150
|
+
* plain omission (there is no "delete this key" wire shape). `fallbackName` keeps a blanked name
|
|
151
|
+
* field from saving an empty string over a policy that has one.
|
|
152
|
+
*/
|
|
153
|
+
export function riskPolicyPatchFromDraft(
|
|
154
|
+
d: RiskPolicyDraft,
|
|
155
|
+
fallbackName: string,
|
|
156
|
+
): UpdateRiskPolicyInput {
|
|
157
|
+
return {
|
|
158
|
+
name: d.name.trim() || fallbackName,
|
|
159
|
+
maxComplexity: d.maxComplexity / 100,
|
|
160
|
+
maxRisk: d.maxRisk / 100,
|
|
161
|
+
maxImpact: d.maxImpact / 100,
|
|
162
|
+
ciMaxAttempts: d.ciMaxAttempts,
|
|
163
|
+
maxRequirementIterations: d.maxRequirementIterations,
|
|
164
|
+
maxRequirementConcernAllowed: d.maxRequirementConcernAllowed,
|
|
165
|
+
autoMergeEnabled: d.autoMergeEnabled,
|
|
166
|
+
autonomy: d.unattended ? 'unattended' : 'attended',
|
|
167
|
+
minAutoAnswerConfidence: d.minAutoAnswerConfidence / 100,
|
|
168
|
+
classRules: d.classRules,
|
|
169
|
+
classRulesByRole: d.classRulesByRole,
|
|
170
|
+
dryRunRoles: d.dryRunRoles,
|
|
171
|
+
submissionClassesByRole: d.submissionClassesByRole,
|
|
172
|
+
forkDecision: forkGatingFromDraft(d),
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** Per-axis label keys for the auto-merge CEILINGS, iterated in the shared axis order. */
|
|
177
|
+
export const CEILING_LABEL_KEYS: Record<RiskPolicyAxis, string> = {
|
|
178
|
+
risk: 'settings.riskPolicy.field.maxRisk',
|
|
179
|
+
impact: 'settings.riskPolicy.field.maxImpact',
|
|
180
|
+
complexity: 'settings.riskPolicy.field.maxComplexity',
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** Per-axis label keys for the fork-decision FLOORS. */
|
|
184
|
+
export const FORK_FLOOR_LABEL_KEYS: Record<RiskPolicyAxis, string> = {
|
|
185
|
+
risk: 'settings.riskPolicy.forkDecision.minRisk',
|
|
186
|
+
impact: 'settings.riskPolicy.forkDecision.minImpact',
|
|
187
|
+
complexity: 'settings.riskPolicy.forkDecision.minComplexity',
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Per-concern-level label keys for the requirements auto-pass threshold (none < low < medium <
|
|
192
|
+
* high). An exhaustive `Record` keyed off the union, each value a LITERAL catalog key so the
|
|
193
|
+
* typed-message-keys check sees it.
|
|
194
|
+
*/
|
|
195
|
+
export const CONCERN_LABEL_KEYS: Record<RequirementConcernLevel, string> = {
|
|
196
|
+
none: 'settings.riskPolicy.concern.none',
|
|
197
|
+
low: 'settings.riskPolicy.concern.low',
|
|
198
|
+
medium: 'settings.riskPolicy.concern.medium',
|
|
199
|
+
high: 'settings.riskPolicy.concern.high',
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** The concern levels in severity order, for the select. */
|
|
203
|
+
export const CONCERN_LEVELS: readonly RequirementConcernLevel[] = ['none', 'low', 'medium', 'high']
|
package/i18n/locales/de.json
CHANGED
|
@@ -116,7 +116,8 @@
|
|
|
116
116
|
"team": "Team & Zugriff",
|
|
117
117
|
"fragments": "Kontextfragmente",
|
|
118
118
|
"skills": "Skills",
|
|
119
|
-
"foundational": "Basisdienste"
|
|
119
|
+
"foundational": "Basisdienste",
|
|
120
|
+
"riskPolicies": "Risikorichtlinien"
|
|
120
121
|
}
|
|
121
122
|
},
|
|
122
123
|
"infrastructure": {
|
|
@@ -559,7 +560,11 @@
|
|
|
559
560
|
"created": "Richtlinie erstellt",
|
|
560
561
|
"createFailed": "Richtlinie konnte nicht erstellt werden",
|
|
561
562
|
"defaultFailed": "Standard konnte nicht festgelegt werden",
|
|
562
|
-
"deleteFailed": "Richtlinie konnte nicht gelöscht werden"
|
|
563
|
+
"deleteFailed": "Richtlinie konnte nicht gelöscht werden",
|
|
564
|
+
"cloned": "Richtlinie in dieses Board geklont",
|
|
565
|
+
"cloneFailed": "Richtlinie konnte nicht geklont werden",
|
|
566
|
+
"hideFailed": "Richtlinie konnte nicht ausgeblendet werden",
|
|
567
|
+
"unhideFailed": "Richtlinie konnte nicht wiederhergestellt werden"
|
|
563
568
|
},
|
|
564
569
|
"forkDecision": {
|
|
565
570
|
"label": "Implementierungs-Weichenentscheidung",
|
|
@@ -615,6 +620,32 @@
|
|
|
615
620
|
"autoAnswer": {
|
|
616
621
|
"label": "Mindestzuversicht für Auto-Antworten (%)",
|
|
617
622
|
"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."
|
|
623
|
+
},
|
|
624
|
+
"tier": {
|
|
625
|
+
"account": "Vom Konto",
|
|
626
|
+
"accountHint": "Für das gesamte Konto definiert. Jedes Board erbt sie; nur eine Kontoadministration kann sie ändern."
|
|
627
|
+
},
|
|
628
|
+
"own": {
|
|
629
|
+
"heading": "Richtlinien dieses Boards"
|
|
630
|
+
},
|
|
631
|
+
"inherited": {
|
|
632
|
+
"heading": "Vom Konto geerbt",
|
|
633
|
+
"hint": "Für alle Boards dieses Kontos gültig. Klone eine Richtlinie, um hier eine Kopie zu bearbeiten, oder blende sie aus, damit keine Aufgabe dieses Boards sie wählen kann.",
|
|
634
|
+
"clone": "Ins Board klonen",
|
|
635
|
+
"cloneHint": "Diese Richtlinie ins Board kopieren, wo du ihre Grenzwerte bearbeiten kannst.",
|
|
636
|
+
"copyName": "{name} (Kopie)",
|
|
637
|
+
"hide": "Ausblenden",
|
|
638
|
+
"hideHint": "Diese Richtlinie auf diesem Board nicht mehr anbieten. Du kannst sie später wiederherstellen."
|
|
639
|
+
},
|
|
640
|
+
"hidden": {
|
|
641
|
+
"heading": "Ausgeblendete Kontorichtlinien",
|
|
642
|
+
"restore": "Wiederherstellen",
|
|
643
|
+
"withdrawn": "Vom Konto nicht mehr definiert",
|
|
644
|
+
"loadFailed": "Diese Liste konnte nicht geladen werden, daher kann eine Richtlinie ausgeblendet sein, ohne hier zu erscheinen."
|
|
645
|
+
},
|
|
646
|
+
"confirmHide": {
|
|
647
|
+
"title": "Diese Richtlinie ausblenden?",
|
|
648
|
+
"body": "„{name}“ wird auf diesem Board nicht mehr angeboten; Aufgaben mit dieser Auswahl fallen auf die Board-Standardrichtlinie zurück. Du kannst sie später wiederherstellen."
|
|
618
649
|
}
|
|
619
650
|
},
|
|
620
651
|
"observabilityConnection": {
|
|
@@ -2847,6 +2878,12 @@
|
|
|
2847
2878
|
"load": "Das Prüfprotokoll konnte nicht geladen werden.",
|
|
2848
2879
|
"loadMore": "Ältere Einträge konnten nicht geladen werden"
|
|
2849
2880
|
}
|
|
2881
|
+
},
|
|
2882
|
+
"accountRiskPolicies": {
|
|
2883
|
+
"intro": "Merge-Haltungen für alle Boards dieses Kontos. Jedes Board erbt sie schreibgeschützt und kann eine klonen, um eine Kopie zu bearbeiten, oder sie ausblenden. Welche Richtlinie eine Aufgabe ohne Auswahl regelt, wird pro Board festgelegt.",
|
|
2884
|
+
"empty": "Noch keine kontoweiten Risikorichtlinien. Boards nutzen ihre eigenen Bibliotheken, bis du eine hinzufügst.",
|
|
2885
|
+
"loadFailed": "Kontorichtlinien konnten nicht geladen werden",
|
|
2886
|
+
"confirmDelete": "„{name}“ wird von allen Boards dieses Kontos zurückgezogen. Aufgaben mit dieser Auswahl fallen auf den Standard ihres Boards zurück."
|
|
2850
2887
|
}
|
|
2851
2888
|
},
|
|
2852
2889
|
"board": {
|
|
@@ -5780,7 +5817,9 @@
|
|
|
5780
5817
|
"document_already_linked": "Dokument bereits angehängt",
|
|
5781
5818
|
"dry_run_not_mergeable": "Probelauf kann nicht zusammengeführt werden",
|
|
5782
5819
|
"submission_not_allowed": "Zusammenführen für diesen Lauf nicht erlaubt",
|
|
5783
|
-
"webhook_limit_reached": "Webhook-Limit erreicht"
|
|
5820
|
+
"webhook_limit_reached": "Webhook-Limit erreicht",
|
|
5821
|
+
"risk_policy_inherited": "Diese Richtlinie gehört zum Konto",
|
|
5822
|
+
"risk_policy_not_inherited": "Diese Richtlinie gehört zu diesem Board"
|
|
5784
5823
|
},
|
|
5785
5824
|
"description": {
|
|
5786
5825
|
"dependencies_unmet": "Diese Aufgabe hängt von anderen ab, die noch nicht abgeschlossen sind. Schließe sie ab oder gib sie frei und starte dann erneut.",
|
|
@@ -5819,7 +5858,9 @@
|
|
|
5819
5858
|
"document_already_linked": "Dieses Dokument ist an eine andere Aufgabe angehängt. Lösen Sie es dort zuerst, oder hängen Sie eine separate Kopie an.",
|
|
5820
5859
|
"dry_run_not_mergeable": "Dieser Pull Request stammt aus einem Probelauf und kann hier nicht zusammengeführt werden. Starte die Aufgabe erneut als echten Lauf, um einen Pull Request zu erzeugen, den dieser Arbeitsbereich zusammenführt.",
|
|
5821
5860
|
"submission_not_allowed": "Die Merge-Richtlinie dieser Aufgabe erlaubt der Rolle, die diesen Lauf gestartet hat, diese Änderungsart nicht zusammenzuführen. Jemand mit einer passenden Rolle kann es tun, oder ein Admin erweitert die Richtlinie in der Merge-Vorlage.",
|
|
5822
|
-
"webhook_limit_reached": "Für diesen Workspace ist bereits die maximale Anzahl ausgehender Webhooks registriert. Entfernen Sie einen nicht mehr benötigten und registrieren Sie diesen erneut."
|
|
5861
|
+
"webhook_limit_reached": "Für diesen Workspace ist bereits die maximale Anzahl ausgehender Webhooks registriert. Entfernen Sie einen nicht mehr benötigten und registrieren Sie diesen erneut.",
|
|
5862
|
+
"risk_policy_inherited": "Sie gilt für alle Boards des Kontos und kann daher nicht von hier geändert werden. Klone sie in dieses Board und bearbeite die Kopie.",
|
|
5863
|
+
"risk_policy_not_inherited": "Sie ist bereits die eigene Richtlinie dieses Boards: bearbeite sie direkt oder lösche sie, wenn sie nicht mehr angeboten werden soll."
|
|
5823
5864
|
},
|
|
5824
5865
|
"action": {
|
|
5825
5866
|
"connectGitHub": "GitHub verbinden",
|
package/i18n/locales/en.json
CHANGED
|
@@ -664,7 +664,9 @@
|
|
|
664
664
|
"document_already_linked": "Document already attached",
|
|
665
665
|
"dry_run_not_mergeable": "Dry run cannot be merged",
|
|
666
666
|
"submission_not_allowed": "Merge not allowed for this run",
|
|
667
|
-
"webhook_limit_reached": "Webhook limit reached"
|
|
667
|
+
"webhook_limit_reached": "Webhook limit reached",
|
|
668
|
+
"risk_policy_inherited": "This policy belongs to the account",
|
|
669
|
+
"risk_policy_not_inherited": "This policy belongs to this board"
|
|
668
670
|
},
|
|
669
671
|
"description": {
|
|
670
672
|
"dependencies_unmet": "This task depends on others that aren't finished yet. Complete or unblock them, then start it again.",
|
|
@@ -706,7 +708,9 @@
|
|
|
706
708
|
"document_already_linked": "That document is attached to another task. Detach it there first, or attach a separate copy.",
|
|
707
709
|
"dry_run_not_mergeable": "This pull request came from a dry run, so it can't be merged from here. Start the task again as a live run to produce a pull request this workspace will merge.",
|
|
708
710
|
"submission_not_allowed": "This task's merge policy doesn't let the role that started this run merge this kind of change. Somebody whose role may merge it can do so, or an admin can widen the policy in the merge preset.",
|
|
709
|
-
"webhook_limit_reached": "This workspace already has the maximum number of outbound webhooks registered. Remove one you no longer need, then register this again."
|
|
711
|
+
"webhook_limit_reached": "This workspace already has the maximum number of outbound webhooks registered. Remove one you no longer need, then register this again.",
|
|
712
|
+
"risk_policy_inherited": "It is shared with every board in the account, so it cannot be changed from here. Clone it to this board and edit the copy.",
|
|
713
|
+
"risk_policy_not_inherited": "It is already this board's own policy: edit it directly, or delete it if you no longer want it offered."
|
|
710
714
|
},
|
|
711
715
|
"action": {
|
|
712
716
|
"connectGitHub": "Connect GitHub",
|
|
@@ -2721,6 +2725,12 @@
|
|
|
2721
2725
|
"load": "The audit log could not be loaded.",
|
|
2722
2726
|
"loadMore": "Could not load older entries"
|
|
2723
2727
|
}
|
|
2728
|
+
},
|
|
2729
|
+
"accountRiskPolicies": {
|
|
2730
|
+
"intro": "Merge postures shared by every board in this account. Each board inherits these read-only, and can clone one to edit a copy or hide it. Which policy governs a task that picked none is set per board.",
|
|
2731
|
+
"empty": "No account-wide risk policies yet. Boards run on their own libraries until you add one.",
|
|
2732
|
+
"loadFailed": "Could not load account risk policies",
|
|
2733
|
+
"confirmDelete": "\"{name}\" will be withdrawn from every board in this account. Tasks that picked it fall back to their board's default."
|
|
2724
2734
|
}
|
|
2725
2735
|
},
|
|
2726
2736
|
"mcpAuthorize": {
|
|
@@ -2840,7 +2850,8 @@
|
|
|
2840
2850
|
"team": "Team & access",
|
|
2841
2851
|
"fragments": "Context fragments",
|
|
2842
2852
|
"skills": "Skills",
|
|
2843
|
-
"foundational": "Foundational services"
|
|
2853
|
+
"foundational": "Foundational services",
|
|
2854
|
+
"riskPolicies": "Risk policies"
|
|
2844
2855
|
}
|
|
2845
2856
|
},
|
|
2846
2857
|
"infrastructure": {
|
|
@@ -3286,7 +3297,11 @@
|
|
|
3286
3297
|
"created": "Policy created",
|
|
3287
3298
|
"createFailed": "Could not create policy",
|
|
3288
3299
|
"defaultFailed": "Could not set default",
|
|
3289
|
-
"deleteFailed": "Could not delete policy"
|
|
3300
|
+
"deleteFailed": "Could not delete policy",
|
|
3301
|
+
"cloned": "Policy cloned to this board",
|
|
3302
|
+
"cloneFailed": "Could not clone policy",
|
|
3303
|
+
"hideFailed": "Could not hide policy",
|
|
3304
|
+
"unhideFailed": "Could not restore policy"
|
|
3290
3305
|
},
|
|
3291
3306
|
"forkDecision": {
|
|
3292
3307
|
"label": "Implementation-fork decision",
|
|
@@ -3351,6 +3366,32 @@
|
|
|
3351
3366
|
"autoAnswer": {
|
|
3352
3367
|
"label": "Auto-answer confidence floor (%)",
|
|
3353
3368
|
"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."
|
|
3369
|
+
},
|
|
3370
|
+
"tier": {
|
|
3371
|
+
"account": "From the account",
|
|
3372
|
+
"accountHint": "Defined for the whole account. Every board inherits it; only an account admin can change it."
|
|
3373
|
+
},
|
|
3374
|
+
"own": {
|
|
3375
|
+
"heading": "This board's policies"
|
|
3376
|
+
},
|
|
3377
|
+
"inherited": {
|
|
3378
|
+
"heading": "Inherited from the account",
|
|
3379
|
+
"hint": "Shared with every board in this account. Clone one to edit a copy here, or hide it so no task on this board can pick it.",
|
|
3380
|
+
"clone": "Clone to board",
|
|
3381
|
+
"cloneHint": "Copy this policy into the board, where you can edit its limits.",
|
|
3382
|
+
"copyName": "{name} (copy)",
|
|
3383
|
+
"hide": "Hide",
|
|
3384
|
+
"hideHint": "Stop offering this policy on this board. You can restore it later."
|
|
3385
|
+
},
|
|
3386
|
+
"hidden": {
|
|
3387
|
+
"heading": "Hidden account policies",
|
|
3388
|
+
"restore": "Restore",
|
|
3389
|
+
"withdrawn": "No longer defined by the account",
|
|
3390
|
+
"loadFailed": "This list could not be loaded, so a policy may be hidden without appearing here."
|
|
3391
|
+
},
|
|
3392
|
+
"confirmHide": {
|
|
3393
|
+
"title": "Hide this policy?",
|
|
3394
|
+
"body": "\"{name}\" will not be offered on this board, and tasks that picked it fall back to the board default. You can restore it later."
|
|
3354
3395
|
}
|
|
3355
3396
|
},
|
|
3356
3397
|
"observabilityConnection": {
|
package/i18n/locales/es.json
CHANGED
|
@@ -595,7 +595,9 @@
|
|
|
595
595
|
"document_already_linked": "El documento ya está adjunto",
|
|
596
596
|
"dry_run_not_mergeable": "Una ejecución de prueba no se puede fusionar",
|
|
597
597
|
"submission_not_allowed": "Fusión no permitida para esta ejecución",
|
|
598
|
-
"webhook_limit_reached": "Límite de webhooks alcanzado"
|
|
598
|
+
"webhook_limit_reached": "Límite de webhooks alcanzado",
|
|
599
|
+
"risk_policy_inherited": "Esta política pertenece a la cuenta",
|
|
600
|
+
"risk_policy_not_inherited": "Esta política pertenece a este tablero"
|
|
599
601
|
},
|
|
600
602
|
"description": {
|
|
601
603
|
"dependencies_unmet": "Esta tarea depende de otras que aún no están terminadas. Complétalas o desbloquéalas y vuelve a iniciarla.",
|
|
@@ -634,7 +636,9 @@
|
|
|
634
636
|
"document_already_linked": "Ese documento está adjunto a otra tarea. Sepáralo allí primero o adjunta una copia aparte.",
|
|
635
637
|
"dry_run_not_mergeable": "Esta pull request proviene de una ejecución de prueba, así que no se puede fusionar desde aquí. Vuelve a iniciar la tarea como ejecución real para producir una pull request que este espacio de trabajo sí fusionará.",
|
|
636
638
|
"submission_not_allowed": "La política de fusión de esta tarea no permite que el rol que inició la ejecución fusione este tipo de cambio. Alguien cuyo rol sí lo permita puede hacerlo, o un administrador puede ampliar la política en el preajuste de fusión.",
|
|
637
|
-
"webhook_limit_reached": "Este espacio de trabajo ya tiene registrado el número máximo de webhooks salientes. Elimina uno que ya no necesites y vuelve a registrar este."
|
|
639
|
+
"webhook_limit_reached": "Este espacio de trabajo ya tiene registrado el número máximo de webhooks salientes. Elimina uno que ya no necesites y vuelve a registrar este.",
|
|
640
|
+
"risk_policy_inherited": "Se comparte con todos los tableros de la cuenta, así que no puede cambiarse desde aquí. Clónala en este tablero y edita la copia.",
|
|
641
|
+
"risk_policy_not_inherited": "Ya es la política propia de este tablero: edítala directamente o elimínala si no quieres que se ofrezca."
|
|
638
642
|
},
|
|
639
643
|
"action": {
|
|
640
644
|
"connectGitHub": "Conectar GitHub",
|
|
@@ -2596,6 +2600,12 @@
|
|
|
2596
2600
|
"load": "No se pudo cargar el registro de auditoría.",
|
|
2597
2601
|
"loadMore": "No se pudieron cargar las entradas anteriores"
|
|
2598
2602
|
}
|
|
2603
|
+
},
|
|
2604
|
+
"accountRiskPolicies": {
|
|
2605
|
+
"intro": "Posturas de fusión compartidas por todos los tableros de esta cuenta. Cada tablero las hereda en modo de solo lectura y puede clonar una para editar una copia u ocultarla. Qué política rige una tarea que no eligió ninguna se define por tablero.",
|
|
2606
|
+
"empty": "Aún no hay políticas de riesgo de cuenta. Los tableros usan sus propias bibliotecas hasta que añadas una.",
|
|
2607
|
+
"loadFailed": "No se pudieron cargar las políticas de riesgo de la cuenta",
|
|
2608
|
+
"confirmDelete": "«{name}» se retirará de todos los tableros de esta cuenta. Las tareas que la eligieron pasarán a la predeterminada de su tablero."
|
|
2599
2609
|
}
|
|
2600
2610
|
},
|
|
2601
2611
|
"mcpAuthorize": {
|
|
@@ -2715,7 +2725,8 @@
|
|
|
2715
2725
|
"team": "Equipo y acceso",
|
|
2716
2726
|
"fragments": "Fragmentos de contexto",
|
|
2717
2727
|
"skills": "Habilidades",
|
|
2718
|
-
"foundational": "Servicios fundamentales"
|
|
2728
|
+
"foundational": "Servicios fundamentales",
|
|
2729
|
+
"riskPolicies": "Políticas de riesgo"
|
|
2719
2730
|
}
|
|
2720
2731
|
},
|
|
2721
2732
|
"providerConnection": {
|
|
@@ -3010,7 +3021,11 @@
|
|
|
3010
3021
|
"created": "Política creada",
|
|
3011
3022
|
"createFailed": "No se pudo crear la política",
|
|
3012
3023
|
"defaultFailed": "No se pudo establecer el predeterminado",
|
|
3013
|
-
"deleteFailed": "No se pudo eliminar la política"
|
|
3024
|
+
"deleteFailed": "No se pudo eliminar la política",
|
|
3025
|
+
"cloned": "Política clonada en este tablero",
|
|
3026
|
+
"cloneFailed": "No se pudo clonar la política",
|
|
3027
|
+
"hideFailed": "No se pudo ocultar la política",
|
|
3028
|
+
"unhideFailed": "No se pudo restaurar la política"
|
|
3014
3029
|
},
|
|
3015
3030
|
"autoMergeOnHint": "Fusionar automáticamente cuando esté dentro de los límites de la política.",
|
|
3016
3031
|
"autoMergeOffHint": "Enviar siempre el PR a revisión humana.",
|
|
@@ -3072,6 +3087,32 @@
|
|
|
3072
3087
|
"autoAnswer": {
|
|
3073
3088
|
"label": "Confianza mínima para autorrespuesta (%)",
|
|
3074
3089
|
"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."
|
|
3090
|
+
},
|
|
3091
|
+
"tier": {
|
|
3092
|
+
"account": "De la cuenta",
|
|
3093
|
+
"accountHint": "Definida para toda la cuenta. Todos los tableros la heredan; solo una administración de cuenta puede cambiarla."
|
|
3094
|
+
},
|
|
3095
|
+
"own": {
|
|
3096
|
+
"heading": "Políticas de este tablero"
|
|
3097
|
+
},
|
|
3098
|
+
"inherited": {
|
|
3099
|
+
"heading": "Heredadas de la cuenta",
|
|
3100
|
+
"hint": "Compartidas con todos los tableros de esta cuenta. Clona una para editar una copia aquí, u ocúltala para que ninguna tarea de este tablero pueda elegirla.",
|
|
3101
|
+
"clone": "Clonar al tablero",
|
|
3102
|
+
"cloneHint": "Copiar esta política al tablero, donde puedes editar sus límites.",
|
|
3103
|
+
"copyName": "{name} (copia)",
|
|
3104
|
+
"hide": "Ocultar",
|
|
3105
|
+
"hideHint": "Dejar de ofrecer esta política en este tablero. Puedes restaurarla más adelante."
|
|
3106
|
+
},
|
|
3107
|
+
"hidden": {
|
|
3108
|
+
"heading": "Políticas de cuenta ocultas",
|
|
3109
|
+
"restore": "Restaurar",
|
|
3110
|
+
"withdrawn": "La cuenta ya no la define",
|
|
3111
|
+
"loadFailed": "No se pudo cargar esta lista, así que puede haber una política oculta que no aparezca aquí."
|
|
3112
|
+
},
|
|
3113
|
+
"confirmHide": {
|
|
3114
|
+
"title": "¿Ocultar esta política?",
|
|
3115
|
+
"body": "«{name}» no se ofrecerá en este tablero y las tareas que la eligieron pasarán a la política predeterminada del tablero. Puedes restaurarla más adelante."
|
|
3075
3116
|
}
|
|
3076
3117
|
},
|
|
3077
3118
|
"observabilityConnection": {
|
package/i18n/locales/fr.json
CHANGED
|
@@ -595,7 +595,9 @@
|
|
|
595
595
|
"document_already_linked": "Document déjà joint",
|
|
596
596
|
"dry_run_not_mergeable": "Une exécution à blanc ne peut pas être fusionnée",
|
|
597
597
|
"submission_not_allowed": "Fusion non autorisée pour cette exécution",
|
|
598
|
-
"webhook_limit_reached": "Limite de webhooks atteinte"
|
|
598
|
+
"webhook_limit_reached": "Limite de webhooks atteinte",
|
|
599
|
+
"risk_policy_inherited": "Cette politique appartient au compte",
|
|
600
|
+
"risk_policy_not_inherited": "Cette politique appartient à ce tableau"
|
|
599
601
|
},
|
|
600
602
|
"description": {
|
|
601
603
|
"dependencies_unmet": "Cette tâche dépend d'autres qui ne sont pas encore terminées. Terminez-les ou débloquez-les, puis relancez-la.",
|
|
@@ -634,7 +636,9 @@
|
|
|
634
636
|
"document_already_linked": "Ce document est joint à une autre tâche. Détachez-le d'abord, ou joignez-en une copie distincte.",
|
|
635
637
|
"dry_run_not_mergeable": "Cette pull request provient d'une exécution à blanc et ne peut pas être fusionnée ici. Relancez la tâche en exécution réelle pour produire une pull request que cet espace de travail fusionnera.",
|
|
636
638
|
"submission_not_allowed": "La politique de fusion de cette tâche n'autorise pas le rôle qui a lancé cette exécution à fusionner ce type de changement. Un coéquipier dont le rôle le permet peut le faire, ou un admin peut élargir la politique dans le préréglage de fusion.",
|
|
637
|
-
"webhook_limit_reached": "Cet espace de travail a déjà enregistré le nombre maximal de webhooks sortants. Supprimez-en un dont vous n’avez plus besoin, puis enregistrez celui-ci à nouveau."
|
|
639
|
+
"webhook_limit_reached": "Cet espace de travail a déjà enregistré le nombre maximal de webhooks sortants. Supprimez-en un dont vous n’avez plus besoin, puis enregistrez celui-ci à nouveau.",
|
|
640
|
+
"risk_policy_inherited": "Elle est partagée par tous les tableaux du compte et ne peut donc pas être modifiée ici. Clonez-la vers ce tableau et modifiez la copie.",
|
|
641
|
+
"risk_policy_not_inherited": "C'est déjà la politique propre à ce tableau : modifiez-la directement, ou supprimez-la si vous ne voulez plus qu'elle soit proposée."
|
|
638
642
|
},
|
|
639
643
|
"action": {
|
|
640
644
|
"connectGitHub": "Connecter GitHub",
|
|
@@ -2596,6 +2600,12 @@
|
|
|
2596
2600
|
"load": "Le journal d’audit n’a pas pu être chargé.",
|
|
2597
2601
|
"loadMore": "Impossible de charger les entrées plus anciennes"
|
|
2598
2602
|
}
|
|
2603
|
+
},
|
|
2604
|
+
"accountRiskPolicies": {
|
|
2605
|
+
"intro": "Postures de fusion partagées par tous les tableaux de ce compte. Chaque tableau en hérite en lecture seule et peut en cloner une pour modifier une copie, ou la masquer. La politique qui régit une tâche sans choix se définit par tableau.",
|
|
2606
|
+
"empty": "Aucune politique de risque du compte pour l'instant. Les tableaux utilisent leurs propres bibliothèques jusqu'à ce que vous en ajoutiez une.",
|
|
2607
|
+
"loadFailed": "Impossible de charger les politiques de risque du compte",
|
|
2608
|
+
"confirmDelete": "« {name} » sera retirée de tous les tableaux de ce compte. Les tâches qui l'avaient choisie repasseront à la politique par défaut de leur tableau."
|
|
2599
2609
|
}
|
|
2600
2610
|
},
|
|
2601
2611
|
"mcpAuthorize": {
|
|
@@ -2715,7 +2725,8 @@
|
|
|
2715
2725
|
"team": "Équipe et accès",
|
|
2716
2726
|
"fragments": "Fragments de contexte",
|
|
2717
2727
|
"skills": "Compétences",
|
|
2718
|
-
"foundational": "Services fondamentaux"
|
|
2728
|
+
"foundational": "Services fondamentaux",
|
|
2729
|
+
"riskPolicies": "Politiques de risque"
|
|
2719
2730
|
}
|
|
2720
2731
|
},
|
|
2721
2732
|
"providerConnection": {
|
|
@@ -3010,7 +3021,11 @@
|
|
|
3010
3021
|
"created": "Politique créée",
|
|
3011
3022
|
"createFailed": "Impossible de créer la politique",
|
|
3012
3023
|
"defaultFailed": "Impossible de définir par défaut",
|
|
3013
|
-
"deleteFailed": "Impossible de supprimer la politique"
|
|
3024
|
+
"deleteFailed": "Impossible de supprimer la politique",
|
|
3025
|
+
"cloned": "Politique clonée vers ce tableau",
|
|
3026
|
+
"cloneFailed": "Impossible de cloner la politique",
|
|
3027
|
+
"hideFailed": "Impossible de masquer la politique",
|
|
3028
|
+
"unhideFailed": "Impossible de rétablir la politique"
|
|
3014
3029
|
},
|
|
3015
3030
|
"autoMergeOnHint": "Fusionner automatiquement si dans les limites de la politique.",
|
|
3016
3031
|
"autoMergeOffHint": "Toujours envoyer la PR en revue humaine.",
|
|
@@ -3072,6 +3087,32 @@
|
|
|
3072
3087
|
"autoAnswer": {
|
|
3073
3088
|
"label": "Confiance minimale pour une réponse automatique (%)",
|
|
3074
3089
|
"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."
|
|
3090
|
+
},
|
|
3091
|
+
"tier": {
|
|
3092
|
+
"account": "Du compte",
|
|
3093
|
+
"accountHint": "Définie pour tout le compte. Chaque tableau en hérite ; seule une administration du compte peut la modifier."
|
|
3094
|
+
},
|
|
3095
|
+
"own": {
|
|
3096
|
+
"heading": "Politiques de ce tableau"
|
|
3097
|
+
},
|
|
3098
|
+
"inherited": {
|
|
3099
|
+
"heading": "Héritées du compte",
|
|
3100
|
+
"hint": "Partagées par tous les tableaux de ce compte. Clonez-en une pour en modifier une copie ici, ou masquez-la afin qu'aucune tâche de ce tableau ne puisse la choisir.",
|
|
3101
|
+
"clone": "Cloner vers le tableau",
|
|
3102
|
+
"cloneHint": "Copier cette politique dans le tableau, où vous pourrez modifier ses limites.",
|
|
3103
|
+
"copyName": "{name} (copie)",
|
|
3104
|
+
"hide": "Masquer",
|
|
3105
|
+
"hideHint": "Ne plus proposer cette politique sur ce tableau. Vous pourrez la rétablir plus tard."
|
|
3106
|
+
},
|
|
3107
|
+
"hidden": {
|
|
3108
|
+
"heading": "Politiques du compte masquées",
|
|
3109
|
+
"restore": "Rétablir",
|
|
3110
|
+
"withdrawn": "Plus définie par le compte",
|
|
3111
|
+
"loadFailed": "Cette liste n'a pas pu être chargée : une politique peut donc être masquée sans figurer ici."
|
|
3112
|
+
},
|
|
3113
|
+
"confirmHide": {
|
|
3114
|
+
"title": "Masquer cette politique ?",
|
|
3115
|
+
"body": "« {name} » ne sera plus proposée sur ce tableau et les tâches qui l'avaient choisie repasseront à la politique par défaut du tableau. Vous pourrez la rétablir plus tard."
|
|
3075
3116
|
}
|
|
3076
3117
|
},
|
|
3077
3118
|
"observabilityConnection": {
|