hecks 3.12.0 → 3.14.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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/examples/pizzas/bluebook/pizzas.bluebook +4 -4
  3. data/lib/hecks/adapters/driven/script_runner.adapter +3 -0
  4. data/lib/hecks/adapters/driven/script_runner.rb +93 -0
  5. data/lib/hecks/adapters/driven.rb +1 -0
  6. data/lib/hecks/bluebook/dsl/attribute_collector.rb +15 -5
  7. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +16 -12
  8. data/lib/hecks/bluebook/meta_validator.rb +28 -21
  9. data/lib/hecks/bluebook/named_pattern.rb +33 -0
  10. data/lib/hecks/bluebook.rb +1 -0
  11. data/lib/hecks/cli/domain_stub.rb +1 -1
  12. data/lib/hecks/cli/interview_aggregate.rb +4 -4
  13. data/lib/hecks/deploy/bluebook/deploy.bluebook +35 -35
  14. data/lib/hecks/framework/bluebook/change.behaviors +30 -0
  15. data/lib/hecks/framework/bluebook/change.bluebook +162 -0
  16. data/lib/hecks/framework/bluebook/change.hecksagon +21 -0
  17. data/lib/hecks/framework/change.oidc.json +34 -0
  18. data/lib/hecks/framework/console_settings.oidc.json +103 -0
  19. data/lib/hecks/framework/governance.oidc.json +28 -0
  20. data/lib/hecks/framework/identity.oidc.json +18 -0
  21. data/lib/hecks/framework/privacy.oidc.json +30 -0
  22. data/lib/hecks/fuzzing/domain_generator/block_rendering.rb +1 -1
  23. data/lib/hecks/gate/stages.yml +3 -0
  24. data/lib/hecks/grammar/translation.oidc.json +48 -0
  25. data/lib/hecks/hecks/adapters/codebase/test_runner.rb +12 -1
  26. data/lib/hecks/hecks/adapters/deploy_toolchain.rb +2 -1
  27. data/lib/hecks/hecks/codebase.bluebook +37 -37
  28. data/lib/hecks/hecks/custodian.bluebook +14 -14
  29. data/lib/hecks/hecks/hecks.bluebook +2 -2
  30. data/lib/hecks/hecks/rehearsal.bluebook +3 -3
  31. data/lib/hecks/hecks/tooling.bluebook +22 -22
  32. data/lib/hecks/language/bluebook/aggregate.bluebook +1 -0
  33. data/lib/hecks/language/bluebook/command.bluebook +1 -0
  34. data/lib/hecks/language/bluebook/entity.bluebook +1 -0
  35. data/lib/hecks/language/bluebook/query.bluebook +1 -0
  36. data/lib/hecks/language/bluebook/shape.bluebook +8 -7
  37. data/lib/hecks/language/hecksagon/port_operation.bluebook +1 -0
  38. data/lib/hecks/projections/deploy/fargate/cdn/lines.rb +12 -1
  39. data/lib/hecks/projections/site/admin_cms/templates/membership.rb +10 -7
  40. data/lib/hecks/projections/site/edge/behaviours.rb +10 -6
  41. data/lib/hecks/projections/site/edge/checks.rb +2 -0
  42. data/lib/hecks/projections/site/edge/function_checks.rb +104 -0
  43. data/lib/hecks/projections/site/edge/function_code.rb +86 -0
  44. data/lib/hecks/projections/site/edge/redirect_host.js.tmpl +65 -0
  45. data/lib/hecks/projections/site/edge.rb +35 -9
  46. data/lib/hecks/projections/site/site_cdn.rb +21 -7
  47. data/lib/hecks/projections/site/table/row_builder.rb +12 -2
  48. data/lib/hecks/projections/site/table.rb +4 -2
  49. data/lib/hecks/quality_control/quality_control.bluebook +51 -51
  50. data/lib/hecks/site/bluebook/site.bluebook +21 -6
  51. data/lib/hecks/sme/bluebook/sme.bluebook +12 -12
  52. data/lib/hecks/tickets/bluebook/tickets.bluebook +3 -3
  53. data/lib/hecks/tools/oidc_manifests.rb +44 -6
  54. data/lib/hecks/tools/site_routes/templates.rb +13 -9
  55. data/lib/hecks/version.rb +1 -1
  56. data/prebuilt/{d74a00e996222c1d8b676d5959092effc46b4dc59e0555f3bf9554ac58e3094a.marshal → 1a6f596be124228be93eba1d86dbc9d2933190fa389b284331241cb9f27115a0.marshal} +0 -0
  57. data/prebuilt/{9ee54e2f0d4d6d3fe046827779b221e02de665fba911a048ae5dd8b8fbfb7d90.marshal → a883a7e568667aa5ac904c82daff356bdf9e996252a36af6def4a4a43efb967e.marshal} +0 -0
  58. data/prebuilt/verdicts-872993b1aa26d73fe48f28251374b8585fed145d02aab42be0f00de386b6ff80.json +1 -0
  59. data/rust/host/HECKS_RELEASE +1 -1
  60. data/rust/host/src/auth.rs +58 -0
  61. data/rust/host/src/payments/roles.rs +159 -0
  62. data/rust/host/src/payments/tests.rs +25 -0
  63. data/rust/host/src/payments.rs +20 -11
  64. data/rust/host/src/platform_signin/session.rs +1 -1
  65. data/rust/parser/src/build/mod.rs +1 -0
  66. data/rust/parser/src/build/named_pattern.rs +23 -0
  67. data/rust/parser/src/keywords.rs +6 -0
  68. data/rust/parser/src/parse/mod.rs +22 -1
  69. metadata +24 -7
  70. data/prebuilt/verdicts-df19f35868d3284a70f55e42dcef87ef4e65e6a678e5135f72e1f6cff4c1357b.json +0 -1
  71. /data/lib/hecks/framework/{oidc.json → compliance.oidc.json} +0 -0
  72. /data/lib/hecks/grammar/{oidc.json → expression.oidc.json} +0 -0
@@ -451,7 +451,7 @@ Hecks.bluebook "Deploy" do
451
451
 
452
452
  # The domain's own directory on disk, where `environments/<slug>.world` is written.
453
453
  value_object "DirectoryPath" do
454
- attribute :value, String, pattern: '[^\t\n\r]'
454
+ attribute :value, String, matches: :not_empty
455
455
  end
456
456
 
457
457
  value_object "Report" do
@@ -581,14 +581,14 @@ Hecks.bluebook "Deploy" do
581
581
  identified_by :run
582
582
 
583
583
  value_object "RunKey" do
584
- attribute :value, String, pattern: '[^ \t\n\r]'
584
+ attribute :value, String, matches: :present
585
585
 
586
586
  invariant("a run is named") { !value.to_s.empty? }
587
587
  end
588
588
 
589
589
  # A domain directory, whose `bluebook/` holds the `.world` that declares `deployed_to`.
590
590
  value_object "DomainPath" do
591
- attribute :value, String, pattern: '[^\t\n\r]'
591
+ attribute :value, String, matches: :not_empty
592
592
 
593
593
  invariant("a domain is named by its path") { !value.to_s.empty? }
594
594
  end
@@ -604,7 +604,7 @@ Hecks.bluebook "Deploy" do
604
604
 
605
605
  # Where the recipe is written, for a domain that lives in a client's repository.
606
606
  value_object "Location" do
607
- attribute :value, String, pattern: '[^\t\n\r]'
607
+ attribute :value, String, matches: :not_empty
608
608
  end
609
609
 
610
610
  # An `environments/<name>.world` overlay of the domain, which must exist.
@@ -707,14 +707,14 @@ Hecks.bluebook "Deploy" do
707
707
  identified_by :run
708
708
 
709
709
  value_object "RunKey" do
710
- attribute :value, String, pattern: '[^ \t\n\r]'
710
+ attribute :value, String, matches: :present
711
711
 
712
712
  invariant("a run is named") { !value.to_s.empty? }
713
713
  end
714
714
 
715
715
  # A domain directory, whose `bluebook/` holds the `.world` that declares `deployed_to`.
716
716
  value_object "DomainPath" do
717
- attribute :value, String, pattern: '[^\t\n\r]'
717
+ attribute :value, String, matches: :not_empty
718
718
 
719
719
  invariant("a domain is named by its path") { !value.to_s.empty? }
720
720
  end
@@ -722,7 +722,7 @@ Hecks.bluebook "Deploy" do
722
722
  # A directory the cleared worlds are written to, at their paths below `bluebook/`, instead of
723
723
  # over the originals.
724
724
  value_object "Location" do
725
- attribute :value, String, pattern: '[^\t\n\r]'
725
+ attribute :value, String, matches: :not_empty
726
726
  end
727
727
 
728
728
  value_object "Report" do
@@ -813,14 +813,14 @@ Hecks.bluebook "Deploy" do
813
813
  identified_by :run
814
814
 
815
815
  value_object "RunKey" do
816
- attribute :value, String, pattern: '[^ \t\n\r]'
816
+ attribute :value, String, matches: :present
817
817
 
818
818
  invariant("a run is named") { !value.to_s.empty? }
819
819
  end
820
820
 
821
821
  # Makefile paths, comma separated; three generated fixture domains when absent.
822
822
  value_object "PathList" do
823
- attribute :value, String, pattern: '[^\t\n\r]'
823
+ attribute :value, String, matches: :not_empty
824
824
  end
825
825
 
826
826
  value_object "Report" do
@@ -909,7 +909,7 @@ Hecks.bluebook "Deploy" do
909
909
  identified_by :run
910
910
 
911
911
  value_object "RunKey" do
912
- attribute :value, String, pattern: '[^ \t\n\r]'
912
+ attribute :value, String, matches: :present
913
913
 
914
914
  invariant("a run is named") { !value.to_s.empty? }
915
915
  end
@@ -1020,13 +1020,13 @@ Hecks.bluebook "Deploy" do
1020
1020
  identified_by :run
1021
1021
 
1022
1022
  value_object "RunKey" do
1023
- attribute :value, String, pattern: '[^ \t\n\r]'
1023
+ attribute :value, String, matches: :present
1024
1024
 
1025
1025
  invariant("a run is named") { !value.to_s.empty? }
1026
1026
  end
1027
1027
 
1028
1028
  value_object "Location" do
1029
- attribute :value, String, pattern: '[^\t\n\r]'
1029
+ attribute :value, String, matches: :not_empty
1030
1030
 
1031
1031
  invariant("a project or script is named by its path") { !value.to_s.empty? }
1032
1032
  end
@@ -1159,13 +1159,13 @@ Hecks.bluebook "Deploy" do
1159
1159
  identified_by :run
1160
1160
 
1161
1161
  value_object "RunKey" do
1162
- attribute :value, String, pattern: '[^ \t\n\r]'
1162
+ attribute :value, String, matches: :present
1163
1163
 
1164
1164
  invariant("a run is named") { !value.to_s.empty? }
1165
1165
  end
1166
1166
 
1167
1167
  value_object "Location" do
1168
- attribute :value, String, pattern: '[^\t\n\r]'
1168
+ attribute :value, String, matches: :not_empty
1169
1169
 
1170
1170
  invariant("a project or script is named by its path") { !value.to_s.empty? }
1171
1171
  end
@@ -1187,7 +1187,7 @@ Hecks.bluebook "Deploy" do
1187
1187
 
1188
1188
  # A local image reference to push, as the script's LOCAL_IMAGE takes it.
1189
1189
  value_object "ImageName" do
1190
- attribute :value, String, pattern: '^[^ \t\n\r]+$'
1190
+ attribute :value, String, matches: :no_whitespace
1191
1191
  end
1192
1192
 
1193
1193
  value_object "Switch" do
@@ -1352,13 +1352,13 @@ Hecks.bluebook "Deploy" do
1352
1352
  identified_by :run
1353
1353
 
1354
1354
  value_object "RunKey" do
1355
- attribute :value, String, pattern: '[^ \t\n\r]'
1355
+ attribute :value, String, matches: :present
1356
1356
 
1357
1357
  invariant("a run is named") { !value.to_s.empty? }
1358
1358
  end
1359
1359
 
1360
1360
  value_object "Location" do
1361
- attribute :value, String, pattern: '[^\t\n\r]'
1361
+ attribute :value, String, matches: :not_empty
1362
1362
 
1363
1363
  invariant("a project or script is named by its path") { !value.to_s.empty? }
1364
1364
  end
@@ -1538,13 +1538,13 @@ Hecks.bluebook "Deploy" do
1538
1538
  identified_by :run
1539
1539
 
1540
1540
  value_object "RunKey" do
1541
- attribute :value, String, pattern: '[^ \t\n\r]'
1541
+ attribute :value, String, matches: :present
1542
1542
 
1543
1543
  invariant("a run is named") { !value.to_s.empty? }
1544
1544
  end
1545
1545
 
1546
1546
  value_object "Location" do
1547
- attribute :value, String, pattern: '[^\t\n\r]'
1547
+ attribute :value, String, matches: :not_empty
1548
1548
 
1549
1549
  invariant("a project or script is named by its path") { !value.to_s.empty? }
1550
1550
  end
@@ -1560,7 +1560,7 @@ Hecks.bluebook "Deploy" do
1560
1560
 
1561
1561
  # A Secrets Manager id or ARN; the script reads the password from it, so no value travels here.
1562
1562
  value_object "Secret" do
1563
- attribute :value, String, pattern: '^[^ \t\n\r]+$'
1563
+ attribute :value, String, matches: :no_whitespace
1564
1564
  end
1565
1565
 
1566
1566
  # A database's name; empty leaves it to the generated script's own default.
@@ -1826,13 +1826,13 @@ Hecks.bluebook "Deploy" do
1826
1826
  identified_by :run
1827
1827
 
1828
1828
  value_object "RunKey" do
1829
- attribute :value, String, pattern: '[^ \t\n\r]'
1829
+ attribute :value, String, matches: :present
1830
1830
 
1831
1831
  invariant("a run is named") { !value.to_s.empty? }
1832
1832
  end
1833
1833
 
1834
1834
  value_object "Location" do
1835
- attribute :value, String, pattern: '[^\t\n\r]'
1835
+ attribute :value, String, matches: :not_empty
1836
1836
 
1837
1837
  invariant("a project or script is named by its path") { !value.to_s.empty? }
1838
1838
  end
@@ -1846,7 +1846,7 @@ Hecks.bluebook "Deploy" do
1846
1846
  end
1847
1847
 
1848
1848
  value_object "Secret" do
1849
- attribute :value, String, pattern: '^[^ \t\n\r]+$'
1849
+ attribute :value, String, matches: :no_whitespace
1850
1850
  end
1851
1851
 
1852
1852
  # A database's name; empty leaves it to the generated script's own default.
@@ -1984,13 +1984,13 @@ Hecks.bluebook "Deploy" do
1984
1984
  identified_by :run
1985
1985
 
1986
1986
  value_object "RunKey" do
1987
- attribute :value, String, pattern: '[^ \t\n\r]'
1987
+ attribute :value, String, matches: :present
1988
1988
 
1989
1989
  invariant("a run is named") { !value.to_s.empty? }
1990
1990
  end
1991
1991
 
1992
1992
  value_object "Location" do
1993
- attribute :value, String, pattern: '[^\t\n\r]'
1993
+ attribute :value, String, matches: :not_empty
1994
1994
 
1995
1995
  invariant("a project, script or file is named by its path") { !value.to_s.empty? }
1996
1996
  end
@@ -2134,13 +2134,13 @@ Hecks.bluebook "Deploy" do
2134
2134
  identified_by :run
2135
2135
 
2136
2136
  value_object "RunKey" do
2137
- attribute :value, String, pattern: '[^ \t\n\r]'
2137
+ attribute :value, String, matches: :present
2138
2138
 
2139
2139
  invariant("a run is named") { !value.to_s.empty? }
2140
2140
  end
2141
2141
 
2142
2142
  value_object "Location" do
2143
- attribute :value, String, pattern: '[^\t\n\r]'
2143
+ attribute :value, String, matches: :not_empty
2144
2144
 
2145
2145
  invariant("a project or script is named by its path") { !value.to_s.empty? }
2146
2146
  end
@@ -2152,7 +2152,7 @@ Hecks.bluebook "Deploy" do
2152
2152
 
2153
2153
  # A git branch name. A preview is never of a production branch.
2154
2154
  value_object "Branch" do
2155
- attribute :value, String, pattern: '^[^ \t\n\r]+$'
2155
+ attribute :value, String, matches: :no_whitespace
2156
2156
 
2157
2157
  invariant("a preview is never of main or master") { value != "main" && value != "master" }
2158
2158
  end
@@ -2510,13 +2510,13 @@ Hecks.bluebook "Deploy" do
2510
2510
  identified_by :run
2511
2511
 
2512
2512
  value_object "RunKey" do
2513
- attribute :value, String, pattern: '[^ \t\n\r]'
2513
+ attribute :value, String, matches: :present
2514
2514
 
2515
2515
  invariant("a run is named") { !value.to_s.empty? }
2516
2516
  end
2517
2517
 
2518
2518
  value_object "Location" do
2519
- attribute :value, String, pattern: '[^\t\n\r]'
2519
+ attribute :value, String, matches: :not_empty
2520
2520
 
2521
2521
  invariant("a project or script is named by its path") { !value.to_s.empty? }
2522
2522
  end
@@ -2656,13 +2656,13 @@ Hecks.bluebook "Deploy" do
2656
2656
  identified_by :run
2657
2657
 
2658
2658
  value_object "RunKey" do
2659
- attribute :value, String, pattern: '[^ \t\n\r]'
2659
+ attribute :value, String, matches: :present
2660
2660
 
2661
2661
  invariant("a run is named") { !value.to_s.empty? }
2662
2662
  end
2663
2663
 
2664
2664
  value_object "Location" do
2665
- attribute :value, String, pattern: '[^\t\n\r]'
2665
+ attribute :value, String, matches: :not_empty
2666
2666
 
2667
2667
  invariant("a template is named by its path") { !value.to_s.empty? }
2668
2668
  end
@@ -2785,14 +2785,14 @@ Hecks.bluebook "Deploy" do
2785
2785
  identified_by :run
2786
2786
 
2787
2787
  value_object "RunKey" do
2788
- attribute :value, String, pattern: '[^ \t\n\r]'
2788
+ attribute :value, String, matches: :present
2789
2789
 
2790
2790
  invariant("a run is named") { !value.to_s.empty? }
2791
2791
  end
2792
2792
 
2793
2793
  # Domain directories, comma separated; every domain of the checkout when absent.
2794
2794
  value_object "DomainList" do
2795
- attribute :value, String, pattern: '[^\t\n\r]'
2795
+ attribute :value, String, matches: :not_empty
2796
2796
  end
2797
2797
 
2798
2798
  value_object "Report" do
@@ -2806,7 +2806,7 @@ Hecks.bluebook "Deploy" do
2806
2806
  end
2807
2807
 
2808
2808
  command "ProjectOidc" do
2809
- goal "Write each domain's OIDC client and scope manifest beside it as oidc.json"
2809
+ goal "Write each domain's OIDC client and scope manifest beside it: oidc.json, or one <chapter>.oidc.json for each chapter of a directory that holds several"
2810
2810
 
2811
2811
  attribute :domains, DomainList, optional: true
2812
2812
  attribute :run, RunKey
@@ -0,0 +1,30 @@
1
+ Hecks.behaviors "Change" do
2
+ vision "A change names its script, faults when that script cannot plan it, and is confirmed only from a plan."
3
+
4
+ loads "change.bluebook", "governance.bluebook", "change.hecksagon", "../../../../spec/fixtures/change/governance.hecksagon"
5
+
6
+ test "Request refuses a change that names no script" do
7
+ tests "Request", on: "Change"
8
+ input run: { value: "c1" }, script: { value: "" }
9
+ expect refused: "must match"
10
+ end
11
+
12
+ test "Request refuses a change that is not named" do
13
+ tests "Request", on: "Change"
14
+ input run: { value: "" }, script: { value: "rename" }
15
+ expect refused: "must match"
16
+ end
17
+
18
+ test "Request faults a change whose script nobody registered" do
19
+ tests "Request", on: "Change"
20
+ input run: { value: "c2" }, script: { value: "no_such_script" }
21
+ expect status: "faulted"
22
+ end
23
+
24
+ test "Confirm refuses a change that was never planned" do
25
+ tests "Confirm", on: "Change"
26
+ setup "Change::Change.Request", run: { value: "c3" }, script: { value: "no_such_script" }
27
+ input run: { value: "c3" }, digest: { value: "ab12" }
28
+ expect refused: "the digest confirmed is the digest planned"
29
+ end
30
+ end
@@ -0,0 +1,162 @@
1
+ Hecks.bluebook "Change" do
2
+ vision "A change you can preview: it is planned, shown, confirmed against exactly that plan, and only then carried out, whatever script it runs."
3
+ supporting
4
+
5
+ # A framework member like Governance and Identity: attach it with `attaches "Change"` in the
6
+ # consuming domain's own `.hecksagon`. The script is the port's adapter, so what a change
7
+ # does lives behind the `Script` port, and this chapter holds only how any change moves.
8
+ aggregate "Change" do
9
+ description "One change a script makes, previewed before it is carried out and applied only if its plan is unchanged."
10
+
11
+ attribute :run, RunKey
12
+ attribute :script, ScriptName
13
+ attribute :arguments, list_of(Argument), optional: true
14
+ attribute :plan, Report, optional: true
15
+ attribute :planned_digest, Digest, optional: true
16
+ attribute :report, Report, optional: true
17
+ attribute :refusal, Report, optional: true
18
+ identified_by :run
19
+
20
+ value_object "RunKey" do
21
+ attribute :value, String, matches: :present
22
+
23
+ invariant("a change is named") { !value.to_s.empty? }
24
+ end
25
+
26
+ # The name the script is registered under with the adapter.
27
+ value_object "ScriptName" do
28
+ attribute :value, String, matches: :present
29
+
30
+ invariant("a change names its script") { !value.to_s.empty? }
31
+ end
32
+
33
+ # One argument of the script, spelled as text; the script says what each key means.
34
+ value_object "Argument" do
35
+ attribute :key, String
36
+ attribute :value, String
37
+ end
38
+
39
+ value_object "Report" do
40
+ attribute :value, String
41
+ end
42
+
43
+ # A fingerprint of the plan, the script and its arguments: confirming one digest applies
44
+ # that plan and no other.
45
+ value_object "Digest" do
46
+ attribute :value, String, pattern: '[0-9a-f]+'
47
+
48
+ invariant("a plan has a digest") { !value.to_s.empty? }
49
+ end
50
+
51
+ lifecycle :status, default: "requested" do
52
+ mark :failure, "faulted"
53
+ transition "Plan" => "planned", from: "requested"
54
+ transition "Confirm" => "confirmed", from: "planned"
55
+ transition "Complete" => "applied", from: "confirmed"
56
+ transition "Fault" => "faulted", from: ["requested", "planned", "confirmed"]
57
+ end
58
+
59
+ command "Request" do
60
+ role "Maintainer"
61
+ goal "Ask for a change by naming its script and giving the script's arguments"
62
+
63
+ attribute :run, RunKey
64
+ attribute :script, ScriptName
65
+ attribute :arguments, list_of(Argument), optional: true
66
+
67
+ sets :run
68
+ sets :script
69
+ sets :arguments
70
+
71
+ emits ChangeRequested
72
+ end
73
+
74
+ command "Plan" do
75
+ role "System"
76
+ goal "Record what the script would do, and the digest that stands for it"
77
+
78
+ reference_to Change
79
+ attribute :plan, Report
80
+ attribute :digest, Digest
81
+
82
+ sets :plan
83
+ sets :planned_digest, to: :digest
84
+
85
+ emits ChangePlanned
86
+ end
87
+
88
+ command "Confirm" do
89
+ role "Maintainer"
90
+ goal "Agree to the plan shown, by naming its digest"
91
+
92
+ reference_to Change
93
+ attribute :digest, Digest
94
+
95
+ given("the digest confirmed is the digest planned") { digest.value == planned_digest.value }
96
+
97
+ emits ChangeConfirmed
98
+ end
99
+
100
+ command "Complete" do
101
+ role "System"
102
+ goal "Record that the confirmed plan was carried out, and what the script reported"
103
+
104
+ reference_to Change
105
+ attribute :report, Report
106
+
107
+ sets :report
108
+
109
+ emits ChangeApplied
110
+ end
111
+
112
+ command "Fault" do
113
+ role "System"
114
+ goal "Record that the change was refused or could not be carried out, and why"
115
+
116
+ reference_to Change
117
+ attribute :refusal, Report
118
+
119
+ sets :refusal
120
+
121
+ emits ChangeFaulted
122
+ end
123
+
124
+ query "Outcome" do
125
+ description "How one change stands: its status, its plan, and what it reported or why it failed."
126
+ attribute :run, RunKey
127
+ where(run: :run)
128
+ order_by :run
129
+ end
130
+
131
+ query "Faulted" do
132
+ description "Every change that was refused or could not be carried out."
133
+ where(status: "faulted")
134
+ order_by :run
135
+ end
136
+ end
137
+
138
+ policy "ExamineWhenRequested" do
139
+ on "Change.ChangeRequested"
140
+ trigger Change::Script::Examine, with: { run: :run }
141
+ end
142
+
143
+ policy "RecordThePlanWhenExamined" do
144
+ on "Change.ChangeExamined"
145
+ trigger Change::Plan, with: { plan: :plan, digest: :digest }
146
+ end
147
+
148
+ policy "PerformWhenConfirmed" do
149
+ on "Change.ChangeConfirmed"
150
+ trigger Change::Script::Perform, with: { run: :run }
151
+ end
152
+
153
+ policy "RecordTheOutcomeWhenPerformed" do
154
+ on "Change.ChangeAnswered"
155
+ trigger Change::Complete, with: { report: :report }
156
+ end
157
+
158
+ policy "RecordTheRefusal" do
159
+ on "Change.ChangeRefused"
160
+ trigger Change::Fault, with: { refusal: :refusal }
161
+ end
162
+ end
@@ -0,0 +1,21 @@
1
+ Hecks.hecksagon "Change" do
2
+ # `Change.Request` and `Change.Confirm` declare roles; same reason as Compliance.
3
+ attaches "Governance"
4
+ persisted_by "Memory"
5
+
6
+ # The change moves through two asks: `Examine` plans it, `Perform` carries it out. What a
7
+ # script does is the adapter's, so the chapter never names one.
8
+ Change::Change.port "Script" do
9
+ asks "Examine", to: Change do
10
+ attribute :run, RunKey
11
+ answers "ChangeExamined"
12
+ refuses "ChangeRefused"
13
+ end
14
+
15
+ asks "Perform", to: Change do
16
+ attribute :run, RunKey
17
+ answers "ChangeAnswered"
18
+ refuses "ChangeRefused"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ {
2
+ "audience": "Change",
3
+ "scopes": [
4
+ {
5
+ "scope": "change:change.complete",
6
+ "verb": "Change::Change.Complete",
7
+ "role": "System"
8
+ },
9
+ {
10
+ "scope": "change:change.confirm",
11
+ "verb": "Change::Change.Confirm",
12
+ "role": "Maintainer"
13
+ },
14
+ {
15
+ "scope": "change:change.fault",
16
+ "verb": "Change::Change.Fault",
17
+ "role": "System"
18
+ },
19
+ {
20
+ "scope": "change:change.plan",
21
+ "verb": "Change::Change.Plan",
22
+ "role": "System"
23
+ },
24
+ {
25
+ "scope": "change:change.request",
26
+ "verb": "Change::Change.Request",
27
+ "role": "Maintainer"
28
+ }
29
+ ],
30
+ "roles": [
31
+ "Maintainer",
32
+ "System"
33
+ ]
34
+ }
@@ -0,0 +1,103 @@
1
+ {
2
+ "audience": "ConsoleSettings",
3
+ "scopes": [
4
+ {
5
+ "scope": "console_settings:collection.declare",
6
+ "verb": "ConsoleSettings::Collection.Declare",
7
+ "role": "Console"
8
+ },
9
+ {
10
+ "scope": "console_settings:collection.replace_columns",
11
+ "verb": "ConsoleSettings::Collection.ReplaceColumns",
12
+ "role": "Console"
13
+ },
14
+ {
15
+ "scope": "console_settings:collection.replace_detail_field_columns",
16
+ "verb": "ConsoleSettings::Collection.ReplaceDetailFieldColumns",
17
+ "role": "Console"
18
+ },
19
+ {
20
+ "scope": "console_settings:collection.replace_detail_fields",
21
+ "verb": "ConsoleSettings::Collection.ReplaceDetailFields",
22
+ "role": "Console"
23
+ },
24
+ {
25
+ "scope": "console_settings:collection.replace_field_formats",
26
+ "verb": "ConsoleSettings::Collection.ReplaceFieldFormats",
27
+ "role": "Console"
28
+ },
29
+ {
30
+ "scope": "console_settings:collection.replace_preconditions",
31
+ "verb": "ConsoleSettings::Collection.ReplacePreconditions",
32
+ "role": "Console"
33
+ },
34
+ {
35
+ "scope": "console_settings:collection.set_extra",
36
+ "verb": "ConsoleSettings::Collection.SetExtra",
37
+ "role": "Console"
38
+ },
39
+ {
40
+ "scope": "console_settings:collection.set_identity",
41
+ "verb": "ConsoleSettings::Collection.SetIdentity",
42
+ "role": "Console"
43
+ },
44
+ {
45
+ "scope": "console_settings:collection.set_key",
46
+ "verb": "ConsoleSettings::Collection.SetKey",
47
+ "role": "Console"
48
+ },
49
+ {
50
+ "scope": "console_settings:collection.set_label",
51
+ "verb": "ConsoleSettings::Collection.SetLabel",
52
+ "role": "Console"
53
+ },
54
+ {
55
+ "scope": "console_settings:collection.set_list_query",
56
+ "verb": "ConsoleSettings::Collection.SetListQuery",
57
+ "role": "Console"
58
+ },
59
+ {
60
+ "scope": "console_settings:collection.set_nav_order",
61
+ "verb": "ConsoleSettings::Collection.SetNavOrder",
62
+ "role": "Console"
63
+ },
64
+ {
65
+ "scope": "console_settings:collection.set_primary_field",
66
+ "verb": "ConsoleSettings::Collection.SetPrimaryField",
67
+ "role": "Console"
68
+ },
69
+ {
70
+ "scope": "console_settings:overview.declare",
71
+ "verb": "ConsoleSettings::Overview.Declare",
72
+ "role": "Console"
73
+ },
74
+ {
75
+ "scope": "console_settings:overview.replace_stats",
76
+ "verb": "ConsoleSettings::Overview.ReplaceStats",
77
+ "role": "Console"
78
+ },
79
+ {
80
+ "scope": "console_settings:state_style.declare",
81
+ "verb": "ConsoleSettings::StateStyle.Declare",
82
+ "role": "Console"
83
+ },
84
+ {
85
+ "scope": "console_settings:state_style.set_attention",
86
+ "verb": "ConsoleSettings::StateStyle.SetAttention",
87
+ "role": "Console"
88
+ },
89
+ {
90
+ "scope": "console_settings:state_style.set_extra",
91
+ "verb": "ConsoleSettings::StateStyle.SetExtra",
92
+ "role": "Console"
93
+ },
94
+ {
95
+ "scope": "console_settings:state_style.set_tone",
96
+ "verb": "ConsoleSettings::StateStyle.SetTone",
97
+ "role": "Console"
98
+ }
99
+ ],
100
+ "roles": [
101
+ "Console"
102
+ ]
103
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "audience": "Governance",
3
+ "scopes": [
4
+ {
5
+ "scope": "governance:role_assignment.assign",
6
+ "verb": "Governance::RoleAssignment.Assign",
7
+ "role": "Governance administrator"
8
+ },
9
+ {
10
+ "scope": "governance:role_assignment.revoke",
11
+ "verb": "Governance::RoleAssignment.Revoke",
12
+ "role": "Governance administrator"
13
+ },
14
+ {
15
+ "scope": "governance:role_transition.grant",
16
+ "verb": "Governance::RoleTransition.Grant",
17
+ "role": "Governance administrator"
18
+ },
19
+ {
20
+ "scope": "governance:role_transition.revoke",
21
+ "verb": "Governance::RoleTransition.Revoke",
22
+ "role": "Governance administrator"
23
+ }
24
+ ],
25
+ "roles": [
26
+ "Governance administrator"
27
+ ]
28
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "audience": "Identity",
3
+ "scopes": [
4
+ {
5
+ "scope": "identity:external_identifier.link",
6
+ "verb": "Identity::ExternalIdentifier.Link",
7
+ "role": "Identity registrar"
8
+ },
9
+ {
10
+ "scope": "identity:identity.register",
11
+ "verb": "Identity::Identity.Register",
12
+ "role": "Identity registrar"
13
+ }
14
+ ],
15
+ "roles": [
16
+ "Identity registrar"
17
+ ]
18
+ }