textus 0.29.0 → 0.35.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/ARCHITECTURE.md +2 -235
  3. data/CHANGELOG.md +169 -0
  4. data/README.md +85 -64
  5. data/SPEC.md +366 -201
  6. data/docs/conventions.md +42 -37
  7. data/lib/textus/boot.rb +93 -76
  8. data/lib/textus/cli/group/{refresh.rb → fetch.rb} +4 -4
  9. data/lib/textus/cli/verb/build.rb +1 -1
  10. data/lib/textus/cli/verb/fetch.rb +14 -0
  11. data/lib/textus/cli/verb/{refresh_stale.rb → fetch_stale.rb} +3 -3
  12. data/lib/textus/cli/verb/get.rb +1 -1
  13. data/lib/textus/cli/verb/hook_run.rb +2 -6
  14. data/lib/textus/cli/verb/hooks.rb +1 -1
  15. data/lib/textus/cli/verb/put.rb +5 -14
  16. data/lib/textus/cli/verb/retain.rb +19 -0
  17. data/lib/textus/cli/verb/rule_list.rb +8 -8
  18. data/lib/textus/cli.rb +21 -18
  19. data/lib/textus/container.rb +1 -2
  20. data/lib/textus/dispatcher.rb +11 -3
  21. data/lib/textus/doctor/check/{refresh_locks.rb → fetch_locks.rb} +7 -7
  22. data/lib/textus/doctor/check/proposal_targets.rb +45 -0
  23. data/lib/textus/doctor/check/rule_ambiguity.rb +3 -3
  24. data/lib/textus/doctor/check.rb +8 -5
  25. data/lib/textus/doctor.rb +2 -1
  26. data/lib/textus/domain/action.rb +3 -3
  27. data/lib/textus/domain/duration.rb +22 -0
  28. data/lib/textus/domain/freshness/evaluator.rb +3 -3
  29. data/lib/textus/domain/freshness/policy.rb +2 -2
  30. data/lib/textus/domain/freshness.rb +7 -7
  31. data/lib/textus/domain/outcome.rb +2 -2
  32. data/lib/textus/domain/permission.rb +2 -10
  33. data/lib/textus/domain/policy/base_guards.rb +25 -0
  34. data/lib/textus/domain/policy/evaluation.rb +18 -0
  35. data/lib/textus/domain/policy/{refresh.rb → fetch.rb} +2 -16
  36. data/lib/textus/domain/policy/guard.rb +35 -0
  37. data/lib/textus/domain/policy/guard_factory.rb +40 -0
  38. data/lib/textus/domain/policy/predicates/author_held.rb +33 -0
  39. data/lib/textus/domain/policy/predicates/etag_match.rb +32 -0
  40. data/lib/textus/domain/policy/predicates/fresh_within.rb +58 -0
  41. data/lib/textus/domain/policy/predicates/registry.rb +39 -0
  42. data/lib/textus/domain/policy/predicates/schema_valid.rb +30 -19
  43. data/lib/textus/domain/policy/predicates/target_is_canon.rb +33 -0
  44. data/lib/textus/domain/policy/predicates/zone_writable_by.rb +39 -0
  45. data/lib/textus/domain/policy/retention.rb +26 -0
  46. data/lib/textus/domain/retention.rb +44 -0
  47. data/lib/textus/domain/staleness/intake_check.rb +6 -6
  48. data/lib/textus/envelope/io/reader.rb +4 -0
  49. data/lib/textus/envelope/io/writer.rb +8 -0
  50. data/lib/textus/envelope.rb +2 -2
  51. data/lib/textus/errors.rb +25 -28
  52. data/lib/textus/hooks/event_bus.rb +12 -24
  53. data/lib/textus/hooks/rpc_registry.rb +9 -35
  54. data/lib/textus/hooks/signature.rb +31 -0
  55. data/lib/textus/init.rb +24 -18
  56. data/lib/textus/maintenance/zone_mv.rb +1 -1
  57. data/lib/textus/manifest/capabilities.rb +29 -0
  58. data/lib/textus/manifest/data.rb +16 -8
  59. data/lib/textus/manifest/entry/base.rb +2 -2
  60. data/lib/textus/manifest/policy.rb +62 -19
  61. data/lib/textus/manifest/rules.rb +25 -14
  62. data/lib/textus/manifest/schema.rb +78 -38
  63. data/lib/textus/manifest.rb +6 -5
  64. data/lib/textus/mcp/server.rb +2 -10
  65. data/lib/textus/mcp/session.rb +7 -23
  66. data/lib/textus/mcp/tool_schemas.rb +3 -3
  67. data/lib/textus/mcp/tools.rb +7 -7
  68. data/lib/textus/ports/audit_subscriber.rb +1 -1
  69. data/lib/textus/ports/{refresh → fetch}/detached.rb +4 -4
  70. data/lib/textus/ports/{refresh → fetch}/lock.rb +1 -1
  71. data/lib/textus/projection.rb +1 -1
  72. data/lib/textus/read/freshness.rb +9 -9
  73. data/lib/textus/read/get.rb +8 -8
  74. data/lib/textus/read/{get_or_refresh.rb → get_or_fetch.rb} +11 -11
  75. data/lib/textus/read/policy_explain.rb +19 -10
  76. data/lib/textus/read/pulse.rb +5 -4
  77. data/lib/textus/read/retainable.rb +17 -0
  78. data/lib/textus/read/validator.rb +1 -1
  79. data/lib/textus/role_scope.rb +3 -2
  80. data/lib/textus/schema/tools.rb +5 -5
  81. data/lib/textus/version.rb +1 -1
  82. data/lib/textus/write/accept.rb +19 -55
  83. data/lib/textus/write/delete.rb +15 -17
  84. data/lib/textus/write/{refresh_all.rb → fetch_all.rb} +6 -6
  85. data/lib/textus/write/{refresh_orchestrator.rb → fetch_orchestrator.rb} +14 -14
  86. data/lib/textus/write/{refresh_worker.rb → fetch_worker.rb} +23 -30
  87. data/lib/textus/write/intake_fetch.rb +23 -0
  88. data/lib/textus/write/mv.rb +17 -15
  89. data/lib/textus/write/put.rb +15 -17
  90. data/lib/textus/write/reject.rb +11 -5
  91. data/lib/textus/write/retention_sweep.rb +55 -0
  92. metadata +32 -18
  93. data/lib/textus/cli/verb/refresh.rb +0 -14
  94. data/lib/textus/domain/authorizer.rb +0 -37
  95. data/lib/textus/domain/policy/predicates/accept_authority_signed.rb +0 -33
  96. data/lib/textus/domain/policy/promote.rb +0 -26
  97. data/lib/textus/domain/policy/promotion.rb +0 -57
  98. data/lib/textus/manifest/role_kinds.rb +0 -21
  99. data/lib/textus/write/authority_gate.rb +0 -24
@@ -1,21 +0,0 @@
1
- module Textus
2
- class Manifest
3
- module RoleKinds
4
- DEFAULT_MAPPING = {
5
- "human" => :accept_authority,
6
- "agent" => :proposer,
7
- "builder" => :generator,
8
- "runner" => :runner,
9
- }.freeze
10
-
11
- # Returns { role_name => kind_symbol }. When `roles:` is declared we use
12
- # exactly that; defaults are *not* layered in (declaring roles is an opt-in
13
- # to a fully user-defined vocabulary).
14
- def self.resolve(raw_roles)
15
- return DEFAULT_MAPPING if raw_roles.nil?
16
-
17
- raw_roles.to_h { |r| [r["name"], r["kind"].to_sym] }.freeze
18
- end
19
- end
20
- end
21
- end
@@ -1,24 +0,0 @@
1
- module Textus
2
- module Write
3
- # Shared gate for write verbs that require the caller to hold the
4
- # manifest's accept_authority role. Provides one method, expressed
5
- # as two early-returns rather than a ternary, so each failure mode
6
- # reads on its own line.
7
- module AuthorityGate
8
- def assert_accept_authority!(verb)
9
- return if @manifest.policy.role_kind(@call.role) == :accept_authority
10
-
11
- authority = @manifest.policy.roles_with_kind(:accept_authority).first
12
- if authority.nil?
13
- raise ProposalError.new(
14
- "no role with accept_authority kind is declared in this manifest; #{verb} is disabled",
15
- )
16
- end
17
-
18
- raise ProposalError.new(
19
- "only #{authority} role can #{verb} proposals; got '#{@call.role}'",
20
- )
21
- end
22
- end
23
- end
24
- end