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.
- checksums.yaml +4 -4
- data/examples/pizzas/bluebook/pizzas.bluebook +4 -4
- data/lib/hecks/adapters/driven/script_runner.adapter +3 -0
- data/lib/hecks/adapters/driven/script_runner.rb +93 -0
- data/lib/hecks/adapters/driven.rb +1 -0
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +15 -5
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +16 -12
- data/lib/hecks/bluebook/meta_validator.rb +28 -21
- data/lib/hecks/bluebook/named_pattern.rb +33 -0
- data/lib/hecks/bluebook.rb +1 -0
- data/lib/hecks/cli/domain_stub.rb +1 -1
- data/lib/hecks/cli/interview_aggregate.rb +4 -4
- data/lib/hecks/deploy/bluebook/deploy.bluebook +35 -35
- data/lib/hecks/framework/bluebook/change.behaviors +30 -0
- data/lib/hecks/framework/bluebook/change.bluebook +162 -0
- data/lib/hecks/framework/bluebook/change.hecksagon +21 -0
- data/lib/hecks/framework/change.oidc.json +34 -0
- data/lib/hecks/framework/console_settings.oidc.json +103 -0
- data/lib/hecks/framework/governance.oidc.json +28 -0
- data/lib/hecks/framework/identity.oidc.json +18 -0
- data/lib/hecks/framework/privacy.oidc.json +30 -0
- data/lib/hecks/fuzzing/domain_generator/block_rendering.rb +1 -1
- data/lib/hecks/gate/stages.yml +3 -0
- data/lib/hecks/grammar/translation.oidc.json +48 -0
- data/lib/hecks/hecks/adapters/codebase/test_runner.rb +12 -1
- data/lib/hecks/hecks/adapters/deploy_toolchain.rb +2 -1
- data/lib/hecks/hecks/codebase.bluebook +37 -37
- data/lib/hecks/hecks/custodian.bluebook +14 -14
- data/lib/hecks/hecks/hecks.bluebook +2 -2
- data/lib/hecks/hecks/rehearsal.bluebook +3 -3
- data/lib/hecks/hecks/tooling.bluebook +22 -22
- data/lib/hecks/language/bluebook/aggregate.bluebook +1 -0
- data/lib/hecks/language/bluebook/command.bluebook +1 -0
- data/lib/hecks/language/bluebook/entity.bluebook +1 -0
- data/lib/hecks/language/bluebook/query.bluebook +1 -0
- data/lib/hecks/language/bluebook/shape.bluebook +8 -7
- data/lib/hecks/language/hecksagon/port_operation.bluebook +1 -0
- data/lib/hecks/projections/deploy/fargate/cdn/lines.rb +12 -1
- data/lib/hecks/projections/site/admin_cms/templates/membership.rb +10 -7
- data/lib/hecks/projections/site/edge/behaviours.rb +10 -6
- data/lib/hecks/projections/site/edge/checks.rb +2 -0
- data/lib/hecks/projections/site/edge/function_checks.rb +104 -0
- data/lib/hecks/projections/site/edge/function_code.rb +86 -0
- data/lib/hecks/projections/site/edge/redirect_host.js.tmpl +65 -0
- data/lib/hecks/projections/site/edge.rb +35 -9
- data/lib/hecks/projections/site/site_cdn.rb +21 -7
- data/lib/hecks/projections/site/table/row_builder.rb +12 -2
- data/lib/hecks/projections/site/table.rb +4 -2
- data/lib/hecks/quality_control/quality_control.bluebook +51 -51
- data/lib/hecks/site/bluebook/site.bluebook +21 -6
- data/lib/hecks/sme/bluebook/sme.bluebook +12 -12
- data/lib/hecks/tickets/bluebook/tickets.bluebook +3 -3
- data/lib/hecks/tools/oidc_manifests.rb +44 -6
- data/lib/hecks/tools/site_routes/templates.rb +13 -9
- data/lib/hecks/version.rb +1 -1
- data/prebuilt/{d74a00e996222c1d8b676d5959092effc46b4dc59e0555f3bf9554ac58e3094a.marshal → 1a6f596be124228be93eba1d86dbc9d2933190fa389b284331241cb9f27115a0.marshal} +0 -0
- data/prebuilt/{9ee54e2f0d4d6d3fe046827779b221e02de665fba911a048ae5dd8b8fbfb7d90.marshal → a883a7e568667aa5ac904c82daff356bdf9e996252a36af6def4a4a43efb967e.marshal} +0 -0
- data/prebuilt/verdicts-872993b1aa26d73fe48f28251374b8585fed145d02aab42be0f00de386b6ff80.json +1 -0
- data/rust/host/HECKS_RELEASE +1 -1
- data/rust/host/src/auth.rs +58 -0
- data/rust/host/src/payments/roles.rs +159 -0
- data/rust/host/src/payments/tests.rs +25 -0
- data/rust/host/src/payments.rs +20 -11
- data/rust/host/src/platform_signin/session.rs +1 -1
- data/rust/parser/src/build/mod.rs +1 -0
- data/rust/parser/src/build/named_pattern.rs +23 -0
- data/rust/parser/src/keywords.rs +6 -0
- data/rust/parser/src/parse/mod.rs +22 -1
- metadata +24 -7
- data/prebuilt/verdicts-df19f35868d3284a70f55e42dcef87ef4e65e6a678e5135f72e1f6cff4c1357b.json +0 -1
- /data/lib/hecks/framework/{oidc.json → compliance.oidc.json} +0 -0
- /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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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
|
+
}
|