@evomap/evolver-core 2.0.0-beta.18 → 2.0.0-beta.19

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 (68) hide show
  1. package/dist/algo/candidateAssembly.js +21 -2
  2. package/dist/algo/cycleEngine.d.ts +12 -0
  3. package/dist/algo/cycleEngine.js +36 -4
  4. package/dist/algo/geneHealth.d.ts +2 -2
  5. package/dist/algo/geneHealth.js +5 -4
  6. package/dist/algo/geneSelection.d.ts +1 -1
  7. package/dist/algo/orchestrator.js +9 -2
  8. package/dist/assetstore/assetSidecarRecords.js +4 -0
  9. package/dist/assetstore/assetStoreHealth.js +41 -24
  10. package/dist/assetstore/assetStoreStorage.d.ts +1 -1
  11. package/dist/assetstore/assetStoreStorage.js +16 -7
  12. package/dist/assetstore/localJsonl.d.ts +2 -1
  13. package/dist/assetstore/localJsonl.js +54 -10
  14. package/dist/assetstore/provenance.d.ts +24 -0
  15. package/dist/assetstore/provenance.js +219 -12
  16. package/dist/assetstore/provider.d.ts +20 -1
  17. package/dist/assetstore/provider.js +34 -1
  18. package/dist/bootstrap/index.d.ts +2 -1
  19. package/dist/bootstrap/index.js +2 -1
  20. package/dist/bootstrap/v1EnvCompat.d.ts +110 -0
  21. package/dist/bootstrap/v1EnvCompat.js +256 -0
  22. package/dist/events/public.d.ts +1 -1
  23. package/dist/events/public.js +1 -1
  24. package/dist/events/reports.d.ts +2 -0
  25. package/dist/events/reports.js +4 -0
  26. package/dist/exec/autoExec.d.ts +1 -1
  27. package/dist/exec/autoExec.js +8 -10
  28. package/dist/exec/autonomousCycle.d.ts +19 -4
  29. package/dist/exec/autonomousCycle.js +63 -13
  30. package/dist/exec/claudeBridge.d.ts +25 -7
  31. package/dist/exec/claudeBridge.js +264 -29
  32. package/dist/exec/prompt.js +5 -1
  33. package/dist/exec/runnerRegistry.d.ts +68 -26
  34. package/dist/exec/runnerRegistry.js +307 -72
  35. package/dist/exec/selfPr.js +1 -7
  36. package/dist/feedback/envelope.d.ts +61 -0
  37. package/dist/feedback/envelope.js +168 -0
  38. package/dist/feedback/index.d.ts +1 -0
  39. package/dist/feedback/index.js +1 -0
  40. package/dist/hub/assetCallLog.d.ts +35 -1
  41. package/dist/hub/assetCallLog.js +124 -1
  42. package/dist/hub/bindings.d.ts +8 -1
  43. package/dist/hub/bindings.js +17 -6
  44. package/dist/hub/capability.d.ts +11 -1
  45. package/dist/hub/fake.d.ts +2 -2
  46. package/dist/hub/fake.js +1 -1
  47. package/dist/index.d.ts +3 -1
  48. package/dist/index.js +4 -1
  49. package/dist/mailbox/dispatch.d.ts +1 -1
  50. package/dist/mailbox/dispatch.js +22 -6
  51. package/dist/mailbox/envelope.d.ts +7 -1
  52. package/dist/mailbox/envelope.js +9 -2
  53. package/dist/mailbox/ipcServer.d.ts +10 -2
  54. package/dist/mailbox/ipcServer.js +163 -13
  55. package/dist/mailbox/store.d.ts +38 -2
  56. package/dist/mailbox/store.js +416 -27
  57. package/dist/signals/curriculum.d.ts +55 -0
  58. package/dist/signals/curriculum.js +202 -0
  59. package/dist/signals/expand.js +17 -6
  60. package/dist/signals/index.d.ts +2 -1
  61. package/dist/signals/index.js +2 -1
  62. package/dist/strategy/constraintAblation.js +115 -369
  63. package/dist/strategy/constraintAblationPredicates.d.ts +31 -0
  64. package/dist/strategy/constraintAblationPredicates.js +339 -0
  65. package/dist/trace/proxyTurns.js +15 -7
  66. package/dist/verify/validation.d.ts +11 -1
  67. package/dist/verify/validation.js +31 -0
  68. package/package.json +4 -1
@@ -1,4 +1,5 @@
1
1
  import { createHash } from 'node:crypto';
2
+ import { classifyProvidedTargetPrefix } from './constraintAblationPredicates.js';
2
3
  import { redactString, scanForLeaks } from '../hub/sanitize.js';
3
4
  const KEY_VALUE_SECRET_RE = /\b(?:api[_-]?key|token|secret)\s*[:=]\s*(?:"[^"\r\n]*"|'[^'\r\n]*'|[^\s,;]+)/gi;
4
5
  const OPENAI_SECRET_RE = /\bsk-[A-Za-z0-9_-]+\b/gi;
@@ -821,357 +822,129 @@ function hasIndependentSimplePastAction(segment, actionForms, inheritsSubject =
821
822
  }
822
823
  return false;
823
824
  }
824
- function hasPotentialConditionalScope(segment, actionForms, targetActionForms, terms) {
825
- const providedTargetPrefixKind = (source) => {
826
- const normalizedSource = normalize(source);
827
- const objectTerms = terms.filter((term) => !term.verb);
828
- if (!normalizedSource || objectTerms.length === 0)
829
- return 'none';
830
- const stream = lexRequiredEvidence(normalizedSource);
831
- const requiredObjectMatches = Math.min(2, objectTerms.length);
832
- const objectForms = objectTerms.map((term) => ({
833
- forms: targetTermForms(term, 'must_not'),
834
- term,
835
- }));
836
- const matchedObjectTerms = new Set();
837
- const matchedObjectIndexes = new Set();
838
- let objectPrefixEnd = -1;
839
- objectPrefix: for (let index = 0; index < stream.tokens.length; index += 1) {
840
- const value = stream.tokens[index]?.value ?? '';
841
- for (const candidate of objectForms) {
842
- if (matchedObjectTerms.has(candidate.term) || !candidate.forms.has(value))
843
- continue;
844
- matchedObjectTerms.add(candidate.term);
845
- matchedObjectIndexes.add(index);
846
- if (matchedObjectTerms.size >= requiredObjectMatches) {
847
- objectPrefixEnd = index;
848
- break objectPrefix;
849
- }
850
- }
851
- }
852
- if (objectPrefixEnd < 0)
853
- return 'none';
854
- const nonObjectPrefix = stream.tokens
855
- .slice(0, objectPrefixEnd + 1)
856
- .filter((_, index) => !matchedObjectIndexes.has(index))
857
- .map((token) => token.value)
858
- .join(' ');
859
- if (finiteClauseSubjectPolarity(nonObjectPrefix) !== 'absent'
860
- || hasIndependentAffirmativeAction(nonObjectPrefix, actionForms))
861
- return 'conditional';
862
- // A leading "provided" is ambiguous; walk bounded tail structures and keep unknown shapes conditional.
863
- const skipProvidedModifiers = (initialIndex) => {
864
- let index = initialIndex;
865
- while (index < stream.tokens.length) {
866
- const term = stream.tokens[index]?.value ?? '';
867
- if (!LEADING_CLAUSE_MODIFIER_TERMS.has(term)
868
- && !PROVIDED_OBJECT_TRAILING_MODIFIER_TERMS.has(term)
869
- && !/ly$/u.test(term))
870
- break;
871
- index += 1;
872
- }
873
- return index;
874
- };
875
- const consumeRemainingObjectTerms = (initialIndex) => {
876
- let index = skipProvidedModifiers(initialIndex);
877
- const remaining = new Set(objectForms.filter((candidate) => !matchedObjectTerms.has(candidate.term)));
878
- while (index < stream.tokens.length) {
879
- const candidate = [...remaining].find((entry) => (entry.forms.has(stream.tokens[index]?.value ?? '')));
880
- if (!candidate)
881
- break;
882
- remaining.delete(candidate);
883
- index = skipProvidedModifiers(index + 1);
884
- }
885
- return index;
886
- };
887
- const isProvidedPastPredicate = (term) => (term.endsWith('ed')
888
- || IRREGULAR_SIMPLE_PAST_FORMS.has(term)
889
- || IRREGULAR_PAST_PARTICIPLE_FORMS.has(term));
890
- const consumeProvidedNominal = (initialIndex) => {
891
- let index = skipProvidedModifiers(initialIndex);
892
- if (SUBJECT_ARTICLE_TERMS.has(stream.tokens[index]?.value ?? ''))
893
- index += 1;
894
- while (index + 1 < stream.tokens.length) {
895
- const term = stream.tokens[index]?.value ?? '';
896
- if (!isAttributiveTargetModifier(term)
897
- && !PROVIDED_OBJECT_NOMINAL_MODIFIER_TERMS.has(term))
898
- break;
899
- index += 1;
900
- }
901
- if (index < stream.tokens.length)
902
- index += 1;
903
- return skipProvidedModifiers(index);
904
- };
905
- const isProvidedObjectForm = (term) => objectForms.some((candidate) => (candidate.forms.has(term)));
906
- const isProvidedMatrixPredicate = (term) => (PROVIDED_OBJECT_MATRIX_PREDICATE_TERMS.has(term)
907
- || isFinitePredicateTerm(term)
908
- || (actionForms.has(term) && !isProvidedObjectForm(term)));
909
- const isProvidedNominalHead = (term) => (PROVIDED_OBJECT_NOMINAL_HEAD_TERMS.has(term) || isProvidedObjectForm(term));
910
- const isProvidedNominalModifier = (term) => (isAttributiveTargetModifier(term)
911
- || PROVIDED_OBJECT_NOMINAL_MODIFIER_TERMS.has(term)
912
- || isProvidedObjectForm(term));
913
- const reachesKnownProvidedNominalHead = (initialIndex, genericModifierBudget) => {
914
- let index = initialIndex;
915
- while (index < stream.tokens.length) {
916
- const term = stream.tokens[index]?.value ?? '';
917
- if (isProvidedNominalHead(term))
918
- return true;
919
- if (!isProvidedNominalModifier(term)) {
920
- if (genericModifierBudget <= 0)
921
- return false;
922
- genericModifierBudget -= 1;
923
- }
924
- index = skipProvidedModifiers(index + 1);
925
- }
926
- return false;
927
- };
928
- const isProvidedMatrixNominalCollocation = (initialIndex) => {
929
- const modifier = stream.tokens[initialIndex]?.value ?? '';
930
- let index = skipProvidedModifiers(initialIndex + 1);
931
- while (index < stream.tokens.length) {
932
- const term = stream.tokens[index]?.value ?? '';
933
- if (isProvidedNominalHead(term)) {
934
- return PROVIDED_OBJECT_MATRIX_NOMINAL_COLLOCATIONS.has(`${modifier}:${term}`);
935
- }
936
- if (!isProvidedNominalModifier(term))
937
- return false;
938
- index = skipProvidedModifiers(index + 1);
939
- }
825
+ function providedTargetPrefixKind(source, context) {
826
+ const objectTerms = context.terms.filter((term) => !term.verb);
827
+ return classifyProvidedTargetPrefix({
828
+ actionForms: context.actionForms,
829
+ lexicon: {
830
+ commaDelimitedPrepositions: COMMA_DELIMITED_PREPOSITION_TERMS,
831
+ conditionalMarkers: CONDITIONAL_MARKER_TERMS,
832
+ irregularPastParticiples: IRREGULAR_PAST_PARTICIPLE_FORMS,
833
+ irregularSimplePast: IRREGULAR_SIMPLE_PAST_FORMS,
834
+ leadingClauseModifiers: LEADING_CLAUSE_MODIFIER_TERMS,
835
+ passiveAuxiliaries: PASSIVE_AUXILIARY_TERMS,
836
+ subjectArticles: SUBJECT_ARTICLE_TERMS,
837
+ },
838
+ objectForms: objectTerms.map((term) => targetTermForms(term, 'must_not')),
839
+ predicates: {
840
+ finiteClauseSubjectPolarity,
841
+ hasIndependentAffirmativeAction,
842
+ isAttributiveTargetModifier,
843
+ isFinitePredicateTerm,
844
+ tokenize: lexRequiredEvidence,
845
+ },
846
+ source: normalize(source),
847
+ });
848
+ }
849
+ function hasTargetActionPrefix(source, targetActionForms) {
850
+ const stream = lexRequiredEvidence(source);
851
+ for (let actionIndex = 0; actionIndex < stream.tokens.length; actionIndex += 1) {
852
+ if (!targetActionForms.has(stream.tokens[actionIndex]?.value ?? ''))
853
+ continue;
854
+ if (actionIndex === 0 || leadingSubjectPolarity(stream, 0, actionIndex) === 'positive')
855
+ return true;
856
+ }
857
+ return false;
858
+ }
859
+ function hasProvidedMatrixAction(source, context) {
860
+ const commaIndex = source.indexOf(',');
861
+ if (commaIndex >= 0) {
862
+ const prefixKind = providedTargetPrefixKind(source.slice(0, commaIndex), context);
863
+ if (prefixKind === 'factual')
940
864
  return false;
941
- };
942
- const consumeProvidedNominalPhrase = (initialIndex) => {
943
- let index = skipProvidedModifiers(initialIndex);
944
- const hadArticle = SUBJECT_ARTICLE_TERMS.has(stream.tokens[index]?.value ?? '');
945
- if (hadArticle)
946
- index += 1;
947
- let sawPrenominalModifier = false;
948
- let genericPrenominalModifiers = 0;
949
- const genericPrenominalLimit = hadArticle ? 2 : 1;
950
- while (index + 1 < stream.tokens.length) {
951
- const term = stream.tokens[index]?.value ?? '';
952
- const nextIndex = skipProvidedModifiers(index + 1);
953
- const next = stream.tokens[nextIndex]?.value ?? '';
954
- if (nextIndex >= stream.tokens.length
955
- || PROVIDED_OBJECT_RELATIVE_TERMS.has(next)
956
- || CONDITIONAL_MARKER_TERMS.has(next)
957
- || PROVIDED_OBJECT_FACTUAL_TAIL_PREFIX_TERMS.has(next)
958
- || SUBJECT_ARTICLE_TERMS.has(next)
959
- || (isProvidedMatrixPredicate(next)
960
- && !isProvidedMatrixNominalCollocation(nextIndex)))
961
- break;
962
- const genericBeforeKnownHead = genericPrenominalModifiers < genericPrenominalLimit
963
- && !isProvidedNominalHead(term)
964
- && reachesKnownProvidedNominalHead(nextIndex, genericPrenominalLimit - genericPrenominalModifiers - 1);
965
- const modifier = isProvidedNominalModifier(term)
966
- || genericBeforeKnownHead;
967
- if (!modifier)
968
- break;
969
- if (!isProvidedNominalModifier(term))
970
- genericPrenominalModifiers += 1;
971
- sawPrenominalModifier = true;
972
- index = nextIndex;
973
- }
974
- const head = stream.tokens[index]?.value ?? '';
975
- if (!head
976
- || PROVIDED_OBJECT_RELATIVE_TERMS.has(head)
977
- || CONDITIONAL_MARKER_TERMS.has(head)
978
- || PROVIDED_OBJECT_FACTUAL_TAIL_PREFIX_TERMS.has(head)
979
- || SUBJECT_ARTICLE_TERMS.has(head)
980
- || isProvidedMatrixPredicate(head)
981
- || (sawPrenominalModifier && !isProvidedNominalHead(head)))
982
- return index;
983
- index = skipProvidedModifiers(index + 1);
984
- while (stream.tokens[index]?.value.endsWith('ing')) {
985
- const complementStart = skipProvidedModifiers(index + 1);
986
- const complementEnd = consumeProvidedNominalPhrase(complementStart);
987
- if (complementEnd <= complementStart)
988
- break;
989
- index = complementEnd;
990
- }
991
- return index;
992
- };
993
- const consumeProvidedTerminalNominal = (initialIndex) => {
994
- const nominalEnd = consumeProvidedNominalPhrase(initialIndex);
995
- if (nominalEnd >= stream.tokens.length)
996
- return nominalEnd;
997
- const rejectedHead = stream.tokens[nominalEnd]?.value ?? '';
998
- let prefixIndex = skipProvidedModifiers(initialIndex);
999
- if (SUBJECT_ARTICLE_TERMS.has(stream.tokens[prefixIndex]?.value ?? '')) {
1000
- prefixIndex = skipProvidedModifiers(prefixIndex + 1);
1001
- }
1002
- while (prefixIndex < nominalEnd
1003
- && !isProvidedNominalHead(stream.tokens[prefixIndex]?.value ?? '')) {
1004
- prefixIndex = skipProvidedModifiers(prefixIndex + 1);
1005
- }
1006
- return isProvidedNominalHead(rejectedHead)
1007
- && prefixIndex === nominalEnd
1008
- && skipProvidedModifiers(nominalEnd + 1) >= stream.tokens.length
1009
- ? stream.tokens.length
1010
- : nominalEnd;
1011
- };
1012
- const classifyProvidedRelativeTail = (initialIndex) => {
1013
- let index = skipProvidedModifiers(initialIndex);
1014
- const first = stream.tokens[index]?.value ?? '';
1015
- if (SUBJECT_ARTICLE_TERMS.has(first)) {
1016
- index = consumeProvidedNominal(index);
1017
- }
1018
- else if (!isProvidedPastPredicate(first)
1019
- && !PASSIVE_AUXILIARY_TERMS.has(first)
1020
- && isProvidedPastPredicate(stream.tokens[index + 1]?.value ?? '')) {
1021
- index = skipProvidedModifiers(index + 1);
1022
- }
1023
- while (PASSIVE_AUXILIARY_TERMS.has(stream.tokens[index]?.value ?? '')) {
1024
- index = skipProvidedModifiers(index + 1);
1025
- }
1026
- const predicate = stream.tokens[index]?.value ?? '';
1027
- if (!isProvidedPastPredicate(predicate))
1028
- return 'conditional';
1029
- index = skipProvidedModifiers(index + 1);
1030
- if (index >= stream.tokens.length)
1031
- return 'factual';
1032
- return consumeProvidedTerminalNominal(index) >= stream.tokens.length ? 'factual' : 'conditional';
1033
- };
1034
- const classifyProvidedSubordinateTail = (initialIndex) => {
1035
- let index = skipProvidedModifiers(initialIndex);
1036
- if (index >= stream.tokens.length)
1037
- return 'factual';
1038
- if (isProvidedPastPredicate(stream.tokens[index]?.value ?? '')) {
1039
- index = skipProvidedModifiers(index + 1);
1040
- if (index >= stream.tokens.length)
1041
- return 'factual';
1042
- }
1043
- return consumeProvidedTerminalNominal(index) >= stream.tokens.length ? 'factual' : 'conditional';
1044
- };
1045
- const classifyProvidedObjectTail = (initialIndex) => {
1046
- let index = skipProvidedModifiers(initialIndex);
1047
- if (index >= stream.tokens.length)
1048
- return 'factual';
1049
- const term = stream.tokens[index]?.value ?? '';
1050
- if (PROVIDED_OBJECT_COORDINATOR_TERMS.has(term)) {
1051
- index = skipProvidedModifiers(index + 1);
1052
- if (index >= stream.tokens.length)
1053
- return 'factual';
1054
- const coordinatedTerm = stream.tokens[index]?.value ?? '';
1055
- const subjectElidedPastAction = actionForms.has(coordinatedTerm)
1056
- && isProvidedPastPredicate(coordinatedTerm);
1057
- if (subjectElidedPastAction) {
1058
- index = skipProvidedModifiers(index + 1);
1059
- if (index >= stream.tokens.length)
1060
- return 'factual';
1061
- if (COMMA_DELIMITED_PREPOSITION_TERMS.has(stream.tokens[index]?.value ?? '')) {
1062
- return classifyProvidedObjectTail(index);
1063
- }
1064
- }
1065
- return classifyProvidedObjectTail(consumeProvidedTerminalNominal(index));
1066
- }
1067
- if (PROVIDED_OBJECT_RELATIVE_TERMS.has(term))
1068
- return classifyProvidedRelativeTail(index + 1);
1069
- if (COMMA_DELIMITED_PREPOSITION_TERMS.has(term)) {
1070
- return classifyProvidedObjectTail(consumeProvidedTerminalNominal(index + 1));
1071
- }
1072
- if (CONDITIONAL_MARKER_TERMS.has(term))
1073
- return 'conditional';
1074
- if (PROVIDED_OBJECT_SUBORDINATOR_TERMS.has(term)) {
1075
- return classifyProvidedSubordinateTail(index + 1);
1076
- }
1077
- if (PROVIDED_OBJECT_FACTUAL_TAIL_PREFIX_TERMS.has(term))
1078
- return 'factual';
1079
- if (term.endsWith('ing')) {
1080
- return classifyProvidedObjectTail(consumeProvidedTerminalNominal(index + 1));
1081
- }
1082
- return 'conditional';
1083
- };
1084
- return classifyProvidedObjectTail(consumeRemainingObjectTerms(objectPrefixEnd + 1));
1085
- };
1086
- const hasTargetActionPrefix = (source) => {
1087
- const stream = lexRequiredEvidence(source);
1088
- for (let actionIndex = 0; actionIndex < stream.tokens.length; actionIndex += 1) {
1089
- if (!targetActionForms.has(stream.tokens[actionIndex]?.value ?? ''))
1090
- continue;
1091
- if (actionIndex === 0 || leadingSubjectPolarity(stream, 0, actionIndex) === 'positive')
1092
- return true;
1093
- }
1094
- return false;
1095
- };
1096
- const hasProvidedMatrixAction = (source) => {
1097
- // Restrict disambiguation to the immediate consequent, not a later factual clause.
1098
- const commaIndex = source.indexOf(',');
1099
- if (commaIndex >= 0) {
1100
- const prefixKind = providedTargetPrefixKind(source.slice(0, commaIndex));
1101
- if (prefixKind === 'factual')
1102
- return false;
1103
- if (prefixKind === 'conditional')
1104
- return true;
1105
- }
1106
- let matrixScope = commaIndex >= 0
1107
- ? source.slice(commaIndex + 1)
1108
- : source.replace(/^\s*that\b/iu, ' ');
1109
- const subordinateIndex = matrixScope.search(/\b(?:after|assuming|because|before|if|once|supposing|that|unless|when|while)\b/iu);
1110
- if (subordinateIndex >= 0)
1111
- matrixScope = matrixScope.slice(0, subordinateIndex);
1112
- const candidates = matrixScope.split(/\b(?:and|but|or|then)\b/iu);
1113
- return (commaIndex >= 0 ? candidates : candidates.slice(0, 1))
1114
- .some((candidate) => hasIndependentAffirmativeAction(candidate, targetActionForms));
1115
- };
1116
- const hasPotentialMarker = (source) => {
1117
- const normalizedSource = source
1118
- .replace(CLOSED_IF_ANYTHING_RE, '$1 ')
1119
- .replace(COORDINATED_PROVIDED_RE, (match, connector, offset, whole) => (!targetActionForms.has('provided')
1120
- || hasTargetActionPrefix(whole.slice(0, offset))
1121
- || hasProvidedMatrixAction(whole.slice(offset + match.length))
1122
- ? match
1123
- : `${connector} `))
1124
- .replace(LEADING_PROVIDED_RE, (match, boundary, offset, whole) => (!targetActionForms.has('provided')
1125
- || hasTargetActionPrefix(whole.slice(0, offset))
1126
- || hasProvidedMatrixAction(whole.slice(offset + match.length))
1127
- ? match
1128
- : `${boundary} `));
1129
- return POTENTIAL_CONDITIONAL_SCOPE_RE.test(normalizedSource)
1130
- || hasTargetActionBeforePostposedConditionalMarker(normalizedSource, targetActionForms);
1131
- };
1132
- const hasFactualProvidedAction = (source) => {
1133
- const stream = lexRequiredEvidence(source);
1134
- for (let index = 0; index < stream.tokens.length; index += 1) {
1135
- const token = stream.tokens[index];
1136
- if (token?.value !== 'provided' || isAdjectivalProvided(stream.tokens, index))
1137
- continue;
1138
- let clauseStart = index;
1139
- while (clauseStart > 0 && stream.tokens[clauseStart - 1]?.clause === token.clause)
1140
- clauseStart -= 1;
1141
- if (leadingSubjectPolarity(stream, clauseStart, index) !== 'positive')
1142
- continue;
1143
- const tail = stream.tokens.slice(index + 1)
1144
- .filter((candidate) => candidate.clause === token.clause)
1145
- .map((candidate) => candidate.value)
1146
- .join(' ');
1147
- if (!hasProvidedMatrixAction(tail))
1148
- return true;
1149
- }
1150
- return false;
1151
- };
1152
- if (!hasPotentialMarker(segment))
1153
- return false;
1154
- const hadProvidedBy = segment.search(PROVIDED_BY_ADJUNCT_RE) >= 0;
865
+ if (prefixKind === 'conditional')
866
+ return true;
867
+ }
868
+ let matrixScope = commaIndex >= 0
869
+ ? source.slice(commaIndex + 1)
870
+ : source.replace(/^\s*that\b/iu, ' ');
871
+ const subordinateIndex = matrixScope.search(/\b(?:after|assuming|because|before|if|once|supposing|that|unless|when|while)\b/iu);
872
+ if (subordinateIndex >= 0)
873
+ matrixScope = matrixScope.slice(0, subordinateIndex);
874
+ const candidates = matrixScope.split(/\b(?:and|but|or|then)\b/iu);
875
+ return (commaIndex >= 0 ? candidates : candidates.slice(0, 1))
876
+ .some((candidate) => hasIndependentAffirmativeAction(candidate, context.targetActionForms));
877
+ }
878
+ function hasPotentialMarker(source, context) {
879
+ const { targetActionForms } = context;
880
+ const normalizedSource = source
881
+ .replace(CLOSED_IF_ANYTHING_RE, '$1 ')
882
+ .replace(COORDINATED_PROVIDED_RE, (match, connector, offset, whole) => (!targetActionForms.has('provided')
883
+ || hasTargetActionPrefix(whole.slice(0, offset), targetActionForms)
884
+ || hasProvidedMatrixAction(whole.slice(offset + match.length), context)
885
+ ? match
886
+ : `${connector} `))
887
+ .replace(LEADING_PROVIDED_RE, (match, boundary, offset, whole) => (!targetActionForms.has('provided')
888
+ || hasTargetActionPrefix(whole.slice(0, offset), targetActionForms)
889
+ || hasProvidedMatrixAction(whole.slice(offset + match.length), context)
890
+ ? match
891
+ : `${boundary} `));
892
+ return POTENTIAL_CONDITIONAL_SCOPE_RE.test(normalizedSource)
893
+ || hasTargetActionBeforePostposedConditionalMarker(normalizedSource, targetActionForms);
894
+ }
895
+ function hasFactualProvidedAction(source, context) {
896
+ const stream = lexRequiredEvidence(source);
897
+ for (let index = 0; index < stream.tokens.length; index += 1) {
898
+ const token = stream.tokens[index];
899
+ if (token?.value !== 'provided' || isAdjectivalProvided(stream.tokens, index))
900
+ continue;
901
+ let clauseStart = index;
902
+ while (clauseStart > 0 && stream.tokens[clauseStart - 1]?.clause === token.clause)
903
+ clauseStart -= 1;
904
+ if (leadingSubjectPolarity(stream, clauseStart, index) !== 'positive')
905
+ continue;
906
+ const tail = stream.tokens.slice(index + 1)
907
+ .filter((candidate) => candidate.clause === token.clause)
908
+ .map((candidate) => candidate.value)
909
+ .join(' ');
910
+ if (!hasProvidedMatrixAction(tail, context))
911
+ return true;
912
+ }
913
+ return false;
914
+ }
915
+ function stripFactualTemporalMarkers(segment, context) {
1155
916
  let probe = segment.replace(PROVIDED_BY_ADJUNCT_RE, ' ');
1156
917
  probe = probe.replace(COORDINATED_TEMPORAL_RE, (match, connector, offset) => {
1157
918
  const prefix = probe.slice(0, offset);
1158
919
  const suffix = probe.slice(offset + match.length);
1159
- return hasIndependentSimplePastPredicate(prefix) && hasIndependentSimplePastAction(suffix, actionForms, true)
920
+ return hasIndependentSimplePastPredicate(prefix)
921
+ && hasIndependentSimplePastAction(suffix, context.actionForms, true)
1160
922
  ? `${connector} `
1161
923
  : match;
1162
924
  });
1163
925
  const leadingTemporal = LEADING_DISCOURSE_TEMPORAL_RE.exec(probe);
1164
- if (leadingTemporal) {
1165
- const suffix = probe.slice(leadingTemporal[0].length);
1166
- if (hasIndependentSimplePastAction(suffix, actionForms)
1167
- || hasFactualProvidedAction(suffix))
1168
- probe = suffix;
1169
- }
1170
- const hasRemainingPotentialMarker = hasPotentialMarker(probe)
1171
- || hasTargetActionBeforePostposedConditionalMarker(probe, targetActionForms);
1172
- return hasRemainingPotentialMarker || (hadProvidedBy
1173
- && !hasFactualProvidedAction(probe)
1174
- && lexRequiredEvidence(probe).conditional.some(Boolean));
926
+ if (!leadingTemporal)
927
+ return probe;
928
+ const suffix = probe.slice(leadingTemporal[0].length);
929
+ return hasIndependentSimplePastAction(suffix, context.actionForms)
930
+ || hasFactualProvidedAction(suffix, context)
931
+ ? suffix
932
+ : probe;
933
+ }
934
+ function hasConditionalEvidence(probe, hadProvidedBy, context) {
935
+ return hasPotentialMarker(probe, context)
936
+ || hasTargetActionBeforePostposedConditionalMarker(probe, context.targetActionForms)
937
+ || (hadProvidedBy
938
+ && !hasFactualProvidedAction(probe, context)
939
+ && lexRequiredEvidence(probe).conditional.some(Boolean));
940
+ }
941
+ function hasPotentialConditionalScope(segment, actionForms, targetActionForms, terms) {
942
+ const context = { actionForms, targetActionForms, terms };
943
+ if (!hasPotentialMarker(segment, context))
944
+ return false;
945
+ const hadProvidedBy = segment.search(PROVIDED_BY_ADJUNCT_RE) >= 0;
946
+ const probe = stripFactualTemporalMarkers(segment, context);
947
+ return hasConditionalEvidence(probe, hadProvidedBy, context);
1175
948
  }
1176
949
  const NON_FACTUAL_MATRIX_AUXILIARIES = new Set([
1177
950
  'can', 'cannot', "can't", 'could', "couldn't", 'may', 'might', "mightn't", 'must', "mustn't",
@@ -1659,33 +1432,6 @@ const COMMA_DELIMITED_PREPOSITION_TERMS = new Set([
1659
1432
  ...PASSIVE_SUBJECT_POSTMODIFIER_TERMS,
1660
1433
  'according', 'despite', 'during', 'inside', 'outside', 'regarding', 'within',
1661
1434
  ]);
1662
- const PROVIDED_OBJECT_FACTUAL_TAIL_PREFIX_TERMS = new Set([
1663
- ...COMMA_DELIMITED_PREPOSITION_TERMS,
1664
- ...PREDICATE_COORDINATOR_TERMS,
1665
- 'after', 'although', 'as', 'because', 'before', 'however', 'since', 'than', 'though',
1666
- 'whereas', 'yet',
1667
- ]);
1668
- const PROVIDED_OBJECT_RELATIVE_TERMS = new Set(['that', 'which', 'who']);
1669
- const PROVIDED_OBJECT_SUBORDINATOR_TERMS = new Set(['after', 'as', 'before']);
1670
- // Bare PP tails are POS-ambiguous; keep this bounded to known prenominal forms with paired tests.
1671
- const PROVIDED_OBJECT_NOMINAL_MODIFIER_TERMS = new Set([
1672
- 'access', 'audit', 'backup', 'cold', 'data', 'offline', 'ongoing',
1673
- 'policy', 'remote', 'secure', 'security', 'token',
1674
- ]);
1675
- const PROVIDED_OBJECT_NOMINAL_HEAD_TERMS = new Set([
1676
- 'access', 'approval', 'archive', 'audit', 'auditor', 'credentials', 'data', 'details',
1677
- 'leak', 'leaks', 'metadata', 'policy', 'receipt', 'records', 'request', 'review', 'server',
1678
- 'storage', 'system', 'transit',
1679
- ]);
1680
- const PROVIDED_OBJECT_MATRIX_NOMINAL_COLLOCATIONS = new Set(['access:policy']);
1681
- const PROVIDED_OBJECT_COORDINATOR_TERMS = new Set(['and', 'or', 'then']);
1682
- const PROVIDED_OBJECT_TRAILING_MODIFIER_TERMS = new Set([
1683
- 'earlier', 'here', 'now', 'soon', 'today', 'tonight', 'there', 'yesterday',
1684
- ]);
1685
- const PROVIDED_OBJECT_MATRIX_PREDICATE_TERMS = new Set([
1686
- 'arrive', 'arrives', 'become', 'becomes', 'exist', 'exists', 'expire', 'expires',
1687
- 'leak', 'leaks', 'match', 'matches', 'pass', 'passes', 'remain', 'remains', 'trigger', 'triggers',
1688
- ]);
1689
1435
  const TOTALITY_TARGET_MODIFIER_TERMS = new Set([
1690
1436
  'complete', 'entire', 'full', 'partial', 'total', 'whole',
1691
1437
  ]);
@@ -0,0 +1,31 @@
1
+ type ProvidedPrefixKind = 'conditional' | 'factual' | 'none';
2
+ interface PredicateTokenStream {
3
+ tokens: readonly {
4
+ value: string;
5
+ }[];
6
+ }
7
+ interface ProvidedPrefixLexicon {
8
+ commaDelimitedPrepositions: ReadonlySet<string>;
9
+ conditionalMarkers: ReadonlySet<string>;
10
+ irregularPastParticiples: ReadonlySet<string>;
11
+ irregularSimplePast: ReadonlySet<string>;
12
+ leadingClauseModifiers: ReadonlySet<string>;
13
+ passiveAuxiliaries: ReadonlySet<string>;
14
+ subjectArticles: ReadonlySet<string>;
15
+ }
16
+ interface ProvidedPrefixPredicates {
17
+ finiteClauseSubjectPolarity(source: string): 'absent' | 'negative' | 'positive';
18
+ hasIndependentAffirmativeAction(source: string, actionForms: ReadonlySet<string>): boolean;
19
+ isAttributiveTargetModifier(term: string): boolean;
20
+ isFinitePredicateTerm(term: string): boolean;
21
+ tokenize(source: string): PredicateTokenStream;
22
+ }
23
+ interface ProvidedPrefixInput {
24
+ actionForms: ReadonlySet<string>;
25
+ lexicon: ProvidedPrefixLexicon;
26
+ objectForms: readonly ReadonlySet<string>[];
27
+ predicates: ProvidedPrefixPredicates;
28
+ source: string;
29
+ }
30
+ export declare function classifyProvidedTargetPrefix(input: ProvidedPrefixInput): ProvidedPrefixKind;
31
+ export {};