@cat-factory/contracts 0.243.0 → 0.244.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/dist/errors.d.ts CHANGED
@@ -29,7 +29,7 @@ export type ApiErrorCode = (typeof API_ERROR_CODES)[number];
29
29
  * type for `ConflictError`, and the SPA keys an exhaustive `Record<ConflictReason, …>` of
30
30
  * localized titles off it — adding a value without a title trips the frontend typecheck.
31
31
  */
32
- export declare const CONFLICT_REASONS: readonly ['providers_unconfigured', 'preset_unsatisfiable', 'dependencies_unmet', 'task_limit_reached', 'tester_infra_unsupported', 'binary_storage_unconfigured', 'agent_backend_unconfigured', 'run_not_retryable', 'no_pr_to_merge', 'dry_run_not_mergeable', 'github_not_connected', 'bootstrap_not_retryable', 'bootstrap_reference_missing', 'document_already_linked', 'provision_type_unhandled', 'visual_pipeline_no_frontend', 'model_policy_blocked', 'model_policy_unsupported', 'deployer_required_before_tester', 'deployer_service_provisioning_incomplete', 'deployer_connection_test_failed', 'env_test_not_a_frame', 'env_test_infraless', 'env_test_not_provisionable', 'env_test_no_vcs', 'env_test_connection_failed', 'review_debt_warn', 'review_debt_blocked', 'prompt_revision_conflict', 'pipeline_schedule_attached', 'pipeline_schedule_requires_recurring', 'pipeline_schedule_intake_unconfigured', 'foundational_service_exists', 'binary_output_service_invalid', 'binary_output_generator_invalid', 'foundational_service_not_inherited', 'ticket_already_linked', 'input_gate_not_parked', 'input_gate_parked'];
32
+ export declare const CONFLICT_REASONS: readonly ['providers_unconfigured', 'preset_unsatisfiable', 'dependencies_unmet', 'task_limit_reached', 'tester_infra_unsupported', 'binary_storage_unconfigured', 'agent_backend_unconfigured', 'run_not_retryable', 'no_pr_to_merge', 'dry_run_not_mergeable', 'submission_not_allowed', 'github_not_connected', 'bootstrap_not_retryable', 'bootstrap_reference_missing', 'document_already_linked', 'provision_type_unhandled', 'visual_pipeline_no_frontend', 'model_policy_blocked', 'model_policy_unsupported', 'deployer_required_before_tester', 'deployer_service_provisioning_incomplete', 'deployer_connection_test_failed', 'env_test_not_a_frame', 'env_test_infraless', 'env_test_not_provisionable', 'env_test_no_vcs', 'env_test_connection_failed', 'review_debt_warn', 'review_debt_blocked', 'prompt_revision_conflict', 'pipeline_schedule_attached', 'pipeline_schedule_requires_recurring', 'pipeline_schedule_intake_unconfigured', 'foundational_service_exists', 'binary_output_service_invalid', 'binary_output_generator_invalid', 'foundational_service_not_inherited', 'ticket_already_linked', 'input_gate_not_parked', 'input_gate_parked'];
33
33
  export type ConflictReason = (typeof CONFLICT_REASONS)[number];
34
34
  /**
35
35
  * Machine-readable reasons behind a 503 (`error.details.reason` on an `UnavailableError`), for
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,YAC7B,WAAW,EACX,YAAY,EACZ,UAAU,EACV,qBAAqB,EACrB,WAAW,EACX,aAAa,EACb,cAAc,EACd,cAAc,CACN,CAAA;AAEV,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEjE;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,iJAA+C,CAAA;AAE3E,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3D;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,YAC3B,wBAAwB,EAKxB,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,mBAAmB,EACnB,gBAAgB,EAKhB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,6BAA6B,EAK7B,yBAAyB,EAGzB,0BAA0B,EAG1B,6BAA6B,EAG7B,sBAAsB,EAGtB,0BAA0B,EAI1B,iCAAiC,EAKjC,0CAA0C,EAK1C,iCAAiC,EAGjC,sBAAsB,EAGtB,oBAAoB,EAGpB,4BAA4B,EAG5B,iBAAiB,EAMjB,4BAA4B,EAK5B,kBAAkB,EAIlB,qBAAqB,EAKrB,0BAA0B,EAO1B,4BAA4B,EAG5B,sCAAsC,EAItC,uCAAuC,EAKvC,6BAA6B,EAS7B,+BAA+B,EAY/B,iCAAiC,EAOjC,oCAAoC,EAOpC,uBAAuB,EAKvB,uBAAuB,EAUvB,mBAAmB,CACX,CAAA;AAEV,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE9D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,mBAAmB,YAC9B,+BAA+B,EAC/B,mCAAmC,CAC3B,CAAA;AAEV,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEpE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,YAAI,qBAAqB,EAAE,yBAAyB,CAAU,CAAA;AAEhG,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAA"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,YAC7B,WAAW,EACX,YAAY,EACZ,UAAU,EACV,qBAAqB,EACrB,WAAW,EACX,aAAa,EACb,cAAc,EACd,cAAc,CACN,CAAA;AAEV,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEjE;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,iJAA+C,CAAA;AAE3E,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3D;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,YAC3B,wBAAwB,EAKxB,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,mBAAmB,EACnB,gBAAgB,EAKhB,uBAAuB,EAOvB,wBAAwB,EACxB,sBAAsB,EACtB,yBAAyB,EACzB,6BAA6B,EAK7B,yBAAyB,EAGzB,0BAA0B,EAG1B,6BAA6B,EAG7B,sBAAsB,EAGtB,0BAA0B,EAI1B,iCAAiC,EAKjC,0CAA0C,EAK1C,iCAAiC,EAGjC,sBAAsB,EAGtB,oBAAoB,EAGpB,4BAA4B,EAG5B,iBAAiB,EAMjB,4BAA4B,EAK5B,kBAAkB,EAIlB,qBAAqB,EAKrB,0BAA0B,EAO1B,4BAA4B,EAG5B,sCAAsC,EAItC,uCAAuC,EAKvC,6BAA6B,EAS7B,+BAA+B,EAY/B,iCAAiC,EAOjC,oCAAoC,EAOpC,uBAAuB,EAKvB,uBAAuB,EAUvB,mBAAmB,CACX,CAAA;AAEV,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE9D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,mBAAmB,YAC9B,+BAA+B,EAC/B,mCAAmC,CAC3B,CAAA;AAEV,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEpE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,YAAI,qBAAqB,EAAE,yBAAyB,CAAU,CAAA;AAEhG,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAA"}
package/dist/errors.js CHANGED
@@ -56,6 +56,13 @@ export const CONFLICT_REASONS = [
56
56
  // authority to land it, and the remedy is to re-run the task live rather than to look for a
57
57
  // PR that does not exist.
58
58
  'dry_run_not_mergeable',
59
+ // The run's initiator holds a role whose merge preset allowlists which change classes it may
60
+ // land, and this pull request's class is outside that list. Kept apart from
61
+ // `dry_run_not_mergeable` because the remedies are opposite: re-running live changes nothing
62
+ // here (the same role would produce the same refusal), and what does resolve it is a teammate
63
+ // whose role may land this class, or an operator widening the allowlist. `details.changeClass`
64
+ // names the class that was refused.
65
+ 'submission_not_allowed',
59
66
  'github_not_connected',
60
67
  'bootstrap_not_retryable',
61
68
  'bootstrap_reference_missing',
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
package/dist/merge.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as v from 'valibot';
2
- import { type ChangeClass } from './mergeTrackRecord.js';
2
+ import { type ChangeClass, type RuleableChangeClass } from './mergeTrackRecord.js';
3
3
  import { type WorkspaceRole } from './workspace-members.js';
4
4
  /**
5
5
  * A `merger` agent's structured assessment of a pull request. Each axis is scored
@@ -620,6 +620,73 @@ export type ClassRulesByRole = v.InferOutput<typeof classRulesByRoleSchema>;
620
620
  */
621
621
  export declare const dryRunRolesSchema: v.ArraySchema<v.PicklistSchema<readonly ["admin", "member", "viewer"], undefined>, undefined>;
622
622
  export type DryRunRoles = v.InferOutput<typeof dryRunRolesSchema>;
623
+ /**
624
+ * The change classes a preset will LAND at all for a given role: a partial map from
625
+ * {@link workspaceRoleSchema} to the list of classes that role's runs may submit.
626
+ *
627
+ * This is the third role-scoped setting, and it answers a question neither of its siblings can.
628
+ * `classRulesByRole` with `never` routes a class to a human, but the human it routes to may be
629
+ * the initiator themselves: the review card carries a merge button and the RBAC write floor is
630
+ * `member`, so a member's run can raise its own card and land on the next tap. `dryRunRoles`
631
+ * closes that by refusing both exits, but only for EVERY class at once. Between them sits the
632
+ * thing a workspace most often wants to say: a product manager may land copy and dependency
633
+ * bumps on this service, and may not land source, however good the scores look.
634
+ *
635
+ * Three readings define it, and each is deliberate:
636
+ *
637
+ * - **An ALLOWLIST, never a denylist.** A class nobody thought about is OUTSIDE the list, so a
638
+ * class added to the vocabulary in a later release is refused for a scoped role rather than
639
+ * silently landed by it. Same safety property as {@link narrowMergeClassRule}: authoring one
640
+ * can subtract capability, never add it.
641
+ * - **Absent means UNRESTRICTED, not empty.** Silence is not an empty allowlist, exactly as an
642
+ * absent class is not a `thresholds` rule in {@link classRulesByRoleSchema}. Only a role
643
+ * somebody wrote an entry for is scoped, so `{}` is the identity the wire contract says it is
644
+ * (and an EMPTY array is a real, different policy: that role lands nothing).
645
+ * - **`unknown` is INERT.** An unreadable diff must not hold back a run that would otherwise
646
+ * have landed, the same reading `resolveMergeClassRule` takes: a VCS outage cannot change
647
+ * policy. This is the OPPOSITE direction from the first reading, and deliberately so: a class
648
+ * we have never heard of is a policy gap, while a class we could not READ is an outage, and
649
+ * only one of those is evidence about the change.
650
+ */
651
+ export declare const submissionClassesByRoleSchema: Omit<v.StrictObjectSchema<{
652
+ admin: v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>;
653
+ member: v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>;
654
+ viewer: v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>;
655
+ }, undefined>, "entries" | "~run" | "~standard" | "~types"> & {
656
+ readonly entries: {
657
+ admin: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>, undefined>;
658
+ member: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>, undefined>;
659
+ viewer: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>, undefined>;
660
+ };
661
+ readonly "~standard": v.StandardProps<{
662
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
663
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
664
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
665
+ }, {
666
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
667
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
668
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
669
+ }>;
670
+ readonly "~run": (dataset: v.UnknownDataset, config: v.Config<v.BaseIssue<unknown>>) => v.OutputDataset<{
671
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
672
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
673
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
674
+ }, v.ArrayIssue | v.PicklistIssue | v.StrictObjectIssue>;
675
+ readonly "~types"?: {
676
+ readonly input: {
677
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
678
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
679
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
680
+ };
681
+ readonly output: {
682
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
683
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
684
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
685
+ };
686
+ readonly issue: v.ArrayIssue | v.PicklistIssue | v.StrictObjectIssue;
687
+ } | undefined;
688
+ };
689
+ export type SubmissionClassesByRole = v.InferOutput<typeof submissionClassesByRoleSchema>;
623
690
  /**
624
691
  * Compose a base rule with a ROLE's rule, taking the STRICTER of the two.
625
692
  *
@@ -702,6 +769,30 @@ export declare function resolveRoleScopedMergeClassRule(input: {
702
769
  * re-decide what an absent role means.
703
770
  */
704
771
  export declare function dryRunForcedForRole(dryRunRoles: readonly WorkspaceRole[] | null | undefined, role: WorkspaceRole | null | undefined): boolean;
772
+ /**
773
+ * The allowlist that governs one run, or `undefined` when nothing does.
774
+ *
775
+ * Kept apart from {@link submissionAllowedForRole} because the two questions differ: "is this run
776
+ * scoped at all" decides whether the merge path owes a classification (one VCS call), and only
777
+ * then does "may it land THIS class" have anything to compare. Reading the boolean first and the
778
+ * verdict second is what keeps an unscoped preset paying for neither.
779
+ */
780
+ export declare function submissionAllowlistForRole(byRole: SubmissionClassesByRole | null | undefined, role: WorkspaceRole | null | undefined): readonly RuleableChangeClass[] | undefined;
781
+ /**
782
+ * Whether a preset lets a run started by `role` LAND a change of `changeClass`.
783
+ *
784
+ * Every absence answers `true`, and each for its own reason: no pinned role matches no entry, a
785
+ * role with no authored entry is unrestricted, and an `unknown` class is an unreadable diff
786
+ * rather than evidence about the change. Only a role that HAS an allowlist, on a diff that
787
+ * classified, can be refused, and then the list is exhaustive, so a class outside it is refused
788
+ * whether the operator excluded it on purpose or the vocabulary gained it after they wrote the
789
+ * policy.
790
+ *
791
+ * It lives in contracts, beside the map it reads, because the SPA has to state the same verdict:
792
+ * a merge control that offered to land a change the engine will refuse would be advertising a
793
+ * capability the person does not have.
794
+ */
795
+ export declare function submissionAllowedForRole(byRole: SubmissionClassesByRole | null | undefined, role: WorkspaceRole | null | undefined, changeClass: ChangeClass): boolean;
705
796
  export declare const mergeAssessmentSchema: v.ObjectSchema<{
706
797
  /** How intricate the change is (size, coupling, subtlety). */
707
798
  readonly complexity: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>]>;
@@ -1373,6 +1464,51 @@ export declare const riskPolicySchema: v.ObjectSchema<{
1373
1464
  * and the PR opens, but nothing merges. Empty on the built-ins.
1374
1465
  */
1375
1466
  readonly dryRunRoles: v.ArraySchema<v.PicklistSchema<readonly ["admin", "member", "viewer"], undefined>, undefined>;
1467
+ /**
1468
+ * Per-ROLE allowlist of the change classes this preset will land at all
1469
+ * ({@link submissionClassesByRoleSchema}). Orthogonal to `classRulesByRole`, and both apply: a
1470
+ * class may be `always` under the role's class rules and still outside its allowlist, and the
1471
+ * allowlist wins, because it bars landing rather than deciding how much review landing takes.
1472
+ * A role with no entry is unrestricted, so `{}` is the identity. Empty on the built-ins.
1473
+ */
1474
+ readonly submissionClassesByRole: Omit<v.StrictObjectSchema<{
1475
+ admin: v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>;
1476
+ member: v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>;
1477
+ viewer: v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>;
1478
+ }, undefined>, "entries" | "~run" | "~standard" | "~types"> & {
1479
+ readonly entries: {
1480
+ admin: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>, undefined>;
1481
+ member: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>, undefined>;
1482
+ viewer: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>, undefined>;
1483
+ };
1484
+ readonly "~standard": v.StandardProps<{
1485
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1486
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1487
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1488
+ }, {
1489
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1490
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1491
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1492
+ }>;
1493
+ readonly "~run": (dataset: v.UnknownDataset, config: v.Config<v.BaseIssue<unknown>>) => v.OutputDataset<{
1494
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1495
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1496
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1497
+ }, v.ArrayIssue | v.PicklistIssue | v.StrictObjectIssue>;
1498
+ readonly "~types"?: {
1499
+ readonly input: {
1500
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1501
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1502
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1503
+ };
1504
+ readonly output: {
1505
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1506
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1507
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
1508
+ };
1509
+ readonly issue: v.ArrayIssue | v.PicklistIssue | v.StrictObjectIssue;
1510
+ } | undefined;
1511
+ };
1376
1512
  /** The workspace's fallback preset, used by tasks that pick none. Exactly one is true. */
1377
1513
  readonly isDefault: v.BooleanSchema<undefined>;
1378
1514
  /**
@@ -1964,6 +2100,45 @@ export declare const createRiskPolicySchema: v.ObjectSchema<{
1964
2100
  }, {}>;
1965
2101
  /** Roles whose runs are forced into dry-run mode; absent ⇒ nobody is sandboxed. */
1966
2102
  readonly dryRunRoles: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["admin", "member", "viewer"], undefined>, undefined>, readonly []>;
2103
+ /** Per-role allowlist of landable change classes; absent ⇒ every role is unrestricted. */
2104
+ readonly submissionClassesByRole: v.OptionalSchema<Omit<v.StrictObjectSchema<{
2105
+ admin: v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>;
2106
+ member: v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>;
2107
+ viewer: v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>;
2108
+ }, undefined>, "entries" | "~run" | "~standard" | "~types"> & {
2109
+ readonly entries: {
2110
+ admin: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>, undefined>;
2111
+ member: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>, undefined>;
2112
+ viewer: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>, undefined>;
2113
+ };
2114
+ readonly "~standard": v.StandardProps<{
2115
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2116
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2117
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2118
+ }, {
2119
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2120
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2121
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2122
+ }>;
2123
+ readonly "~run": (dataset: v.UnknownDataset, config: v.Config<v.BaseIssue<unknown>>) => v.OutputDataset<{
2124
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2125
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2126
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2127
+ }, v.ArrayIssue | v.PicklistIssue | v.StrictObjectIssue>;
2128
+ readonly "~types"?: {
2129
+ readonly input: {
2130
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2131
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2132
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2133
+ };
2134
+ readonly output: {
2135
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2136
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2137
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2138
+ };
2139
+ readonly issue: v.ArrayIssue | v.PicklistIssue | v.StrictObjectIssue;
2140
+ } | undefined;
2141
+ }, {}>;
1967
2142
  /** Make this the workspace default (demotes the previous default). */
1968
2143
  readonly isDefault: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
1969
2144
  }, undefined>;
@@ -2545,6 +2720,45 @@ export declare const updateRiskPolicySchema: v.ObjectSchema<{
2545
2720
  }, undefined>;
2546
2721
  /** Replaces the whole list, so un-sandboxing a role is a plain omission. */
2547
2722
  readonly dryRunRoles: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["admin", "member", "viewer"], undefined>, undefined>, undefined>;
2723
+ /** Replaces the whole map, so un-scoping a role is a plain omission (never an empty array). */
2724
+ readonly submissionClassesByRole: v.OptionalSchema<Omit<v.StrictObjectSchema<{
2725
+ admin: v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>;
2726
+ member: v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>;
2727
+ viewer: v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>;
2728
+ }, undefined>, "entries" | "~run" | "~standard" | "~types"> & {
2729
+ readonly entries: {
2730
+ admin: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>, undefined>;
2731
+ member: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>, undefined>;
2732
+ viewer: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>, undefined>;
2733
+ };
2734
+ readonly "~standard": v.StandardProps<{
2735
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2736
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2737
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2738
+ }, {
2739
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2740
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2741
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2742
+ }>;
2743
+ readonly "~run": (dataset: v.UnknownDataset, config: v.Config<v.BaseIssue<unknown>>) => v.OutputDataset<{
2744
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2745
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2746
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2747
+ }, v.ArrayIssue | v.PicklistIssue | v.StrictObjectIssue>;
2748
+ readonly "~types"?: {
2749
+ readonly input: {
2750
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2751
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2752
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2753
+ };
2754
+ readonly output: {
2755
+ admin?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2756
+ member?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2757
+ viewer?: ("config" | "dependency" | "docs" | "schema" | "source" | "test")[] | undefined;
2758
+ };
2759
+ readonly issue: v.ArrayIssue | v.PicklistIssue | v.StrictObjectIssue;
2760
+ } | undefined;
2761
+ }, undefined>;
2548
2762
  readonly isDefault: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
2549
2763
  }, undefined>;
2550
2764
  export type UpdateRiskPolicyInput = v.InferOutput<typeof updateRiskPolicySchema>;
@@ -2583,6 +2797,17 @@ export declare const mergeDecisionThresholdsSchema: v.ObjectSchema<{
2583
2797
  * someone else".
2584
2798
  */
2585
2799
  readonly roleRule: v.OptionalSchema<v.PicklistSchema<readonly ["thresholds", "always", "never"], undefined>, undefined>;
2800
+ /**
2801
+ * The change classes the initiator's role may land at all, recorded whenever that role carried
2802
+ * a submission allowlist, not only when the allowlist is what held the PR back.
2803
+ *
2804
+ * Present-means-scoped is the useful reading here (the opposite of `roleRule` above, which is
2805
+ * recorded only when it changed the outcome): an allowlist that PERMITTED this class is the
2806
+ * fact that explains why an otherwise identical PR on another class will not land, and a
2807
+ * banner that mentioned the scope only on the refusal would make the permission look like an
2808
+ * absence of policy.
2809
+ */
2810
+ readonly submissionClasses: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>, undefined>;
2586
2811
  }, undefined>;
2587
2812
  export type MergeDecisionThresholds = v.InferOutput<typeof mergeDecisionThresholdsSchema>;
2588
2813
  export declare const mergeDecisionSchema: v.ObjectSchema<{
@@ -2611,12 +2836,18 @@ export declare const mergeDecisionSchema: v.ObjectSchema<{
2611
2836
  * `class_requires_review` because the two need opposite fixes: one is a policy about the
2612
2837
  * KIND of change (edit the class rule), the other about WHO started it (a teammate on a
2613
2838
  * higher tier can merge this PR as it stands).
2839
+ * - `submission_not_allowed`: review; the initiator's role carries a submission allowlist and
2840
+ * this run's change class is outside it, so the platform will not land the work whatever the
2841
+ * scores or the class rules say. Kept apart from `role_requires_review` because the remedies
2842
+ * differ in kind: that one is satisfied by ANY reviewer merging the PR through this
2843
+ * platform, while this one refuses the platform merge path outright (the PR is still a real
2844
+ * PR, and someone with write access on the host can merge it there).
2614
2845
  * - `dry_run`: review; the run was a DRY RUN, so no outcome of the assessment could have
2615
2846
  * merged it. The master switch above every other reason, including `auto_merge_disabled`:
2616
2847
  * a preset that would otherwise auto-merge must not report a dry run's PR as "held back by
2617
2848
  * the scores", which would send someone editing thresholds that were never consulted.
2618
2849
  */
2619
- readonly reason: v.PicklistSchema<["within_thresholds", "exceeded_thresholds", "auto_merge_disabled", "no_rationale", "no_assessment", "merge_failed", "merge_partial", "class_auto_merge", "class_requires_review", "role_requires_review", "dry_run"], undefined>;
2850
+ readonly reason: v.PicklistSchema<["within_thresholds", "exceeded_thresholds", "auto_merge_disabled", "no_rationale", "no_assessment", "merge_failed", "merge_partial", "class_auto_merge", "class_requires_review", "role_requires_review", "submission_not_allowed", "dry_run"], undefined>;
2620
2851
  /** The merger's assessment (absent only when it produced no parseable one). */
2621
2852
  readonly assessment: v.OptionalSchema<v.ObjectSchema<{
2622
2853
  /** How intricate the change is (size, coupling, subtlety). */
@@ -2657,6 +2888,17 @@ export declare const mergeDecisionSchema: v.ObjectSchema<{
2657
2888
  * someone else".
2658
2889
  */
2659
2890
  readonly roleRule: v.OptionalSchema<v.PicklistSchema<readonly ["thresholds", "always", "never"], undefined>, undefined>;
2891
+ /**
2892
+ * The change classes the initiator's role may land at all, recorded whenever that role carried
2893
+ * a submission allowlist, not only when the allowlist is what held the PR back.
2894
+ *
2895
+ * Present-means-scoped is the useful reading here (the opposite of `roleRule` above, which is
2896
+ * recorded only when it changed the outcome): an allowlist that PERMITTED this class is the
2897
+ * fact that explains why an otherwise identical PR on another class will not land, and a
2898
+ * banner that mentioned the scope only on the refusal would make the permission look like an
2899
+ * absence of policy.
2900
+ */
2901
+ readonly submissionClasses: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["docs", "test", "dependency", "config", "source", "schema"], undefined>, undefined>, undefined>;
2660
2902
  }, undefined>;
2661
2903
  /** The axes that exceeded their ceiling (empty unless `reason` is `exceeded_thresholds`). */
2662
2904
  readonly exceededAxes: v.ArraySchema<v.PicklistSchema<["complexity", "risk", "impact"], undefined>, undefined>;
@@ -1 +1 @@
1
- {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"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"}
package/dist/merge.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as v from 'valibot';
2
2
  import { stepGatingSchema } from './consensus.js';
3
- import { changeClassSchema, RULEABLE_CHANGE_CLASSES } from './mergeTrackRecord.js';
3
+ import { changeClassSchema, RULEABLE_CHANGE_CLASSES, } from './mergeTrackRecord.js';
4
4
  import { DEFAULT_JUDGE_MAX_BOUNCES, DEFAULT_JUDGE_MIN_SCORE } from './judge.js';
5
5
  import { WORKSPACE_ROLES, workspaceRoleSchema } from './workspace-members.js';
6
6
  // ---------------------------------------------------------------------------
@@ -101,6 +101,40 @@ v.strictObject(Object.fromEntries(WORKSPACE_ROLES.map((r) => [r, mergeClassRules
101
101
  * cannot start runs at all (`viewer`, which holds no `runs.execute`) may be listed without effect.
102
102
  */
103
103
  export const dryRunRolesSchema = v.array(workspaceRoleSchema);
104
+ /** A picklist over the classes a rule (or an allowlist entry) may be authored for. */
105
+ const ruleableChangeClassSchema = v.picklist(RULEABLE_CHANGE_CLASSES);
106
+ /**
107
+ * The change classes a preset will LAND at all for a given role: a partial map from
108
+ * {@link workspaceRoleSchema} to the list of classes that role's runs may submit.
109
+ *
110
+ * This is the third role-scoped setting, and it answers a question neither of its siblings can.
111
+ * `classRulesByRole` with `never` routes a class to a human, but the human it routes to may be
112
+ * the initiator themselves: the review card carries a merge button and the RBAC write floor is
113
+ * `member`, so a member's run can raise its own card and land on the next tap. `dryRunRoles`
114
+ * closes that by refusing both exits, but only for EVERY class at once. Between them sits the
115
+ * thing a workspace most often wants to say: a product manager may land copy and dependency
116
+ * bumps on this service, and may not land source, however good the scores look.
117
+ *
118
+ * Three readings define it, and each is deliberate:
119
+ *
120
+ * - **An ALLOWLIST, never a denylist.** A class nobody thought about is OUTSIDE the list, so a
121
+ * class added to the vocabulary in a later release is refused for a scoped role rather than
122
+ * silently landed by it. Same safety property as {@link narrowMergeClassRule}: authoring one
123
+ * can subtract capability, never add it.
124
+ * - **Absent means UNRESTRICTED, not empty.** Silence is not an empty allowlist, exactly as an
125
+ * absent class is not a `thresholds` rule in {@link classRulesByRoleSchema}. Only a role
126
+ * somebody wrote an entry for is scoped, so `{}` is the identity the wire contract says it is
127
+ * (and an EMPTY array is a real, different policy: that role lands nothing).
128
+ * - **`unknown` is INERT.** An unreadable diff must not hold back a run that would otherwise
129
+ * have landed, the same reading `resolveMergeClassRule` takes: a VCS outage cannot change
130
+ * policy. This is the OPPOSITE direction from the first reading, and deliberately so: a class
131
+ * we have never heard of is a policy gap, while a class we could not READ is an outage, and
132
+ * only one of those is evidence about the change.
133
+ */
134
+ export const submissionClassesByRoleSchema = v.partial(
135
+ // STRICT for the same reason both rule maps are: a caller who thinks they authored an
136
+ // allowlist must not be told it worked when the role name was a typo.
137
+ v.strictObject(Object.fromEntries(WORKSPACE_ROLES.map((r) => [r, v.array(ruleableChangeClassSchema)]))));
104
138
  /**
105
139
  * How much review a rule DEMANDS, higher is stricter. The ordering is the point of the scale:
106
140
  * `always` merges with nothing consulted, `thresholds` merges only within the score ceilings, and
@@ -204,6 +238,42 @@ export function resolveRoleScopedMergeClassRule(input) {
204
238
  export function dryRunForcedForRole(dryRunRoles, role) {
205
239
  return !!role && !!dryRunRoles?.includes(role);
206
240
  }
241
+ /**
242
+ * The allowlist that governs one run, or `undefined` when nothing does.
243
+ *
244
+ * Kept apart from {@link submissionAllowedForRole} because the two questions differ: "is this run
245
+ * scoped at all" decides whether the merge path owes a classification (one VCS call), and only
246
+ * then does "may it land THIS class" have anything to compare. Reading the boolean first and the
247
+ * verdict second is what keeps an unscoped preset paying for neither.
248
+ */
249
+ export function submissionAllowlistForRole(byRole, role) {
250
+ // A run with no pinned role matches no entry, exactly as `dryRunForcedForRole` reads one: a
251
+ // schedule fire / public-API start / auth-disabled dev is not a tier, and treating it as one
252
+ // would scope every unattributed run in a deployment the day somebody first scopes a role.
253
+ if (!role)
254
+ return undefined;
255
+ return byRole?.[role];
256
+ }
257
+ /**
258
+ * Whether a preset lets a run started by `role` LAND a change of `changeClass`.
259
+ *
260
+ * Every absence answers `true`, and each for its own reason: no pinned role matches no entry, a
261
+ * role with no authored entry is unrestricted, and an `unknown` class is an unreadable diff
262
+ * rather than evidence about the change. Only a role that HAS an allowlist, on a diff that
263
+ * classified, can be refused, and then the list is exhaustive, so a class outside it is refused
264
+ * whether the operator excluded it on purpose or the vocabulary gained it after they wrote the
265
+ * policy.
266
+ *
267
+ * It lives in contracts, beside the map it reads, because the SPA has to state the same verdict:
268
+ * a merge control that offered to land a change the engine will refuse would be advertising a
269
+ * capability the person does not have.
270
+ */
271
+ export function submissionAllowedForRole(byRole, role, changeClass) {
272
+ if (changeClass === 'unknown')
273
+ return true;
274
+ const allowed = submissionAllowlistForRole(byRole, role);
275
+ return !allowed || allowed.includes(changeClass);
276
+ }
207
277
  export const mergeAssessmentSchema = v.object({
208
278
  /** How intricate the change is (size, coupling, subtlety). */
209
279
  complexity: v.pipe(v.number(), v.minValue(0), v.maxValue(1)),
@@ -320,6 +390,14 @@ export const riskPolicySchema = v.object({
320
390
  * and the PR opens, but nothing merges. Empty on the built-ins.
321
391
  */
322
392
  dryRunRoles: dryRunRolesSchema,
393
+ /**
394
+ * Per-ROLE allowlist of the change classes this preset will land at all
395
+ * ({@link submissionClassesByRoleSchema}). Orthogonal to `classRulesByRole`, and both apply: a
396
+ * class may be `always` under the role's class rules and still outside its allowlist, and the
397
+ * allowlist wins, because it bars landing rather than deciding how much review landing takes.
398
+ * A role with no entry is unrestricted, so `{}` is the identity. Empty on the built-ins.
399
+ */
400
+ submissionClassesByRole: submissionClassesByRoleSchema,
323
401
  /** The workspace's fallback preset, used by tasks that pick none. Exactly one is true. */
324
402
  isDefault: v.boolean(),
325
403
  /**
@@ -365,6 +443,8 @@ export const createRiskPolicySchema = v.object({
365
443
  classRulesByRole: v.optional(classRulesByRoleSchema, {}),
366
444
  /** Roles whose runs are forced into dry-run mode; absent ⇒ nobody is sandboxed. */
367
445
  dryRunRoles: v.optional(dryRunRolesSchema, []),
446
+ /** Per-role allowlist of landable change classes; absent ⇒ every role is unrestricted. */
447
+ submissionClassesByRole: v.optional(submissionClassesByRoleSchema, {}),
368
448
  /** Make this the workspace default (demotes the previous default). */
369
449
  isDefault: v.optional(v.boolean(), false),
370
450
  });
@@ -391,6 +471,8 @@ export const updateRiskPolicySchema = v.object({
391
471
  classRulesByRole: v.optional(classRulesByRoleSchema),
392
472
  /** Replaces the whole list, so un-sandboxing a role is a plain omission. */
393
473
  dryRunRoles: v.optional(dryRunRolesSchema),
474
+ /** Replaces the whole map, so un-scoping a role is a plain omission (never an empty array). */
475
+ submissionClassesByRole: v.optional(submissionClassesByRoleSchema),
394
476
  isDefault: v.optional(v.boolean()),
395
477
  });
396
478
  /** Parse-or-throw an assessment payload an agent returned (the engine validates it). */
@@ -436,6 +518,17 @@ export const mergeDecisionThresholdsSchema = v.object({
436
518
  * someone else".
437
519
  */
438
520
  roleRule: v.optional(mergeClassRuleSchema),
521
+ /**
522
+ * The change classes the initiator's role may land at all, recorded whenever that role carried
523
+ * a submission allowlist, not only when the allowlist is what held the PR back.
524
+ *
525
+ * Present-means-scoped is the useful reading here (the opposite of `roleRule` above, which is
526
+ * recorded only when it changed the outcome): an allowlist that PERMITTED this class is the
527
+ * fact that explains why an otherwise identical PR on another class will not land, and a
528
+ * banner that mentioned the scope only on the refusal would make the permission look like an
529
+ * absence of policy.
530
+ */
531
+ submissionClasses: v.optional(v.array(ruleableChangeClassSchema)),
439
532
  });
440
533
  export const mergeDecisionSchema = v.object({
441
534
  /** What the engine did: merged the PR for real, or left it open for a human. */
@@ -463,6 +556,12 @@ export const mergeDecisionSchema = v.object({
463
556
  * `class_requires_review` because the two need opposite fixes: one is a policy about the
464
557
  * KIND of change (edit the class rule), the other about WHO started it (a teammate on a
465
558
  * higher tier can merge this PR as it stands).
559
+ * - `submission_not_allowed`: review; the initiator's role carries a submission allowlist and
560
+ * this run's change class is outside it, so the platform will not land the work whatever the
561
+ * scores or the class rules say. Kept apart from `role_requires_review` because the remedies
562
+ * differ in kind: that one is satisfied by ANY reviewer merging the PR through this
563
+ * platform, while this one refuses the platform merge path outright (the PR is still a real
564
+ * PR, and someone with write access on the host can merge it there).
466
565
  * - `dry_run`: review; the run was a DRY RUN, so no outcome of the assessment could have
467
566
  * merged it. The master switch above every other reason, including `auto_merge_disabled`:
468
567
  * a preset that would otherwise auto-merge must not report a dry run's PR as "held back by
@@ -479,6 +578,7 @@ export const mergeDecisionSchema = v.object({
479
578
  'class_auto_merge',
480
579
  'class_requires_review',
481
580
  'role_requires_review',
581
+ 'submission_not_allowed',
482
582
  'dry_run',
483
583
  ]),
484
584
  /** The merger's assessment (absent only when it produced no parseable one). */