fix(polish): gate test-build style generation at 1,250 chars and cap export at 5,000
Remove the test-mode unlimited personal-style corpus bypass and replace it with a real 1,250-character minimum gate. Production stays at 2,500. Training-corpus export and the diagnostics view now use a 5,000-character upper bound so the user's full private history never leaves the device in a single export. - Add PolishStyleLearningCorpusBuilder.testBuildEffectiveCharacterCount (1,250) and trainingExtractionMaximumCharacterCount (5,000); trainingWindow(from:maximumCharacterCount:) accepts a custom cap. - PolishStylesView: drop bypassesStyleLearningCharacterGate in favor of styleLearningMinimumCharacterCount, unify the ready/remaining text, remove the obsolete polishStyles.learn.testBuildReady key. - PolishStyleCorpusExportStore: pass the 5,000 cap to trainingWindow and expose trainingExtractionMaximumCharacterCount in the export schema. - FlowDiagnosticsSettingsView: show the export-sized (5,000-cap) corpus so the diagnostics match what the export ZIP actually contains. - Tests: rewrite the export cap test for 5,000, add below-cap coverage, add trainingWindow(maximumCharacterCount:) unit coverage, and convert the old UI test into a regression test for the 1,250 test-build minimum. - L10n: drop the testBuildReady string in en + zh-Hans, update diagnostics.corpus.ready to mention 5,000. - CHANGELOG: bilingual entry under [Unreleased].
This commit is contained in:
@@ -150,8 +150,24 @@ public struct PolishStyleLearningCorpus: Equatable, Sendable {
|
||||
}
|
||||
|
||||
public enum PolishStyleLearningCorpusBuilder {
|
||||
/// Production minimum effective character count required to unlock
|
||||
/// personal style generation. App Store builds enforce this gate.
|
||||
public static let requiredEffectiveCharacterCount = 2_500
|
||||
|
||||
/// Test builds (Debug + TestFlight) lower the unlock threshold so
|
||||
/// internal testers can exercise the complete generation pipeline
|
||||
/// without dictating a full production corpus. The threshold is
|
||||
/// still a real gate; the previous "0 / unlimited" bypass is gone.
|
||||
public static let testBuildEffectiveCharacterCount = 1_250
|
||||
|
||||
/// Upper bound on effective characters included in a single
|
||||
/// training-corpus export. Even when the user has accumulated
|
||||
/// significantly more history than the unlock threshold, the
|
||||
/// exported training set never exceeds this cap so the user's
|
||||
/// full private dictation history does not leave the device in
|
||||
/// one shot.
|
||||
public static let trainingExtractionMaximumCharacterCount = 5_000
|
||||
|
||||
public static func build(
|
||||
from entries: [SpeechHistoryEntry]
|
||||
) -> PolishStyleLearningCorpus {
|
||||
@@ -167,12 +183,23 @@ public enum PolishStyleLearningCorpusBuilder {
|
||||
)
|
||||
}
|
||||
|
||||
/// Selects the newest complete examples until the learning threshold is
|
||||
/// reached. If less history is available, every eligible example is kept.
|
||||
/// The returned order is chronological for export and model input.
|
||||
/// Selects the newest complete examples until `maximumCharacterCount`
|
||||
/// is reached. If less history is available, every eligible example
|
||||
/// is kept. The returned order is chronological for export and
|
||||
/// model input.
|
||||
///
|
||||
/// - Parameter maximumCharacterCount: Hard upper bound for the
|
||||
/// selected window. Defaults to the production unlock threshold
|
||||
/// (2,500) so live generation still fits the LLM request budget.
|
||||
/// Callers that build a training-corpus export should pass
|
||||
/// `trainingExtractionMaximumCharacterCount` (5,000) so the
|
||||
/// export can carry up to the broader extraction cap when the
|
||||
/// user has accumulated more history than the live gate.
|
||||
public static func trainingWindow(
|
||||
from examples: [PolishStyleLearningExample]
|
||||
from examples: [PolishStyleLearningExample],
|
||||
maximumCharacterCount: Int = requiredEffectiveCharacterCount
|
||||
) -> PolishStyleLearningCorpus {
|
||||
let limit = max(0, maximumCharacterCount)
|
||||
let newestFirst = examples.sorted { $0.createdAt > $1.createdAt }
|
||||
var selected: [PolishStyleLearningExample] = []
|
||||
var effectiveCharacterCount = 0
|
||||
@@ -182,7 +209,7 @@ public enum PolishStyleLearningCorpusBuilder {
|
||||
effectiveCharacterCount += self.effectiveCharacterCount(
|
||||
in: example.prePolishText
|
||||
)
|
||||
if effectiveCharacterCount >= requiredEffectiveCharacterCount {
|
||||
if effectiveCharacterCount >= limit {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user