adopt-cli 0.4.2__tar.gz → 0.4.4__tar.gz
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.
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/PKG-INFO +1 -1
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/pyproject.toml +1 -1
- adopt_cli-0.4.4/src/adopt_cli/_build_info.py +6 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_handover_support.py +7 -2
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_knowledge_support.py +28 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_pack_support.py +18 -8
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/knowledge.py +87 -13
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/store_option.py +11 -0
- adopt_cli-0.4.2/src/adopt_cli/_build_info.py +0 -6
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/.gitignore +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/LICENSE +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/NOTICE +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/__init__.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/__init__.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_ask_support.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_ci_sense_probes.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_ci_sense_support.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_conflict_support.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_coverage_support.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_draft_support.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_drafting.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_map_support.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_probe_support.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_refresh_support.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_remote_support.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/_review_remote.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/agent.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/answer.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/ask.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/boundary.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/ci_sense.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/coverage.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/detect.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/doctor.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/draft.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/freshness.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/handover.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/identity.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/init.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/interchange.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/map_command.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/pack.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/policy.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/probe.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/pull.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/refresh.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/serve.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/store.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/commands/version.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/config.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/json_out.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/main.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/py.typed +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/remote.py +0 -0
- {adopt_cli-0.4.2 → adopt_cli-0.4.4}/src/adopt_cli/replica.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: adopt-cli
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.4
|
|
4
4
|
Summary: The adopt command surface: config resolution, JSON mode, exit codes.
|
|
5
5
|
Project-URL: Homepage, https://github.com/onboardux/onboard-core
|
|
6
6
|
Project-URL: Source, https://github.com/onboardux/onboard-core
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"""Generated by scripts/embed_build_info.py; do not edit in a release build."""
|
|
2
|
+
|
|
3
|
+
from typing import Final
|
|
4
|
+
|
|
5
|
+
SBOM_SHA256: Final[str | None] = '7ac34a2179a12abe098bc85d0bb92f3bfaf3b739137331be994bd2e5cdd9ffe9'
|
|
6
|
+
BUILD_ID: Final[str | None] = 'github:onboardux/onboard-core:37424931824:1:4e9cd060543afa8eed40b405d4f8c8d73379ffd4'
|
|
@@ -447,9 +447,14 @@ def opening_position(handle: Any, *, system: ResolvedSystem, now: _dt.datetime)
|
|
|
447
447
|
accumulated before it (v6.1 §6's sales-motion note), and a closure that
|
|
448
448
|
cannot say where it started cannot say what it added.
|
|
449
449
|
"""
|
|
450
|
+
from adopt_knowledge import is_live
|
|
451
|
+
|
|
450
452
|
coverage = _coverage(handle, system)
|
|
451
|
-
|
|
452
|
-
|
|
453
|
+
# Live referents only, as `adopt gaps` counts them: a retired identity is
|
|
454
|
+
# not part of the system being handed over.
|
|
455
|
+
live = [row for row in coverage.identities if is_live(row)]
|
|
456
|
+
identities = len(live)
|
|
457
|
+
covered = sum(1 for row in live if row.covered)
|
|
453
458
|
|
|
454
459
|
confirmed = 0
|
|
455
460
|
unverified = 0
|
|
@@ -50,6 +50,7 @@ __all__ = [
|
|
|
50
50
|
"identity_views",
|
|
51
51
|
"pending_items",
|
|
52
52
|
"presented_revisions",
|
|
53
|
+
"presented_texts",
|
|
53
54
|
"rebind_target",
|
|
54
55
|
"refresh_population",
|
|
55
56
|
"resolve_identity",
|
|
@@ -327,6 +328,33 @@ def presented_revisions(handle: KnowledgeStoreView) -> frozenset[str]:
|
|
|
327
328
|
)
|
|
328
329
|
|
|
329
330
|
|
|
331
|
+
def presented_texts(handle: KnowledgeStoreView) -> frozenset[tuple[str, str]]:
|
|
332
|
+
"""`(item_id, document digest)` for every text an ingest suggestion batch carried.
|
|
333
|
+
|
|
334
|
+
`presented_revisions`' own rule -- "new text means a new revision" -- stated
|
|
335
|
+
the other way round, because one writer breaks it: `confirm-current`
|
|
336
|
+
appends a revision with the same text and the same digest, and the next
|
|
337
|
+
ingest used to re-propose every suggestion the reviewer had rejected for
|
|
338
|
+
that text. Suggestion batches only: a verification batch asked whether the
|
|
339
|
+
text is true, not what it is about.
|
|
340
|
+
"""
|
|
341
|
+
suggestion_batches = {
|
|
342
|
+
row.id
|
|
343
|
+
for row in _rows(handle, "review_batch", ReviewBatch)
|
|
344
|
+
if source_of(row.batch_key) == SOURCE_INGEST
|
|
345
|
+
}
|
|
346
|
+
carried = {
|
|
347
|
+
row.proposed_revision_id
|
|
348
|
+
for row in _rows(handle, "review_item", ReviewItem)
|
|
349
|
+
if row.review_batch_id in suggestion_batches and row.proposed_revision_id is not None
|
|
350
|
+
}
|
|
351
|
+
return frozenset(
|
|
352
|
+
(row.item_id, row.source_version)
|
|
353
|
+
for row in _rows(handle, "knowledge_revision", KnowledgeRevision)
|
|
354
|
+
if row.id in carried and row.source_version is not None
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
|
|
330
358
|
def resolve_identity(handle: KnowledgeStoreView, uri: str) -> Identity | None:
|
|
331
359
|
"""An identity by URI, following an alias to the identity that replaced it.
|
|
332
360
|
|
|
@@ -130,19 +130,28 @@ def build_drafts(handle: Any, *, system_id: str, environment_id: str | None) ->
|
|
|
130
130
|
|
|
131
131
|
|
|
132
132
|
def build_identities(
|
|
133
|
-
handle: Any,
|
|
133
|
+
handle: Any,
|
|
134
|
+
*,
|
|
135
|
+
system_id: str,
|
|
136
|
+
environment_id: str | None,
|
|
137
|
+
covered: frozenset[str],
|
|
138
|
+
live: frozenset[str],
|
|
134
139
|
) -> _Reader:
|
|
135
140
|
"""The inventory, with coverage taken from the recompute rather than the cache.
|
|
136
141
|
|
|
137
142
|
`identity.covered_cache` is a cache that alarms rather than self-heals, and
|
|
138
143
|
a pack must not be the thing that reads it: the recompute result the caller
|
|
139
|
-
already holds is the authority (Build 0's rule, unchanged).
|
|
144
|
+
already holds is the authority (Build 0's rule, unchanged). Only `live`
|
|
145
|
+
referents are listed: a pack describes the system as it is, and a retired
|
|
146
|
+
identity counted into "covered N of M" makes the handover read worse with
|
|
147
|
+
every rename (`adopt_knowledge.is_live`).
|
|
140
148
|
"""
|
|
141
149
|
rows = [
|
|
142
150
|
PackIdentity(uri=str(row.uri), kind=str(row.identity_kind), covered=str(row.id) in covered)
|
|
143
151
|
for row in handle.pack_records().identities_in_scope(
|
|
144
152
|
system_id=system_id, environment_id=environment_id
|
|
145
153
|
)
|
|
154
|
+
if str(row.id) in live
|
|
146
155
|
]
|
|
147
156
|
return _Reader(tuple(rows))
|
|
148
157
|
|
|
@@ -238,23 +247,24 @@ def assemble_pack(handle: Any, *, audience: str, system_id: str, environment_id:
|
|
|
238
247
|
rendering it is a pure function and the caller may close the store first.
|
|
239
248
|
"""
|
|
240
249
|
from adopt_handover import assemble
|
|
241
|
-
from adopt_knowledge import rank_gaps
|
|
250
|
+
from adopt_knowledge import is_live, rank_gaps
|
|
242
251
|
|
|
243
252
|
from adopt_coverage import recompute_coverage
|
|
244
253
|
|
|
245
254
|
coverage = recompute_coverage(handle.coverage_records(), system_id, environment_id)
|
|
246
255
|
covered = frozenset(row.identity_id for row in coverage.identities if row.covered)
|
|
256
|
+
live = frozenset(row.identity_id for row in coverage.identities if is_live(row))
|
|
247
257
|
ranked = rank_gaps(coverage.identities)
|
|
248
|
-
# Every identity the recompute evaluated, by URI. The conflict join
|
|
249
|
-
# it, and it is the same population the inventory renders -- so a
|
|
250
|
-
# can never name an identity this pack does not list.
|
|
251
|
-
uris = {row.identity_id: row.uri for row in coverage.identities}
|
|
258
|
+
# Every live identity the recompute evaluated, by URI. The conflict join
|
|
259
|
+
# needs it, and it is the same population the inventory renders -- so a
|
|
260
|
+
# conflict can never name an identity this pack does not list.
|
|
261
|
+
uris = {row.identity_id: row.uri for row in coverage.identities if row.identity_id in live}
|
|
252
262
|
|
|
253
263
|
return assemble(
|
|
254
264
|
audience=audience,
|
|
255
265
|
knowledge=build_knowledge(handle, system_id=system_id, environment_id=environment_id),
|
|
256
266
|
identities=build_identities(
|
|
257
|
-
handle, system_id=system_id, environment_id=environment_id, covered=covered
|
|
267
|
+
handle, system_id=system_id, environment_id=environment_id, covered=covered, live=live
|
|
258
268
|
),
|
|
259
269
|
freshness=FreshnessCache(handle),
|
|
260
270
|
boundary=build_boundary(handle, system_id=system_id, environment_id=environment_id),
|
|
@@ -45,6 +45,19 @@ ActorOption = Annotated[
|
|
|
45
45
|
str | None,
|
|
46
46
|
typer.Option("--actor", help="Who is running this. Recorded on every revision written."),
|
|
47
47
|
]
|
|
48
|
+
UnverifiedOption = Annotated[
|
|
49
|
+
bool,
|
|
50
|
+
typer.Option(
|
|
51
|
+
"--unverified",
|
|
52
|
+
help=(
|
|
53
|
+
"Land these documents unverified, each queued for a person to confirm in "
|
|
54
|
+
"`adopt review`. Use it for text nobody has vouched for -- anything an agent "
|
|
55
|
+
"wrote or helped write. Until confirmed it counts toward no coverage, serves "
|
|
56
|
+
"no answer and reaches no pack. Its name-match suggestions are held back "
|
|
57
|
+
"(`suggestions_deferred`) and queued by the next ingest of the confirmed text."
|
|
58
|
+
),
|
|
59
|
+
),
|
|
60
|
+
]
|
|
48
61
|
StoreOption = Annotated[Path | None, typer.Option("--store", help="Store path override.")]
|
|
49
62
|
JsonOption = Annotated[bool, typer.Option("--json", help="Emit the strict JSON envelope only.")]
|
|
50
63
|
|
|
@@ -54,6 +67,7 @@ def ingest(
|
|
|
54
67
|
scope: ScopeOption = None,
|
|
55
68
|
audience: AudienceOption = None,
|
|
56
69
|
actor: ActorOption = None,
|
|
70
|
+
unverified: UnverifiedOption = False,
|
|
57
71
|
store: StoreOption = None,
|
|
58
72
|
json_output: JsonOption = False,
|
|
59
73
|
) -> None:
|
|
@@ -66,6 +80,7 @@ def ingest(
|
|
|
66
80
|
bound_pairs,
|
|
67
81
|
identity_views,
|
|
68
82
|
presented_revisions,
|
|
83
|
+
presented_texts,
|
|
69
84
|
stored_documents,
|
|
70
85
|
)
|
|
71
86
|
from adopt_cli.commands._map_support import resolve_scope
|
|
@@ -87,7 +102,9 @@ def ingest(
|
|
|
87
102
|
unit=StoreUnitOfWork(handle),
|
|
88
103
|
bound_pairs=bound_pairs(handle),
|
|
89
104
|
presented_revisions=presented_revisions(handle),
|
|
105
|
+
presented_texts=presented_texts(handle),
|
|
90
106
|
actor_id=actor,
|
|
107
|
+
unverified=unverified,
|
|
91
108
|
)
|
|
92
109
|
payload = _ingest_payload(report)
|
|
93
110
|
finally:
|
|
@@ -107,6 +124,13 @@ def _ingest_payload(report: Any) -> dict[str, Any]:
|
|
|
107
124
|
"suggestions": report.suggestions,
|
|
108
125
|
"review_batch": report.review_batch_id,
|
|
109
126
|
"review_items": list(report.review_item_ids),
|
|
127
|
+
# Additive (`--unverified`): what this run wrote unverified, and the
|
|
128
|
+
# batch a person confirms it in. Present on every run so the envelope
|
|
129
|
+
# is one shape whichever way the flag was set.
|
|
130
|
+
"unverified": report.unverified,
|
|
131
|
+
"verification_batch": report.verification_batch_id,
|
|
132
|
+
"verification_items": list(report.verification_item_ids),
|
|
133
|
+
"suggestions_deferred": report.suggestions_deferred,
|
|
110
134
|
"unknown_audiences": list(report.unknown_audiences),
|
|
111
135
|
"ingested": [
|
|
112
136
|
{
|
|
@@ -286,10 +310,17 @@ def bind(
|
|
|
286
310
|
|
|
287
311
|
For the links no heuristic finds. A binding made here is human-justified by
|
|
288
312
|
construction, which is the same standing a confirmed suggestion has.
|
|
313
|
+
|
|
314
|
+
**A pair bound before is revived, not refused.** One item and one identity
|
|
315
|
+
have one binding for ever, so a link a `rebind` superseded or a retirement
|
|
316
|
+
withdrew cannot be created again -- and until this path existed, nothing
|
|
317
|
+
could restore it. Binding such a pair appends an `active` revision to its
|
|
318
|
+
chain and restarts its freshness, and the payload says `reactivated`. A pair
|
|
319
|
+
that is live already is still refused.
|
|
289
320
|
"""
|
|
290
321
|
from adopt_knowledge.ingest import EXTRACTOR_MANUAL, INGEST_EXTRACTOR_VERSION
|
|
291
322
|
|
|
292
|
-
from adopt_cli.commands._knowledge_support import resolve_identity
|
|
323
|
+
from adopt_cli.commands._knowledge_support import StoreUnitOfWork, resolve_identity
|
|
293
324
|
from adopt_obs import AdoptError, ErrorCode
|
|
294
325
|
|
|
295
326
|
handle = open_configured_store(store, read_only=False, verb="bind")
|
|
@@ -312,22 +343,50 @@ def bind(
|
|
|
312
343
|
)
|
|
313
344
|
from adopt_cli.commands._coverage_support import coverage_cache_kept_current
|
|
314
345
|
|
|
346
|
+
bindings = handle.bindings()
|
|
347
|
+
earlier = next(
|
|
348
|
+
(row for row in bindings.for_identity(identity.id) if row.item_id == knowledge_id),
|
|
349
|
+
None,
|
|
350
|
+
)
|
|
351
|
+
head_status = (
|
|
352
|
+
None
|
|
353
|
+
if earlier is None
|
|
354
|
+
else handle.freshness_records().head_binding_statuses([earlier.id]).get(earlier.id)
|
|
355
|
+
)
|
|
315
356
|
with coverage_cache_kept_current(handle, identity.system_id):
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
357
|
+
if earlier is not None and head_status in _REVIVABLE_BINDING_STATUSES:
|
|
358
|
+
with StoreUnitOfWork(handle).transaction():
|
|
359
|
+
revision_id = bindings.reactivate(
|
|
360
|
+
binding_id=earlier.id,
|
|
361
|
+
expected_head_id=earlier.current_revision_id,
|
|
362
|
+
extractor=EXTRACTOR_MANUAL,
|
|
363
|
+
extractor_version=INGEST_EXTRACTOR_VERSION,
|
|
364
|
+
actor_id=actor,
|
|
365
|
+
)
|
|
366
|
+
handle.changes().restart_bindings([earlier.id])
|
|
367
|
+
binding_id = earlier.id
|
|
368
|
+
# The pair's row keeps the load-bearing flag it was created with;
|
|
369
|
+
# report what is true of it rather than what was asked for.
|
|
370
|
+
is_load_bearing = bool(earlier.is_load_bearing)
|
|
371
|
+
else:
|
|
372
|
+
# A new pair, or the facade's refusal of one that is live already.
|
|
373
|
+
binding_id, revision_id = bindings.bind(
|
|
374
|
+
item_id=knowledge_id,
|
|
375
|
+
identity_id=identity.id,
|
|
376
|
+
is_load_bearing=not not_load_bearing,
|
|
377
|
+
extractor=EXTRACTOR_MANUAL,
|
|
378
|
+
extractor_version=INGEST_EXTRACTOR_VERSION,
|
|
379
|
+
actor_id=actor,
|
|
380
|
+
)
|
|
381
|
+
is_load_bearing = not not_load_bearing
|
|
324
382
|
payload = {
|
|
325
383
|
"binding": binding_id,
|
|
326
384
|
"revision": revision_id,
|
|
327
385
|
"item": knowledge_id,
|
|
328
386
|
"identity": identity.id,
|
|
329
387
|
"uri": identity.uri,
|
|
330
|
-
"is_load_bearing":
|
|
388
|
+
"is_load_bearing": is_load_bearing,
|
|
389
|
+
"reactivated": earlier is not None and head_status in _REVIVABLE_BINDING_STATUSES,
|
|
331
390
|
# Stated because the alias is silent otherwise: binding to a moved
|
|
332
391
|
# identity's old address is correct and surprising, and the operator
|
|
333
392
|
# should see which referent they actually bound.
|
|
@@ -339,6 +398,11 @@ def bind(
|
|
|
339
398
|
emit(payload, as_json=json_output, title="adopt bind")
|
|
340
399
|
|
|
341
400
|
|
|
401
|
+
#: A binding head a person may take up again: replaced by a `rebind`, or
|
|
402
|
+
#: withdrawn. `active` is absent on purpose -- that pair is bound already.
|
|
403
|
+
_REVIVABLE_BINDING_STATUSES: Final[frozenset[str]] = frozenset({"moved", "retired"})
|
|
404
|
+
|
|
405
|
+
|
|
342
406
|
AckOption = Annotated[
|
|
343
407
|
str | None,
|
|
344
408
|
typer.Option("--ack", help="Acknowledge one gap by its gap-key: someone owns closing it."),
|
|
@@ -550,10 +614,19 @@ def _parse_until(value: str | None) -> _dt.datetime | None:
|
|
|
550
614
|
def _gaps_payload(
|
|
551
615
|
result: Any, ranked: tuple[Any, ...], dispositions: dict[str, Any]
|
|
552
616
|
) -> dict[str, Any]:
|
|
617
|
+
from adopt_knowledge import is_live
|
|
618
|
+
|
|
619
|
+
# Counted over live referents, the population the gap list is drawn from,
|
|
620
|
+
# so `uncovered` is the length of `gaps`. `not_active` is what was set
|
|
621
|
+
# aside, so the numbers still reconcile with `adopt coverage recompute`.
|
|
622
|
+
evaluated = () if result is None else tuple(result.identities)
|
|
623
|
+
live = [row for row in evaluated if is_live(row)]
|
|
624
|
+
covered = sum(1 for row in live if row.covered)
|
|
553
625
|
return {
|
|
554
|
-
"identities":
|
|
555
|
-
"covered":
|
|
556
|
-
"uncovered":
|
|
626
|
+
"identities": len(live),
|
|
627
|
+
"covered": covered,
|
|
628
|
+
"uncovered": len(live) - covered,
|
|
629
|
+
"not_active": len(evaluated) - len(live),
|
|
557
630
|
"gaps": [
|
|
558
631
|
{
|
|
559
632
|
"kind": gap.kind,
|
|
@@ -959,6 +1032,7 @@ def _resolve_change(
|
|
|
959
1032
|
target_identity_id=target_id,
|
|
960
1033
|
target_uri=target_uri,
|
|
961
1034
|
actor_id=actor,
|
|
1035
|
+
freshener=handle.changes(),
|
|
962
1036
|
)
|
|
963
1037
|
else:
|
|
964
1038
|
outcome = confirm_current_item(
|
|
@@ -101,6 +101,17 @@ def open_configured_store(
|
|
|
101
101
|
**capture** paths are refused separately, where they write canon.
|
|
102
102
|
"""
|
|
103
103
|
path = configured_store_path(override)
|
|
104
|
+
if not path.exists():
|
|
105
|
+
# The library's own hint names `migrate=True`, an argument no operator can
|
|
106
|
+
# pass. Missing here means `init` has not run, or the command ran from
|
|
107
|
+
# somewhere other than the repository -- say which, and how to tell.
|
|
108
|
+
raise AdoptError(
|
|
109
|
+
ErrorCode.SCHEMA_MIGRATION_PENDING,
|
|
110
|
+
message=f"no store exists at {path}",
|
|
111
|
+
hint="Run `adopt init` in the repository first, or run this from the directory "
|
|
112
|
+
"that holds `.adopt/`, or name the store with --store or ADOPT_STORE_PATH. "
|
|
113
|
+
"`adopt doctor` shows which store path resolved and where it came from.",
|
|
114
|
+
)
|
|
104
115
|
if not read_only and non_canon_reason is None:
|
|
105
116
|
refuse_write_to_replica(path, verb=verb)
|
|
106
117
|
return open_store(path, read_only=read_only)
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
"""Generated by scripts/embed_build_info.py; do not edit in a release build."""
|
|
2
|
-
|
|
3
|
-
from typing import Final
|
|
4
|
-
|
|
5
|
-
SBOM_SHA256: Final[str | None] = 'd9c82e3f0197e2d81b8ef92be4bdbb2f9f38710ee54d8db9ca3baa099047fda8'
|
|
6
|
-
BUILD_ID: Final[str | None] = 'github:onboardux/onboard-core:37286165801:1:b50f2ec2a85b4271c0d445d8432b105574a8978a'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|