@deftai/directive-content 0.55.2 → 0.56.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.githooks/pre-commit +143 -0
- package/.githooks/pre-push +121 -0
- package/QUICK-START.md +2 -2
- package/Taskfile.yml +934 -0
- package/UPGRADING.md +47 -1
- package/events/README.md +3 -3
- package/package.json +5 -4
- 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/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 +1 -1
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""policy_set.py -- write the typed branch policy to PROJECT-DEFINITION.
|
|
3
|
+
|
|
4
|
+
Backs ``task policy:enforce-branches`` and ``task policy:allow-direct-commits``
|
|
5
|
+
(#746). Always writes through :func:`scripts.policy.set_policy` so the legacy
|
|
6
|
+
narrative key is migrated in the same pass and an audit-log entry is appended
|
|
7
|
+
to ``meta/policy-changes.log``.
|
|
8
|
+
|
|
9
|
+
Subcommands:
|
|
10
|
+
|
|
11
|
+
- ``enforce-branches`` -- set ``allowDirectCommitsToMaster=False``.
|
|
12
|
+
- ``allow-direct-commits`` -- set ``allowDirectCommitsToMaster=True``. Requires
|
|
13
|
+
``--confirm`` (capability-cost disclosure: branch-protection turns OFF).
|
|
14
|
+
|
|
15
|
+
Exit codes:
|
|
16
|
+
|
|
17
|
+
- ``0`` -- write succeeded (or no-op if value already matched).
|
|
18
|
+
- ``1`` -- refusal (e.g. ``allow-direct-commits`` without ``--confirm``).
|
|
19
|
+
- ``2`` -- config error (PROJECT-DEFINITION missing / malformed).
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
import argparse
|
|
25
|
+
import sys
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
|
|
28
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
29
|
+
|
|
30
|
+
from policy import ( # noqa: E402
|
|
31
|
+
DEFAULT_WIP_CAP,
|
|
32
|
+
KNOWN_SUBAGENT_BACKEND_IDS,
|
|
33
|
+
disclosure_line,
|
|
34
|
+
probe_subagent_backends,
|
|
35
|
+
resolve_policy,
|
|
36
|
+
resolve_swarm_subagent_backend,
|
|
37
|
+
resolve_wip_cap,
|
|
38
|
+
set_policy,
|
|
39
|
+
set_swarm_subagent_backend,
|
|
40
|
+
set_wip_cap,
|
|
41
|
+
subagent_backends_to_json,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
CAPABILITY_COST_DISCLOSURE = (
|
|
45
|
+
"⚠ Capability-cost disclosure -- enabling direct commits to the default "
|
|
46
|
+
"branch turns OFF the deft branch-protection policy.\n"
|
|
47
|
+
" • Pre-commit + pre-push hooks will no longer block default-branch "
|
|
48
|
+
"commits.\n"
|
|
49
|
+
" • verify:branch will pass on the default branch.\n"
|
|
50
|
+
" • The CI sanity check (head_ref != base_ref) is still independent and "
|
|
51
|
+
"will continue to flag master->master PRs.\n"
|
|
52
|
+
" • This change is reversible: run `task policy:enforce-branches` to "
|
|
53
|
+
"re-enable the gate.\n"
|
|
54
|
+
" • The change is recorded to meta/policy-changes.log for auditability."
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _build_parser() -> argparse.ArgumentParser:
|
|
59
|
+
parser = argparse.ArgumentParser(prog="policy_set.py")
|
|
60
|
+
sub = parser.add_subparsers(dest="cmd", required=True)
|
|
61
|
+
|
|
62
|
+
enforce = sub.add_parser(
|
|
63
|
+
"enforce-branches",
|
|
64
|
+
help="Set allowDirectCommitsToMaster=False (enforce feature branches).",
|
|
65
|
+
)
|
|
66
|
+
enforce.add_argument("--actor", default="task policy:enforce-branches")
|
|
67
|
+
enforce.add_argument("--note", default="")
|
|
68
|
+
enforce.add_argument("--project-root", default=".")
|
|
69
|
+
|
|
70
|
+
allow = sub.add_parser(
|
|
71
|
+
"allow-direct-commits",
|
|
72
|
+
help="Set allowDirectCommitsToMaster=True. Requires --confirm.",
|
|
73
|
+
)
|
|
74
|
+
allow.add_argument(
|
|
75
|
+
"--confirm",
|
|
76
|
+
action="store_true",
|
|
77
|
+
help=(
|
|
78
|
+
"Required to actually apply the change. Without it, the command "
|
|
79
|
+
"prints the capability-cost disclosure and exits 1."
|
|
80
|
+
),
|
|
81
|
+
)
|
|
82
|
+
allow.add_argument("--actor", default="task policy:allow-direct-commits")
|
|
83
|
+
allow.add_argument("--note", default="")
|
|
84
|
+
allow.add_argument("--project-root", default=".")
|
|
85
|
+
|
|
86
|
+
# ---------------------------------------------------------------
|
|
87
|
+
# wip-cap subcommand (#1124 / D4 of #1119)
|
|
88
|
+
# ---------------------------------------------------------------
|
|
89
|
+
wip = sub.add_parser(
|
|
90
|
+
"wip-cap",
|
|
91
|
+
help=(
|
|
92
|
+
"Set plan.policy.wipCap=<N>. Default cap is "
|
|
93
|
+
f"{DEFAULT_WIP_CAP} per umbrella #1119 Current Shape v3."
|
|
94
|
+
),
|
|
95
|
+
)
|
|
96
|
+
wip.add_argument(
|
|
97
|
+
"--set",
|
|
98
|
+
dest="cap",
|
|
99
|
+
type=int,
|
|
100
|
+
required=True,
|
|
101
|
+
help="New WIP cap value (>= 0; 0 freezes promotion entirely).",
|
|
102
|
+
)
|
|
103
|
+
wip.add_argument(
|
|
104
|
+
"--confirm",
|
|
105
|
+
action="store_true",
|
|
106
|
+
help=(
|
|
107
|
+
"Required to actually apply the change. Without it, the "
|
|
108
|
+
"command prints the capability-cost disclosure and exits 1."
|
|
109
|
+
),
|
|
110
|
+
)
|
|
111
|
+
wip.add_argument("--actor", default="task policy:wip-cap")
|
|
112
|
+
wip.add_argument("--note", default="")
|
|
113
|
+
wip.add_argument("--project-root", default=".")
|
|
114
|
+
|
|
115
|
+
subagent = sub.add_parser(
|
|
116
|
+
"subagent-backend",
|
|
117
|
+
help=(
|
|
118
|
+
"Set plan.policy.swarmSubagentBackend to a known coding "
|
|
119
|
+
"sub-agent provider id (#1531a)."
|
|
120
|
+
),
|
|
121
|
+
)
|
|
122
|
+
subagent.add_argument(
|
|
123
|
+
"--set",
|
|
124
|
+
dest="backend_id",
|
|
125
|
+
required=True,
|
|
126
|
+
choices=sorted(KNOWN_SUBAGENT_BACKEND_IDS),
|
|
127
|
+
help="Backend id (composer, grok-build, cursor-cloud).",
|
|
128
|
+
)
|
|
129
|
+
subagent.add_argument("--actor", default="task policy:subagent-backend")
|
|
130
|
+
subagent.add_argument("--note", default="")
|
|
131
|
+
subagent.add_argument("--project-root", default=".")
|
|
132
|
+
|
|
133
|
+
backends = sub.add_parser(
|
|
134
|
+
"subagent-backends",
|
|
135
|
+
help=(
|
|
136
|
+
"List stable sub-agent backend ids, role capabilities, and "
|
|
137
|
+
"harness availability without invoking a real harness (#1531a)."
|
|
138
|
+
),
|
|
139
|
+
)
|
|
140
|
+
backends.add_argument(
|
|
141
|
+
"--format",
|
|
142
|
+
choices=("text", "json"),
|
|
143
|
+
default="text",
|
|
144
|
+
help="Output format (default: text).",
|
|
145
|
+
)
|
|
146
|
+
backends.add_argument("--project-root", default=".")
|
|
147
|
+
return parser
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
_WIP_CAP_DISCLOSURE = (
|
|
151
|
+
"\u26a0 Capability-cost disclosure -- changing plan.policy.wipCap "
|
|
152
|
+
"alters the refusal threshold on task scope:promote (#1124 / D4 of #1119).\n"
|
|
153
|
+
" \u2022 Raising the cap lets more vBRIEFs sit in pending/+active/ "
|
|
154
|
+
"before promotion is refused.\n"
|
|
155
|
+
" \u2022 Lowering the cap may put the project over cap immediately; "
|
|
156
|
+
"use `task scope:demote` / `task scope:demote --batch --older-than-days 30` "
|
|
157
|
+
"to drain.\n"
|
|
158
|
+
" \u2022 cap=0 freezes promotion entirely (useful for code-freeze "
|
|
159
|
+
"windows; restore by setting a positive value).\n"
|
|
160
|
+
" \u2022 This change is reversible and recorded to "
|
|
161
|
+
"meta/policy-changes.log for auditability."
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def main(argv: list[str] | None = None) -> int:
|
|
166
|
+
parser = _build_parser()
|
|
167
|
+
args = parser.parse_args(argv)
|
|
168
|
+
project_root = Path(args.project_root).resolve()
|
|
169
|
+
|
|
170
|
+
if args.cmd == "enforce-branches":
|
|
171
|
+
target = False
|
|
172
|
+
elif args.cmd == "allow-direct-commits":
|
|
173
|
+
if not args.confirm:
|
|
174
|
+
print(CAPABILITY_COST_DISCLOSURE)
|
|
175
|
+
print()
|
|
176
|
+
print(
|
|
177
|
+
"Re-run with --confirm to apply: "
|
|
178
|
+
"task policy:allow-direct-commits -- --confirm"
|
|
179
|
+
)
|
|
180
|
+
return 1
|
|
181
|
+
target = True
|
|
182
|
+
elif args.cmd == "wip-cap":
|
|
183
|
+
return _apply_wip_cap(args, project_root)
|
|
184
|
+
elif args.cmd == "subagent-backend":
|
|
185
|
+
return _apply_subagent_backend(args, project_root)
|
|
186
|
+
elif args.cmd == "subagent-backends":
|
|
187
|
+
return _apply_subagent_backends(args, project_root)
|
|
188
|
+
else: # pragma: no cover -- argparse enforces one of the above
|
|
189
|
+
parser.print_help()
|
|
190
|
+
return 2
|
|
191
|
+
|
|
192
|
+
try:
|
|
193
|
+
changed, audit_entry = set_policy(
|
|
194
|
+
project_root,
|
|
195
|
+
allow_direct_commits=target,
|
|
196
|
+
actor=args.actor,
|
|
197
|
+
note=args.note,
|
|
198
|
+
)
|
|
199
|
+
except FileNotFoundError as exc:
|
|
200
|
+
print(f"\u274c {exc}", file=sys.stderr)
|
|
201
|
+
print(
|
|
202
|
+
" Recovery: run `task setup` to generate "
|
|
203
|
+
"vbrief/PROJECT-DEFINITION.vbrief.json.",
|
|
204
|
+
file=sys.stderr,
|
|
205
|
+
)
|
|
206
|
+
return 2
|
|
207
|
+
except (ValueError, OSError) as exc:
|
|
208
|
+
print(f"\u274c Config error: {exc}", file=sys.stderr)
|
|
209
|
+
return 2
|
|
210
|
+
|
|
211
|
+
state = "ON" if not target else "OFF"
|
|
212
|
+
print(
|
|
213
|
+
f"✓ plan.policy.allowDirectCommitsToMaster={'true' if target else 'false'} "
|
|
214
|
+
f"(branch-protection {state})."
|
|
215
|
+
)
|
|
216
|
+
if changed:
|
|
217
|
+
print(f" audit: meta/policy-changes.log :: {audit_entry}")
|
|
218
|
+
else:
|
|
219
|
+
print(" no-op: value already matched (audit entry still appended for trail).")
|
|
220
|
+
|
|
221
|
+
# Print resolved disclosure for completeness.
|
|
222
|
+
print(disclosure_line(resolve_policy(project_root)))
|
|
223
|
+
return 0
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def _apply_wip_cap(args, project_root: Path) -> int:
|
|
227
|
+
"""Handle the ``wip-cap`` subcommand (#1124 / D4 of #1119)."""
|
|
228
|
+
if args.cap < 0:
|
|
229
|
+
print(
|
|
230
|
+
f"\u274c --set must be >= 0; got {args.cap}.",
|
|
231
|
+
file=sys.stderr,
|
|
232
|
+
)
|
|
233
|
+
return 1
|
|
234
|
+
if not args.confirm:
|
|
235
|
+
print(_WIP_CAP_DISCLOSURE)
|
|
236
|
+
print()
|
|
237
|
+
print(
|
|
238
|
+
"Re-run with --confirm to apply: "
|
|
239
|
+
f"task policy:wip-cap -- --set {args.cap} --confirm"
|
|
240
|
+
)
|
|
241
|
+
return 1
|
|
242
|
+
try:
|
|
243
|
+
changed, audit_entry = set_wip_cap(
|
|
244
|
+
project_root,
|
|
245
|
+
cap=int(args.cap),
|
|
246
|
+
actor=args.actor,
|
|
247
|
+
note=args.note,
|
|
248
|
+
)
|
|
249
|
+
except FileNotFoundError as exc:
|
|
250
|
+
print(f"\u274c {exc}", file=sys.stderr)
|
|
251
|
+
print(
|
|
252
|
+
" Recovery: run `task setup` to generate "
|
|
253
|
+
"vbrief/PROJECT-DEFINITION.vbrief.json.",
|
|
254
|
+
file=sys.stderr,
|
|
255
|
+
)
|
|
256
|
+
return 2
|
|
257
|
+
except (ValueError, OSError) as exc:
|
|
258
|
+
print(f"\u274c Config error: {exc}", file=sys.stderr)
|
|
259
|
+
return 2
|
|
260
|
+
|
|
261
|
+
print(f"\u2713 plan.policy.wipCap={args.cap}.")
|
|
262
|
+
if changed:
|
|
263
|
+
print(f" audit: meta/policy-changes.log :: {audit_entry}")
|
|
264
|
+
else:
|
|
265
|
+
print(" no-op: value already matched (audit entry still appended for trail).")
|
|
266
|
+
result = resolve_wip_cap(project_root)
|
|
267
|
+
print(
|
|
268
|
+
f"[deft policy] plan.policy.wipCap={result.cap} (source: {result.source})."
|
|
269
|
+
)
|
|
270
|
+
return 0
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def _apply_subagent_backend(args, project_root: Path) -> int:
|
|
274
|
+
"""Handle the ``subagent-backend`` subcommand (#1531a)."""
|
|
275
|
+
try:
|
|
276
|
+
changed, audit_entry = set_swarm_subagent_backend(
|
|
277
|
+
project_root,
|
|
278
|
+
backend_id=args.backend_id,
|
|
279
|
+
actor=args.actor,
|
|
280
|
+
note=args.note,
|
|
281
|
+
)
|
|
282
|
+
except FileNotFoundError as exc:
|
|
283
|
+
print(f"\u274c {exc}", file=sys.stderr)
|
|
284
|
+
print(
|
|
285
|
+
" Recovery: run `task setup` to generate "
|
|
286
|
+
"vbrief/PROJECT-DEFINITION.vbrief.json.",
|
|
287
|
+
file=sys.stderr,
|
|
288
|
+
)
|
|
289
|
+
return 2
|
|
290
|
+
except (ValueError, OSError) as exc:
|
|
291
|
+
print(f"\u274c Config error: {exc}", file=sys.stderr)
|
|
292
|
+
return 2
|
|
293
|
+
|
|
294
|
+
print(f"\u2713 plan.policy.swarmSubagentBackend={args.backend_id}.")
|
|
295
|
+
if changed:
|
|
296
|
+
print(f" audit: meta/policy-changes.log :: {audit_entry}")
|
|
297
|
+
else:
|
|
298
|
+
print(" no-op: value already matched (audit entry still appended for trail).")
|
|
299
|
+
result = resolve_swarm_subagent_backend(project_root)
|
|
300
|
+
print(
|
|
301
|
+
"[deft policy] plan.policy.swarmSubagentBackend="
|
|
302
|
+
f"{result.backend_id!r} (source: {result.source})."
|
|
303
|
+
)
|
|
304
|
+
return 0
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def _apply_subagent_backends(args, project_root: Path) -> int:
|
|
308
|
+
"""Handle the ``subagent-backends`` probe/list subcommand (#1531a)."""
|
|
309
|
+
_ = project_root # reserved for future project-scoped adapters
|
|
310
|
+
entries = probe_subagent_backends()
|
|
311
|
+
if args.format == "json":
|
|
312
|
+
print(subagent_backends_to_json(entries))
|
|
313
|
+
return 0
|
|
314
|
+
for entry in entries:
|
|
315
|
+
roles = ", ".join(entry.roles)
|
|
316
|
+
avail = "available" if entry.available else "unavailable"
|
|
317
|
+
print(
|
|
318
|
+
f"{entry.backend_id}\t{entry.display_name}\troles=[{roles}]\t{avail}"
|
|
319
|
+
)
|
|
320
|
+
return 0
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
if __name__ == "__main__":
|
|
324
|
+
sys.exit(main())
|