textus 0.54.2 → 0.55.2
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/CHANGELOG.md +38 -1
- data/README.md +17 -10
- data/SPEC.md +39 -11
- data/docs/architecture/README.md +23 -11
- data/docs/reference/conventions.md +5 -2
- data/exe/textus +1 -1
- data/lib/textus/boot.rb +64 -93
- data/lib/textus/dispatch/binder.rb +48 -0
- data/lib/textus/dispatch/contracts.rb +63 -0
- data/lib/textus/dispatch/handler_registry.rb +21 -0
- data/lib/textus/dispatch/middleware/audit_index.rb +51 -0
- data/lib/textus/dispatch/middleware/auth.rb +40 -0
- data/lib/textus/dispatch/middleware/base.rb +26 -0
- data/lib/textus/dispatch/middleware/binder.rb +20 -0
- data/lib/textus/dispatch/middleware/cascade.rb +53 -0
- data/lib/textus/dispatch/pipeline.rb +35 -0
- data/lib/textus/doctor/check/audit_log.rb +2 -2
- data/lib/textus/doctor/check/generator_drift.rb +4 -4
- data/lib/textus/doctor/check/orphaned_publish_targets.rb +3 -3
- data/lib/textus/doctor/check/protocol_version.rb +2 -2
- data/lib/textus/doctor/check/raw_asset_paths.rb +1 -1
- data/lib/textus/doctor/check/schema_parse_error.rb +1 -1
- data/lib/textus/doctor/check/schema_violations.rb +2 -2
- data/lib/textus/doctor/check/schemas.rb +1 -1
- data/lib/textus/doctor/check/{notebook_sources.rb → scratchpad_sources.rb} +10 -5
- data/lib/textus/doctor/check/sentinels.rb +4 -4
- data/lib/textus/doctor/check/templates.rb +1 -1
- data/lib/textus/doctor/check/unowned_schema_fields.rb +1 -1
- data/lib/textus/doctor/check.rb +9 -10
- data/lib/textus/doctor.rb +2 -2
- data/lib/textus/errors.rb +8 -0
- data/lib/textus/format/base.rb +34 -10
- data/lib/textus/format/json.rb +5 -27
- data/lib/textus/format/markdown.rb +5 -27
- data/lib/textus/format/text.rb +5 -4
- data/lib/textus/format/yaml.rb +30 -27
- data/lib/textus/format.rb +22 -1
- data/lib/textus/handlers/maintenance/boot_store.rb +15 -0
- data/lib/textus/handlers/maintenance/doctor_store.rb +15 -0
- data/lib/textus/handlers/maintenance/drain_store.rb +21 -0
- data/lib/textus/handlers/maintenance/ingest_entry.rb +159 -0
- data/lib/textus/handlers/maintenance/jobs_action.rb +21 -0
- data/lib/textus/handlers/maintenance/published_entries.rb +17 -0
- data/lib/textus/handlers/maintenance/rule_explain.rb +77 -0
- data/lib/textus/handlers/maintenance/rule_lint.rb +54 -0
- data/lib/textus/handlers/maintenance/rule_list.rb +32 -0
- data/lib/textus/handlers/maintenance/schema_envelope.rb +19 -0
- data/lib/textus/handlers/read/audit_entries.rb +48 -0
- data/lib/textus/handlers/read/blame_entry.rb +71 -0
- data/lib/textus/handlers/read/deps_entry.rb +17 -0
- data/lib/textus/handlers/read/get_entry.rb +68 -0
- data/lib/textus/handlers/read/list_keys.rb +36 -0
- data/lib/textus/handlers/read/pulse_entries.rb +66 -0
- data/lib/textus/handlers/read/rdeps_entry.rb +21 -0
- data/lib/textus/handlers/read/uid_entry.rb +18 -0
- data/lib/textus/handlers/read/where_entry.rb +18 -0
- data/lib/textus/handlers/write/accept_proposal.rb +39 -0
- data/lib/textus/handlers/write/data_mv.rb +55 -0
- data/lib/textus/handlers/write/delete_key.rb +17 -0
- data/lib/textus/handlers/write/enqueue_job.rb +27 -0
- data/lib/textus/handlers/write/key_delete_prefix.rb +32 -0
- data/lib/textus/handlers/write/key_mv_prefix.rb +45 -0
- data/lib/textus/handlers/write/move_key.rb +80 -0
- data/lib/textus/handlers/write/propose_entry.rb +29 -0
- data/lib/textus/handlers/write/put_entry.rb +29 -0
- data/lib/textus/handlers/write/reject_proposal.rb +29 -0
- data/lib/textus/init.rb +5 -7
- data/lib/textus/jobs.rb +3 -9
- data/lib/textus/manifest/capabilities.rb +4 -4
- data/lib/textus/manifest/entry/base.rb +3 -3
- data/lib/textus/manifest/entry/publish/subtree_mirror.rb +2 -2
- data/lib/textus/manifest/entry/publish/to_paths.rb +2 -2
- data/lib/textus/manifest/policy/predicates/author_held.rb +22 -0
- data/lib/textus/manifest/policy/predicates/etag_match.rb +18 -0
- data/lib/textus/manifest/policy/predicates/fresh_within.rb +13 -0
- data/lib/textus/manifest/policy/predicates/lane_deletable_by.rb +31 -0
- data/lib/textus/manifest/policy/predicates/lane_writable_by.rb +23 -0
- data/lib/textus/manifest/policy/predicates/raw_lane_ingest_only.rb +25 -0
- data/lib/textus/manifest/policy/predicates/raw_write_once.rb +24 -0
- data/lib/textus/manifest/policy/predicates/schema_valid.rb +41 -0
- data/lib/textus/manifest/policy/predicates/target_is_canon.rb +20 -0
- data/lib/textus/manifest/policy/predicates.rb +54 -0
- data/lib/textus/manifest/policy/retention.rb +1 -1
- data/lib/textus/manifest/schema/semantics/cross_field.rb +53 -0
- data/lib/textus/manifest/schema/semantics/invariants.rb +125 -0
- data/lib/textus/manifest/schema/semantics/migration.rb +83 -0
- data/lib/textus/manifest/schema/semantics.rb +11 -216
- data/lib/textus/orchestration.rb +55 -0
- data/lib/textus/{ports → port}/audit_log.rb +46 -6
- data/lib/textus/{ports → port}/build_lock.rb +2 -2
- data/lib/textus/{ports → port}/clock.rb +1 -1
- data/lib/textus/{ports → port}/publisher.rb +5 -5
- data/lib/textus/{core → port}/sentinel.rb +1 -6
- data/lib/textus/{ports → port}/sentinel_store.rb +4 -4
- data/lib/textus/{ports → port}/storage/file_stat.rb +1 -1
- data/lib/textus/port/storage/file_store.rb +49 -0
- data/lib/textus/port/storage/interface.rb +17 -0
- data/lib/textus/port/store.rb +149 -0
- data/lib/textus/{ports → port}/watcher_lock.rb +3 -3
- data/lib/textus/produce/engine.rb +1 -11
- data/lib/textus/produce/publisher.rb +21 -0
- data/lib/textus/schema/registry.rb +42 -0
- data/lib/textus/schema/tools.rb +7 -10
- data/lib/textus/store/container.rb +173 -0
- data/lib/textus/store/cursor.rb +26 -0
- data/lib/textus/store/entry/reader.rb +47 -0
- data/lib/textus/store/entry/writer.rb +219 -0
- data/lib/textus/store/envelope/meta.rb +61 -0
- data/lib/textus/store/freshness/drift_detector.rb +93 -0
- data/lib/textus/store/freshness/evaluator.rb +20 -0
- data/lib/textus/store/freshness/ttl_evaluator.rb +57 -0
- data/lib/textus/{core → store}/freshness/verdict.rb +1 -11
- data/lib/textus/store/freshness.rb +8 -0
- data/lib/textus/store/index/builder.rb +76 -0
- data/lib/textus/store/index/lookup.rb +60 -0
- data/lib/textus/store/jobs/base.rb +13 -0
- data/lib/textus/store/jobs/index.rb +15 -0
- data/lib/textus/store/jobs/materialize.rb +15 -0
- data/lib/textus/store/jobs/plan.rb +11 -0
- data/lib/textus/store/jobs/planner.rb +124 -0
- data/lib/textus/store/jobs/queue.rb +162 -0
- data/lib/textus/store/jobs/registry.rb +19 -0
- data/lib/textus/store/jobs/retention/base.rb +52 -0
- data/lib/textus/store/jobs/retention/sweep.rb +55 -0
- data/lib/textus/store/jobs/retention.rb +8 -0
- data/lib/textus/store/jobs/sweep.rb +21 -0
- data/lib/textus/store/jobs/worker.rb +64 -0
- data/lib/textus/store/layout.rb +97 -0
- data/lib/textus/store.rb +63 -32
- data/lib/textus/{surfaces → surface}/cli/group/data.rb +1 -1
- data/lib/textus/{surfaces → surface}/cli/group/key.rb +1 -1
- data/lib/textus/{surfaces → surface}/cli/group/mcp.rb +1 -1
- data/lib/textus/{surfaces → surface}/cli/group/rule.rb +1 -1
- data/lib/textus/{surfaces → surface}/cli/group/schema.rb +1 -1
- data/lib/textus/{surfaces → surface}/cli/group.rb +2 -2
- data/lib/textus/{surfaces → surface}/cli/runner.rb +14 -68
- data/lib/textus/surface/cli/sources.rb +41 -0
- data/lib/textus/{surfaces → surface}/cli/verb/doctor.rb +5 -6
- data/lib/textus/{surfaces → surface}/cli/verb/get.rb +7 -5
- data/lib/textus/{surfaces → surface}/cli/verb/init.rb +1 -1
- data/lib/textus/{surfaces → surface}/cli/verb/mcp_serve.rb +3 -3
- data/lib/textus/surface/cli/verb/put.rb +27 -0
- data/lib/textus/{surfaces → surface}/cli/verb/schema_diff.rb +1 -1
- data/lib/textus/{surfaces → surface}/cli/verb/schema_init.rb +1 -1
- data/lib/textus/{surfaces → surface}/cli/verb/schema_migrate.rb +1 -1
- data/lib/textus/{surfaces → surface}/cli/verb/watch.rb +2 -2
- data/lib/textus/{surfaces → surface}/cli/verb.rb +3 -8
- data/lib/textus/{surfaces → surface}/cli.rb +1 -1
- data/lib/textus/surface/mcp/catalog.rb +58 -0
- data/lib/textus/{surfaces → surface}/mcp/errors.rb +1 -11
- data/lib/textus/surface/mcp/projector.rb +20 -0
- data/lib/textus/{surfaces → surface}/mcp/server.rb +24 -35
- data/lib/textus/{surfaces → surface}/mcp.rb +2 -2
- data/lib/textus/{surfaces → surface}/watcher.rb +8 -8
- data/lib/textus/value/call.rb +30 -0
- data/lib/textus/value/command.rb +16 -0
- data/lib/textus/{core → value}/duration.rb +1 -4
- data/lib/textus/value/envelope.rb +90 -0
- data/lib/textus/value/etag.rb +39 -0
- data/lib/textus/value/payload.rb +7 -0
- data/lib/textus/value/result.rb +46 -0
- data/lib/textus/value/role.rb +38 -0
- data/lib/textus/value/types.rb +13 -0
- data/lib/textus/{uid.rb → value/uid.rb} +9 -7
- data/lib/textus/verb_registry.rb +417 -0
- data/lib/textus/version.rb +1 -1
- data/lib/textus/workflow/loader.rb +4 -4
- data/lib/textus/workflow/runner.rb +11 -33
- data/lib/textus.rb +4 -69
- metadata +142 -105
- data/lib/textus/action/accept.rb +0 -44
- data/lib/textus/action/audit.rb +0 -131
- data/lib/textus/action/base.rb +0 -42
- data/lib/textus/action/blame.rb +0 -97
- data/lib/textus/action/boot.rb +0 -17
- data/lib/textus/action/data_mv.rb +0 -69
- data/lib/textus/action/deps.rb +0 -34
- data/lib/textus/action/doctor.rb +0 -24
- data/lib/textus/action/drain.rb +0 -39
- data/lib/textus/action/enqueue.rb +0 -53
- data/lib/textus/action/get.rb +0 -78
- data/lib/textus/action/ingest.rb +0 -203
- data/lib/textus/action/jobs.rb +0 -36
- data/lib/textus/action/key_delete.rb +0 -36
- data/lib/textus/action/key_delete_prefix.rb +0 -44
- data/lib/textus/action/key_mv.rb +0 -129
- data/lib/textus/action/key_mv_prefix.rb +0 -57
- data/lib/textus/action/list.rb +0 -42
- data/lib/textus/action/propose.rb +0 -52
- data/lib/textus/action/published.rb +0 -24
- data/lib/textus/action/pulse.rb +0 -56
- data/lib/textus/action/put.rb +0 -52
- data/lib/textus/action/rdeps.rb +0 -39
- data/lib/textus/action/reject.rb +0 -37
- data/lib/textus/action/rule_explain.rb +0 -91
- data/lib/textus/action/rule_lint.rb +0 -68
- data/lib/textus/action/rule_list.rb +0 -42
- data/lib/textus/action/schema_envelope.rb +0 -29
- data/lib/textus/action/uid.rb +0 -33
- data/lib/textus/action/where.rb +0 -36
- data/lib/textus/action/write_verb.rb +0 -44
- data/lib/textus/call.rb +0 -28
- data/lib/textus/command.rb +0 -41
- data/lib/textus/container.rb +0 -26
- data/lib/textus/contract/around.rb +0 -29
- data/lib/textus/contract/binder.rb +0 -88
- data/lib/textus/contract/resources/build_lock.rb +0 -17
- data/lib/textus/contract/resources/cursor.rb +0 -26
- data/lib/textus/contract/sources.rb +0 -39
- data/lib/textus/contract/view.rb +0 -15
- data/lib/textus/contract.rb +0 -174
- data/lib/textus/core/freshness/evaluator.rb +0 -150
- data/lib/textus/core/freshness.rb +0 -11
- data/lib/textus/core/retention/sweep.rb +0 -57
- data/lib/textus/core/retention.rb +0 -11
- data/lib/textus/cursor_store.rb +0 -24
- data/lib/textus/envelope/reader.rb +0 -46
- data/lib/textus/envelope/writer.rb +0 -209
- data/lib/textus/envelope.rb +0 -79
- data/lib/textus/etag.rb +0 -36
- data/lib/textus/gate/auth.rb +0 -227
- data/lib/textus/gate.rb +0 -116
- data/lib/textus/jobs/base.rb +0 -23
- data/lib/textus/jobs/materialize.rb +0 -20
- data/lib/textus/jobs/plan.rb +0 -9
- data/lib/textus/jobs/planner.rb +0 -101
- data/lib/textus/jobs/retention.rb +0 -48
- data/lib/textus/jobs/sweep.rb +0 -27
- data/lib/textus/jobs/worker.rb +0 -67
- data/lib/textus/layout.rb +0 -91
- data/lib/textus/ports/job_store/job.rb +0 -65
- data/lib/textus/ports/job_store.rb +0 -123
- data/lib/textus/ports/raw_index.rb +0 -61
- data/lib/textus/ports/storage/file_store.rb +0 -26
- data/lib/textus/role.rb +0 -36
- data/lib/textus/schemas.rb +0 -54
- data/lib/textus/session.rb +0 -35
- data/lib/textus/surfaces/cli/verb/put.rb +0 -30
- data/lib/textus/surfaces/mcp/catalog.rb +0 -111
- data/lib/textus/surfaces/role_scope.rb +0 -34
- data/lib/textus/types.rb +0 -15
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: textus
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.55.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patrick
|
|
@@ -93,6 +93,20 @@ dependencies:
|
|
|
93
93
|
- - ">="
|
|
94
94
|
- !ruby/object:Gem::Version
|
|
95
95
|
version: '3.2'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: sqlite3
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '2.0'
|
|
103
|
+
type: :runtime
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '2.0'
|
|
96
110
|
- !ruby/object:Gem::Dependency
|
|
97
111
|
name: zeitwerk
|
|
98
112
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -152,63 +166,22 @@ files:
|
|
|
152
166
|
- docs/reference/conventions.md
|
|
153
167
|
- exe/textus
|
|
154
168
|
- lib/textus.rb
|
|
155
|
-
- lib/textus/action/accept.rb
|
|
156
|
-
- lib/textus/action/audit.rb
|
|
157
|
-
- lib/textus/action/base.rb
|
|
158
|
-
- lib/textus/action/blame.rb
|
|
159
|
-
- lib/textus/action/boot.rb
|
|
160
|
-
- lib/textus/action/data_mv.rb
|
|
161
|
-
- lib/textus/action/deps.rb
|
|
162
|
-
- lib/textus/action/doctor.rb
|
|
163
|
-
- lib/textus/action/drain.rb
|
|
164
|
-
- lib/textus/action/enqueue.rb
|
|
165
|
-
- lib/textus/action/get.rb
|
|
166
|
-
- lib/textus/action/ingest.rb
|
|
167
|
-
- lib/textus/action/jobs.rb
|
|
168
|
-
- lib/textus/action/key_delete.rb
|
|
169
|
-
- lib/textus/action/key_delete_prefix.rb
|
|
170
|
-
- lib/textus/action/key_mv.rb
|
|
171
|
-
- lib/textus/action/key_mv_prefix.rb
|
|
172
|
-
- lib/textus/action/list.rb
|
|
173
|
-
- lib/textus/action/propose.rb
|
|
174
|
-
- lib/textus/action/published.rb
|
|
175
|
-
- lib/textus/action/pulse.rb
|
|
176
|
-
- lib/textus/action/put.rb
|
|
177
|
-
- lib/textus/action/rdeps.rb
|
|
178
|
-
- lib/textus/action/reject.rb
|
|
179
|
-
- lib/textus/action/rule_explain.rb
|
|
180
|
-
- lib/textus/action/rule_lint.rb
|
|
181
|
-
- lib/textus/action/rule_list.rb
|
|
182
|
-
- lib/textus/action/schema_envelope.rb
|
|
183
|
-
- lib/textus/action/uid.rb
|
|
184
|
-
- lib/textus/action/where.rb
|
|
185
|
-
- lib/textus/action/write_verb.rb
|
|
186
169
|
- lib/textus/boot.rb
|
|
187
|
-
- lib/textus/
|
|
188
|
-
- lib/textus/
|
|
189
|
-
- lib/textus/
|
|
190
|
-
- lib/textus/
|
|
191
|
-
- lib/textus/
|
|
192
|
-
- lib/textus/
|
|
193
|
-
- lib/textus/
|
|
194
|
-
- lib/textus/
|
|
195
|
-
- lib/textus/
|
|
196
|
-
- lib/textus/contract/view.rb
|
|
197
|
-
- lib/textus/core/duration.rb
|
|
198
|
-
- lib/textus/core/freshness.rb
|
|
199
|
-
- lib/textus/core/freshness/evaluator.rb
|
|
200
|
-
- lib/textus/core/freshness/verdict.rb
|
|
201
|
-
- lib/textus/core/retention.rb
|
|
202
|
-
- lib/textus/core/retention/sweep.rb
|
|
203
|
-
- lib/textus/core/sentinel.rb
|
|
204
|
-
- lib/textus/cursor_store.rb
|
|
170
|
+
- lib/textus/dispatch/binder.rb
|
|
171
|
+
- lib/textus/dispatch/contracts.rb
|
|
172
|
+
- lib/textus/dispatch/handler_registry.rb
|
|
173
|
+
- lib/textus/dispatch/middleware/audit_index.rb
|
|
174
|
+
- lib/textus/dispatch/middleware/auth.rb
|
|
175
|
+
- lib/textus/dispatch/middleware/base.rb
|
|
176
|
+
- lib/textus/dispatch/middleware/binder.rb
|
|
177
|
+
- lib/textus/dispatch/middleware/cascade.rb
|
|
178
|
+
- lib/textus/dispatch/pipeline.rb
|
|
205
179
|
- lib/textus/doctor.rb
|
|
206
180
|
- lib/textus/doctor/check.rb
|
|
207
181
|
- lib/textus/doctor/check/audit_log.rb
|
|
208
182
|
- lib/textus/doctor/check/generator_drift.rb
|
|
209
183
|
- lib/textus/doctor/check/illegal_keys.rb
|
|
210
184
|
- lib/textus/doctor/check/manifest_files.rb
|
|
211
|
-
- lib/textus/doctor/check/notebook_sources.rb
|
|
212
185
|
- lib/textus/doctor/check/orphaned_publish_targets.rb
|
|
213
186
|
- lib/textus/doctor/check/proposal_targets.rb
|
|
214
187
|
- lib/textus/doctor/check/protocol_version.rb
|
|
@@ -218,38 +191,54 @@ files:
|
|
|
218
191
|
- lib/textus/doctor/check/schema_parse_error.rb
|
|
219
192
|
- lib/textus/doctor/check/schema_violations.rb
|
|
220
193
|
- lib/textus/doctor/check/schemas.rb
|
|
194
|
+
- lib/textus/doctor/check/scratchpad_sources.rb
|
|
221
195
|
- lib/textus/doctor/check/sentinels.rb
|
|
222
196
|
- lib/textus/doctor/check/stale_reviewed_stamp.rb
|
|
223
197
|
- lib/textus/doctor/check/templates.rb
|
|
224
198
|
- lib/textus/doctor/check/unowned_schema_fields.rb
|
|
225
199
|
- lib/textus/doctor/validator.rb
|
|
226
|
-
- lib/textus/envelope.rb
|
|
227
|
-
- lib/textus/envelope/reader.rb
|
|
228
|
-
- lib/textus/envelope/writer.rb
|
|
229
200
|
- lib/textus/errors.rb
|
|
230
|
-
- lib/textus/etag.rb
|
|
231
201
|
- lib/textus/format.rb
|
|
232
202
|
- lib/textus/format/base.rb
|
|
233
203
|
- lib/textus/format/json.rb
|
|
234
204
|
- lib/textus/format/markdown.rb
|
|
235
205
|
- lib/textus/format/text.rb
|
|
236
206
|
- lib/textus/format/yaml.rb
|
|
237
|
-
- lib/textus/
|
|
238
|
-
- lib/textus/
|
|
207
|
+
- lib/textus/handlers/maintenance/boot_store.rb
|
|
208
|
+
- lib/textus/handlers/maintenance/doctor_store.rb
|
|
209
|
+
- lib/textus/handlers/maintenance/drain_store.rb
|
|
210
|
+
- lib/textus/handlers/maintenance/ingest_entry.rb
|
|
211
|
+
- lib/textus/handlers/maintenance/jobs_action.rb
|
|
212
|
+
- lib/textus/handlers/maintenance/published_entries.rb
|
|
213
|
+
- lib/textus/handlers/maintenance/rule_explain.rb
|
|
214
|
+
- lib/textus/handlers/maintenance/rule_lint.rb
|
|
215
|
+
- lib/textus/handlers/maintenance/rule_list.rb
|
|
216
|
+
- lib/textus/handlers/maintenance/schema_envelope.rb
|
|
217
|
+
- lib/textus/handlers/read/audit_entries.rb
|
|
218
|
+
- lib/textus/handlers/read/blame_entry.rb
|
|
219
|
+
- lib/textus/handlers/read/deps_entry.rb
|
|
220
|
+
- lib/textus/handlers/read/get_entry.rb
|
|
221
|
+
- lib/textus/handlers/read/list_keys.rb
|
|
222
|
+
- lib/textus/handlers/read/pulse_entries.rb
|
|
223
|
+
- lib/textus/handlers/read/rdeps_entry.rb
|
|
224
|
+
- lib/textus/handlers/read/uid_entry.rb
|
|
225
|
+
- lib/textus/handlers/read/where_entry.rb
|
|
226
|
+
- lib/textus/handlers/write/accept_proposal.rb
|
|
227
|
+
- lib/textus/handlers/write/data_mv.rb
|
|
228
|
+
- lib/textus/handlers/write/delete_key.rb
|
|
229
|
+
- lib/textus/handlers/write/enqueue_job.rb
|
|
230
|
+
- lib/textus/handlers/write/key_delete_prefix.rb
|
|
231
|
+
- lib/textus/handlers/write/key_mv_prefix.rb
|
|
232
|
+
- lib/textus/handlers/write/move_key.rb
|
|
233
|
+
- lib/textus/handlers/write/propose_entry.rb
|
|
234
|
+
- lib/textus/handlers/write/put_entry.rb
|
|
235
|
+
- lib/textus/handlers/write/reject_proposal.rb
|
|
239
236
|
- lib/textus/init.rb
|
|
240
237
|
- lib/textus/jobs.rb
|
|
241
|
-
- lib/textus/jobs/base.rb
|
|
242
|
-
- lib/textus/jobs/materialize.rb
|
|
243
|
-
- lib/textus/jobs/plan.rb
|
|
244
|
-
- lib/textus/jobs/planner.rb
|
|
245
|
-
- lib/textus/jobs/retention.rb
|
|
246
|
-
- lib/textus/jobs/sweep.rb
|
|
247
|
-
- lib/textus/jobs/worker.rb
|
|
248
238
|
- lib/textus/key/distance.rb
|
|
249
239
|
- lib/textus/key/grammar.rb
|
|
250
240
|
- lib/textus/key/matching.rb
|
|
251
241
|
- lib/textus/key/path.rb
|
|
252
|
-
- lib/textus/layout.rb
|
|
253
242
|
- lib/textus/manifest.rb
|
|
254
243
|
- lib/textus/manifest/capabilities.rb
|
|
255
244
|
- lib/textus/manifest/data.rb
|
|
@@ -273,6 +262,16 @@ files:
|
|
|
273
262
|
- lib/textus/manifest/entry/validators/publish.rb
|
|
274
263
|
- lib/textus/manifest/policy.rb
|
|
275
264
|
- lib/textus/manifest/policy/matcher.rb
|
|
265
|
+
- lib/textus/manifest/policy/predicates.rb
|
|
266
|
+
- lib/textus/manifest/policy/predicates/author_held.rb
|
|
267
|
+
- lib/textus/manifest/policy/predicates/etag_match.rb
|
|
268
|
+
- lib/textus/manifest/policy/predicates/fresh_within.rb
|
|
269
|
+
- lib/textus/manifest/policy/predicates/lane_deletable_by.rb
|
|
270
|
+
- lib/textus/manifest/policy/predicates/lane_writable_by.rb
|
|
271
|
+
- lib/textus/manifest/policy/predicates/raw_lane_ingest_only.rb
|
|
272
|
+
- lib/textus/manifest/policy/predicates/raw_write_once.rb
|
|
273
|
+
- lib/textus/manifest/policy/predicates/schema_valid.rb
|
|
274
|
+
- lib/textus/manifest/policy/predicates/target_is_canon.rb
|
|
276
275
|
- lib/textus/manifest/policy/publish_target.rb
|
|
277
276
|
- lib/textus/manifest/policy/react.rb
|
|
278
277
|
- lib/textus/manifest/policy/retention.rb
|
|
@@ -283,53 +282,91 @@ files:
|
|
|
283
282
|
- lib/textus/manifest/schema/contract.rb
|
|
284
283
|
- lib/textus/manifest/schema/keys.rb
|
|
285
284
|
- lib/textus/manifest/schema/semantics.rb
|
|
285
|
+
- lib/textus/manifest/schema/semantics/cross_field.rb
|
|
286
|
+
- lib/textus/manifest/schema/semantics/invariants.rb
|
|
287
|
+
- lib/textus/manifest/schema/semantics/migration.rb
|
|
286
288
|
- lib/textus/manifest/schema/validator.rb
|
|
287
289
|
- lib/textus/manifest/schema/vocabulary.rb
|
|
288
|
-
- lib/textus/
|
|
289
|
-
- lib/textus/
|
|
290
|
-
- lib/textus/
|
|
291
|
-
- lib/textus/
|
|
292
|
-
- lib/textus/
|
|
293
|
-
- lib/textus/
|
|
294
|
-
- lib/textus/
|
|
295
|
-
- lib/textus/
|
|
296
|
-
- lib/textus/
|
|
297
|
-
- lib/textus/
|
|
298
|
-
- lib/textus/
|
|
290
|
+
- lib/textus/orchestration.rb
|
|
291
|
+
- lib/textus/port/audit_log.rb
|
|
292
|
+
- lib/textus/port/build_lock.rb
|
|
293
|
+
- lib/textus/port/clock.rb
|
|
294
|
+
- lib/textus/port/publisher.rb
|
|
295
|
+
- lib/textus/port/sentinel.rb
|
|
296
|
+
- lib/textus/port/sentinel_store.rb
|
|
297
|
+
- lib/textus/port/storage/file_stat.rb
|
|
298
|
+
- lib/textus/port/storage/file_store.rb
|
|
299
|
+
- lib/textus/port/storage/interface.rb
|
|
300
|
+
- lib/textus/port/store.rb
|
|
301
|
+
- lib/textus/port/watcher_lock.rb
|
|
299
302
|
- lib/textus/produce/engine.rb
|
|
303
|
+
- lib/textus/produce/publisher.rb
|
|
300
304
|
- lib/textus/produce/render.rb
|
|
301
|
-
- lib/textus/role.rb
|
|
302
305
|
- lib/textus/schema.rb
|
|
306
|
+
- lib/textus/schema/registry.rb
|
|
303
307
|
- lib/textus/schema/tools.rb
|
|
304
|
-
- lib/textus/schemas.rb
|
|
305
|
-
- lib/textus/session.rb
|
|
306
308
|
- lib/textus/store.rb
|
|
307
|
-
- lib/textus/
|
|
308
|
-
- lib/textus/
|
|
309
|
-
- lib/textus/
|
|
310
|
-
- lib/textus/
|
|
311
|
-
- lib/textus/
|
|
312
|
-
- lib/textus/
|
|
313
|
-
- lib/textus/
|
|
314
|
-
- lib/textus/
|
|
315
|
-
- lib/textus/
|
|
316
|
-
- lib/textus/
|
|
317
|
-
- lib/textus/
|
|
318
|
-
- lib/textus/
|
|
319
|
-
- lib/textus/
|
|
320
|
-
- lib/textus/
|
|
321
|
-
- lib/textus/
|
|
322
|
-
- lib/textus/
|
|
323
|
-
- lib/textus/
|
|
324
|
-
- lib/textus/
|
|
325
|
-
- lib/textus/
|
|
326
|
-
- lib/textus/
|
|
327
|
-
- lib/textus/
|
|
328
|
-
- lib/textus/
|
|
329
|
-
- lib/textus/
|
|
330
|
-
- lib/textus/
|
|
331
|
-
- lib/textus/
|
|
332
|
-
- lib/textus/
|
|
309
|
+
- lib/textus/store/container.rb
|
|
310
|
+
- lib/textus/store/cursor.rb
|
|
311
|
+
- lib/textus/store/entry/reader.rb
|
|
312
|
+
- lib/textus/store/entry/writer.rb
|
|
313
|
+
- lib/textus/store/envelope/meta.rb
|
|
314
|
+
- lib/textus/store/freshness.rb
|
|
315
|
+
- lib/textus/store/freshness/drift_detector.rb
|
|
316
|
+
- lib/textus/store/freshness/evaluator.rb
|
|
317
|
+
- lib/textus/store/freshness/ttl_evaluator.rb
|
|
318
|
+
- lib/textus/store/freshness/verdict.rb
|
|
319
|
+
- lib/textus/store/index/builder.rb
|
|
320
|
+
- lib/textus/store/index/lookup.rb
|
|
321
|
+
- lib/textus/store/jobs/base.rb
|
|
322
|
+
- lib/textus/store/jobs/index.rb
|
|
323
|
+
- lib/textus/store/jobs/materialize.rb
|
|
324
|
+
- lib/textus/store/jobs/plan.rb
|
|
325
|
+
- lib/textus/store/jobs/planner.rb
|
|
326
|
+
- lib/textus/store/jobs/queue.rb
|
|
327
|
+
- lib/textus/store/jobs/registry.rb
|
|
328
|
+
- lib/textus/store/jobs/retention.rb
|
|
329
|
+
- lib/textus/store/jobs/retention/base.rb
|
|
330
|
+
- lib/textus/store/jobs/retention/sweep.rb
|
|
331
|
+
- lib/textus/store/jobs/sweep.rb
|
|
332
|
+
- lib/textus/store/jobs/worker.rb
|
|
333
|
+
- lib/textus/store/layout.rb
|
|
334
|
+
- lib/textus/surface/cli.rb
|
|
335
|
+
- lib/textus/surface/cli/group.rb
|
|
336
|
+
- lib/textus/surface/cli/group/data.rb
|
|
337
|
+
- lib/textus/surface/cli/group/key.rb
|
|
338
|
+
- lib/textus/surface/cli/group/mcp.rb
|
|
339
|
+
- lib/textus/surface/cli/group/rule.rb
|
|
340
|
+
- lib/textus/surface/cli/group/schema.rb
|
|
341
|
+
- lib/textus/surface/cli/runner.rb
|
|
342
|
+
- lib/textus/surface/cli/sources.rb
|
|
343
|
+
- lib/textus/surface/cli/verb.rb
|
|
344
|
+
- lib/textus/surface/cli/verb/doctor.rb
|
|
345
|
+
- lib/textus/surface/cli/verb/get.rb
|
|
346
|
+
- lib/textus/surface/cli/verb/init.rb
|
|
347
|
+
- lib/textus/surface/cli/verb/mcp_serve.rb
|
|
348
|
+
- lib/textus/surface/cli/verb/put.rb
|
|
349
|
+
- lib/textus/surface/cli/verb/schema_diff.rb
|
|
350
|
+
- lib/textus/surface/cli/verb/schema_init.rb
|
|
351
|
+
- lib/textus/surface/cli/verb/schema_migrate.rb
|
|
352
|
+
- lib/textus/surface/cli/verb/watch.rb
|
|
353
|
+
- lib/textus/surface/mcp.rb
|
|
354
|
+
- lib/textus/surface/mcp/catalog.rb
|
|
355
|
+
- lib/textus/surface/mcp/errors.rb
|
|
356
|
+
- lib/textus/surface/mcp/projector.rb
|
|
357
|
+
- lib/textus/surface/mcp/server.rb
|
|
358
|
+
- lib/textus/surface/watcher.rb
|
|
359
|
+
- lib/textus/value/call.rb
|
|
360
|
+
- lib/textus/value/command.rb
|
|
361
|
+
- lib/textus/value/duration.rb
|
|
362
|
+
- lib/textus/value/envelope.rb
|
|
363
|
+
- lib/textus/value/etag.rb
|
|
364
|
+
- lib/textus/value/payload.rb
|
|
365
|
+
- lib/textus/value/result.rb
|
|
366
|
+
- lib/textus/value/role.rb
|
|
367
|
+
- lib/textus/value/types.rb
|
|
368
|
+
- lib/textus/value/uid.rb
|
|
369
|
+
- lib/textus/verb_registry.rb
|
|
333
370
|
- lib/textus/version.rb
|
|
334
371
|
- lib/textus/workflow.rb
|
|
335
372
|
- lib/textus/workflow/collector.rb
|
data/lib/textus/action/accept.rb
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Textus
|
|
4
|
-
module Action
|
|
5
|
-
class Accept < WriteVerb
|
|
6
|
-
extend Textus::Contract::DSL
|
|
7
|
-
|
|
8
|
-
verb :accept
|
|
9
|
-
summary "apply a queued proposal to its target zone; requires the author capability"
|
|
10
|
-
surfaces :cli, :mcp
|
|
11
|
-
cli "accept"
|
|
12
|
-
arg :pending_key, String, required: true, positional: true, description: "the queued proposal's key"
|
|
13
|
-
|
|
14
|
-
def initialize(pending_key:)
|
|
15
|
-
super()
|
|
16
|
-
@pending_key = pending_key
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def call(container:, call:)
|
|
20
|
-
env = Textus::Action::Get.new(key: @pending_key).call(container: container, call: call)
|
|
21
|
-
proposal = env.meta["proposal"] or raise Textus::ProposalError.new("entry has no proposal block: #{@pending_key}")
|
|
22
|
-
target = proposal["target_key"] or raise Textus::ProposalError.new("proposal missing target_key")
|
|
23
|
-
action = proposal["action"] || "put"
|
|
24
|
-
|
|
25
|
-
case action
|
|
26
|
-
when "put"
|
|
27
|
-
Textus::Action::Put.new(
|
|
28
|
-
key: target,
|
|
29
|
-
meta: env.meta["_meta"] || {},
|
|
30
|
-
body: env.body,
|
|
31
|
-
).call(container: container, call: call)
|
|
32
|
-
when "delete"
|
|
33
|
-
Textus::Action::KeyDelete.new(key: target).call(container: container, call: call)
|
|
34
|
-
else
|
|
35
|
-
raise Textus::ProposalError.new("unknown action: #{action}")
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
Textus::Action::KeyDelete.new(key: @pending_key).call(container: container, call: call)
|
|
39
|
-
|
|
40
|
-
{ "protocol" => Textus::PROTOCOL, "accepted" => @pending_key, "target_key" => target, "action" => action }
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
data/lib/textus/action/audit.rb
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "json"
|
|
4
|
-
require "time"
|
|
5
|
-
|
|
6
|
-
module Textus
|
|
7
|
-
module Action
|
|
8
|
-
class Audit < Base
|
|
9
|
-
extend Textus::Contract::DSL
|
|
10
|
-
|
|
11
|
-
verb :audit
|
|
12
|
-
summary "Query the audit log with optional filters."
|
|
13
|
-
surfaces :cli
|
|
14
|
-
cli "audit"
|
|
15
|
-
arg :key, String, required: false, description: "filter to rows for this key"
|
|
16
|
-
arg :lane, String, required: false, description: "filter to keys in this lane"
|
|
17
|
-
arg :role, String, required: false, description: "filter to rows written under this role"
|
|
18
|
-
arg :verb, String, required: false, description: "filter to rows for this verb"
|
|
19
|
-
arg :since, String, required: false,
|
|
20
|
-
coerce: ->(s) { Textus::Action::Audit.parse_since(s, now: Time.now) },
|
|
21
|
-
description: "ISO-8601 timestamp or relative offset (e.g. 1h, 30m)"
|
|
22
|
-
arg :seq_since, Integer, required: false, description: "return rows with seq > this cursor value"
|
|
23
|
-
arg :correlation_id, String, required: false, description: "filter to rows with this correlation_id"
|
|
24
|
-
arg :limit, Integer, required: false, description: "maximum number of rows to return"
|
|
25
|
-
view(:cli) { |rows, _i| { "verb" => "audit", "rows" => rows } }
|
|
26
|
-
|
|
27
|
-
def initialize(**kwargs)
|
|
28
|
-
super()
|
|
29
|
-
@query = Query.build(**kwargs.slice(:key, :lane, :role, :verb, :since, :seq_since, :correlation_id, :limit))
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def args
|
|
33
|
-
@query.to_h.compact
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def call(container:, **)
|
|
37
|
-
@manifest = container.manifest
|
|
38
|
-
@root = container.root
|
|
39
|
-
@log_path = Textus::Layout.audit_log(container.root)
|
|
40
|
-
@audit_log = container.audit_log
|
|
41
|
-
|
|
42
|
-
query = @query
|
|
43
|
-
check_cursor_expiry!(query.seq_since)
|
|
44
|
-
|
|
45
|
-
files = all_log_files
|
|
46
|
-
return [] if files.empty?
|
|
47
|
-
|
|
48
|
-
rows = []
|
|
49
|
-
files.each do |file|
|
|
50
|
-
File.foreach(file) do |line|
|
|
51
|
-
parsed = parse_row(line.chomp)
|
|
52
|
-
next unless parsed
|
|
53
|
-
next unless query.matches?(parsed)
|
|
54
|
-
next if query.lane && !key_in_lane?(parsed["key"], query.lane)
|
|
55
|
-
|
|
56
|
-
rows << parsed
|
|
57
|
-
break if limit_reached?(rows, query)
|
|
58
|
-
end
|
|
59
|
-
break if limit_reached?(rows, query)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
rows
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def self.parse_since(str, now: Time.now.utc)
|
|
66
|
-
return nil if str.nil? || str.empty?
|
|
67
|
-
return Time.parse(str) if str =~ /\A\d{4}-\d{2}-\d{2}/
|
|
68
|
-
|
|
69
|
-
match = str.match(/\A(\d+)([smhd])\z/) or return nil
|
|
70
|
-
mult = { "s" => 1, "m" => 60, "h" => 3600, "d" => 86_400 }[match[2]]
|
|
71
|
-
now - (match[1].to_i * mult)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
Query = Data.define(:key, :lane, :role, :verb, :since, :seq_since, :correlation_id, :limit) do
|
|
75
|
-
# rubocop:disable Metrics/ParameterLists
|
|
76
|
-
def self.build(key: nil, lane: nil, role: nil, verb: nil,
|
|
77
|
-
since: nil, seq_since: nil, correlation_id: nil, limit: nil)
|
|
78
|
-
new(key:, lane:, role:, verb:, since:, seq_since:, correlation_id:, limit:)
|
|
79
|
-
end
|
|
80
|
-
# rubocop:enable Metrics/ParameterLists
|
|
81
|
-
|
|
82
|
-
def matches?(row)
|
|
83
|
-
return false if key && row["key"] != key
|
|
84
|
-
return false if role && row["role"] != role
|
|
85
|
-
return false if verb && row["verb"] != verb
|
|
86
|
-
return false if since && (row["ts"].nil? || Time.parse(row["ts"]) < since)
|
|
87
|
-
return false if seq_since && (row["seq"].nil? || row["seq"] <= seq_since)
|
|
88
|
-
return false if correlation_id && row.dig("extras", "correlation_id") != correlation_id
|
|
89
|
-
|
|
90
|
-
true
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
private
|
|
95
|
-
|
|
96
|
-
def limit_reached?(rows, query) = query.limit && rows.length >= query.limit
|
|
97
|
-
|
|
98
|
-
def check_cursor_expiry!(seq_since)
|
|
99
|
-
return unless seq_since
|
|
100
|
-
|
|
101
|
-
log = @audit_log || Textus::Ports::AuditLog.new(@root)
|
|
102
|
-
min = log.min_available_seq
|
|
103
|
-
raise Textus::CursorExpired.new(requested: seq_since, min_available: min) if min && seq_since < min - 1
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def all_log_files
|
|
107
|
-
rotated = Dir.glob(File.join(Textus::Layout.audit_dir(@root), "audit.log.*"))
|
|
108
|
-
.reject { |path| path.end_with?(".meta.json") }
|
|
109
|
-
.sort_by { |path| -path.scan(/\d+$/).first.to_i }
|
|
110
|
-
active = File.exist?(@log_path) ? [@log_path] : []
|
|
111
|
-
rotated + active
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def parse_row(line)
|
|
115
|
-
return nil if line.empty?
|
|
116
|
-
return nil unless line.start_with?("{")
|
|
117
|
-
|
|
118
|
-
JSON.parse(line)
|
|
119
|
-
rescue JSON::ParserError
|
|
120
|
-
nil
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def key_in_lane?(key, lane)
|
|
124
|
-
mentry = @manifest.resolver.resolve(key).entry
|
|
125
|
-
mentry && mentry.lane == lane
|
|
126
|
-
rescue Textus::Error
|
|
127
|
-
false
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
end
|
data/lib/textus/action/base.rb
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Textus
|
|
4
|
-
module Action
|
|
5
|
-
@registry = {}
|
|
6
|
-
|
|
7
|
-
def self.registry = @registry
|
|
8
|
-
|
|
9
|
-
def self.register(klass)
|
|
10
|
-
@registry[klass.name.gsub("::", "/").downcase] = klass
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def self.fetch(type)
|
|
14
|
-
return @registry[type] if @registry[type]
|
|
15
|
-
|
|
16
|
-
match = @registry.values.find { |k| k.const_defined?(:TYPE, false) && type == k::TYPE }
|
|
17
|
-
raise Textus::UsageError.new("unknown action type: #{type}") unless match
|
|
18
|
-
|
|
19
|
-
@registry[type] = match
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
class Base
|
|
23
|
-
def self.inherited(subclass)
|
|
24
|
-
super
|
|
25
|
-
Textus::Action.register(subclass) if subclass.name
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def call(**)
|
|
29
|
-
raise NotImplementedError.new("#{self.class}#call")
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def args
|
|
33
|
-
params = self.class.instance_method(:initialize).parameters
|
|
34
|
-
names = params.select { |t,| %i[key keyreq].include?(t) }.map(&:last)
|
|
35
|
-
names.each_with_object({}) do |name, h|
|
|
36
|
-
val = instance_variable_get(:"@#{name}")
|
|
37
|
-
h[name] = val unless val.nil?
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
data/lib/textus/action/blame.rb
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "open3"
|
|
4
|
-
|
|
5
|
-
module Textus
|
|
6
|
-
module Action
|
|
7
|
-
class Blame < Base
|
|
8
|
-
extend Textus::Contract::DSL
|
|
9
|
-
|
|
10
|
-
verb :blame
|
|
11
|
-
summary "Annotate audit rows for a key with the git commit that introduced each file state."
|
|
12
|
-
surfaces :cli
|
|
13
|
-
cli "blame"
|
|
14
|
-
arg :key, String, required: true, positional: true, description: "entry key to blame"
|
|
15
|
-
arg :limit, Integer, required: false, description: "maximum number of audit rows to return"
|
|
16
|
-
view(:cli) { |rows, inputs| { "verb" => "blame", "key" => inputs[:key], "rows" => rows } }
|
|
17
|
-
|
|
18
|
-
def initialize(key:, limit: nil)
|
|
19
|
-
super()
|
|
20
|
-
@key = key
|
|
21
|
-
@limit = limit
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def call(container:, **)
|
|
25
|
-
@container = container
|
|
26
|
-
@manifest = container.manifest
|
|
27
|
-
@root = container.root
|
|
28
|
-
|
|
29
|
-
audit_rows = Textus::Action::Audit.new(key: @key, limit: @limit).call(container: container)
|
|
30
|
-
path = resolve_path(@key)
|
|
31
|
-
return audit_rows.map { |row| row.merge("git" => nil) } unless git_tracked?(path)
|
|
32
|
-
|
|
33
|
-
audit_rows.map { |row| row.merge("git" => git_commit_at(path, timestamp: row["ts"])) }
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def self.new(*args, **kwargs)
|
|
37
|
-
return super(**kwargs) unless args.any?
|
|
38
|
-
|
|
39
|
-
positional = instance_method(:initialize).parameters.slice(:keyreq, :key).map(&:last)
|
|
40
|
-
mapped = positional.zip(args).to_h
|
|
41
|
-
super(**mapped.merge(kwargs))
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
private
|
|
45
|
-
|
|
46
|
-
def resolve_path(key)
|
|
47
|
-
res = @manifest.resolver.resolve(key)
|
|
48
|
-
mentry = res.entry
|
|
49
|
-
path = res.path
|
|
50
|
-
path || Textus::Key::Path.resolve(@manifest.data, mentry)
|
|
51
|
-
rescue Textus::Error
|
|
52
|
-
nil
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def git_tracked?(path)
|
|
56
|
-
return false if path.nil?
|
|
57
|
-
return false unless File.exist?(path)
|
|
58
|
-
return false unless git_repo?
|
|
59
|
-
|
|
60
|
-
_out, _err, status = Open3.capture3(
|
|
61
|
-
"git", "ls-files", "--error-unmatch", path,
|
|
62
|
-
chdir: @root
|
|
63
|
-
)
|
|
64
|
-
status.success?
|
|
65
|
-
rescue Errno::ENOENT
|
|
66
|
-
false
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def git_repo?
|
|
70
|
-
dir = @root
|
|
71
|
-
loop do
|
|
72
|
-
return true if File.directory?(File.join(dir, ".git"))
|
|
73
|
-
|
|
74
|
-
parent = File.dirname(dir)
|
|
75
|
-
return false if parent == dir
|
|
76
|
-
|
|
77
|
-
dir = parent
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def git_commit_at(path, timestamp:)
|
|
82
|
-
args = ["git", "log", "-1"]
|
|
83
|
-
args << "--before=#{timestamp}" if timestamp
|
|
84
|
-
args += ["--format=%H%x09%an%x09%aI%x09%s", "--", path]
|
|
85
|
-
out, _err, status = Open3.capture3(*args, chdir: @root)
|
|
86
|
-
return nil unless status.success?
|
|
87
|
-
|
|
88
|
-
sha, author, date, subject = out.strip.split("\t", 4)
|
|
89
|
-
return nil if sha.nil? || sha.empty?
|
|
90
|
-
|
|
91
|
-
{ "sha" => sha, "author" => author, "date" => date, "subject" => subject }
|
|
92
|
-
rescue Errno::ENOENT
|
|
93
|
-
nil
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
end
|
data/lib/textus/action/boot.rb
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Textus
|
|
4
|
-
module Action
|
|
5
|
-
class Boot < Base
|
|
6
|
-
extend Textus::Contract::DSL
|
|
7
|
-
|
|
8
|
-
verb :boot
|
|
9
|
-
summary "Return the orientation contract: lanes, agent_quickstart, agent_protocol, and pre-computed artifacts."
|
|
10
|
-
surfaces :cli, :mcp
|
|
11
|
-
|
|
12
|
-
def call(container:, **)
|
|
13
|
-
Textus::Boot.build(container: container)
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|