@deftai/directive-content 0.55.1 → 0.56.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.
- package/.githooks/pre-commit +143 -0
- package/.githooks/pre-push +121 -0
- package/QUICK-START.md +13 -3
- package/Taskfile.yml +934 -0
- package/UPGRADING.md +82 -11
- package/events/README.md +3 -3
- package/package.json +5 -4
- package/packs/skills/skills-pack-0.1.json +22 -22
- package/scripts/_agents_md.py +494 -0
- package/scripts/_cache_fetch.py +635 -0
- package/scripts/_cache_quota.py +529 -0
- package/scripts/_cache_refresh.py +163 -0
- package/scripts/_cache_validate.py +209 -0
- package/scripts/_content_root.py +42 -0
- package/scripts/_doctor_state.py +277 -0
- package/scripts/_event_detect.py +305 -0
- package/scripts/_events.py +514 -0
- package/scripts/_lifecycle_hygiene.py +568 -0
- package/scripts/_pathspec.py +91 -0
- package/scripts/_policy_show_cli.py +266 -0
- package/scripts/_precutover.py +92 -0
- package/scripts/_project_context.py +224 -0
- package/scripts/_project_definition_io.py +164 -0
- package/scripts/_relocate_snapshot.py +209 -0
- package/scripts/_relocate_states.py +343 -0
- package/scripts/_resolve_preflight_path.py +152 -0
- package/scripts/_safe_subprocess.py +167 -0
- package/scripts/_session_start_hook.py +205 -0
- package/scripts/_sor_gate_diff.py +365 -0
- package/scripts/_stdio_utf8.py +59 -0
- package/scripts/_triage_bootstrap_gitignore.py +904 -0
- package/scripts/_triage_classify_cli.py +122 -0
- package/scripts/_triage_queue_cli.py +625 -0
- package/scripts/_triage_scope_cli.py +343 -0
- package/scripts/_triage_scope_drift_cli.py +121 -0
- package/scripts/_triage_scope_ignores.py +286 -0
- package/scripts/_triage_scope_milestone.py +432 -0
- package/scripts/_triage_scope_mutations.py +337 -0
- package/scripts/_triage_scope_renderers.py +207 -0
- package/scripts/_triage_smoketest_stages.py +674 -0
- package/scripts/_triage_subscribe_cli.py +140 -0
- package/scripts/_triage_welcome_cli.py +421 -0
- package/scripts/_vbrief_build.py +239 -0
- package/scripts/_vbrief_fidelity.py +479 -0
- package/scripts/_vbrief_legacy.py +589 -0
- package/scripts/_vbrief_reconciliation.py +883 -0
- package/scripts/_vbrief_routing.py +277 -0
- package/scripts/_vbrief_safety.py +778 -0
- package/scripts/_vbrief_sources.py +312 -0
- package/scripts/_vbrief_speckit.py +262 -0
- package/scripts/_vbrief_story_quality.py +353 -0
- package/scripts/_vbrief_validation.py +299 -0
- package/scripts/build_dist.py +412 -0
- package/scripts/cache.py +1078 -0
- package/scripts/cache_scanner.py +745 -0
- package/scripts/candidates_log.py +432 -0
- package/scripts/capacity_backfill.py +680 -0
- package/scripts/capacity_show.py +653 -0
- package/scripts/ci_local.py +689 -0
- package/scripts/code_structure_validate.py +765 -0
- package/scripts/codebase_default_extractor.py +495 -0
- package/scripts/codebase_map.py +304 -0
- package/scripts/codebase_map_fresh.py +104 -0
- package/scripts/codebase_projection_registry.py +94 -0
- package/scripts/codebase_provider.py +582 -0
- package/scripts/doctor.py +2257 -0
- package/scripts/framework_commands.py +505 -0
- package/scripts/gh_rest.py +882 -0
- package/scripts/github_auth_modes.py +437 -0
- package/scripts/github_body.py +292 -0
- package/scripts/ip_risk.py +531 -0
- package/scripts/issue_emit.py +670 -0
- package/scripts/issue_ingest.py +1064 -0
- package/scripts/migrate_preflight.py +418 -0
- package/scripts/migrate_vbrief.py +2677 -0
- package/scripts/monitor_pr.py +401 -0
- package/scripts/pack_migrate_lessons.py +336 -0
- package/scripts/pack_migrate_patterns.py +254 -0
- package/scripts/pack_migrate_rules.py +350 -0
- package/scripts/pack_migrate_skills.py +423 -0
- package/scripts/pack_migrate_strategies.py +311 -0
- package/scripts/pack_migrate_swarm_spec.py +250 -0
- package/scripts/pack_render.py +434 -0
- package/scripts/packs_slice.py +712 -0
- package/scripts/platform_capabilities.py +336 -0
- package/scripts/policy.py +2826 -0
- package/scripts/policy_set.py +324 -0
- package/scripts/pr_check_closing_keywords.py +524 -0
- package/scripts/pr_check_protected_issues.py +267 -0
- package/scripts/pr_merge_readiness.py +1004 -0
- package/scripts/pr_wait_mergeable.py +669 -0
- package/scripts/prd_render.py +159 -0
- package/scripts/preflight_architecture_sor.py +974 -0
- package/scripts/preflight_branch.py +289 -0
- package/scripts/preflight_cache.py +974 -0
- package/scripts/preflight_gh.py +721 -0
- package/scripts/preflight_implementation.py +272 -0
- package/scripts/preflight_story_start.py +838 -0
- package/scripts/preflight_wip_cap.py +149 -0
- package/scripts/probe_session.py +545 -0
- package/scripts/project_render.py +293 -0
- package/scripts/quarantine_ext.py +237 -0
- package/scripts/reconcile_issues.py +1442 -0
- package/scripts/refresh-path.ps1 +107 -0
- package/scripts/release.py +2030 -0
- package/scripts/release_e2e.py +1011 -0
- package/scripts/release_publish.py +486 -0
- package/scripts/release_rollback.py +980 -0
- package/scripts/relocate.py +1034 -0
- package/scripts/resolve_changelog_unreleased.py +667 -0
- package/scripts/resolve_version.py +490 -0
- package/scripts/resume_conditions.py +706 -0
- package/scripts/ritual_sentinel.py +609 -0
- package/scripts/roadmap_render.py +635 -0
- package/scripts/rule_ownership_lint.py +325 -0
- package/scripts/scm.py +591 -0
- package/scripts/scope_audit_log.py +387 -0
- package/scripts/scope_decompose.py +654 -0
- package/scripts/scope_demote.py +509 -0
- package/scripts/scope_lifecycle.py +1126 -0
- package/scripts/scope_undo.py +772 -0
- package/scripts/session_start.py +406 -0
- package/scripts/setup_ghx.py +339 -0
- package/scripts/setup_windows.ps1 +220 -0
- package/scripts/slice_audit.py +585 -0
- package/scripts/slice_record.py +530 -0
- package/scripts/slice_record_existing.py +692 -0
- package/scripts/slug_normalize.py +178 -0
- package/scripts/spec_render.py +477 -0
- package/scripts/spec_validate.py +238 -0
- package/scripts/subagent_monitor.py +658 -0
- package/scripts/swarm_complete_cohort.py +644 -0
- package/scripts/swarm_launch.py +1206 -0
- package/scripts/swarm_readiness.py +554 -0
- package/scripts/swarm_verify_review_clean.py +438 -0
- package/scripts/swarm_worktrees.py +497 -0
- package/scripts/toolchain-check.py +52 -0
- package/scripts/triage_actions.py +871 -0
- package/scripts/triage_bootstrap.py +1153 -0
- package/scripts/triage_bulk.py +630 -0
- package/scripts/triage_classify.py +932 -0
- package/scripts/triage_help.py +1685 -0
- package/scripts/triage_queue.py +1944 -0
- package/scripts/triage_reconcile.py +581 -0
- package/scripts/triage_refresh.py +643 -0
- package/scripts/triage_scope.py +999 -0
- package/scripts/triage_scope_drift.py +575 -0
- package/scripts/triage_smoketest.py +396 -0
- package/scripts/triage_subscribe.py +399 -0
- package/scripts/triage_summary.py +1011 -0
- package/scripts/triage_welcome.py +1178 -0
- package/scripts/ts_check_lane.py +86 -0
- package/scripts/validate-links.py +64 -0
- package/scripts/validate_strategy_output.py +212 -0
- package/scripts/vbrief_activate.py +228 -0
- package/scripts/vbrief_migrate_conformance.py +368 -0
- package/scripts/vbrief_reconcile_graph.py +306 -0
- package/scripts/vbrief_reconcile_labels.py +460 -0
- package/scripts/vbrief_reconcile_umbrellas.py +741 -0
- package/scripts/vbrief_validate.py +1195 -0
- package/scripts/verify-stubs.py +61 -0
- package/scripts/verify_capacity.py +160 -0
- package/scripts/verify_encoding.py +699 -0
- package/scripts/verify_hooks_installed.py +206 -0
- package/scripts/verify_investigation.py +360 -0
- package/scripts/verify_judgment_gates.py +827 -0
- package/scripts/verify_no_task_runtime.py +171 -0
- package/scripts/verify_scm_boundary.py +509 -0
- package/scripts/verify_session_ritual.py +389 -0
- package/scripts/verify_tools.py +426 -0
- package/scripts/verify_vbrief_conformance.py +478 -0
- package/skills/deft-directive-swarm/SKILL.md +7 -26
- package/skills/deft-directive-sync/SKILL.md +1 -1
- package/tasks/architecture.yml +13 -0
- package/tasks/cache.yml +69 -0
- package/tasks/capacity.yml +38 -0
- package/tasks/change.yml +46 -0
- package/tasks/changelog.yml +24 -0
- package/tasks/ci.yml +49 -0
- package/tasks/codebase.yml +47 -0
- package/tasks/commit.yml +30 -0
- package/tasks/core.yml +126 -0
- package/tasks/deployments.yml +54 -0
- package/tasks/framework.yml +74 -0
- package/tasks/install.yml +60 -0
- package/tasks/issue.yml +50 -0
- package/tasks/migrate.yml +73 -0
- package/tasks/packs.yml +92 -0
- package/tasks/policy.yml +75 -0
- package/tasks/pr.yml +89 -0
- package/tasks/prd.yml +39 -0
- package/tasks/project.yml +27 -0
- package/tasks/reconcile.yml +32 -0
- package/tasks/relocate.yml +56 -0
- package/tasks/roadmap.yml +28 -0
- package/tasks/scm.yml +126 -0
- package/tasks/scope-undo.yml +36 -0
- package/tasks/scope.yml +141 -0
- package/tasks/session.yml +19 -0
- package/tasks/setup.yml +37 -0
- package/tasks/slice.yml +69 -0
- package/tasks/spec.yml +41 -0
- package/tasks/swarm.yml +85 -0
- package/tasks/toolchain.yml +13 -0
- package/tasks/triage-actions.yml +94 -0
- package/tasks/triage-bootstrap.yml +43 -0
- package/tasks/triage-bulk.yml +75 -0
- package/tasks/triage-classify.yml +30 -0
- package/tasks/triage-queue.yml +50 -0
- package/tasks/triage-reconcile.yml +29 -0
- package/tasks/triage-scope-drift.yml +29 -0
- package/tasks/triage-scope.yml +31 -0
- package/tasks/triage-smoketest.yml +33 -0
- package/tasks/triage-subscribe.yml +36 -0
- package/tasks/triage-summary.yml +29 -0
- package/tasks/triage-welcome.yml +32 -0
- package/tasks/ts.yml +328 -0
- package/tasks/vbrief.yml +206 -0
- package/tasks/verify.yml +292 -0
- package/templates/agents-entry.md +2 -2
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"""Shared helpers for building scope vBRIEF dicts.
|
|
2
|
+
|
|
3
|
+
Extracted from ``scripts/migrate_vbrief.py`` so ``scripts/issue_ingest.py`` (and
|
|
4
|
+
any future ingestion / generation script) can reuse them without cross-importing
|
|
5
|
+
the migrator. The canonical names are the public ``slugify`` / ``TODAY`` /
|
|
6
|
+
``create_scope_vbrief`` surface; ``migrate_vbrief.py`` continues to re-export
|
|
7
|
+
the legacy underscore-prefixed aliases for backwards compatibility.
|
|
8
|
+
|
|
9
|
+
Story: #454 (task issue:ingest).
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import copy
|
|
15
|
+
import re
|
|
16
|
+
from datetime import UTC, datetime
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
19
|
+
# ----------------------------------------------------------------------------
|
|
20
|
+
# Date helper
|
|
21
|
+
# ----------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
# Exposed for callers that want the canonical YYYY-MM-DD date used across
|
|
24
|
+
# ingestion / migration filenames. Kept module-level so monkeypatching in tests
|
|
25
|
+
# is straightforward.
|
|
26
|
+
TODAY: str = datetime.now(UTC).strftime("%Y-%m-%d")
|
|
27
|
+
|
|
28
|
+
# ----------------------------------------------------------------------------
|
|
29
|
+
# Emitted vBRIEF version (#533)
|
|
30
|
+
# ----------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
# Canonical ``vBRIEFInfo.version`` string emitted on every scope vBRIEF built
|
|
33
|
+
# via :func:`create_scope_vbrief`. Bumped from ``"0.5"`` to ``"0.6"`` as part
|
|
34
|
+
# of the Agent 2 schema vendor transition (#533). During the transition the
|
|
35
|
+
# validator accepts both strings; ingestion/generation paths only emit the
|
|
36
|
+
# newer one.
|
|
37
|
+
EMITTED_VBRIEF_VERSION: str = "0.6"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# ----------------------------------------------------------------------------
|
|
41
|
+
# Slugification
|
|
42
|
+
# ----------------------------------------------------------------------------
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def slugify(text: str) -> str:
|
|
46
|
+
"""Convert a title to a filename-safe slug.
|
|
47
|
+
|
|
48
|
+
- Lowercase, collapse whitespace/underscores to single hyphens
|
|
49
|
+
- Drop characters that are not [a-z0-9-]
|
|
50
|
+
- Trim to 60 characters maximum and strip leading/trailing hyphens
|
|
51
|
+
"""
|
|
52
|
+
slug = text.lower().strip()
|
|
53
|
+
# Preserve underscores through the strip pass so the next line can fold
|
|
54
|
+
# them into hyphens (matches the documented contract).
|
|
55
|
+
slug = re.sub(r"[^a-z0-9\s_-]", "", slug)
|
|
56
|
+
slug = re.sub(r"[\s_]+", "-", slug)
|
|
57
|
+
slug = re.sub(r"-+", "-", slug)
|
|
58
|
+
return slug[:60].strip("-")
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# ----------------------------------------------------------------------------
|
|
62
|
+
# Migrator provenance metadata namespace (#616)
|
|
63
|
+
# ----------------------------------------------------------------------------
|
|
64
|
+
|
|
65
|
+
# Per issue #616 (option A, scope-clamped), per-issue scope vBRIEFs emit
|
|
66
|
+
# ``plan.narratives`` as an empty object because a ROADMAP.md row does not
|
|
67
|
+
# carry enough data to populate any canonical narrative key meaningfully
|
|
68
|
+
# (Goals / ProblemStatement / UserStories need hand-authoring). Migrator-
|
|
69
|
+
# internal provenance (Phase, Tier, PhaseDescription plus reconciler-
|
|
70
|
+
# emitted fields) is relocated under ``plan.metadata`` in the
|
|
71
|
+
# ``x-migrator/*`` namespace so downstream readers can still access it
|
|
72
|
+
# without it leaking into user-visible narratives.
|
|
73
|
+
#
|
|
74
|
+
# The surface key is a string (``"x-migrator"``) rather than a dotted
|
|
75
|
+
# path because ``plan.metadata`` is the extension point for tool-specific
|
|
76
|
+
# metadata. Using the ``x-migrator`` namespace signals "this value comes
|
|
77
|
+
# from `task migrate:vbrief`" at a glance and keeps the payload compatible
|
|
78
|
+
# with the vendored v0.6 schema without touching it.
|
|
79
|
+
MIGRATOR_METADATA_KEY: str = "x-migrator"
|
|
80
|
+
|
|
81
|
+
# ----------------------------------------------------------------------------
|
|
82
|
+
# Reference provenance / trust helpers (#480)
|
|
83
|
+
# ----------------------------------------------------------------------------
|
|
84
|
+
|
|
85
|
+
INTERNAL_REFERENCE_TYPES = {"x-vbrief/plan", "x-vbrief/spec-section", "x-vbrief/user-request"}
|
|
86
|
+
EXTERNAL_REFERENCE_TYPES = {
|
|
87
|
+
"x-vbrief/github-issue",
|
|
88
|
+
"x-vbrief/github-pr",
|
|
89
|
+
"x-vbrief/jira-ticket",
|
|
90
|
+
"x-vbrief/web-page",
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def reference_with_default_trust(ref: dict[str, Any]) -> dict[str, Any]:
|
|
95
|
+
"""Return a copied reference with the default TrustLevel filled when known."""
|
|
96
|
+
normalized = copy.deepcopy(ref)
|
|
97
|
+
if "TrustLevel" in normalized:
|
|
98
|
+
return normalized
|
|
99
|
+
ref_type = normalized.get("type")
|
|
100
|
+
if ref_type in INTERNAL_REFERENCE_TYPES:
|
|
101
|
+
normalized["TrustLevel"] = "internal"
|
|
102
|
+
elif ref_type in EXTERNAL_REFERENCE_TYPES:
|
|
103
|
+
normalized["TrustLevel"] = "external"
|
|
104
|
+
return normalized
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _github_issue_reference(
|
|
108
|
+
*, repo_url: str, number: Any, title: Any
|
|
109
|
+
) -> dict[str, str] | None:
|
|
110
|
+
cleaned_repo = str(repo_url or "").strip().rstrip("/")
|
|
111
|
+
cleaned_number = str(number or "").strip().lstrip("#").strip()
|
|
112
|
+
if not cleaned_repo or not cleaned_number:
|
|
113
|
+
return None
|
|
114
|
+
cleaned_title = str(title or "").strip()
|
|
115
|
+
ref_title = (
|
|
116
|
+
f"Issue #{cleaned_number}: {cleaned_title}"
|
|
117
|
+
if cleaned_title and cleaned_title != "Untitled"
|
|
118
|
+
else f"Issue #{cleaned_number}"
|
|
119
|
+
)
|
|
120
|
+
return {
|
|
121
|
+
"uri": f"{cleaned_repo}/issues/{cleaned_number}",
|
|
122
|
+
"type": "x-vbrief/github-issue",
|
|
123
|
+
"title": ref_title,
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _reference_has_required_fields(ref: dict[str, Any] | None) -> bool:
|
|
128
|
+
if ref is None:
|
|
129
|
+
return False
|
|
130
|
+
for key in ("uri", "type"):
|
|
131
|
+
value = ref.get(key)
|
|
132
|
+
if not isinstance(value, str) or not value.strip():
|
|
133
|
+
return False
|
|
134
|
+
return True
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# ----------------------------------------------------------------------------
|
|
138
|
+
# Scope vBRIEF construction
|
|
139
|
+
# ----------------------------------------------------------------------------
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def create_scope_vbrief(
|
|
143
|
+
item: dict,
|
|
144
|
+
repo_url: str = "",
|
|
145
|
+
status: str = "pending",
|
|
146
|
+
phase_description: str = "",
|
|
147
|
+
) -> dict:
|
|
148
|
+
"""Build a scope vBRIEF dict for a roadmap or issue item.
|
|
149
|
+
|
|
150
|
+
``item`` is a generic dict with the following recognised keys:
|
|
151
|
+
- ``number`` (str): GitHub issue number (without '#')
|
|
152
|
+
- ``title`` (str): scope title (required in practice)
|
|
153
|
+
- ``phase`` (str): roadmap phase label (optional)
|
|
154
|
+
- ``tier`` (str): sub-phase tier label (optional)
|
|
155
|
+
|
|
156
|
+
The returned structure conforms to the canonical vBRIEF version emitted
|
|
157
|
+
by deft (``EMITTED_VBRIEF_VERSION``, currently ``"0.6"`` per #533):
|
|
158
|
+
- ``vBRIEFInfo.version = EMITTED_VBRIEF_VERSION``
|
|
159
|
+
- ``plan.title`` is ``item['title']`` verbatim
|
|
160
|
+
- ``plan.status`` is ``status`` (default ``pending``)
|
|
161
|
+
- ``plan.narratives`` is ``{}`` (empty). Per-issue scope vBRIEFs
|
|
162
|
+
intentionally ship with no narratives -- ROADMAP rows do not
|
|
163
|
+
carry enough data for any canonical narrative key, and inventing
|
|
164
|
+
keys leaked migrator internals into user-visible narratives
|
|
165
|
+
(#616). Migrator-internal provenance (``Phase`` / ``Tier`` /
|
|
166
|
+
``PhaseDescription``) lives in ``plan.metadata['x-migrator']``
|
|
167
|
+
when populated.
|
|
168
|
+
- ``plan.references`` carries the canonical v0.6 origin-provenance
|
|
169
|
+
entry ``{uri, type: "x-vbrief/github-issue", title}`` when
|
|
170
|
+
``item['number']`` is non-empty AND ``repo_url`` can be resolved
|
|
171
|
+
to a GitHub owner/repo (#613). Legacy readers that used to
|
|
172
|
+
receive a bare ``{type: "github-issue", id: "#N"}`` must migrate
|
|
173
|
+
to the canonical shape -- see ``scripts/reconcile_issues.py``
|
|
174
|
+
for a bilingual reader example.
|
|
175
|
+
"""
|
|
176
|
+
number = str(item.get("number", "") or "").strip().lstrip("#").strip()
|
|
177
|
+
title = str(item.get("title", "Untitled") or "Untitled").strip() or "Untitled"
|
|
178
|
+
phase = item.get("phase", "")
|
|
179
|
+
tier = item.get("tier", "")
|
|
180
|
+
|
|
181
|
+
desc_label = f"#{number}: {title}" if number else title
|
|
182
|
+
|
|
183
|
+
vbrief: dict = {
|
|
184
|
+
"vBRIEFInfo": {
|
|
185
|
+
"version": EMITTED_VBRIEF_VERSION,
|
|
186
|
+
"description": f"Scope vBRIEF for {desc_label}",
|
|
187
|
+
},
|
|
188
|
+
"plan": {
|
|
189
|
+
"title": title,
|
|
190
|
+
"status": status,
|
|
191
|
+
"narratives": {},
|
|
192
|
+
"items": [],
|
|
193
|
+
},
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
# #616: relocate migrator-internal provenance from plan.narratives to
|
|
197
|
+
# plan.metadata['x-migrator'] so downstream tools (roadmap_render) keep
|
|
198
|
+
# working without leaking invented keys into user-visible narratives.
|
|
199
|
+
migrator_meta: dict[str, str] = {}
|
|
200
|
+
if phase:
|
|
201
|
+
migrator_meta["Phase"] = phase
|
|
202
|
+
if tier:
|
|
203
|
+
migrator_meta["Tier"] = tier
|
|
204
|
+
if phase_description:
|
|
205
|
+
migrator_meta["PhaseDescription"] = phase_description
|
|
206
|
+
if migrator_meta:
|
|
207
|
+
vbrief["plan"].setdefault("metadata", {})[MIGRATOR_METADATA_KEY] = migrator_meta
|
|
208
|
+
|
|
209
|
+
# #613: origin provenance per RFC #309 D11 + conventions/references.md.
|
|
210
|
+
# Canonical shape: {uri, type: "x-vbrief/github-issue", title}. A
|
|
211
|
+
# reference is only emitted when BOTH ``number`` and ``repo_url`` are
|
|
212
|
+
# present -- the schema's VBriefReference definition requires ``uri``
|
|
213
|
+
# so we cannot honestly emit a reference without a resolvable URL.
|
|
214
|
+
# ROADMAP bare-text rows (no issue number) legitimately ship with no
|
|
215
|
+
# origin reference; the migrator logs them as proposed/ orphans.
|
|
216
|
+
canonical_ref = _github_issue_reference(
|
|
217
|
+
repo_url=repo_url,
|
|
218
|
+
number=number,
|
|
219
|
+
title=title,
|
|
220
|
+
)
|
|
221
|
+
trusted_ref = (
|
|
222
|
+
reference_with_default_trust(canonical_ref)
|
|
223
|
+
if _reference_has_required_fields(canonical_ref)
|
|
224
|
+
else None
|
|
225
|
+
)
|
|
226
|
+
if trusted_ref is not None and _reference_has_required_fields(trusted_ref):
|
|
227
|
+
vbrief["plan"]["references"] = [trusted_ref]
|
|
228
|
+
|
|
229
|
+
return vbrief
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
__all__ = [
|
|
233
|
+
"EMITTED_VBRIEF_VERSION",
|
|
234
|
+
"MIGRATOR_METADATA_KEY",
|
|
235
|
+
"TODAY",
|
|
236
|
+
"reference_with_default_trust",
|
|
237
|
+
"slugify",
|
|
238
|
+
"create_scope_vbrief",
|
|
239
|
+
]
|