hecks 3.2.0 → 3.3.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 (187) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hecks/bluebook/assembly/contracts.rb +2 -1
  3. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +1 -0
  4. data/lib/hecks/bluebook/dsl/command_builder.rb +2 -39
  5. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +3 -3
  6. data/lib/hecks/bluebook/dsl/need_word.rb +50 -0
  7. data/lib/hecks/bluebook/dsl/query_builder.rb +6 -1
  8. data/lib/hecks/bluebook/query.rb +8 -5
  9. data/lib/hecks/cli/check_era.rb +3 -39
  10. data/lib/hecks/cli/interview_draft.rb +86 -31
  11. data/lib/hecks/cli/interview_session.rb +77 -26
  12. data/lib/hecks/cli/interview_shape.rb +179 -0
  13. data/lib/hecks/doors/cli_runner.rb +14 -1
  14. data/lib/hecks/doors/launcher_options.rb +13 -3
  15. data/lib/hecks/doors/mcp_door.rb +16 -2
  16. data/lib/hecks/doors/mcp_door_scope.rb +45 -5
  17. data/lib/hecks/doors/mcp_guide_cache.rb +75 -0
  18. data/lib/hecks/doors.rb +1 -1
  19. data/lib/hecks/embryonaut_bluebook/manifest.rb +117 -0
  20. data/lib/hecks/embryonaut_bluebook/registry.rb +209 -0
  21. data/lib/hecks/embryonaut_bluebook/vendor.rb +1 -1
  22. data/lib/hecks/embryonaut_bluebook.rb +2 -0
  23. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +17 -1
  24. data/lib/hecks/fuzzing/qa_settings.rb +15 -34
  25. data/lib/hecks/gate/stages.yml +113 -8
  26. data/lib/hecks/hecks/adapters/codebase/regeneration.rb +10 -1
  27. data/lib/hecks/hecks/adapters/codebase/test_runner.rb +10 -2
  28. data/lib/hecks/hecks/adapters/first_admin.rb +108 -0
  29. data/lib/hecks/hecks/adapters/git.rb +59 -0
  30. data/lib/hecks/hecks/adapters/in_process_access.rb +25 -0
  31. data/lib/hecks/hecks/adapters/in_process_boot.rb +2 -0
  32. data/lib/hecks/hecks/adapters/rust_toolchain.rb +18 -3
  33. data/lib/hecks/hecks/adapters/rust_workspace.rb +1 -1
  34. data/lib/hecks/hecks/adapters/site_toolchain.rb +88 -11
  35. data/lib/hecks/hecks/codebase.behaviors +6 -0
  36. data/lib/hecks/hecks/codebase.bluebook +21 -0
  37. data/lib/hecks/hecks/custodian.behaviors +6 -0
  38. data/lib/hecks/hecks/custodian.bluebook +217 -0
  39. data/lib/hecks/hecks/hecks.hecksagon +24 -0
  40. data/lib/hecks/hecks/hecks.world +8 -3
  41. data/lib/hecks/hecks/site.world +5 -2
  42. data/lib/hecks/language/bluebook/query.bluebook +25 -0
  43. data/lib/hecks/language/bluebook/vocabulary.bluebook +220 -7
  44. data/lib/hecks/language/hecksagon/hecksagon.bluebook +1 -1
  45. data/lib/hecks/language/oidc.json +5 -0
  46. data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +3 -3
  47. data/lib/hecks/projections/deploy/box/hosting.rb +170 -0
  48. data/lib/hecks/projections/deploy/box/hosting_settings.rb +123 -0
  49. data/lib/hecks/projections/deploy/box/settings.rb +40 -6
  50. data/lib/hecks/projections/deploy/box/templates/deploy-box.sh.tmpl +2 -0
  51. data/lib/hecks/projections/deploy/box/templates/deploy-service.services-roll.part +33 -0
  52. data/lib/hecks/projections/deploy/box/templates/deploy-service.sh.tmpl +79 -0
  53. data/lib/hecks/projections/deploy/box/templates/deploy-service.taskdef-roll.part +77 -0
  54. data/lib/hecks/projections/deploy/box/templates/deploy-service.taskdef.part +12 -0
  55. data/lib/hecks/projections/deploy/box/templates/hosting.mk.tmpl +24 -0
  56. data/lib/hecks/projections/deploy/box/templates/render-compose-taskdef.sh.tmpl +17 -0
  57. data/lib/hecks/projections/deploy/box/templates/smoke-after-deploy.sh.tmpl +271 -0
  58. data/lib/hecks/projections/deploy/box.rb +28 -4
  59. data/lib/hecks/projections/deploy/fargate.rb +3 -3
  60. data/lib/hecks/projections/deploy/lambda.rb +8 -8
  61. data/lib/hecks/projections/model/deviations.rb +1 -1
  62. data/lib/hecks/projections/site/edge/behaviours.rb +5 -3
  63. data/lib/hecks/projections/site/edge/checks.rb +31 -5
  64. data/lib/hecks/projections/site/edge.rb +25 -11
  65. data/lib/hecks/projections/site/live_edge.rb +162 -0
  66. data/lib/hecks/projections/site/routes_ts.rb +50 -27
  67. data/lib/hecks/projections/site/site_cdn.rb +7 -4
  68. data/lib/hecks/projections/site/table/checks.rb +53 -7
  69. data/lib/hecks/projections/site/table/link_builder.rb +64 -0
  70. data/lib/hecks/projections/site/table/row_builder.rb +21 -6
  71. data/lib/hecks/projections/site/table.rb +16 -5
  72. data/lib/hecks/quality_control/adapters/git_pr.rb +0 -14
  73. data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +1 -1
  74. data/lib/hecks/quality_control/cli/qa_open_pr.rb +32 -16
  75. data/lib/hecks/quality_control/cli/qa_seed_angles.rb +2 -2
  76. data/lib/hecks/quality_control/cli/qa_seed_targets.rb +1 -2
  77. data/lib/hecks/quality_control/quality_control.bluebook +76 -124
  78. data/lib/hecks/runtime/interpreting.rb +3 -22
  79. data/lib/hecks/runtime/needs.rb +48 -0
  80. data/lib/hecks/runtime/query_interpreter.rb +3 -0
  81. data/lib/hecks/runtime/registry/verification.rb +3 -3
  82. data/lib/hecks/rust_build/host.rb +147 -0
  83. data/lib/hecks/rust_build/kernel_input.rb +51 -17
  84. data/lib/hecks/rust_build/project_rust/codegen_run.rb +0 -18
  85. data/lib/hecks/rust_build/project_rust.rb +7 -140
  86. data/lib/hecks/rust_build.rb +1 -0
  87. data/lib/hecks/site/bluebook/site.bluebook +80 -14
  88. data/lib/hecks/site/bluebook/site.ports.hecksagon +6 -0
  89. data/lib/hecks/sme/bluebook/sme.bluebook +128 -1
  90. data/lib/hecks/storehouse.rb +35 -1
  91. data/lib/hecks/tools/comment_style.rb +4 -2
  92. data/lib/hecks/tools/gate.rb +1 -1
  93. data/lib/hecks/tools/rust_comment_style.rb +2 -4
  94. data/lib/hecks/tools/site_routes.rb +69 -28
  95. data/lib/hecks/tools/tools_doc.rb +204 -0
  96. data/lib/hecks/tools.rb +1 -0
  97. data/lib/hecks/version.rb +1 -1
  98. data/lib/hecks/vocabulary.rb +152 -1
  99. data/lib/hecks.rb +1 -0
  100. data/qa/settings.yml +1 -2
  101. data/rust/build/src/lineage_pass.rs +31 -16
  102. data/rust/build/src/main.rs +4 -2
  103. data/rust/build/src/pipeline.rs +9 -20
  104. data/rust/codegen/src/attr.rs +1 -1
  105. data/rust/codegen/src/bridging.rs +8 -8
  106. data/rust/codegen/src/commands.rs +1 -1
  107. data/rust/codegen/src/constraints.rs +1 -1
  108. data/rust/codegen/src/dependency_planning.rs +1 -1
  109. data/rust/codegen/src/domain_generator.rs +2 -2
  110. data/rust/codegen/src/exemplar.rs +1 -1
  111. data/rust/codegen/src/expr_emitter.rs +1 -1
  112. data/rust/codegen/src/fielded.rs +1 -1
  113. data/rust/codegen/src/json.rs +214 -23
  114. data/rust/codegen/src/json_codec.rs +1 -1
  115. data/rust/codegen/src/literal.rs +6 -3
  116. data/rust/codegen/src/main.rs +23 -13
  117. data/rust/codegen/src/mutations.rs +1 -1
  118. data/rust/codegen/src/naming.rs +5 -3
  119. data/rust/codegen/src/optional_pass.rs +226 -0
  120. data/rust/codegen/src/ports.rs +1 -1
  121. data/rust/codegen/src/queries.rs +3 -3
  122. data/rust/codegen/src/reactions.rs +1 -1
  123. data/rust/codegen/src/read_models.rs +2 -2
  124. data/rust/codegen/src/reference_specs.rs +1 -1
  125. data/rust/codegen/src/registry.rs +4 -4
  126. data/rust/codegen/src/shared.rs +1 -1
  127. data/rust/{build → codegen}/src/sidecars.rs +9 -5
  128. data/rust/codegen/src/skip_reason.rs +1 -1
  129. data/rust/codegen/src/types.rs +4 -4
  130. data/rust/host/HECKS_RELEASE +1 -1
  131. data/rust/host/src/api.rs +1 -1
  132. data/rust/host/src/dispatch.rs +5 -0
  133. data/rust/host/src/needs.rs +193 -29
  134. data/rust/host/src/resend.rs +4 -4
  135. data/rust/host/src/ui_schema.rs +1 -1
  136. data/rust/parser/src/emit.rs +12 -0
  137. data/rust/parser/src/ir.rs +2 -0
  138. data/rust/parser/src/keywords.rs +2 -0
  139. data/rust/parser/src/main.rs +1 -0
  140. data/rust/parser/src/parse/command.rs +2 -44
  141. data/rust/parser/src/parse/mod.rs +1 -0
  142. data/rust/parser/src/parse/needs.rs +60 -0
  143. data/rust/parser/src/parse/query.rs +3 -0
  144. data/rust/src/exemplar/commands.rs +1 -1
  145. data/rust/src/exemplar/constraints.rs +1 -1
  146. data/rust/src/exemplar/fielded.rs +1 -1
  147. data/rust/src/exemplar/json.rs +1 -1
  148. data/rust/src/exemplar/mod.rs +1 -1
  149. data/rust/src/exemplar/mutations.rs +1 -1
  150. data/rust/src/exemplar/queries.rs +1 -1
  151. data/rust/src/exemplar/reactions.rs +1 -1
  152. data/rust/src/exemplar/read_models.rs +1 -1
  153. data/rust/src/exemplar/registry.rs +1 -1
  154. data/rust/src/exemplar/types.rs +1 -1
  155. data/rust/src/kernel/cli.rs +18 -8
  156. data/rust/src/kernel/needs.rs +104 -9
  157. data/rust/src/kernel/read_model.rs +1 -1
  158. data/rust/src/lib.rs +1 -1
  159. metadata +24 -30
  160. data/lib/hecks/rust_build/append_optionals.rb +0 -79
  161. data/lib/hecks/rust_build/rust_literal.rb +0 -33
  162. data/lib/hecks/three_zero/forms.yml +0 -127
  163. data/lib/hecks/three_zero.rb +0 -12
  164. data/rust/build/src/json.rs +0 -421
  165. data/rust/build/src/optional_pass.rs +0 -150
  166. data/rust/project/bridging.rb +0 -257
  167. data/rust/project/commands.rb +0 -877
  168. data/rust/project/constraints.rb +0 -86
  169. data/rust/project/dependency_planning.rb +0 -178
  170. data/rust/project/domain_generator.rb +0 -983
  171. data/rust/project/exemplar.rb +0 -148
  172. data/rust/project/expr_emitter.rb +0 -72
  173. data/rust/project/fielded.rb +0 -141
  174. data/rust/project/json_codec.rb +0 -641
  175. data/rust/project/mutations.rb +0 -695
  176. data/rust/project/naming.rb +0 -223
  177. data/rust/project/ports.rb +0 -65
  178. data/rust/project/queries.rb +0 -493
  179. data/rust/project/reactions.rb +0 -317
  180. data/rust/project/read_models.rb +0 -690
  181. data/rust/project/reference_specs.rb +0 -27
  182. data/rust/project/registry.rb +0 -396
  183. data/rust/project/skip_reason.rb +0 -29
  184. data/rust/project/types.rb +0 -225
  185. data/rust/project/write_if_changed.rb +0 -7
  186. data/rust/project.rb +0 -30
  187. data/rust/project_rust_pipeline.rb +0 -391
@@ -238,6 +238,9 @@ Hecks.bluebook "Hecks" do
238
238
  attribute :payload_file, PayloadFile, optional: true
239
239
  attribute :health_path, RoutePath, optional: true
240
240
  attribute :state_path, RoutePath, optional: true
241
+ attribute :email, Email, optional: true
242
+ attribute :name, PersonName, optional: true
243
+ attribute :role, RoleName, optional: true
241
244
  attribute :output, Output, optional: true
242
245
  attribute :refusal, Output, optional: true
243
246
  identified_by :run
@@ -294,6 +297,19 @@ Hecks.bluebook "Hecks" do
294
297
  attribute :value, String
295
298
  end
296
299
 
300
+ # Who the first administrator is: a person of the domain's membership chapter.
301
+ value_object "Email" do
302
+ attribute :value, String, pattern: '^[^ \t\n\r@]+@[^ \t\n\r@]+$'
303
+ end
304
+
305
+ value_object "PersonName" do
306
+ attribute :value, String, pattern: '[^\t\n\r]'
307
+ end
308
+
309
+ value_object "RoleName" do
310
+ attribute :value, String, pattern: '^[^ \t\n\r]+$'
311
+ end
312
+
297
313
  lifecycle :status, default: "requested" do
298
314
  transition "Succeed" => "succeeded", from: "requested"
299
315
  transition "Fail" => "failed", from: "requested"
@@ -404,6 +420,32 @@ Hecks.bluebook "Hecks" do
404
420
  emits SmokeHttpRequested
405
421
  end
406
422
 
423
+ # `hecks operation.bootstrap_admin <domain> email=<email> [name=<name>] [role=<role>]`. A
424
+ # domain whose chapter `provides "membership"` has nobody who may grant access until someone is
425
+ # granted it. This admits the person and grants them the role the grant command is gated to
426
+ # (or `role`), as a caller that names that role and binds no `actor_id`: Governance checks that
427
+ # caller by the role it states, which is how the first grant gets made (ADR 0025). It is
428
+ # refused once anyone holds the administrator role (`Admin`, or `Owner`), and the domain's
429
+ # persistence must be the one the service runs on (`DATABASE_URL`), not Memory.
430
+ command "BootstrapAdmin" do
431
+ role "Operator"
432
+ goal "Admit the first administrator of a domain's membership chapter and grant them access"
433
+
434
+ attribute :run, OperationKey
435
+ attribute :subject, Subject
436
+ attribute :email, Email
437
+ attribute :name, PersonName, optional: true
438
+ attribute :role, RoleName, optional: true
439
+
440
+ sets :run
441
+ sets :subject
442
+ sets :email
443
+ sets :name
444
+ sets :role
445
+
446
+ emits AdminBootstrapRequested
447
+ end
448
+
407
449
  command "Succeed" do
408
450
  role "System"
409
451
  goal "Record that the operation ended well, and what it reported"
@@ -494,6 +536,11 @@ Hecks.bluebook "Hecks" do
494
536
  trigger Operation::DomainRuntime::Smoke, with: { run: :run }
495
537
  end
496
538
 
539
+ policy "BootstrapWhenRequested" do
540
+ on "Operation.AdminBootstrapRequested"
541
+ trigger Operation::DomainRuntime::Bootstrap, with: { run: :run }
542
+ end
543
+
497
544
  policy "OpenWhenRequested" do
498
545
  on "Operation.ConsoleRequested"
499
546
  trigger Operation::Terminal::Open, with: { run: :run }
@@ -1173,6 +1220,11 @@ policy "RecordTheEra" do
1173
1220
  attribute :value, String
1174
1221
  end
1175
1222
 
1223
+ # An answer that is one document of text, exactly as the tool that produced it wrote it.
1224
+ value_object "Document" do
1225
+ attribute :text, String
1226
+ end
1227
+
1176
1228
  lifecycle :status, default: "requested" do
1177
1229
  transition "Revendor" => "requested", from: %w[vendored refused]
1178
1230
  transition "Complete" => "vendored", from: "requested"
@@ -1248,6 +1300,14 @@ policy "RecordTheEra" do
1248
1300
  where(status: "refused")
1249
1301
  order_by :package
1250
1302
  end
1303
+
1304
+ # `hecks package.verify [root=path]`: a read of the files, so it keeps no record. The manifest
1305
+ # is the answer; a package that disagrees with its lock refuses it, naming each one.
1306
+ query "Verify" do
1307
+ description "Check every vendored package against its bluebook.lock, then describe them as the manifest a client image carries."
1308
+ attribute :root, Location, optional: true
1309
+ returns Document
1310
+ end
1251
1311
  end
1252
1312
 
1253
1313
  policy "PinWhenVendored" do
@@ -1270,6 +1330,125 @@ policy "RecordTheEra" do
1270
1330
  trigger Package::Abandon, with: { refusal: :refusal }
1271
1331
  end
1272
1332
 
1333
+ aggregate "Registry" do
1334
+ description "A bluebook registry repository: packages versioned in it and released as tags."
1335
+
1336
+ attribute :run, RegistryKey
1337
+ attribute :package, PackageName, optional: true
1338
+ attribute :root, Location, optional: true
1339
+ attribute :report, Report, optional: true
1340
+ attribute :refusal, Report, optional: true
1341
+ identified_by :run
1342
+
1343
+ value_object "RegistryKey" do
1344
+ attribute :value, String, pattern: '[^ \t\n\r]'
1345
+
1346
+ invariant("a release is named") { !value.to_s.empty? }
1347
+ end
1348
+
1349
+ value_object "PackageName" do
1350
+ attribute :value, String, pattern: '^[a-z][a-z0-9_]*$'
1351
+ end
1352
+
1353
+ # The registry repository: the current directory when absent.
1354
+ value_object "Location" do
1355
+ attribute :value, String, pattern: '[^\t\n\r]'
1356
+ end
1357
+
1358
+ value_object "Report" do
1359
+ attribute :value, String
1360
+ end
1361
+
1362
+ # An answer that is one document of text, exactly as the tool that produced it wrote it.
1363
+ value_object "Document" do
1364
+ attribute :text, String
1365
+ end
1366
+
1367
+ lifecycle :status, default: "requested" do
1368
+ transition "Complete" => "tagged", from: "requested"
1369
+ transition "Abandon" => "refused", from: "requested"
1370
+ end
1371
+
1372
+ # `hecks package.release <package> [root=path]`. Tags the package's current version as
1373
+ # `<package>-vX.Y.Z` in the local repository and never pushes; the report ends in the command
1374
+ # that does. A refusal says which rule the package broke.
1375
+ command "Release" do
1376
+ role "Operator"
1377
+ goal "Tag a package of this registry at the version its bluebook.yml carries"
1378
+
1379
+ attribute :run, RegistryKey
1380
+ attribute :package, PackageName
1381
+ attribute :root, Location, optional: true
1382
+
1383
+ sets :run
1384
+ sets :package
1385
+ sets :root
1386
+
1387
+ emits ReleaseRequested
1388
+ end
1389
+
1390
+ command "Complete" do
1391
+ role "System"
1392
+ goal "Record that the release was tagged, and the command that publishes it"
1393
+
1394
+ reference_to Registry
1395
+ attribute :report, Report
1396
+
1397
+ sets :report
1398
+
1399
+ emits ReleaseRecorded
1400
+ end
1401
+
1402
+ command "Abandon" do
1403
+ role "System"
1404
+ goal "Record that the release was refused, and why"
1405
+
1406
+ reference_to Registry
1407
+ attribute :refusal, Report
1408
+
1409
+ sets :refusal
1410
+
1411
+ emits ReleaseAbandoned
1412
+ end
1413
+
1414
+ # `hecks package.check [root=path]`: a read of the repository's files and tags, so it keeps no
1415
+ # record. A package that changed since its latest release without a version bump and a changelog
1416
+ # entry refuses it, naming each one.
1417
+ query "Check" do
1418
+ description "Judge every package against its latest release: a changed package needs a newer version and a changelog entry."
1419
+ attribute :root, Location, optional: true
1420
+ returns Document
1421
+ end
1422
+
1423
+ query "Releasing" do
1424
+ description "What releasing one run did: its status, and the report or the refusal."
1425
+ attribute :run, RegistryKey
1426
+ where(run: :run)
1427
+ order_by :run
1428
+ end
1429
+
1430
+ query "Refused" do
1431
+ description "Every release that was refused."
1432
+ where(status: "refused")
1433
+ order_by :run
1434
+ end
1435
+ end
1436
+
1437
+ policy "TagWhenReleased" do
1438
+ on "Registry.ReleaseRequested"
1439
+ trigger Registry::Git::Tag, with: { run: :run }
1440
+ end
1441
+
1442
+ policy "RecordTheTag" do
1443
+ on "Registry.ReleaseTagged"
1444
+ trigger Registry::Complete, with: { report: :report }
1445
+ end
1446
+
1447
+ policy "RecordTheRefusedTag" do
1448
+ on "Registry.ReleaseRefused"
1449
+ trigger Registry::Abandon, with: { refusal: :refusal }
1450
+ end
1451
+
1273
1452
  # A run record for opening a door onto the framework, not a door: the doors live in `Hecks::Doors`.
1274
1453
  aggregate "Door" do
1275
1454
  description "A way into the framework opened for a project: its launchers, or an MCP server."
@@ -1481,6 +1660,8 @@ policy "RecordTheEra" do
1481
1660
  attribute :domain, DomainPath, optional: true
1482
1661
  attribute :script, ScriptPath, optional: true
1483
1662
  attribute :artifact, Artifact, optional: true
1663
+ attribute :target, TargetTriple, optional: true
1664
+ attribute :stage_dir, StagePath, optional: true
1484
1665
  attribute :seeds, Count, optional: true
1485
1666
  attribute :steps, Count, optional: true
1486
1667
  attribute :output, Report, optional: true
@@ -1515,6 +1696,17 @@ policy "RecordTheEra" do
1515
1696
  attribute :value, String, pattern: '[^ \t\n\r]'
1516
1697
  end
1517
1698
 
1699
+ # A Rust target triple: `<arch>-<vendor>-<os>` with an optional `-<env>`. The toolchain
1700
+ # refuses the triples a host cannot be built for (a wasm target) and the ones not installed.
1701
+ value_object "TargetTriple" do
1702
+ attribute :value, String, pattern: '^[a-z0-9_]+(-[a-z0-9_.]+){2,3}$'
1703
+ end
1704
+
1705
+ # The directory a host build stages its files in.
1706
+ value_object "StagePath" do
1707
+ attribute :value, String, pattern: '[^\t\n\r]'
1708
+ end
1709
+
1518
1710
  value_object "Count" do
1519
1711
  attribute :value, Integer
1520
1712
 
@@ -1563,6 +1755,26 @@ policy "RecordTheEra" do
1563
1755
  emits WasmBuildRequested
1564
1756
  end
1565
1757
 
1758
+ # Compiles the host binary from the installed gem's workspace for the target and stages it with
1759
+ # the domain's `.wasm` and `.ir.json` (in `.hecks/host/<target>/` unless `stage_dir` names a
1760
+ # directory), the files a container image copies in.
1761
+ command "BuildHost" do
1762
+ role "Operator"
1763
+ goal "Build the Rust host for a domain, with its wasm and IR, ready to copy into an image"
1764
+
1765
+ attribute :domain, DomainPath
1766
+ attribute :run, BuildKey
1767
+ attribute :target, TargetTriple, optional: true
1768
+ attribute :stage_dir, StagePath, optional: true
1769
+
1770
+ sets :domain
1771
+ sets :run
1772
+ sets :target
1773
+ sets :stage_dir
1774
+
1775
+ emits HostBuildRequested
1776
+ end
1777
+
1566
1778
  command "BuildBrowserWasm" do
1567
1779
  role "Operator"
1568
1780
  goal "Compile a domain to an ES module a browser can import"
@@ -1685,6 +1897,11 @@ policy "RecordTheEra" do
1685
1897
  trigger Build::RustToolchain::Wasm, with: { run: :run }
1686
1898
  end
1687
1899
 
1900
+ policy "BuildHostWhenRequested" do
1901
+ on "Build.HostBuildRequested"
1902
+ trigger Build::RustToolchain::Host, with: { run: :run }
1903
+ end
1904
+
1688
1905
  policy "CompileBrowserWasmWhenRequested" do
1689
1906
  on "Build.BrowserWasmBuildRequested"
1690
1907
  trigger Build::RustToolchain::BrowserWasm, with: { run: :run }
@@ -43,6 +43,12 @@ Hecks.hecksagon "Hecks" do
43
43
  refuses "OperationRefused"
44
44
  end
45
45
 
46
+ asks "Bootstrap", to: Operation do
47
+ attribute :run, OperationKey
48
+ answers "OperationAnswered"
49
+ refuses "OperationRefused"
50
+ end
51
+
46
52
  answers_query "Follow"
47
53
  end
48
54
 
@@ -87,6 +93,18 @@ Hecks.hecksagon "Hecks" do
87
93
  answers "PackagePinned"
88
94
  refuses "PinRefused"
89
95
  end
96
+
97
+ answers_query "Verify"
98
+ end
99
+
100
+ Hecks::Registry.port "Git" do
101
+ asks "Tag", to: Registry do
102
+ attribute :run, RegistryKey
103
+ answers "ReleaseTagged"
104
+ refuses "ReleaseRefused"
105
+ end
106
+
107
+ answers_query "Check"
90
108
  end
91
109
 
92
110
  Hecks::Door.port "Workspace" do
@@ -130,6 +148,12 @@ Hecks.hecksagon "Hecks" do
130
148
  refuses "BuildRefused"
131
149
  end
132
150
 
151
+ asks "Host", to: Build do
152
+ attribute :run, BuildKey
153
+ answers "BuildAnswered"
154
+ refuses "BuildRefused"
155
+ end
156
+
133
157
  asks "BrowserWasm", to: Build do
134
158
  attribute :run, BuildKey
135
159
  answers "BuildAnswered"
@@ -25,8 +25,10 @@
25
25
  # `Doors::LauncherOptions`): `run_keys` mints a `run` key for a creating command given none,
26
26
  # `failure_states` are the lifecycle states `--wait` reports as exit 1 (every failure state the
27
27
  # chapter's lifecycles declare), `names` gives a command the launcher name clients type,
28
- # `executable` is where `hecks project_cli` writes this chapter's launcher (the gem's
29
- # `exe/hecks`), `streams` lists the questions `--stream` may tail (`Follow`), `memory_commands` names
28
+ # `settled` names the commands that always wait for their reactions, as if `--wait` were given, so a
29
+ # refusal is an exit status and a reason on standard error (`package.vendor`, which a script runs
30
+ # for its outcome), `executable` is where `hecks project_cli` writes this chapter's launcher (the
31
+ # gem's `exe/hecks`), `streams` lists the questions `--stream` may tail (`Follow`), `memory_commands` names
30
32
  # the commands that launcher runs on the Memory environment unless `HECKS_ENVIRONMENT` is set (so
31
33
  # `hecks console` needs no database), and `legacy` names the commands it hands to `Hecks::CLI` in the
32
34
  # positional forms ADR 0066 shipped.
@@ -37,8 +39,11 @@ Hecks.world "Hecks" do
37
39
  launcher "Launcher", run_keys: true,
38
40
  failure_states: %w[flagged failed drifted unreachable refused faulted halted stopped
39
41
  abandoned red needs_fix],
42
+ settled: %w[package.vendor package.revendor package.release
43
+ operation.bootstrap_admin],
40
44
  names: { "mcp" => "door.serve_mcp", "console" => "operation.open_console", "init" => "door.init",
41
- "interview" => "door.interview" },
45
+ "interview" => "door.interview", "package.check" => "registry.check",
46
+ "package.release" => "registry.release" },
42
47
  streams: %w[Follow],
43
48
  executable: "exe/hecks",
44
49
  memory_commands: %w[console init interview],
@@ -3,8 +3,11 @@
3
3
  # here: hecks.world's `default_adapter` fills the gap, so the memory overlay swaps it with the rest.
4
4
  #
5
5
  # `run_keys` mints the `run` key of a projection, and `--wait` reports a faulted projection (a
6
- # routes.ts out of date under `--check`, or a route table the projector refused) as exit 1.
6
+ # routes.ts out of date under `--check`, or a route table the projector refused) as exit 1, and
7
+ # `settled` makes `site_projection.check_live` wait for its reactions without the flag, so a live
8
+ # distribution that differs from the project is an exit status.
7
9
  Hecks.world "Site" do
8
10
  launcher "Launcher", run_keys: true,
9
- failure_states: %w[faulted refused halted stopped abandoned red needs_fix]
11
+ failure_states: %w[faulted refused halted stopped abandoned red needs_fix],
12
+ settled: %w[site_projection.check_live]
10
13
  end
@@ -20,6 +20,8 @@ Hecks.bluebook "Bluebook" do
20
20
  attribute :returns, QueryText
21
21
  attribute :wheres, list_of(Filter)
22
22
  attribute :attributes, list_of(AskArgument)
23
+ # Outside facts the runtime supplies before the filter reads the arguments (ADR 0081): `needs :now`.
24
+ attribute :needs, list_of(Need)
23
25
  # Every other option a query carries, as an open map: rows of option name, key within it, and
24
26
  # value. No value object can hold a map, so options ride as a list on the ask.
25
27
  attribute :options, list_of(AskOption)
@@ -33,6 +35,14 @@ Hecks.bluebook "Bluebook" do
33
35
  attribute :value, String
34
36
  end
35
37
 
38
+ value_object "Need" do
39
+ attribute :fact, String
40
+ end
41
+
42
+ value_object "FactName" do
43
+ attribute :value, String
44
+ end
45
+
36
46
  value_object "Filter" do
37
47
  attribute :field, String
38
48
  # The comparator set is declared by the language (Vocabulary::QueryComparator).
@@ -138,6 +148,19 @@ Hecks.bluebook "Bluebook" do
138
148
  emits OptionAttached
139
149
  end
140
150
 
151
+ command "Need" do
152
+ role "Language"
153
+ goal "Name an outside fact the runtime supplies before the query's filter reads its arguments"
154
+
155
+ attribute :fact, FactName
156
+
157
+ given("a fact is named") { !fact.value.to_s.empty? }
158
+
159
+ sets :needs, append: { fact: :fact }
160
+
161
+ emits AskNeedNamed
162
+ end
163
+
141
164
  command "Argument" do
142
165
  role "Language"
143
166
  goal "Attach one parameter to the query"
@@ -179,6 +202,7 @@ Hecks.bluebook "Bluebook" do
179
202
  member word: "authorize", context: "Query", body: "none", inner: "", opens: "", fills: "options", calls: "authorize_impl"
180
203
  member word: "inspect_query", context: "Query", body: "none", inner: "", opens: "", fills: "options"
181
204
  member word: "returns", context: "Query", body: "none", inner: "", opens: "", fills: "returns"
205
+ member word: "needs", context: "Query", body: "none", inner: "", opens: "", fills: "needs", calls: "needs_impl"
182
206
 
183
207
  end
184
208
 
@@ -217,6 +241,7 @@ Hecks.bluebook "Bluebook" do
217
241
  member keyword: "authorize", context: "Query", at: "", named: "tenant", kind: "symbol", required: "false", fills: "tenant"
218
242
  member keyword: "inspect_query", context: "Query", at: "1", named: "", kind: "symbol", required: "false", fills: "mode"
219
243
  member keyword: "returns", context: "Query", at: "1", named: "", kind: "constant", required: "true", fills: "type"
244
+ member keyword: "needs", context: "Query", at: "1", named: "", kind: "symbol", required: "true", fills: "fact"
220
245
 
221
246
  end
222
247
  end