@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,61 @@
|
|
|
1
|
+
"""Scan source files for stub patterns (TODO, FIXME, HACK, return null, bare pass)."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
PATTERNS = [
|
|
8
|
+
(re.compile(r"\bTODO\b"), "TODO"),
|
|
9
|
+
(re.compile(r"\bFIXME\b"), "FIXME"),
|
|
10
|
+
(re.compile(r"\bHACK\b"), "HACK"),
|
|
11
|
+
(re.compile(r"\breturn\s+null\b"), "return null"),
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
EXCLUDE_DIRS = {
|
|
15
|
+
"tests", "vendor", ".git", "backup", "history",
|
|
16
|
+
"node_modules", ".venv", "__pycache__", "dist",
|
|
17
|
+
"scripts", # exclude tooling scripts (contain pattern strings)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
EXTENSIONS = {".py", ".go", ".sh"}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def main() -> int:
|
|
24
|
+
findings = []
|
|
25
|
+
|
|
26
|
+
for f in sorted(Path(".").rglob("*")):
|
|
27
|
+
if not f.is_file() or f.suffix not in EXTENSIONS:
|
|
28
|
+
continue
|
|
29
|
+
if any(p in f.parts for p in EXCLUDE_DIRS):
|
|
30
|
+
continue
|
|
31
|
+
try:
|
|
32
|
+
text = f.read_text("utf-8", errors="replace")
|
|
33
|
+
lines = text.splitlines()
|
|
34
|
+
for i, line in enumerate(lines, 1):
|
|
35
|
+
stripped = line.strip()
|
|
36
|
+
# Detect bare 'pass' after a colon-ending line (stub function/method)
|
|
37
|
+
if stripped == "pass" and f.suffix == ".py" and i >= 2:
|
|
38
|
+
prev = lines[i - 2].strip()
|
|
39
|
+
if prev.endswith(":") and not prev.startswith("#"):
|
|
40
|
+
findings.append((str(f), i, "bare pass", line.rstrip()))
|
|
41
|
+
# Detect keyword patterns
|
|
42
|
+
for pat, label in PATTERNS:
|
|
43
|
+
if pat.search(line):
|
|
44
|
+
findings.append((str(f), i, label, line.rstrip()))
|
|
45
|
+
except Exception:
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
if findings:
|
|
49
|
+
print(f"Found {len(findings)} stub(s):")
|
|
50
|
+
for fp, ln, label, text in findings[:50]:
|
|
51
|
+
print(f" {fp}:{ln} [{label}] {text[:120]}")
|
|
52
|
+
if len(findings) > 50:
|
|
53
|
+
print(f" ... and {len(findings) - 50} more")
|
|
54
|
+
return 1
|
|
55
|
+
|
|
56
|
+
print("No stub patterns found in source files")
|
|
57
|
+
return 0
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if __name__ == "__main__":
|
|
61
|
+
sys.exit(main())
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""verify_capacity.py -- three-state ADVISORY capacity gate (#1419 Slice 4).
|
|
3
|
+
|
|
4
|
+
Surfaced via ``task verify:capacity``. Reuses the offline accounting engine in
|
|
5
|
+
:mod:`scripts.capacity_show` to evaluate whether the trailing-window backward
|
|
6
|
+
mix has drifted away from the configured ``capacityAllocation`` targets.
|
|
7
|
+
|
|
8
|
+
Advisory by construction
|
|
9
|
+
------------------------
|
|
10
|
+
``plan.policy.capacityAllocation.enforcement`` defaults to ``"advise"``, and in
|
|
11
|
+
that posture this gate ALWAYS exits 0 -- it reports the mix and defers to the
|
|
12
|
+
selection ordering. It is therefore safe to run anywhere and is deliberately
|
|
13
|
+
NOT wired into the ``task check`` aggregate: a capacity deficit on the
|
|
14
|
+
framework's own tree MUST NOT fail-closed and wedge master.
|
|
15
|
+
|
|
16
|
+
A non-zero "deficit" exit (1) only fires when ALL of the following hold:
|
|
17
|
+
|
|
18
|
+
* ``enforcement == "enforce"`` (explicit per-project opt-in), AND
|
|
19
|
+
* the classified-completion sample is at or above ``minSampleSize`` (so the
|
|
20
|
+
signal is load-bearing, not noise), AND
|
|
21
|
+
* at least one protected bucket is starved past
|
|
22
|
+
:data:`DEFICIT_TOLERANCE` of the trailing window's completed weight.
|
|
23
|
+
|
|
24
|
+
Exit codes (three-state, mirrors the other deft verify gates):
|
|
25
|
+
|
|
26
|
+
* ``0`` -- within targets, OR advisory posture, OR insufficient sample, OR no
|
|
27
|
+
capacity policy configured. (This is the only state reachable on the
|
|
28
|
+
framework's own ``advise``-default tree.)
|
|
29
|
+
* ``1`` -- ``enforce`` posture with a real, sampled deficit.
|
|
30
|
+
* ``2`` -- config error (``--project-root`` is not a directory).
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
from __future__ import annotations
|
|
34
|
+
|
|
35
|
+
import argparse
|
|
36
|
+
import sys
|
|
37
|
+
from datetime import datetime
|
|
38
|
+
from pathlib import Path
|
|
39
|
+
|
|
40
|
+
# Make sibling helpers importable both as __main__ and when imported by tests.
|
|
41
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
42
|
+
|
|
43
|
+
from _stdio_utf8 import reconfigure_stdio # noqa: E402
|
|
44
|
+
from capacity_show import CapacityReport, compute_report, render_report # noqa: E402
|
|
45
|
+
from policy import resolve_capacity_allocation # noqa: E402
|
|
46
|
+
|
|
47
|
+
reconfigure_stdio()
|
|
48
|
+
|
|
49
|
+
#: Minimum absolute backward-weight deficit (in the report's unit) that an
|
|
50
|
+
#: ``enforce``-posture bucket may carry before the gate flags it. A small
|
|
51
|
+
#: tolerance absorbs rounding and single-item lumpiness so the gate fires only
|
|
52
|
+
#: on a genuine, sustained shortfall.
|
|
53
|
+
DEFICIT_TOLERANCE: float = 1.0
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _worst_deficit(report: CapacityReport) -> tuple[str, float]:
|
|
57
|
+
"""Return the ``(bucket_id, deficit)`` with the largest positive deficit."""
|
|
58
|
+
worst_id = ""
|
|
59
|
+
worst = 0.0
|
|
60
|
+
for tally in report.buckets:
|
|
61
|
+
deficit = report.bucket_deficit(tally)
|
|
62
|
+
if deficit > worst:
|
|
63
|
+
worst = deficit
|
|
64
|
+
worst_id = tally.bucket_id
|
|
65
|
+
return worst_id, worst
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def evaluate(
|
|
69
|
+
project_root: Path, *, now: datetime | None = None
|
|
70
|
+
) -> tuple[int, str]:
|
|
71
|
+
"""Pure entry point: returns ``(exit_code, message)``.
|
|
72
|
+
|
|
73
|
+
See the module docstring for the three-state contract. The ``advise``
|
|
74
|
+
default guarantees exit 0 on the framework's own tree.
|
|
75
|
+
"""
|
|
76
|
+
if not project_root.is_dir():
|
|
77
|
+
return 2, (
|
|
78
|
+
f"verify_capacity: --project-root is not a directory: {project_root}\n"
|
|
79
|
+
" Recovery: pass an existing project root."
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
allocation = resolve_capacity_allocation(project_root)
|
|
83
|
+
report = compute_report(project_root, now=now, allocation=allocation)
|
|
84
|
+
rendered = render_report(report)
|
|
85
|
+
|
|
86
|
+
if allocation.enforcement != "enforce":
|
|
87
|
+
return 0, (
|
|
88
|
+
f"{rendered}\n"
|
|
89
|
+
"verify_capacity: OK -- advisory posture "
|
|
90
|
+
f"(enforcement={allocation.enforcement!r}); deferring to ordering."
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
if not report.configured:
|
|
94
|
+
return 0, (
|
|
95
|
+
f"{rendered}\n"
|
|
96
|
+
"verify_capacity: OK -- no capacityAllocation buckets configured."
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
if report.advisory_mode:
|
|
100
|
+
return 0, (
|
|
101
|
+
f"{rendered}\n"
|
|
102
|
+
"verify_capacity: OK -- sample below minSampleSize "
|
|
103
|
+
f"({report.classified_completions}/{report.min_sample_size}); "
|
|
104
|
+
"capacity stays advisory until enough classified completions accrue."
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
worst_id, worst = _worst_deficit(report)
|
|
108
|
+
if worst > DEFICIT_TOLERANCE:
|
|
109
|
+
return 1, (
|
|
110
|
+
f"{rendered}\n"
|
|
111
|
+
f"verify_capacity: DEFICIT -- bucket {worst_id!r} is starved by "
|
|
112
|
+
f"{worst:.2f} (enforce posture; tolerance {DEFICIT_TOLERANCE}). "
|
|
113
|
+
"Prioritize that bucket or relax its target."
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
return 0, (
|
|
117
|
+
f"{rendered}\n"
|
|
118
|
+
"verify_capacity: OK -- all buckets within target tolerance."
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _build_parser() -> argparse.ArgumentParser:
|
|
123
|
+
parser = argparse.ArgumentParser(
|
|
124
|
+
prog="verify_capacity.py",
|
|
125
|
+
description=(
|
|
126
|
+
"Three-state ADVISORY capacity gate (#1419 Slice 4). Exits 0 in the "
|
|
127
|
+
"default advise posture (and on insufficient sample / unconfigured "
|
|
128
|
+
"policy); exits 1 only under an explicit enforce posture with a "
|
|
129
|
+
"sampled deficit; exits 2 on config error. Not wired into "
|
|
130
|
+
"`task check` -- capacity must never fail-closed on the framework tree."
|
|
131
|
+
),
|
|
132
|
+
)
|
|
133
|
+
parser.add_argument(
|
|
134
|
+
"--project-root",
|
|
135
|
+
default=".",
|
|
136
|
+
help="Project root path (default: current working directory).",
|
|
137
|
+
)
|
|
138
|
+
parser.add_argument(
|
|
139
|
+
"--quiet",
|
|
140
|
+
action="store_true",
|
|
141
|
+
help="Suppress the OK message (errors / deficits still print).",
|
|
142
|
+
)
|
|
143
|
+
return parser
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def main(argv: list[str] | None = None) -> int:
|
|
147
|
+
parser = _build_parser()
|
|
148
|
+
args = parser.parse_args(argv)
|
|
149
|
+
project_root = Path(args.project_root).resolve()
|
|
150
|
+
code, message = evaluate(project_root)
|
|
151
|
+
if code == 0:
|
|
152
|
+
if not args.quiet:
|
|
153
|
+
print(message)
|
|
154
|
+
else:
|
|
155
|
+
print(message, file=sys.stderr)
|
|
156
|
+
return code
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
if __name__ == "__main__":
|
|
160
|
+
sys.exit(main())
|