@humanagencyp/hap-core 0.10.0 → 0.10.1
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/dist/index.d.mts +33 -2
- package/dist/index.d.ts +33 -2
- package/dist/index.js +26 -2
- package/dist/index.mjs +25 -2
- package/package.json +1 -1
- package/src/gatekeeper.ts +36 -2
- package/src/types.ts +21 -1
package/dist/index.d.mts
CHANGED
|
@@ -610,7 +610,21 @@ interface ExecutionLogQuery {
|
|
|
610
610
|
* Sum a field's values within a time window for a given profile.
|
|
611
611
|
* Use field="_count" to count executions instead of summing a field.
|
|
612
612
|
*/
|
|
613
|
-
sumByWindow(profileId: string, path: string, field: string, window: CumulativeWindow, now?: number
|
|
613
|
+
sumByWindow(profileId: string, path: string, field: string, window: CumulativeWindow, now?: number,
|
|
614
|
+
/**
|
|
615
|
+
* Only count executions whose `execution.action_type` is one of these.
|
|
616
|
+
* Omitted → every execution counts (a bound that governs all action types).
|
|
617
|
+
*
|
|
618
|
+
* Consumption is partitioned by action type (*Cumulative Tracking* rule 4):
|
|
619
|
+
* a bound counts only the action types it governs. Without the filter a
|
|
620
|
+
* profile with several action types feeds every bound the combined total —
|
|
621
|
+
* sales' "orders per day" counted quotes and sends too, and its daily order
|
|
622
|
+
* value summed quote values. Use {@link boundActionTypes} to derive it.
|
|
623
|
+
*
|
|
624
|
+
* Implementations SHOULD count an entry that carries no `action_type`
|
|
625
|
+
* against every filter: an unknown action is not evidence of headroom.
|
|
626
|
+
*/
|
|
627
|
+
actionTypes?: readonly string[]): number;
|
|
614
628
|
}
|
|
615
629
|
/**
|
|
616
630
|
* Agent frame parameters — mixed types (strings and numbers).
|
|
@@ -1126,6 +1140,23 @@ declare function verifyAttestationV4(blob: string, publicKeyHex: string, expecte
|
|
|
1126
1140
|
* @param executionLog - Optional execution log for resolving cumulative fields
|
|
1127
1141
|
*/
|
|
1128
1142
|
declare function verify(request: GatekeeperRequest, publicKeyHex: string, now?: number, executionLog?: ExecutionLogQuery): Promise<GatekeeperResult>;
|
|
1143
|
+
/**
|
|
1144
|
+
* Which action types' executions count toward this cumulative bound's running
|
|
1145
|
+
* total. `undefined` means all of them.
|
|
1146
|
+
*
|
|
1147
|
+
* `boundGovernsAction` decides whether a bound applies to the current call; this
|
|
1148
|
+
* decides what the bound's total is made of. Both are needed: selecting the right
|
|
1149
|
+
* bound and then feeding it the profile's combined total is still wrong — sales'
|
|
1150
|
+
* "orders per day" was checked only on orders, but counted every quote and send.
|
|
1151
|
+
* Consumption is partitioned by action type (*Cumulative Tracking* rule 4), as
|
|
1152
|
+
* the Authority Server already does.
|
|
1153
|
+
*
|
|
1154
|
+
* Same answer, same order of preference as `boundGovernsAction`: the declared
|
|
1155
|
+
* `appliesTo`; else, for a count bound named for an action (`delete_daily_max`),
|
|
1156
|
+
* that action; else every action type. Exported so display surfaces report the
|
|
1157
|
+
* same totals the gate enforces.
|
|
1158
|
+
*/
|
|
1159
|
+
declare function boundActionTypes(fieldName: string, fieldDef: ProfileBoundsField): readonly string[] | undefined;
|
|
1129
1160
|
|
|
1130
1161
|
/**
|
|
1131
1162
|
* Profile Registry — dynamically populated from git-hosted profile sources.
|
|
@@ -1322,4 +1353,4 @@ interface ReceiptPayload {
|
|
|
1322
1353
|
*/
|
|
1323
1354
|
declare function verifyReceiptSignature(receipt: ReceiptPayload, publicKeyHex: string): Promise<void>;
|
|
1324
1355
|
|
|
1325
|
-
export { type AgentBoundsParams, type AgentContextParams, type AgentFrameParams, type AgentProfile, type ApprovalObject, type Attestation, type AttestationHeader, type AttestationPayload, type BoundType, CanonicalValueError, type ContentBinding, ContentBindingError, type ContentBindingErrorCode, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type ExecutionMappingTransform, type ExecutionMappingValue, type ExecutionPath, type FieldConstraint, type FieldUnit, type GateQuestion, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, type MandateBinding, MandateError, type MandateProjection, type OwnerMandate, type ProfileBoundsField, type ProfileContextField, type ProfileFrameField, type ProfileToolGating, type ProfileToolGatingEntry, type ReceiptPayload, type ResolvedDomain, type SigningSurface, type Subject, type SubjectValidation, approvalSigningBytes, attestationId, bindingAppliesTo, buildMandateProjection, canonicalBounds, canonicalContext, canonicalFrame, canonicalize, canonicalizeText, checkAttestationExpiry, clearProfiles, computeBoundsHash, computeContentHash, computeContextHash, computeFieldsContentHash, computeFrameHash, computeIntentDisclosureHash, computeIntentHash, contentCanonicalBytes, decodeAttestationBlob, decodeDidKey, deriveIdentityLine, encodeAttestationBlob, encodeDidKey, frameHash, getAllProfiles, getProfile, intentDisclosureCanonicalBytes, isFieldBinding, isKeyBearingDid, isV4Attestation, listProfiles, mandateSigningBytes, registerProfile, selectBoundFields, signApproval, signMandateProjection, validateBoundsParams, validateContextParams, validateFrameParams, validateSubject, verify, verifyApproval, verifyAttestation, verifyAttestationSignature, verifyAttestationV4, verifyBoundsHash, verifyContextHash, verifyFrameHash, verifyOwnerMandate, verifyOwnerMandates, verifyReceiptSignature };
|
|
1356
|
+
export { type AgentBoundsParams, type AgentContextParams, type AgentFrameParams, type AgentProfile, type ApprovalObject, type Attestation, type AttestationHeader, type AttestationPayload, type BoundType, CanonicalValueError, type ContentBinding, ContentBindingError, type ContentBindingErrorCode, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type ExecutionMappingTransform, type ExecutionMappingValue, type ExecutionPath, type FieldConstraint, type FieldUnit, type GateQuestion, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, type MandateBinding, MandateError, type MandateProjection, type OwnerMandate, type ProfileBoundsField, type ProfileContextField, type ProfileFrameField, type ProfileToolGating, type ProfileToolGatingEntry, type ReceiptPayload, type ResolvedDomain, type SigningSurface, type Subject, type SubjectValidation, approvalSigningBytes, attestationId, bindingAppliesTo, boundActionTypes, buildMandateProjection, canonicalBounds, canonicalContext, canonicalFrame, canonicalize, canonicalizeText, checkAttestationExpiry, clearProfiles, computeBoundsHash, computeContentHash, computeContextHash, computeFieldsContentHash, computeFrameHash, computeIntentDisclosureHash, computeIntentHash, contentCanonicalBytes, decodeAttestationBlob, decodeDidKey, deriveIdentityLine, encodeAttestationBlob, encodeDidKey, frameHash, getAllProfiles, getProfile, intentDisclosureCanonicalBytes, isFieldBinding, isKeyBearingDid, isV4Attestation, listProfiles, mandateSigningBytes, registerProfile, selectBoundFields, signApproval, signMandateProjection, validateBoundsParams, validateContextParams, validateFrameParams, validateSubject, verify, verifyApproval, verifyAttestation, verifyAttestationSignature, verifyAttestationV4, verifyBoundsHash, verifyContextHash, verifyFrameHash, verifyOwnerMandate, verifyOwnerMandates, verifyReceiptSignature };
|
package/dist/index.d.ts
CHANGED
|
@@ -610,7 +610,21 @@ interface ExecutionLogQuery {
|
|
|
610
610
|
* Sum a field's values within a time window for a given profile.
|
|
611
611
|
* Use field="_count" to count executions instead of summing a field.
|
|
612
612
|
*/
|
|
613
|
-
sumByWindow(profileId: string, path: string, field: string, window: CumulativeWindow, now?: number
|
|
613
|
+
sumByWindow(profileId: string, path: string, field: string, window: CumulativeWindow, now?: number,
|
|
614
|
+
/**
|
|
615
|
+
* Only count executions whose `execution.action_type` is one of these.
|
|
616
|
+
* Omitted → every execution counts (a bound that governs all action types).
|
|
617
|
+
*
|
|
618
|
+
* Consumption is partitioned by action type (*Cumulative Tracking* rule 4):
|
|
619
|
+
* a bound counts only the action types it governs. Without the filter a
|
|
620
|
+
* profile with several action types feeds every bound the combined total —
|
|
621
|
+
* sales' "orders per day" counted quotes and sends too, and its daily order
|
|
622
|
+
* value summed quote values. Use {@link boundActionTypes} to derive it.
|
|
623
|
+
*
|
|
624
|
+
* Implementations SHOULD count an entry that carries no `action_type`
|
|
625
|
+
* against every filter: an unknown action is not evidence of headroom.
|
|
626
|
+
*/
|
|
627
|
+
actionTypes?: readonly string[]): number;
|
|
614
628
|
}
|
|
615
629
|
/**
|
|
616
630
|
* Agent frame parameters — mixed types (strings and numbers).
|
|
@@ -1126,6 +1140,23 @@ declare function verifyAttestationV4(blob: string, publicKeyHex: string, expecte
|
|
|
1126
1140
|
* @param executionLog - Optional execution log for resolving cumulative fields
|
|
1127
1141
|
*/
|
|
1128
1142
|
declare function verify(request: GatekeeperRequest, publicKeyHex: string, now?: number, executionLog?: ExecutionLogQuery): Promise<GatekeeperResult>;
|
|
1143
|
+
/**
|
|
1144
|
+
* Which action types' executions count toward this cumulative bound's running
|
|
1145
|
+
* total. `undefined` means all of them.
|
|
1146
|
+
*
|
|
1147
|
+
* `boundGovernsAction` decides whether a bound applies to the current call; this
|
|
1148
|
+
* decides what the bound's total is made of. Both are needed: selecting the right
|
|
1149
|
+
* bound and then feeding it the profile's combined total is still wrong — sales'
|
|
1150
|
+
* "orders per day" was checked only on orders, but counted every quote and send.
|
|
1151
|
+
* Consumption is partitioned by action type (*Cumulative Tracking* rule 4), as
|
|
1152
|
+
* the Authority Server already does.
|
|
1153
|
+
*
|
|
1154
|
+
* Same answer, same order of preference as `boundGovernsAction`: the declared
|
|
1155
|
+
* `appliesTo`; else, for a count bound named for an action (`delete_daily_max`),
|
|
1156
|
+
* that action; else every action type. Exported so display surfaces report the
|
|
1157
|
+
* same totals the gate enforces.
|
|
1158
|
+
*/
|
|
1159
|
+
declare function boundActionTypes(fieldName: string, fieldDef: ProfileBoundsField): readonly string[] | undefined;
|
|
1129
1160
|
|
|
1130
1161
|
/**
|
|
1131
1162
|
* Profile Registry — dynamically populated from git-hosted profile sources.
|
|
@@ -1322,4 +1353,4 @@ interface ReceiptPayload {
|
|
|
1322
1353
|
*/
|
|
1323
1354
|
declare function verifyReceiptSignature(receipt: ReceiptPayload, publicKeyHex: string): Promise<void>;
|
|
1324
1355
|
|
|
1325
|
-
export { type AgentBoundsParams, type AgentContextParams, type AgentFrameParams, type AgentProfile, type ApprovalObject, type Attestation, type AttestationHeader, type AttestationPayload, type BoundType, CanonicalValueError, type ContentBinding, ContentBindingError, type ContentBindingErrorCode, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type ExecutionMappingTransform, type ExecutionMappingValue, type ExecutionPath, type FieldConstraint, type FieldUnit, type GateQuestion, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, type MandateBinding, MandateError, type MandateProjection, type OwnerMandate, type ProfileBoundsField, type ProfileContextField, type ProfileFrameField, type ProfileToolGating, type ProfileToolGatingEntry, type ReceiptPayload, type ResolvedDomain, type SigningSurface, type Subject, type SubjectValidation, approvalSigningBytes, attestationId, bindingAppliesTo, buildMandateProjection, canonicalBounds, canonicalContext, canonicalFrame, canonicalize, canonicalizeText, checkAttestationExpiry, clearProfiles, computeBoundsHash, computeContentHash, computeContextHash, computeFieldsContentHash, computeFrameHash, computeIntentDisclosureHash, computeIntentHash, contentCanonicalBytes, decodeAttestationBlob, decodeDidKey, deriveIdentityLine, encodeAttestationBlob, encodeDidKey, frameHash, getAllProfiles, getProfile, intentDisclosureCanonicalBytes, isFieldBinding, isKeyBearingDid, isV4Attestation, listProfiles, mandateSigningBytes, registerProfile, selectBoundFields, signApproval, signMandateProjection, validateBoundsParams, validateContextParams, validateFrameParams, validateSubject, verify, verifyApproval, verifyAttestation, verifyAttestationSignature, verifyAttestationV4, verifyBoundsHash, verifyContextHash, verifyFrameHash, verifyOwnerMandate, verifyOwnerMandates, verifyReceiptSignature };
|
|
1356
|
+
export { type AgentBoundsParams, type AgentContextParams, type AgentFrameParams, type AgentProfile, type ApprovalObject, type Attestation, type AttestationHeader, type AttestationPayload, type BoundType, CanonicalValueError, type ContentBinding, ContentBindingError, type ContentBindingErrorCode, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type ExecutionMappingTransform, type ExecutionMappingValue, type ExecutionPath, type FieldConstraint, type FieldUnit, type GateQuestion, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, type MandateBinding, MandateError, type MandateProjection, type OwnerMandate, type ProfileBoundsField, type ProfileContextField, type ProfileFrameField, type ProfileToolGating, type ProfileToolGatingEntry, type ReceiptPayload, type ResolvedDomain, type SigningSurface, type Subject, type SubjectValidation, approvalSigningBytes, attestationId, bindingAppliesTo, boundActionTypes, buildMandateProjection, canonicalBounds, canonicalContext, canonicalFrame, canonicalize, canonicalizeText, checkAttestationExpiry, clearProfiles, computeBoundsHash, computeContentHash, computeContextHash, computeFieldsContentHash, computeFrameHash, computeIntentDisclosureHash, computeIntentHash, contentCanonicalBytes, decodeAttestationBlob, decodeDidKey, deriveIdentityLine, encodeAttestationBlob, encodeDidKey, frameHash, getAllProfiles, getProfile, intentDisclosureCanonicalBytes, isFieldBinding, isKeyBearingDid, isV4Attestation, listProfiles, mandateSigningBytes, registerProfile, selectBoundFields, signApproval, signMandateProjection, validateBoundsParams, validateContextParams, validateFrameParams, validateSubject, verify, verifyApproval, verifyAttestation, verifyAttestationSignature, verifyAttestationV4, verifyBoundsHash, verifyContextHash, verifyFrameHash, verifyOwnerMandate, verifyOwnerMandates, verifyReceiptSignature };
|
package/dist/index.js
CHANGED
|
@@ -36,6 +36,7 @@ __export(index_exports, {
|
|
|
36
36
|
approvalSigningBytes: () => approvalSigningBytes,
|
|
37
37
|
attestationId: () => attestationId,
|
|
38
38
|
bindingAppliesTo: () => bindingAppliesTo,
|
|
39
|
+
boundActionTypes: () => boundActionTypes,
|
|
39
40
|
buildMandateProjection: () => buildMandateProjection,
|
|
40
41
|
canonicalBounds: () => canonicalBounds,
|
|
41
42
|
canonicalContext: () => canonicalContext,
|
|
@@ -785,6 +786,14 @@ function boundGovernsAction(fieldName, fieldDef, bt, actionType) {
|
|
|
785
786
|
const matches = prefix === actionType || prefix.startsWith("transaction");
|
|
786
787
|
return !namedForAnAction || matches;
|
|
787
788
|
}
|
|
789
|
+
function boundActionTypes(fieldName, fieldDef) {
|
|
790
|
+
if (fieldDef.appliesTo) return fieldDef.appliesTo;
|
|
791
|
+
const bt = fieldDef.boundType;
|
|
792
|
+
if (!bt || bt.kind !== "cumulative_count") return void 0;
|
|
793
|
+
const prefix = fieldName.replace(/_(?:daily|monthly|weekly)_max$/, "");
|
|
794
|
+
if (prefix === fieldName || prefix.startsWith("transaction")) return void 0;
|
|
795
|
+
return [prefix];
|
|
796
|
+
}
|
|
788
797
|
function checkBoundsV4(request, profile, executionLog, now) {
|
|
789
798
|
const errors = [];
|
|
790
799
|
if (!profile.boundsSchema) return errors;
|
|
@@ -845,7 +854,14 @@ function checkBoundsV4(request, profile, executionLog, now) {
|
|
|
845
854
|
break;
|
|
846
855
|
}
|
|
847
856
|
if (!executionLog) break;
|
|
848
|
-
const runningTotal = executionLog.sumByWindow(
|
|
857
|
+
const runningTotal = executionLog.sumByWindow(
|
|
858
|
+
profileId,
|
|
859
|
+
path,
|
|
860
|
+
bt.of,
|
|
861
|
+
bt.window,
|
|
862
|
+
now,
|
|
863
|
+
boundActionTypes(fieldName, fieldDef)
|
|
864
|
+
);
|
|
849
865
|
const currentRaw = request.execution[bt.of];
|
|
850
866
|
const current = typeof currentRaw === "number" ? currentRaw : currentRaw !== void 0 ? Number(currentRaw) : 0;
|
|
851
867
|
const total = runningTotal + current;
|
|
@@ -872,7 +888,14 @@ function checkBoundsV4(request, profile, executionLog, now) {
|
|
|
872
888
|
break;
|
|
873
889
|
}
|
|
874
890
|
if (!executionLog) break;
|
|
875
|
-
const runningCount = executionLog.sumByWindow(
|
|
891
|
+
const runningCount = executionLog.sumByWindow(
|
|
892
|
+
profileId,
|
|
893
|
+
path,
|
|
894
|
+
"_count",
|
|
895
|
+
bt.window,
|
|
896
|
+
now,
|
|
897
|
+
boundActionTypes(fieldName, fieldDef)
|
|
898
|
+
);
|
|
876
899
|
const total = runningCount + 1;
|
|
877
900
|
if (total > boundValue) {
|
|
878
901
|
errors.push({
|
|
@@ -1207,6 +1230,7 @@ async function verifyReceiptSignature(receipt, publicKeyHex) {
|
|
|
1207
1230
|
approvalSigningBytes,
|
|
1208
1231
|
attestationId,
|
|
1209
1232
|
bindingAppliesTo,
|
|
1233
|
+
boundActionTypes,
|
|
1210
1234
|
buildMandateProjection,
|
|
1211
1235
|
canonicalBounds,
|
|
1212
1236
|
canonicalContext,
|
package/dist/index.mjs
CHANGED
|
@@ -695,6 +695,14 @@ function boundGovernsAction(fieldName, fieldDef, bt, actionType) {
|
|
|
695
695
|
const matches = prefix === actionType || prefix.startsWith("transaction");
|
|
696
696
|
return !namedForAnAction || matches;
|
|
697
697
|
}
|
|
698
|
+
function boundActionTypes(fieldName, fieldDef) {
|
|
699
|
+
if (fieldDef.appliesTo) return fieldDef.appliesTo;
|
|
700
|
+
const bt = fieldDef.boundType;
|
|
701
|
+
if (!bt || bt.kind !== "cumulative_count") return void 0;
|
|
702
|
+
const prefix = fieldName.replace(/_(?:daily|monthly|weekly)_max$/, "");
|
|
703
|
+
if (prefix === fieldName || prefix.startsWith("transaction")) return void 0;
|
|
704
|
+
return [prefix];
|
|
705
|
+
}
|
|
698
706
|
function checkBoundsV4(request, profile, executionLog, now) {
|
|
699
707
|
const errors = [];
|
|
700
708
|
if (!profile.boundsSchema) return errors;
|
|
@@ -755,7 +763,14 @@ function checkBoundsV4(request, profile, executionLog, now) {
|
|
|
755
763
|
break;
|
|
756
764
|
}
|
|
757
765
|
if (!executionLog) break;
|
|
758
|
-
const runningTotal = executionLog.sumByWindow(
|
|
766
|
+
const runningTotal = executionLog.sumByWindow(
|
|
767
|
+
profileId,
|
|
768
|
+
path,
|
|
769
|
+
bt.of,
|
|
770
|
+
bt.window,
|
|
771
|
+
now,
|
|
772
|
+
boundActionTypes(fieldName, fieldDef)
|
|
773
|
+
);
|
|
759
774
|
const currentRaw = request.execution[bt.of];
|
|
760
775
|
const current = typeof currentRaw === "number" ? currentRaw : currentRaw !== void 0 ? Number(currentRaw) : 0;
|
|
761
776
|
const total = runningTotal + current;
|
|
@@ -782,7 +797,14 @@ function checkBoundsV4(request, profile, executionLog, now) {
|
|
|
782
797
|
break;
|
|
783
798
|
}
|
|
784
799
|
if (!executionLog) break;
|
|
785
|
-
const runningCount = executionLog.sumByWindow(
|
|
800
|
+
const runningCount = executionLog.sumByWindow(
|
|
801
|
+
profileId,
|
|
802
|
+
path,
|
|
803
|
+
"_count",
|
|
804
|
+
bt.window,
|
|
805
|
+
now,
|
|
806
|
+
boundActionTypes(fieldName, fieldDef)
|
|
807
|
+
);
|
|
786
808
|
const total = runningCount + 1;
|
|
787
809
|
if (total > boundValue) {
|
|
788
810
|
errors.push({
|
|
@@ -1116,6 +1138,7 @@ export {
|
|
|
1116
1138
|
approvalSigningBytes,
|
|
1117
1139
|
attestationId,
|
|
1118
1140
|
bindingAppliesTo,
|
|
1141
|
+
boundActionTypes,
|
|
1119
1142
|
buildMandateProjection,
|
|
1120
1143
|
canonicalBounds,
|
|
1121
1144
|
canonicalContext,
|
package/package.json
CHANGED
package/src/gatekeeper.ts
CHANGED
|
@@ -469,6 +469,36 @@ function boundGovernsAction(
|
|
|
469
469
|
return !namedForAnAction || matches;
|
|
470
470
|
}
|
|
471
471
|
|
|
472
|
+
/**
|
|
473
|
+
* Which action types' executions count toward this cumulative bound's running
|
|
474
|
+
* total. `undefined` means all of them.
|
|
475
|
+
*
|
|
476
|
+
* `boundGovernsAction` decides whether a bound applies to the current call; this
|
|
477
|
+
* decides what the bound's total is made of. Both are needed: selecting the right
|
|
478
|
+
* bound and then feeding it the profile's combined total is still wrong — sales'
|
|
479
|
+
* "orders per day" was checked only on orders, but counted every quote and send.
|
|
480
|
+
* Consumption is partitioned by action type (*Cumulative Tracking* rule 4), as
|
|
481
|
+
* the Authority Server already does.
|
|
482
|
+
*
|
|
483
|
+
* Same answer, same order of preference as `boundGovernsAction`: the declared
|
|
484
|
+
* `appliesTo`; else, for a count bound named for an action (`delete_daily_max`),
|
|
485
|
+
* that action; else every action type. Exported so display surfaces report the
|
|
486
|
+
* same totals the gate enforces.
|
|
487
|
+
*/
|
|
488
|
+
export function boundActionTypes(
|
|
489
|
+
fieldName: string,
|
|
490
|
+
fieldDef: ProfileBoundsField,
|
|
491
|
+
): readonly string[] | undefined {
|
|
492
|
+
if (fieldDef.appliesTo) return fieldDef.appliesTo;
|
|
493
|
+
|
|
494
|
+
const bt = fieldDef.boundType;
|
|
495
|
+
if (!bt || bt.kind !== 'cumulative_count') return undefined;
|
|
496
|
+
|
|
497
|
+
const prefix = fieldName.replace(/_(?:daily|monthly|weekly)_max$/, '');
|
|
498
|
+
if (prefix === fieldName || prefix.startsWith('transaction')) return undefined;
|
|
499
|
+
return [prefix];
|
|
500
|
+
}
|
|
501
|
+
|
|
472
502
|
function checkBoundsV4(
|
|
473
503
|
request: GatekeeperRequest,
|
|
474
504
|
profile: AgentProfile,
|
|
@@ -552,7 +582,9 @@ function checkBoundsV4(
|
|
|
552
582
|
}
|
|
553
583
|
if (!executionLog) break;
|
|
554
584
|
|
|
555
|
-
const runningTotal = executionLog.sumByWindow(
|
|
585
|
+
const runningTotal = executionLog.sumByWindow(
|
|
586
|
+
profileId, path, bt.of, bt.window, now, boundActionTypes(fieldName, fieldDef),
|
|
587
|
+
);
|
|
556
588
|
const currentRaw = request.execution[bt.of];
|
|
557
589
|
const current = typeof currentRaw === 'number'
|
|
558
590
|
? currentRaw
|
|
@@ -584,7 +616,9 @@ function checkBoundsV4(
|
|
|
584
616
|
}
|
|
585
617
|
if (!executionLog) break;
|
|
586
618
|
|
|
587
|
-
const runningCount = executionLog.sumByWindow(
|
|
619
|
+
const runningCount = executionLog.sumByWindow(
|
|
620
|
+
profileId, path, '_count', bt.window, now, boundActionTypes(fieldName, fieldDef),
|
|
621
|
+
);
|
|
588
622
|
const total = runningCount + 1;
|
|
589
623
|
|
|
590
624
|
if (total > boundValue) {
|
package/src/types.ts
CHANGED
|
@@ -636,7 +636,27 @@ export interface ExecutionLogQuery {
|
|
|
636
636
|
* Sum a field's values within a time window for a given profile.
|
|
637
637
|
* Use field="_count" to count executions instead of summing a field.
|
|
638
638
|
*/
|
|
639
|
-
sumByWindow(
|
|
639
|
+
sumByWindow(
|
|
640
|
+
profileId: string,
|
|
641
|
+
path: string,
|
|
642
|
+
field: string,
|
|
643
|
+
window: CumulativeWindow,
|
|
644
|
+
now?: number,
|
|
645
|
+
/**
|
|
646
|
+
* Only count executions whose `execution.action_type` is one of these.
|
|
647
|
+
* Omitted → every execution counts (a bound that governs all action types).
|
|
648
|
+
*
|
|
649
|
+
* Consumption is partitioned by action type (*Cumulative Tracking* rule 4):
|
|
650
|
+
* a bound counts only the action types it governs. Without the filter a
|
|
651
|
+
* profile with several action types feeds every bound the combined total —
|
|
652
|
+
* sales' "orders per day" counted quotes and sends too, and its daily order
|
|
653
|
+
* value summed quote values. Use {@link boundActionTypes} to derive it.
|
|
654
|
+
*
|
|
655
|
+
* Implementations SHOULD count an entry that carries no `action_type`
|
|
656
|
+
* against every filter: an unknown action is not evidence of headroom.
|
|
657
|
+
*/
|
|
658
|
+
actionTypes?: readonly string[],
|
|
659
|
+
): number;
|
|
640
660
|
}
|
|
641
661
|
|
|
642
662
|
// ─── Frame Types ─────────────────────────────────────────────────────────────
|