@deftai/directive 0.126.0-beta.2 → 0.126.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/dist/agents-refresh.d.ts +11 -0
- package/dist/agents-refresh.js +90 -0
- package/dist/authz.d.ts +7 -0
- package/dist/authz.js +732 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.js +3 -4333
- package/dist/branch-fixtures.d.ts +45 -0
- package/dist/branch-fixtures.js +156 -0
- package/dist/cache.d.ts +4 -0
- package/dist/cache.js +10 -0
- package/dist/capacity-backfill.d.ts +3 -0
- package/dist/capacity-backfill.js +9 -0
- package/dist/capacity-show.d.ts +3 -0
- package/dist/capacity-show.js +9 -0
- package/dist/change-init.d.ts +3 -0
- package/dist/change-init.js +59 -0
- package/dist/changelog-check.d.ts +3 -0
- package/dist/changelog-check.js +52 -0
- package/dist/check.d.ts +15 -0
- package/dist/check.js +150 -0
- package/dist/cli-package-version.d.ts +3 -0
- package/dist/cli-package-version.js +23 -0
- package/dist/cli-router/index.d.ts +8 -0
- package/dist/cli-router/index.js +44 -0
- package/dist/cli-router/route-argv.d.ts +40 -0
- package/dist/cli-router/route-argv.js +371 -0
- package/dist/codebase-default-extractor.d.ts +3 -0
- package/dist/codebase-default-extractor.js +9 -0
- package/dist/codebase-map-fresh.d.ts +3 -0
- package/dist/codebase-map-fresh.js +9 -0
- package/dist/codebase-map.d.ts +3 -0
- package/dist/codebase-map.js +9 -0
- package/dist/codebase-projection-registry.d.ts +3 -0
- package/dist/codebase-projection-registry.js +9 -0
- package/dist/codebase-provider.d.ts +3 -0
- package/dist/codebase-provider.js +9 -0
- package/dist/commit-lint.d.ts +3 -0
- package/dist/commit-lint.js +44 -0
- package/dist/content-validate-cli/validate-links.d.ts +11 -0
- package/dist/content-validate-cli/validate-links.js +37 -0
- package/dist/content-validate-cli/validate-strategy-output.d.ts +13 -0
- package/dist/content-validate-cli/validate-strategy-output.js +56 -0
- package/dist/content-validate-cli/verify-capacity.d.ts +12 -0
- package/dist/content-validate-cli/verify-capacity.js +54 -0
- package/dist/coverage-hotspots.d.ts +21 -0
- package/dist/coverage-hotspots.js +198 -0
- package/dist/design-critique-spend-resolve.d.ts +18 -0
- package/dist/design-critique-spend-resolve.js +191 -0
- package/dist/directive-finish-loop.d.ts +3 -0
- package/dist/directive-finish-loop.js +10 -0
- package/dist/dispatch.d.ts +193 -0
- package/dist/dispatch.js +3091 -0
- package/dist/doctor.d.ts +19 -0
- package/dist/doctor.js +155 -0
- package/dist/entrypoint.d.ts +6 -0
- package/dist/entrypoint.js +19 -0
- package/dist/escalation-cli.d.ts +4 -0
- package/dist/escalation-cli.js +301 -0
- package/dist/eval-health.d.ts +13 -0
- package/dist/eval-health.js +63 -0
- package/dist/eval-report.d.ts +15 -0
- package/dist/eval-report.js +97 -0
- package/dist/eval-run.d.ts +17 -0
- package/dist/eval-run.js +122 -0
- package/dist/eval-triggers.d.ts +12 -0
- package/dist/eval-triggers.js +56 -0
- package/dist/framework-check-updates.d.ts +10 -0
- package/dist/framework-check-updates.js +68 -0
- package/dist/gates-cli/_helpers.d.ts +24 -0
- package/dist/gates-cli/_helpers.js +115 -0
- package/dist/gates-cli/verify-bridge-drift.d.ts +11 -0
- package/dist/gates-cli/verify-bridge-drift.js +47 -0
- package/dist/gates-cli/verify-go-freeze.d.ts +11 -0
- package/dist/gates-cli/verify-go-freeze.js +48 -0
- package/dist/hook-bin.d.ts +3 -0
- package/dist/hook-bin.js +11 -0
- package/dist/hook-dispatch.d.ts +80 -0
- package/dist/hook-dispatch.js +186 -0
- package/dist/human-presence-mint.d.ts +70 -0
- package/dist/human-presence-mint.js +204 -0
- package/dist/identity-banner.d.ts +13 -0
- package/dist/identity-banner.js +19 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +14 -0
- package/dist/init-cli/constants.d.ts +42 -0
- package/dist/init-cli/constants.js +42 -0
- package/dist/init-cli/help.d.ts +9 -0
- package/dist/init-cli/help.js +43 -0
- package/dist/init-cli/init.d.ts +26 -0
- package/dist/init-cli/init.js +80 -0
- package/dist/init-cli/migrate.d.ts +3 -0
- package/dist/init-cli/migrate.js +51 -0
- package/dist/init-cli/resolve-binary.d.ts +34 -0
- package/dist/init-cli/resolve-binary.js +78 -0
- package/dist/init-cli/run-deft-install.d.ts +23 -0
- package/dist/init-cli/run-deft-install.js +71 -0
- package/dist/init-cli/update.d.ts +5 -0
- package/dist/init-cli/update.js +38 -0
- package/dist/install-cli/coverage-map.d.ts +14 -0
- package/dist/install-cli/coverage-map.js +113 -0
- package/dist/install-uninstall.d.ts +3 -0
- package/dist/install-uninstall.js +44 -0
- package/dist/install-upgrade.d.ts +41 -0
- package/dist/install-upgrade.js +86 -0
- package/dist/lifecycle-cli/coverage-map.d.ts +16 -0
- package/dist/lifecycle-cli/coverage-map.js +254 -0
- package/dist/lifecycle-cli/helpers.d.ts +8 -0
- package/dist/lifecycle-cli/helpers.js +20 -0
- package/dist/lifecycle-event.d.ts +11 -0
- package/dist/lifecycle-event.js +45 -0
- package/dist/lifecycle-stats.d.ts +12 -0
- package/dist/lifecycle-stats.js +100 -0
- package/dist/migrate-category-b.d.ts +9 -0
- package/dist/migrate-category-b.js +52 -0
- package/dist/migrate-preflight.d.ts +10 -0
- package/dist/migrate-preflight.js +85 -0
- package/dist/migrate-xbrief.d.ts +11 -0
- package/dist/migrate-xbrief.js +88 -0
- package/dist/occupancy-grant.d.ts +18 -0
- package/dist/occupancy-grant.js +121 -0
- package/dist/occupancy-heartbeat.d.ts +8 -0
- package/dist/occupancy-heartbeat.js +63 -0
- package/dist/occupancy-release.d.ts +23 -0
- package/dist/occupancy-release.js +102 -0
- package/dist/occupancy-steal.d.ts +10 -0
- package/dist/occupancy-steal.js +83 -0
- package/dist/occupancy-unrecognized.d.ts +3 -0
- package/dist/occupancy-unrecognized.js +5 -0
- package/dist/orchestration-cli/coverage-map.d.ts +21 -0
- package/dist/orchestration-cli/coverage-map.js +225 -0
- package/dist/orchestration-cli/helpers.d.ts +11 -0
- package/dist/orchestration-cli/helpers.js +35 -0
- package/dist/ownership-doctor.d.ts +10 -0
- package/dist/ownership-doctor.js +96 -0
- package/dist/ownership-fix.d.ts +10 -0
- package/dist/ownership-fix.js +93 -0
- package/dist/plan-sequence.d.ts +14 -0
- package/dist/plan-sequence.js +258 -0
- package/dist/policy-fixtures.d.ts +33 -0
- package/dist/policy-fixtures.js +118 -0
- package/dist/policy.d.ts +37 -0
- package/dist/policy.js +744 -0
- package/dist/pr-closing-keywords.d.ts +3 -0
- package/dist/pr-closing-keywords.js +10 -0
- package/dist/pr-finish-loop.d.ts +3 -0
- package/dist/pr-finish-loop.js +10 -0
- package/dist/pr-merge-readiness.d.ts +3 -0
- package/dist/pr-merge-readiness.js +10 -0
- package/dist/pr-monitor.d.ts +3 -0
- package/dist/pr-monitor.js +10 -0
- package/dist/pr-protected-issues.d.ts +3 -0
- package/dist/pr-protected-issues.js +10 -0
- package/dist/pr-wait-mergeable.d.ts +3 -0
- package/dist/pr-wait-mergeable.js +10 -0
- package/dist/pr-watch.d.ts +3 -0
- package/dist/pr-watch.js +10 -0
- package/dist/pre-pr-run.d.ts +39 -0
- package/dist/pre-pr-run.js +514 -0
- package/dist/preflight-cache.d.ts +18 -0
- package/dist/preflight-cache.js +113 -0
- package/dist/preflight-gh.d.ts +15 -0
- package/dist/preflight-gh.js +143 -0
- package/dist/probe-session.d.ts +3 -0
- package/dist/probe-session.js +10 -0
- package/dist/release-e2e-fixtures.d.ts +29 -0
- package/dist/release-e2e-fixtures.js +38 -0
- package/dist/release-e2e.d.ts +3 -0
- package/dist/release-e2e.js +10 -0
- package/dist/release-publish.d.ts +3 -0
- package/dist/release-publish.js +10 -0
- package/dist/release-rollback.d.ts +3 -0
- package/dist/release-rollback.js +10 -0
- package/dist/release-wait-npm.d.ts +3 -0
- package/dist/release-wait-npm.js +10 -0
- package/dist/release.d.ts +3 -0
- package/dist/release.js +10 -0
- package/dist/render-cli/deft-ts-runner.d.ts +17 -0
- package/dist/render-cli/deft-ts-runner.js +19 -0
- package/dist/render-cli/export-spec-cli.d.ts +2 -0
- package/dist/render-cli/export-spec-cli.js +6 -0
- package/dist/render-cli/prd-render-cli.d.ts +2 -0
- package/dist/render-cli/prd-render-cli.js +37 -0
- package/dist/render-cli/project-render-cli.d.ts +2 -0
- package/dist/render-cli/project-render-cli.js +6 -0
- package/dist/render-cli/rule-map-cli.d.ts +2 -0
- package/dist/render-cli/rule-map-cli.js +5 -0
- package/dist/render-cli/spec-reconstruct-cli.d.ts +3 -0
- package/dist/render-cli/spec-reconstruct-cli.js +15 -0
- package/dist/render-cli/spec-render-cli.d.ts +2 -0
- package/dist/render-cli/spec-render-cli.js +39 -0
- package/dist/render-cli/spec-validate-cli.d.ts +2 -0
- package/dist/render-cli/spec-validate-cli.js +38 -0
- package/dist/review-monitor-register.d.ts +19 -0
- package/dist/review-monitor-register.js +183 -0
- package/dist/review-monitor-release.d.ts +14 -0
- package/dist/review-monitor-release.js +123 -0
- package/dist/scm-sync-default.d.ts +34 -0
- package/dist/scm-sync-default.js +210 -0
- package/dist/scope-lifecycle.d.ts +4 -0
- package/dist/scope-lifecycle.js +34 -0
- package/dist/scope-record-approved-scope.d.ts +29 -0
- package/dist/scope-record-approved-scope.js +319 -0
- package/dist/scope-record-intent-constraint.d.ts +16 -0
- package/dist/scope-record-intent-constraint.js +202 -0
- package/dist/scope-record-observable-scope.d.ts +16 -0
- package/dist/scope-record-observable-scope.js +204 -0
- package/dist/session-ready.d.ts +15 -0
- package/dist/session-ready.js +144 -0
- package/dist/session-start.d.ts +56 -0
- package/dist/session-start.js +581 -0
- package/dist/slice.d.ts +4 -0
- package/dist/slice.js +34 -0
- package/dist/story-ready-fixtures.d.ts +47 -0
- package/dist/story-ready-fixtures.js +137 -0
- package/dist/subagent-monitor.d.ts +3 -0
- package/dist/subagent-monitor.js +10 -0
- package/dist/subagent-pre-cancel.d.ts +21 -0
- package/dist/subagent-pre-cancel.js +240 -0
- package/dist/subagent-steer-write.d.ts +41 -0
- package/dist/subagent-steer-write.js +333 -0
- package/dist/toolchain-check.d.ts +8 -0
- package/dist/toolchain-check.js +54 -0
- package/dist/triage-actions.d.ts +23 -0
- package/dist/triage-actions.js +233 -0
- package/dist/triage-aux-a-fixtures.d.ts +33 -0
- package/dist/triage-aux-a-fixtures.js +107 -0
- package/dist/triage-aux-b-fixtures.d.ts +30 -0
- package/dist/triage-aux-b-fixtures.js +167 -0
- package/dist/triage-bootstrap-fixtures.d.ts +42 -0
- package/dist/triage-bootstrap-fixtures.js +139 -0
- package/dist/triage-bootstrap.d.ts +24 -0
- package/dist/triage-bootstrap.js +175 -0
- package/dist/triage-bulk.d.ts +17 -0
- package/dist/triage-bulk.js +154 -0
- package/dist/triage-classify-fixtures.d.ts +38 -0
- package/dist/triage-classify-fixtures.js +137 -0
- package/dist/triage-classify.d.ts +45 -0
- package/dist/triage-classify.js +287 -0
- package/dist/triage-evaluate.d.ts +14 -0
- package/dist/triage-evaluate.js +153 -0
- package/dist/triage-help.d.ts +3 -0
- package/dist/triage-help.js +10 -0
- package/dist/triage-queue-fixtures.d.ts +59 -0
- package/dist/triage-queue-fixtures.js +284 -0
- package/dist/triage-queue.d.ts +38 -0
- package/dist/triage-queue.js +391 -0
- package/dist/triage-reconcile.d.ts +11 -0
- package/dist/triage-reconcile.js +76 -0
- package/dist/triage-refresh.d.ts +7 -0
- package/dist/triage-refresh.js +37 -0
- package/dist/triage-scope-drift.d.ts +12 -0
- package/dist/triage-scope-drift.js +117 -0
- package/dist/triage-scope-fixtures.d.ts +32 -0
- package/dist/triage-scope-fixtures.js +131 -0
- package/dist/triage-scope.d.ts +4 -0
- package/dist/triage-scope.js +34 -0
- package/dist/triage-smoketest.d.ts +3 -0
- package/dist/triage-smoketest.js +43 -0
- package/dist/triage-strip-withdrawn.d.ts +21 -0
- package/dist/triage-strip-withdrawn.js +102 -0
- package/dist/triage-subscribe.d.ts +15 -0
- package/dist/triage-subscribe.js +157 -0
- package/dist/triage-summary.d.ts +14 -0
- package/dist/triage-summary.js +83 -0
- package/dist/triage-welcome.d.ts +14 -0
- package/dist/triage-welcome.js +121 -0
- package/dist/ts-check-lane.d.ts +9 -0
- package/dist/ts-check-lane.js +49 -0
- package/dist/umbrella-current-shape.d.ts +9 -0
- package/dist/umbrella-current-shape.js +56 -0
- package/dist/vbrief-activate.d.ts +3 -0
- package/dist/vbrief-activate.js +7 -0
- package/dist/vbrief-build.d.ts +3 -0
- package/dist/vbrief-build.js +8 -0
- package/dist/vbrief-preflight-fixtures.d.ts +32 -0
- package/dist/vbrief-preflight-fixtures.js +79 -0
- package/dist/vbrief-preflight.d.ts +13 -0
- package/dist/vbrief-preflight.js +141 -0
- package/dist/vbrief-reconcile.d.ts +3 -0
- package/dist/vbrief-reconcile.js +7 -0
- package/dist/vbrief-validate.d.ts +3 -0
- package/dist/vbrief-validate.js +8 -0
- package/dist/vbrief-validation.d.ts +3 -0
- package/dist/vbrief-validation.js +8 -0
- package/dist/verify-ac.d.ts +28 -0
- package/dist/verify-ac.js +439 -0
- package/dist/verify-agents-md-advisory.d.ts +19 -0
- package/dist/verify-agents-md-advisory.js +65 -0
- package/dist/verify-agents-md-budget.d.ts +12 -0
- package/dist/verify-agents-md-budget.js +71 -0
- package/dist/verify-branch.d.ts +14 -0
- package/dist/verify-branch.js +81 -0
- package/dist/verify-class-checks.d.ts +11 -0
- package/dist/verify-class-checks.js +71 -0
- package/dist/verify-cohort-review-monitors.d.ts +5 -0
- package/dist/verify-cohort-review-monitors.js +11 -0
- package/dist/verify-completed-tracked.d.ts +19 -0
- package/dist/verify-completed-tracked.js +202 -0
- package/dist/verify-completed-write-guard.d.ts +13 -0
- package/dist/verify-completed-write-guard.js +84 -0
- package/dist/verify-consumer-check-contract.d.ts +12 -0
- package/dist/verify-consumer-check-contract.js +70 -0
- package/dist/verify-consumer-header-placeholder.d.ts +12 -0
- package/dist/verify-consumer-header-placeholder.js +73 -0
- package/dist/verify-consumer-test-lane.d.ts +12 -0
- package/dist/verify-consumer-test-lane.js +57 -0
- package/dist/verify-durable-effect-acquisition.d.ts +13 -0
- package/dist/verify-durable-effect-acquisition.js +70 -0
- package/dist/verify-encoding.d.ts +15 -0
- package/dist/verify-encoding.js +83 -0
- package/dist/verify-eval-health-relocation.d.ts +16 -0
- package/dist/verify-eval-health-relocation.js +93 -0
- package/dist/verify-eval-triggers-relocation.d.ts +14 -0
- package/dist/verify-eval-triggers-relocation.js +74 -0
- package/dist/verify-evaluator-surface.d.ts +15 -0
- package/dist/verify-evaluator-surface.js +87 -0
- package/dist/verify-forward-coverage.d.ts +19 -0
- package/dist/verify-forward-coverage.js +144 -0
- package/dist/verify-hooks-installed.d.ts +24 -0
- package/dist/verify-hooks-installed.js +140 -0
- package/dist/verify-intent-constraint.d.ts +15 -0
- package/dist/verify-intent-constraint.js +86 -0
- package/dist/verify-investigation.d.ts +3 -0
- package/dist/verify-investigation.js +10 -0
- package/dist/verify-judgment-gates.d.ts +3 -0
- package/dist/verify-judgment-gates.js +10 -0
- package/dist/verify-l4-owner.d.ts +15 -0
- package/dist/verify-l4-owner.js +132 -0
- package/dist/verify-lifecycle-visible.d.ts +13 -0
- package/dist/verify-lifecycle-visible.js +68 -0
- package/dist/verify-literal-ac.d.ts +14 -0
- package/dist/verify-literal-ac.js +168 -0
- package/dist/verify-no-task-runtime.d.ts +3 -0
- package/dist/verify-no-task-runtime.js +16 -0
- package/dist/verify-observable-scope.d.ts +15 -0
- package/dist/verify-observable-scope.js +86 -0
- package/dist/verify-operator-scope-limit.d.ts +17 -0
- package/dist/verify-operator-scope-limit.js +285 -0
- package/dist/verify-orphan-active.d.ts +17 -0
- package/dist/verify-orphan-active.js +135 -0
- package/dist/verify-ownership.d.ts +10 -0
- package/dist/verify-ownership.js +90 -0
- package/dist/verify-persisted-planning-narratives.d.ts +12 -0
- package/dist/verify-persisted-planning-narratives.js +82 -0
- package/dist/verify-plan-sequence.d.ts +14 -0
- package/dist/verify-plan-sequence.js +138 -0
- package/dist/verify-pr-closeout-attestable.d.ts +15 -0
- package/dist/verify-pr-closeout-attestable.js +114 -0
- package/dist/verify-presentation-ceiling.d.ts +11 -0
- package/dist/verify-presentation-ceiling.js +71 -0
- package/dist/verify-presentation-coverage.d.ts +14 -0
- package/dist/verify-presentation-coverage.js +90 -0
- package/dist/verify-review-monitor.d.ts +25 -0
- package/dist/verify-review-monitor.js +341 -0
- package/dist/verify-scope-provenance.d.ts +16 -0
- package/dist/verify-scope-provenance.js +91 -0
- package/dist/verify-session-ritual.d.ts +23 -0
- package/dist/verify-session-ritual.js +144 -0
- package/dist/verify-source-cli/rule-ownership-lint.d.ts +12 -0
- package/dist/verify-source-cli/rule-ownership-lint.js +61 -0
- package/dist/verify-source-cli/verify-biome-config.d.ts +11 -0
- package/dist/verify-source-cli/verify-biome-config.js +46 -0
- package/dist/verify-source-cli/verify-closing-keywords.d.ts +35 -0
- package/dist/verify-source-cli/verify-closing-keywords.js +139 -0
- package/dist/verify-source-cli/verify-consumer-hard-stops.d.ts +16 -0
- package/dist/verify-source-cli/verify-consumer-hard-stops.js +99 -0
- package/dist/verify-source-cli/verify-contained-writes.d.ts +13 -0
- package/dist/verify-source-cli/verify-contained-writes.js +67 -0
- package/dist/verify-source-cli/verify-content-manifest.d.ts +12 -0
- package/dist/verify-source-cli/verify-content-manifest.js +61 -0
- package/dist/verify-source-cli/verify-contract-drift.d.ts +11 -0
- package/dist/verify-source-cli/verify-contract-drift.js +47 -0
- package/dist/verify-source-cli/verify-cursor-tier1.d.ts +12 -0
- package/dist/verify-source-cli/verify-cursor-tier1.js +51 -0
- package/dist/verify-source-cli/verify-deposit-closure.d.ts +12 -0
- package/dist/verify-source-cli/verify-deposit-closure.js +52 -0
- package/dist/verify-source-cli/verify-openclaw-tier1.d.ts +12 -0
- package/dist/verify-source-cli/verify-openclaw-tier1.js +51 -0
- package/dist/verify-source-cli/verify-scm-boundary.d.ts +13 -0
- package/dist/verify-source-cli/verify-scm-boundary.js +66 -0
- package/dist/verify-source-cli/verify-semantic-single-source.d.ts +11 -0
- package/dist/verify-source-cli/verify-semantic-single-source.js +49 -0
- package/dist/verify-source-cli/verify-skill-external-fetch-gate.d.ts +11 -0
- package/dist/verify-source-cli/verify-skill-external-fetch-gate.js +46 -0
- package/dist/verify-source-cli/verify-spec-drift.d.ts +3 -0
- package/dist/verify-source-cli/verify-spec-drift.js +15 -0
- package/dist/verify-source-cli/verify-spec-prd-fresh.d.ts +3 -0
- package/dist/verify-source-cli/verify-spec-prd-fresh.js +15 -0
- package/dist/verify-source-cli/verify-stubs.d.ts +11 -0
- package/dist/verify-source-cli/verify-stubs.js +27 -0
- package/dist/verify-source-cli/verify-telemetry-coverage.d.ts +13 -0
- package/dist/verify-source-cli/verify-telemetry-coverage.js +67 -0
- package/dist/verify-source-cli/verify-xbrief-drift.d.ts +15 -0
- package/dist/verify-source-cli/verify-xbrief-drift.js +80 -0
- package/dist/verify-story-ready.d.ts +18 -0
- package/dist/verify-story-ready.js +190 -0
- package/dist/verify-subagent-alive.d.ts +21 -0
- package/dist/verify-subagent-alive.js +219 -0
- package/dist/verify-subagent-steer.d.ts +19 -0
- package/dist/verify-subagent-steer.js +136 -0
- package/dist/verify-test-boundary.d.ts +12 -0
- package/dist/verify-test-boundary.js +80 -0
- package/dist/verify-tools.d.ts +13 -0
- package/dist/verify-tools.js +67 -0
- package/dist/verify-wip-cap.d.ts +13 -0
- package/dist/verify-wip-cap.js +62 -0
- package/dist/windows-bin-ps1.d.ts +39 -0
- package/dist/windows-bin-ps1.js +226 -0
- package/dist/wip-cap-fixtures.d.ts +37 -0
- package/dist/wip-cap-fixtures.js +122 -0
- package/dist/wsl-ownership-guard.d.ts +2 -0
- package/dist/wsl-ownership-guard.js +15 -0
- package/dist/xbrief-create.d.ts +3 -0
- package/dist/xbrief-create.js +9 -0
- package/dist/xbrief-verify.d.ts +3 -0
- package/dist/xbrief-verify.js +9 -0
- package/package.json +23 -12
- package/scripts/remove-windows-ps1-shims.mjs +26 -0
- package/bin/deft-hook +0 -14
- package/bin/deft-hook.cmd +0 -14
package/dist/authz.js
ADDED
|
@@ -0,0 +1,732 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Authz CLI (#2944 Wave 1 + #1095 Wave 4 + #3110 + #3291): human-origin grants + UAT lease +
|
|
4
|
+
* AFK closed-verb templates + structural scope:decompose apply grants
|
|
5
|
+
* (mint via mintHumanOriginGrant / mintDecomposeStructuralApplyGrant only).
|
|
6
|
+
*
|
|
7
|
+
* deft authz:show
|
|
8
|
+
* deft authz:uat-start -- --campaign <id> [--actor <name>] [--note <text>] [--confirm]
|
|
9
|
+
* deft authz:uat-suspend [--confirm]
|
|
10
|
+
* deft authz:grant -- --operations edit,push --surfaces 'src/**' --cohort <id> ... [--confirm]
|
|
11
|
+
* deft authz:grant -- --template release-publish --target 0.30.0 [--confirm]
|
|
12
|
+
* deft authz:grant -- --template finish-loop [--confirm]
|
|
13
|
+
* deft authz:grant -- --template spec-drift-override --target <baseline> --plan-ref <scopeId> --story-ids <ids> [--confirm]
|
|
14
|
+
* deft authz:grant -- --template gate-override --target <refuseCode> --plan-ref <attemptId> \\
|
|
15
|
+
* --base-sha <sha> --head-sha <sha> --tree-hash <hash> [--confirm]
|
|
16
|
+
* deft authz:grant -- --parent <parent.xbrief.json> --draft <draft.json> [--repo owner/name] [--confirm]
|
|
17
|
+
* deft authz:revoke -- <grant-id> [--confirm]
|
|
18
|
+
*
|
|
19
|
+
* **UAT-active mint refuse (#3110 / #4632):** while any UAT lease is active,
|
|
20
|
+
* `uat-start`, `grant`, and `revoke` refuse unconditionally — no TTY, `--confirm`,
|
|
21
|
+
* or typed phrase path. `uat-suspend` skips that mint-refuse and still requires
|
|
22
|
+
* multi-factor human presence (real operator console). Suspend reuses the typed
|
|
23
|
+
* phrase `mint`; it is not a remint.
|
|
24
|
+
*
|
|
25
|
+
* **Outside UAT:** mutating verbs require multi-factor human presence: interactive
|
|
26
|
+
* TTY + controlling terminal + `--confirm` + typed phrase `mint`; agent/CI env
|
|
27
|
+
* markers refuse fail-closed. Argv `--confirm` alone is never enough.
|
|
28
|
+
*/
|
|
29
|
+
import { existsSync } from "node:fs";
|
|
30
|
+
import { isAbsolute, resolve } from "node:path";
|
|
31
|
+
import { onePrUnit } from "@deftai/directive-core";
|
|
32
|
+
import { AFK_TEMPLATE_NAMES, AUTHZ_OPERATIONS, CLOSED_VERB_TEMPLATE_NAMES, FINISH_LOOP_TEMPLATE_NAME, formatDecomposeStructuralMintCommand, GATE_OVERRIDE_TEMPLATE_NAME, isAfkTemplateName, isClosedVerbTemplateName, isFinishLoopTemplateName, isGateOverrideTemplateName, mintAfkTemplateGrant, mintDecomposeStructuralApplyGrant, mintGateOverrideTemplateGrant, mintHumanOriginGrant, revokeGrant, showAuthzSnapshot, startUatLease, suspendUatLease, toProjectRelativePosix, } from "@deftai/directive-core/authz";
|
|
33
|
+
import { uatCampaignEndSeal } from "@deftai/directive-core/authz/campaign-end-seal";
|
|
34
|
+
import { isSpecDriftOverrideTemplateName, mintSpecDriftOverrideTemplateGrant, SPEC_DRIFT_OVERRIDE_TEMPLATE_NAME, } from "@deftai/directive-core/policy";
|
|
35
|
+
import { refuseMintWhileUatActive, refuseNonInteractiveMint, resolveHumanPresenceMintSeams, } from "./human-presence-mint.js";
|
|
36
|
+
export { AUTHZ_AGENT_SHELL_ENV_MARKERS, AUTHZ_INTERACTIVE_CONFIRM_PHRASE, } from "./human-presence-mint.js";
|
|
37
|
+
function parseOps(raw) {
|
|
38
|
+
const allowed = new Set(AUTHZ_OPERATIONS);
|
|
39
|
+
const out = [];
|
|
40
|
+
for (const part of raw.split(/[,\s]+/)) {
|
|
41
|
+
const op = part.trim().toLowerCase();
|
|
42
|
+
if (op.length === 0)
|
|
43
|
+
continue;
|
|
44
|
+
if (!allowed.has(op)) {
|
|
45
|
+
throw new Error(`unknown operation '${op}'; expected one of ${AUTHZ_OPERATIONS.join(", ")}`);
|
|
46
|
+
}
|
|
47
|
+
out.push(op);
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
function parseArgv(argv) {
|
|
52
|
+
const base = {
|
|
53
|
+
cmd: "show",
|
|
54
|
+
projectRoot: process.cwd(),
|
|
55
|
+
campaign: null,
|
|
56
|
+
actor: "operator",
|
|
57
|
+
note: null,
|
|
58
|
+
operations: [],
|
|
59
|
+
surfaces: [],
|
|
60
|
+
cohort: null,
|
|
61
|
+
planRef: null,
|
|
62
|
+
repo: null,
|
|
63
|
+
branch: null,
|
|
64
|
+
storyIds: [],
|
|
65
|
+
issueIds: [],
|
|
66
|
+
expiresAt: null,
|
|
67
|
+
singleUse: false,
|
|
68
|
+
grantId: null,
|
|
69
|
+
template: null,
|
|
70
|
+
target: null,
|
|
71
|
+
parent: null,
|
|
72
|
+
draft: null,
|
|
73
|
+
baseSha: null,
|
|
74
|
+
headSha: null,
|
|
75
|
+
treeHash: null,
|
|
76
|
+
worktree: null,
|
|
77
|
+
evaluatorId: null,
|
|
78
|
+
format: "text",
|
|
79
|
+
confirm: false,
|
|
80
|
+
};
|
|
81
|
+
const args = [...argv];
|
|
82
|
+
// Drop leading `--` separators from task-style invocation.
|
|
83
|
+
while (args[0] === "--")
|
|
84
|
+
args.shift();
|
|
85
|
+
if (args.length > 0 && !args[0]?.startsWith("-")) {
|
|
86
|
+
const cmd = args.shift();
|
|
87
|
+
if (cmd === "show" ||
|
|
88
|
+
cmd === "uat-start" ||
|
|
89
|
+
cmd === "uat-suspend" ||
|
|
90
|
+
cmd === "grant" ||
|
|
91
|
+
cmd === "revoke") {
|
|
92
|
+
base.cmd = cmd;
|
|
93
|
+
}
|
|
94
|
+
else if (cmd.startsWith("grant-")) {
|
|
95
|
+
base.cmd = "revoke";
|
|
96
|
+
base.grantId = cmd;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
return { ...base, error: `unknown authz subcommand: ${cmd}` };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
while (args[0] === "--")
|
|
103
|
+
args.shift();
|
|
104
|
+
for (let i = 0; i < args.length; i++) {
|
|
105
|
+
const a = args[i];
|
|
106
|
+
if (a === undefined)
|
|
107
|
+
break;
|
|
108
|
+
if (a === "--project-root" || a === "--projectRoot") {
|
|
109
|
+
base.projectRoot = args[++i] ?? base.projectRoot;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (a === "--campaign") {
|
|
113
|
+
base.campaign = args[++i] ?? null;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (a === "--actor") {
|
|
117
|
+
base.actor = args[++i] ?? base.actor;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (a === "--note") {
|
|
121
|
+
base.note = args[++i] ?? null;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (a === "--operations" || a === "--ops") {
|
|
125
|
+
try {
|
|
126
|
+
base.operations = parseOps(args[++i] ?? "");
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
return { ...base, error: String(err) };
|
|
130
|
+
}
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (a === "--surfaces") {
|
|
134
|
+
const raw = args[++i] ?? "";
|
|
135
|
+
base.surfaces = raw
|
|
136
|
+
.split(/[,\s]+/)
|
|
137
|
+
.map((s) => s.trim())
|
|
138
|
+
.filter((s) => s.length > 0);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (a === "--cohort") {
|
|
142
|
+
base.cohort = args[++i] ?? null;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (a === "--plan-ref" || a === "--planRef") {
|
|
146
|
+
base.planRef = args[++i] ?? null;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (a === "--repo") {
|
|
150
|
+
base.repo = args[++i] ?? null;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (a === "--branch") {
|
|
154
|
+
base.branch = args[++i] ?? null;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (a === "--stories" || a === "--story-ids") {
|
|
158
|
+
const raw = args[++i] ?? "";
|
|
159
|
+
base.storyIds = raw
|
|
160
|
+
.split(/[,\s]+/)
|
|
161
|
+
.map((s) => s.trim())
|
|
162
|
+
.filter((s) => s.length > 0);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (a === "--issues" || a === "--issue-ids") {
|
|
166
|
+
const raw = args[++i] ?? "";
|
|
167
|
+
base.issueIds = raw
|
|
168
|
+
.split(/[,\s]+/)
|
|
169
|
+
.map((s) => Number(s.trim()))
|
|
170
|
+
.filter((n) => Number.isFinite(n));
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (a === "--expires" || a === "--expires-at") {
|
|
174
|
+
base.expiresAt = args[++i] ?? null;
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (a === "--single-use") {
|
|
178
|
+
base.singleUse = true;
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (a === "--format") {
|
|
182
|
+
const fmt = (args[++i] ?? "text").toLowerCase();
|
|
183
|
+
base.format = fmt === "json" ? "json" : "text";
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (a === "--grant-id") {
|
|
187
|
+
base.grantId = args[++i] ?? null;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
if (a === "--template") {
|
|
191
|
+
base.template = args[++i] ?? null;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (a === "--target") {
|
|
195
|
+
base.target = args[++i] ?? null;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (a === "--parent") {
|
|
199
|
+
base.parent = args[++i] ?? null;
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
if (a === "--draft") {
|
|
203
|
+
base.draft = args[++i] ?? null;
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (a === "--base-sha" || a === "--baseSha") {
|
|
207
|
+
base.baseSha = args[++i] ?? null;
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
if (a === "--head-sha" || a === "--headSha") {
|
|
211
|
+
base.headSha = args[++i] ?? null;
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (a === "--tree-hash" || a === "--treeHash") {
|
|
215
|
+
base.treeHash = args[++i] ?? null;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (a === "--worktree") {
|
|
219
|
+
base.worktree = args[++i] ?? null;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
if (a === "--evaluator-id" || a === "--evaluatorId") {
|
|
223
|
+
base.evaluatorId = args[++i] ?? null;
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
if (a === "--confirm") {
|
|
227
|
+
base.confirm = true;
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
if (!a.startsWith("-") && base.cmd === "revoke" && base.grantId === null) {
|
|
231
|
+
base.grantId = a;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (a === "--help" || a === "-h") {
|
|
235
|
+
return { ...base, error: "help" };
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return base;
|
|
239
|
+
}
|
|
240
|
+
function helpText() {
|
|
241
|
+
return [
|
|
242
|
+
"Usage:",
|
|
243
|
+
" deft authz:show [--format json]",
|
|
244
|
+
" deft authz:uat-start -- --campaign <id> [--actor <name>] [--note <text>] [--confirm]",
|
|
245
|
+
" deft authz:uat-suspend [--confirm]",
|
|
246
|
+
" deft authz:grant -- --operations edit,push --surfaces 'src/**' --cohort <id> \\",
|
|
247
|
+
" [--stories 2944] [--plan-ref <id>] [--repo owner/name] [--branch <b>] [--expires ISO] [--confirm]",
|
|
248
|
+
" deft authz:grant -- --template release-publish --target 0.30.0 [--actor <name>] [--expires ISO] [--confirm]",
|
|
249
|
+
" deft authz:grant -- --template finish-loop [--actor <name>] [--expires ISO] [--confirm]",
|
|
250
|
+
" deft authz:grant -- --parent <parent.xbrief.json> --draft <draft.json> \\",
|
|
251
|
+
" [--repo owner/name] [--expires ISO] [--single-use] [--actor <name>] [--confirm]",
|
|
252
|
+
" deft authz:revoke -- <grant-id> [--confirm]",
|
|
253
|
+
"",
|
|
254
|
+
"Human-origin grants are minted only via this CLI (origin.kind=operator-cli).",
|
|
255
|
+
"Self-authored xBRIEF/lifecycle/dispatch tokens never satisfy implement gates (#2944).",
|
|
256
|
+
"While any UAT lease is ACTIVE (#3110 / #4632): grant / uat-start / revoke refuse",
|
|
257
|
+
" unconditionally — no TTY, --confirm, or phrase path. Self-approval remint under",
|
|
258
|
+
" UAT is impossible by construction. Mint grants BEFORE uat-start.",
|
|
259
|
+
" uat-suspend is reachable from a real operator console: listed agent/CI markers",
|
|
260
|
+
" empty, stdin+stdout TTY, controlling terminal, --confirm, typed phrase 'mint'",
|
|
261
|
+
" (suspend reuses the mint phrase; it is not a remint). Agent/CI and missing-factor",
|
|
262
|
+
" seams still refuse (exit 2). After suspend, grant is available again through",
|
|
263
|
+
" the same human-presence gate.",
|
|
264
|
+
"Outside UAT, mutating verbs require multi-factor human presence (#3110):",
|
|
265
|
+
" - Interactive TTY (stdin+stdout) + controlling terminal (/dev/tty|\\\\.\\CONIN$)",
|
|
266
|
+
" - Explicit --confirm (argv flag alone never enough)",
|
|
267
|
+
" - Typed phrase 'mint' on the controlling TTY (PTY+--confirm alone never enough)",
|
|
268
|
+
" - Known agent/CI env markers always refuse (fail-closed).",
|
|
269
|
+
"",
|
|
270
|
+
"Structural scope:decompose apply (#3239 / #3291):",
|
|
271
|
+
" Pass --parent + --draft (paths under project root). Digest is SHA-256 of exact",
|
|
272
|
+
" draft bytes; binds parent, target, worktree, and optional --repo. Mints only",
|
|
273
|
+
" scope.decompose.apply.structural via mintDecomposeStructuralApplyGrant.",
|
|
274
|
+
" Example (after --check validates the draft):",
|
|
275
|
+
" deft authz:grant -- --parent xbrief/pending/epic.xbrief.json \\",
|
|
276
|
+
" --draft xbrief/.triage-cache/decompositions/draft.json --confirm",
|
|
277
|
+
" Then: deft scope:decompose -- <parent> --draft <draft>",
|
|
278
|
+
" scope:decompose --check remains ungated (no structural grant required).",
|
|
279
|
+
"",
|
|
280
|
+
`AFK templates (#1095 / #871): ${AFK_TEMPLATE_NAMES.join(", ")}`,
|
|
281
|
+
` Closed-verb (#1095): ${CLOSED_VERB_TEMPLATE_NAMES.join(", ")} — require --target`,
|
|
282
|
+
` Finish-loop (#871): ${FINISH_LOOP_TEMPLATE_NAME} — edit/push/pr/merge (no release ops)`,
|
|
283
|
+
" Templates call mintHumanOriginGrant only — no second session-auth mint engine.",
|
|
284
|
+
" Env bypass for a single shell: DEFT_ALLOW_RELEASE_PUBLISH=1 / DEFT_ALLOW_FINISH_LOOP=1.",
|
|
285
|
+
"",
|
|
286
|
+
`Gate-override (#5542): ${GATE_OVERRIDE_TEMPLATE_NAME}`,
|
|
287
|
+
" deft authz:grant -- --template gate-override --target <refuseCode> --plan-ref <attemptId> \\",
|
|
288
|
+
" --base-sha <sha> --head-sha <sha> --tree-hash <hash> [--worktree <id>] [--evaluator-id <id>] [--confirm]",
|
|
289
|
+
" operator-cli human-presence only; waived ≠ passed; no independent push/merge.",
|
|
290
|
+
].join("\n");
|
|
291
|
+
}
|
|
292
|
+
export function main(argv = process.argv.slice(2), seams = {}) {
|
|
293
|
+
const args = parseArgv(argv);
|
|
294
|
+
if (args.error === "help") {
|
|
295
|
+
process.stdout.write(`${helpText()}\n`);
|
|
296
|
+
return 0;
|
|
297
|
+
}
|
|
298
|
+
if (args.error !== undefined) {
|
|
299
|
+
process.stderr.write(`authz: ${args.error}\n`);
|
|
300
|
+
process.stderr.write(`${helpText()}\n`);
|
|
301
|
+
return 2;
|
|
302
|
+
}
|
|
303
|
+
const resolved = resolveHumanPresenceMintSeams(seams);
|
|
304
|
+
/**
|
|
305
|
+
* Mutating-verb gate stack (#3110 / #4632):
|
|
306
|
+
* 1. Active UAT mint-refuse for grant / uat-start / revoke (no multi-factor escape)
|
|
307
|
+
* 2. uat-suspend skips that mint-refuse so campaign-end stays reachable
|
|
308
|
+
* 3. Multi-factor human presence: TTY + controlling tty + --confirm + typed phrase;
|
|
309
|
+
* agent/CI markers refuse. Suspend reuses phrase `mint`.
|
|
310
|
+
* Required-arg validation runs before this so missing --campaign / --ops still report clearly.
|
|
311
|
+
*/
|
|
312
|
+
const gateConfirm = () => {
|
|
313
|
+
if (args.cmd === "show")
|
|
314
|
+
return null;
|
|
315
|
+
if (args.cmd !== "uat-suspend") {
|
|
316
|
+
const uatBlocked = refuseMintWhileUatActive(`authz:${args.cmd}`, args.projectRoot);
|
|
317
|
+
if (uatBlocked !== null)
|
|
318
|
+
return uatBlocked;
|
|
319
|
+
}
|
|
320
|
+
return refuseNonInteractiveMint({
|
|
321
|
+
verb: `authz:${args.cmd}`,
|
|
322
|
+
confirm: args.confirm,
|
|
323
|
+
isTty: resolved.isTty,
|
|
324
|
+
environ: resolved.environ,
|
|
325
|
+
hasControllingTerminal: resolved.hasControllingTerminal,
|
|
326
|
+
readInteractiveConfirm: resolved.readInteractiveConfirm,
|
|
327
|
+
});
|
|
328
|
+
};
|
|
329
|
+
try {
|
|
330
|
+
switch (args.cmd) {
|
|
331
|
+
case "show": {
|
|
332
|
+
const snap = showAuthzSnapshot(args.projectRoot);
|
|
333
|
+
if (args.format === "json") {
|
|
334
|
+
process.stdout.write(`${JSON.stringify(snap, null, 2)}\n`);
|
|
335
|
+
return 0;
|
|
336
|
+
}
|
|
337
|
+
const uat = snap.state.uat;
|
|
338
|
+
if (uat === null) {
|
|
339
|
+
process.stdout.write("UAT lease: inactive\n");
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
process.stdout.write(`UAT lease: ${uat.active ? "ACTIVE" : "suspended"} campaign=${uat.campaignId}\n`);
|
|
343
|
+
process.stdout.write(` started=${uat.startedAt} by=${uat.startedBy.actor} (${uat.startedBy.kind})\n`);
|
|
344
|
+
if (uat.suspendedAt)
|
|
345
|
+
process.stdout.write(` suspended=${uat.suspendedAt}\n`);
|
|
346
|
+
}
|
|
347
|
+
process.stdout.write(`Active human-origin grants: ${snap.activeGrants.length}\n`);
|
|
348
|
+
for (const g of snap.activeGrants) {
|
|
349
|
+
process.stdout.write(` - ${g.id} ops=[${g.scope.operations.join(",")}] ` +
|
|
350
|
+
`cohort=${g.scope.cohortId ?? "-"} surfaces=${g.scope.surfaces.join("|") || "*"}\n`);
|
|
351
|
+
}
|
|
352
|
+
const rejected = snap.allGrants.length - snap.activeGrants.length;
|
|
353
|
+
if (rejected > 0) {
|
|
354
|
+
process.stdout.write(`(${rejected} grant file(s) present but not active/human-origin)\n`);
|
|
355
|
+
}
|
|
356
|
+
return 0;
|
|
357
|
+
}
|
|
358
|
+
case "uat-start": {
|
|
359
|
+
if (args.campaign === null || args.campaign.trim().length === 0) {
|
|
360
|
+
process.stderr.write("authz:uat-start requires --campaign <id>\n");
|
|
361
|
+
return 2;
|
|
362
|
+
}
|
|
363
|
+
const blocked = gateConfirm();
|
|
364
|
+
if (blocked !== null)
|
|
365
|
+
return blocked;
|
|
366
|
+
// Result narrowing; pinActive mint wiring stays parked (class 4).
|
|
367
|
+
const started = startUatLease({
|
|
368
|
+
projectRoot: args.projectRoot,
|
|
369
|
+
campaignId: args.campaign,
|
|
370
|
+
actor: args.actor,
|
|
371
|
+
note: args.note,
|
|
372
|
+
});
|
|
373
|
+
if (!started.ok) {
|
|
374
|
+
process.stderr.write(`authz:uat-start: ${started.reason}\n`);
|
|
375
|
+
return 2;
|
|
376
|
+
}
|
|
377
|
+
process.stdout.write(`✓ UAT lease ACTIVE campaign=${started.lease.campaignId} (human-origin operator-cli)\n`);
|
|
378
|
+
process.stdout.write(" Product edit/push/PR/merge denied until a named fix cohort grant is minted.\n");
|
|
379
|
+
process.stdout.write(" Tests, evidence capture, and issue filing remain allowed.\n");
|
|
380
|
+
return 0;
|
|
381
|
+
}
|
|
382
|
+
case "uat-suspend": {
|
|
383
|
+
const blocked = gateConfirm();
|
|
384
|
+
if (blocked !== null)
|
|
385
|
+
return blocked;
|
|
386
|
+
// Sealed campaign-end only after CLI human-presence gateConfirm (#4233).
|
|
387
|
+
// pinActive mint wiring stays parked (class 4 follow-up).
|
|
388
|
+
const suspended = suspendUatLease({
|
|
389
|
+
projectRoot: args.projectRoot,
|
|
390
|
+
actor: args.actor,
|
|
391
|
+
campaignEndSeal: uatCampaignEndSeal(),
|
|
392
|
+
});
|
|
393
|
+
if (!suspended.ok) {
|
|
394
|
+
process.stderr.write(`authz:uat-suspend: ${suspended.reason}\n`);
|
|
395
|
+
return 2;
|
|
396
|
+
}
|
|
397
|
+
const state = suspended.state;
|
|
398
|
+
if (state.uat === null) {
|
|
399
|
+
process.stdout.write("UAT lease was already inactive.\n");
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
process.stdout.write(`✓ UAT lease suspended campaign=${state.uat.campaignId} at ${state.uat.suspendedAt}\n`);
|
|
403
|
+
}
|
|
404
|
+
return 0;
|
|
405
|
+
}
|
|
406
|
+
case "grant": {
|
|
407
|
+
// Structural decompose apply path (#3291): --parent + --draft → mintDecomposeStructuralApplyGrant.
|
|
408
|
+
const parentRaw = args.parent?.trim() ?? "";
|
|
409
|
+
const draftRaw = args.draft?.trim() ?? "";
|
|
410
|
+
const hasParent = parentRaw.length > 0;
|
|
411
|
+
const hasDraft = draftRaw.length > 0;
|
|
412
|
+
if (hasParent !== hasDraft) {
|
|
413
|
+
process.stderr.write("authz:grant structural mint requires both --parent <path> and --draft <path>\n" +
|
|
414
|
+
` Example: ${formatDecomposeStructuralMintCommand(hasParent ? parentRaw : "xbrief/pending/parent.xbrief.json", hasDraft ? draftRaw : "xbrief/.triage-cache/decompositions/draft.json", { repo: args.repo })}\n`);
|
|
415
|
+
return 2;
|
|
416
|
+
}
|
|
417
|
+
if (hasParent && hasDraft) {
|
|
418
|
+
if (args.template !== null && args.template.trim().length > 0) {
|
|
419
|
+
process.stderr.write("authz:grant: --parent/--draft structural mint cannot be combined with --template\n");
|
|
420
|
+
return 2;
|
|
421
|
+
}
|
|
422
|
+
if (args.operations.length > 0) {
|
|
423
|
+
process.stderr.write("authz:grant: --parent/--draft structural mint cannot be combined with --operations " +
|
|
424
|
+
"(operation is fixed to scope.decompose.apply.structural)\n");
|
|
425
|
+
return 2;
|
|
426
|
+
}
|
|
427
|
+
const root = resolve(args.projectRoot);
|
|
428
|
+
const parentAbs = isAbsolute(parentRaw) ? resolve(parentRaw) : resolve(root, parentRaw);
|
|
429
|
+
const draftAbs = isAbsolute(draftRaw) ? resolve(draftRaw) : resolve(root, draftRaw);
|
|
430
|
+
const parentRel = toProjectRelativePosix(root, parentAbs);
|
|
431
|
+
const draftRel = toProjectRelativePosix(root, draftAbs);
|
|
432
|
+
if (parentRel === null) {
|
|
433
|
+
process.stderr.write(`authz:grant: --parent path is outside project root: ${parentRaw}\n`);
|
|
434
|
+
return 2;
|
|
435
|
+
}
|
|
436
|
+
if (draftRel === null) {
|
|
437
|
+
process.stderr.write(`authz:grant: --draft path is outside project root: ${draftRaw}\n`);
|
|
438
|
+
return 2;
|
|
439
|
+
}
|
|
440
|
+
if (!existsSync(parentAbs)) {
|
|
441
|
+
process.stderr.write(`authz:grant: --parent path does not exist: ${parentRaw}\n`);
|
|
442
|
+
return 2;
|
|
443
|
+
}
|
|
444
|
+
if (!existsSync(draftAbs)) {
|
|
445
|
+
process.stderr.write(`authz:grant: --draft path does not exist: ${draftRaw}\n`);
|
|
446
|
+
return 2;
|
|
447
|
+
}
|
|
448
|
+
const blocked = gateConfirm();
|
|
449
|
+
if (blocked !== null)
|
|
450
|
+
return blocked;
|
|
451
|
+
const minted = mintDecomposeStructuralApplyGrant({
|
|
452
|
+
projectRoot: root,
|
|
453
|
+
parentPath: parentAbs,
|
|
454
|
+
draftPath: draftAbs,
|
|
455
|
+
actor: args.actor,
|
|
456
|
+
repo: args.repo,
|
|
457
|
+
expiresAt: args.expiresAt,
|
|
458
|
+
singleUse: args.singleUse,
|
|
459
|
+
});
|
|
460
|
+
if (!minted.ok) {
|
|
461
|
+
process.stderr.write(`authz:grant: ${minted.reason}\n`);
|
|
462
|
+
return 2;
|
|
463
|
+
}
|
|
464
|
+
const grant = minted.grant;
|
|
465
|
+
// mintDecomposeStructuralApplyGrant always sets contentDigest + worktree.
|
|
466
|
+
const digest = grant.scope.contentDigest || "";
|
|
467
|
+
process.stdout.write(`✓ human-origin structural grant minted id=${grant.id} origin=${grant.origin.kind}\n`);
|
|
468
|
+
process.stdout.write(` ops=[${grant.scope.operations.join(",")}] digest=${digest.slice(0, 12)}…\n`);
|
|
469
|
+
process.stdout.write(` parent=${parentRel} draft=${draftRel}\n`);
|
|
470
|
+
if (grant.scope.repo) {
|
|
471
|
+
process.stdout.write(` repo=${grant.scope.repo}\n`);
|
|
472
|
+
}
|
|
473
|
+
process.stdout.write(` worktree=${grant.scope.worktree || root}\n`);
|
|
474
|
+
if (grant.semantics.singleUse) {
|
|
475
|
+
process.stdout.write(" single-use=true (spent on first successful apply)\n");
|
|
476
|
+
}
|
|
477
|
+
process.stdout.write(" Apply: deft scope:decompose -- <parent> --draft <draft>\n" +
|
|
478
|
+
" Authorization SoT: Wave 1 grant store (.deft/authz/grants) — not session-auth.\n");
|
|
479
|
+
return 0;
|
|
480
|
+
}
|
|
481
|
+
if (args.template !== null && args.template.trim().toLowerCase() === "one-pr-unit") {
|
|
482
|
+
if (args.repo === null || args.repo.trim().length === 0) {
|
|
483
|
+
process.stderr.write("authz:grant --template one-pr-unit requires --repo owner/name\n");
|
|
484
|
+
return 2;
|
|
485
|
+
}
|
|
486
|
+
if (args.issueIds.length < 2) {
|
|
487
|
+
process.stderr.write("authz:grant --template one-pr-unit requires --issue-ids with at least two origins\n");
|
|
488
|
+
return 2;
|
|
489
|
+
}
|
|
490
|
+
const blocked = gateConfirm();
|
|
491
|
+
if (blocked !== null)
|
|
492
|
+
return blocked;
|
|
493
|
+
if ((process.env.DEFT_ONE_PR_UNIT_APP ?? "").trim().length === 0) {
|
|
494
|
+
process.stderr.write("authz:grant --template one-pr-unit requires DEFT_ONE_PR_UNIT_APP (durable Directive App store). " +
|
|
495
|
+
"The in-process simulator is test-only and is discarded on process exit.\n");
|
|
496
|
+
return 2;
|
|
497
|
+
}
|
|
498
|
+
const resolved = onePrUnit.resolveProductionAppStore(process.env);
|
|
499
|
+
if (!resolved.ok) {
|
|
500
|
+
process.stderr.write(`${resolved.message}\n`);
|
|
501
|
+
return 2;
|
|
502
|
+
}
|
|
503
|
+
const claim = onePrUnit.mintOnePrUnitGrant({
|
|
504
|
+
actor: args.actor,
|
|
505
|
+
approvalRef: args.note ?? "authz:grant --template one-pr-unit",
|
|
506
|
+
rationale: args.note ?? "one-PR-unit",
|
|
507
|
+
origins: args.issueIds.map((issueId) => ({ repo: args.repo, issueId })),
|
|
508
|
+
repo: args.repo,
|
|
509
|
+
store: resolved.store,
|
|
510
|
+
});
|
|
511
|
+
process.stdout.write(`✓ one-PR-unit claim minted id=${claim.id} state=${claim.state} (reserved unbound)\n`);
|
|
512
|
+
process.stdout.write(" Opaque id is not a bearer. Only the App store plus the bound PR node id authorizes.\n");
|
|
513
|
+
process.stdout.write(` origins=${claim.origins.map((o) => `${o.repo}#${o.issueId}`).join(",")}\n`);
|
|
514
|
+
return 0;
|
|
515
|
+
}
|
|
516
|
+
// Gate-override hatch (#5542 Prefer-A Bound): coverage-applicability refuse waiver.
|
|
517
|
+
if (args.template !== null && isGateOverrideTemplateName(args.template)) {
|
|
518
|
+
if (args.target === null || args.target.trim().length === 0) {
|
|
519
|
+
process.stderr.write("authz:grant --template gate-override requires --target <refuseCode>\n");
|
|
520
|
+
return 2;
|
|
521
|
+
}
|
|
522
|
+
if (args.planRef === null || args.planRef.trim().length === 0) {
|
|
523
|
+
process.stderr.write("authz:grant --template gate-override requires --plan-ref <attemptId>\n");
|
|
524
|
+
return 2;
|
|
525
|
+
}
|
|
526
|
+
if (args.baseSha === null ||
|
|
527
|
+
args.baseSha.trim().length === 0 ||
|
|
528
|
+
args.headSha === null ||
|
|
529
|
+
args.headSha.trim().length === 0 ||
|
|
530
|
+
args.treeHash === null ||
|
|
531
|
+
args.treeHash.trim().length === 0) {
|
|
532
|
+
process.stderr.write("authz:grant --template gate-override requires --base-sha --head-sha --tree-hash\n");
|
|
533
|
+
return 2;
|
|
534
|
+
}
|
|
535
|
+
const blockedGate = gateConfirm();
|
|
536
|
+
if (blockedGate !== null)
|
|
537
|
+
return blockedGate;
|
|
538
|
+
const mintedGate = mintGateOverrideTemplateGrant({
|
|
539
|
+
projectRoot: args.projectRoot,
|
|
540
|
+
target: args.target,
|
|
541
|
+
planRef: args.planRef,
|
|
542
|
+
baseSha: args.baseSha,
|
|
543
|
+
headSha: args.headSha,
|
|
544
|
+
treeHash: args.treeHash,
|
|
545
|
+
actor: args.actor,
|
|
546
|
+
expiresAt: args.expiresAt,
|
|
547
|
+
// gate-override template is always single-use (#5542 Greptile P2).
|
|
548
|
+
singleUse: true,
|
|
549
|
+
repo: args.repo,
|
|
550
|
+
branch: args.branch,
|
|
551
|
+
worktree: args.worktree,
|
|
552
|
+
evaluatorId: args.evaluatorId,
|
|
553
|
+
failedGateEvidence: args.note,
|
|
554
|
+
});
|
|
555
|
+
if (!mintedGate.ok) {
|
|
556
|
+
process.stderr.write(`authz:grant: ${mintedGate.reason}\n`);
|
|
557
|
+
return 2;
|
|
558
|
+
}
|
|
559
|
+
const gateGrant = mintedGate.grant;
|
|
560
|
+
process.stdout.write(`✓ human-origin grant minted id=${gateGrant.id} origin=${gateGrant.origin.kind} ` +
|
|
561
|
+
`template=${GATE_OVERRIDE_TEMPLATE_NAME}\n`);
|
|
562
|
+
process.stdout.write(` ops=[${gateGrant.scope.operations.join(",")}] attempt=${gateGrant.scope.planRef} ` +
|
|
563
|
+
`surfaces=${gateGrant.scope.surfaces.join(", ")}\n`);
|
|
564
|
+
process.stdout.write(" Hatch: waives coverage-applicability refuse for bound attempt/tree only; " +
|
|
565
|
+
"waived ≠ passed; reviewObligation=pre-merge-human-review-required.\n");
|
|
566
|
+
process.stdout.write(" Authorization SoT: Wave 1 grant store (.deft/authz/grants) — not session-auth / chat.\n");
|
|
567
|
+
return 0;
|
|
568
|
+
}
|
|
569
|
+
// Spec-drift override hatch (#5350): policy module, not authz/** (class 4).
|
|
570
|
+
if (args.template !== null && isSpecDriftOverrideTemplateName(args.template)) {
|
|
571
|
+
if (args.target === null || args.target.trim().length === 0) {
|
|
572
|
+
process.stderr.write("authz:grant --template spec-drift-override requires --target <baselineRevision>\n");
|
|
573
|
+
return 2;
|
|
574
|
+
}
|
|
575
|
+
if (args.planRef === null || args.planRef.trim().length === 0) {
|
|
576
|
+
process.stderr.write("authz:grant --template spec-drift-override requires --plan-ref <scopeId>\n");
|
|
577
|
+
return 2;
|
|
578
|
+
}
|
|
579
|
+
if (args.storyIds.length === 0) {
|
|
580
|
+
process.stderr.write("authz:grant --template spec-drift-override requires --story-ids <covered-item-ids>\n");
|
|
581
|
+
return 2;
|
|
582
|
+
}
|
|
583
|
+
const blockedOverride = gateConfirm();
|
|
584
|
+
if (blockedOverride !== null)
|
|
585
|
+
return blockedOverride;
|
|
586
|
+
const mintedOverride = mintSpecDriftOverrideTemplateGrant({
|
|
587
|
+
projectRoot: args.projectRoot,
|
|
588
|
+
target: args.target,
|
|
589
|
+
planRef: args.planRef,
|
|
590
|
+
storyIds: args.storyIds,
|
|
591
|
+
actor: args.actor,
|
|
592
|
+
expiresAt: args.expiresAt,
|
|
593
|
+
singleUse: args.singleUse,
|
|
594
|
+
repo: args.repo,
|
|
595
|
+
branch: args.branch,
|
|
596
|
+
});
|
|
597
|
+
if (!mintedOverride.ok) {
|
|
598
|
+
process.stderr.write(`authz:grant: ${mintedOverride.reason}\n`);
|
|
599
|
+
return 2;
|
|
600
|
+
}
|
|
601
|
+
const overrideGrant = mintedOverride.grant;
|
|
602
|
+
process.stdout.write(`✓ human-origin grant minted id=${overrideGrant.id} origin=${overrideGrant.origin.kind} ` +
|
|
603
|
+
`template=${SPEC_DRIFT_OVERRIDE_TEMPLATE_NAME}\n`);
|
|
604
|
+
process.stdout.write(` ops=[${overrideGrant.scope.operations.join(",")}] scope=${overrideGrant.scope.planRef} ` +
|
|
605
|
+
`items=${overrideGrant.scope.storyIds.join(",")} surfaces=${overrideGrant.scope.surfaces.join(", ")}\n`);
|
|
606
|
+
process.stdout.write(" Hatch: discharges rewrite/coverage refuse for bound ids only under enforce; single-use preferred.\n");
|
|
607
|
+
process.stdout.write(" Authorization SoT: Wave 1 grant store (.deft/authz/grants) — not session-auth.\n");
|
|
608
|
+
return 0;
|
|
609
|
+
}
|
|
610
|
+
// AFK template path (#1095 / #871): presets only — still mintHumanOriginGrant.
|
|
611
|
+
if (args.template !== null && args.template.trim().length > 0) {
|
|
612
|
+
if (!isAfkTemplateName(args.template)) {
|
|
613
|
+
process.stderr.write(`authz:grant unknown --template '${args.template}'; expected one of: ${AFK_TEMPLATE_NAMES.join(", ")}, ${SPEC_DRIFT_OVERRIDE_TEMPLATE_NAME}, ${GATE_OVERRIDE_TEMPLATE_NAME}\n`);
|
|
614
|
+
return 2;
|
|
615
|
+
}
|
|
616
|
+
if (isClosedVerbTemplateName(args.template) &&
|
|
617
|
+
(args.target === null || args.target.trim().length === 0)) {
|
|
618
|
+
process.stderr.write(`authz:grant --template ${args.template} requires --target <version>\n`);
|
|
619
|
+
return 2;
|
|
620
|
+
}
|
|
621
|
+
const blocked = gateConfirm();
|
|
622
|
+
if (blocked !== null)
|
|
623
|
+
return blocked;
|
|
624
|
+
const minted = mintAfkTemplateGrant({
|
|
625
|
+
projectRoot: args.projectRoot,
|
|
626
|
+
template: args.template,
|
|
627
|
+
target: args.target,
|
|
628
|
+
actor: args.actor,
|
|
629
|
+
expiresAt: args.expiresAt,
|
|
630
|
+
singleUse: args.singleUse,
|
|
631
|
+
planRef: args.planRef,
|
|
632
|
+
repo: args.repo,
|
|
633
|
+
branch: args.branch,
|
|
634
|
+
surfaces: args.surfaces,
|
|
635
|
+
storyIds: args.storyIds,
|
|
636
|
+
issueIds: args.issueIds,
|
|
637
|
+
cohortId: args.cohort,
|
|
638
|
+
});
|
|
639
|
+
if (!minted.ok) {
|
|
640
|
+
process.stderr.write(`authz:grant: ${minted.reason}\n`);
|
|
641
|
+
return 2;
|
|
642
|
+
}
|
|
643
|
+
const grant = minted.grant;
|
|
644
|
+
process.stdout.write(`✓ human-origin grant minted id=${grant.id} origin=${grant.origin.kind} ` +
|
|
645
|
+
`template=${args.template}\n`);
|
|
646
|
+
if (isFinishLoopTemplateName(args.template)) {
|
|
647
|
+
process.stdout.write(` ops=[${grant.scope.operations.join(",")}] ` +
|
|
648
|
+
`(finish-loop walk-away; release-* NOT authorized)\n`);
|
|
649
|
+
}
|
|
650
|
+
else {
|
|
651
|
+
process.stdout.write(` ops=[${grant.scope.operations.join(",")}] target surfaces=${grant.scope.surfaces.join(", ")}\n`);
|
|
652
|
+
}
|
|
653
|
+
process.stdout.write(" Authorization SoT: Wave 1 grant store (.deft/authz/grants) — not session-auth.\n");
|
|
654
|
+
return 0;
|
|
655
|
+
}
|
|
656
|
+
if (args.operations.length === 0) {
|
|
657
|
+
process.stderr.write("authz:grant requires --operations <edit,push,...>, --template <finish-loop|release-*|spec-drift-override|gate-override>, " +
|
|
658
|
+
"or --parent + --draft (structural scope:decompose apply)\n");
|
|
659
|
+
return 2;
|
|
660
|
+
}
|
|
661
|
+
{
|
|
662
|
+
const blocked = gateConfirm();
|
|
663
|
+
if (blocked !== null)
|
|
664
|
+
return blocked;
|
|
665
|
+
}
|
|
666
|
+
const minted = mintHumanOriginGrant({
|
|
667
|
+
projectRoot: args.projectRoot,
|
|
668
|
+
actor: args.actor,
|
|
669
|
+
operations: args.operations,
|
|
670
|
+
surfaces: args.surfaces,
|
|
671
|
+
cohortId: args.cohort,
|
|
672
|
+
planRef: args.planRef,
|
|
673
|
+
repo: args.repo,
|
|
674
|
+
branch: args.branch,
|
|
675
|
+
storyIds: args.storyIds,
|
|
676
|
+
issueIds: args.issueIds,
|
|
677
|
+
expiresAt: args.expiresAt,
|
|
678
|
+
singleUse: args.singleUse,
|
|
679
|
+
});
|
|
680
|
+
if (!minted.ok) {
|
|
681
|
+
process.stderr.write(`authz:grant: ${minted.reason}\n`);
|
|
682
|
+
return 2;
|
|
683
|
+
}
|
|
684
|
+
const grant = minted.grant;
|
|
685
|
+
process.stdout.write(`✓ human-origin grant minted id=${grant.id} origin=${grant.origin.kind}\n`);
|
|
686
|
+
process.stdout.write(` ops=[${grant.scope.operations.join(",")}] cohort=${grant.scope.cohortId ?? "-"}\n`);
|
|
687
|
+
if (grant.scope.surfaces.length > 0) {
|
|
688
|
+
process.stdout.write(` surfaces=${grant.scope.surfaces.join(", ")}\n`);
|
|
689
|
+
}
|
|
690
|
+
return 0;
|
|
691
|
+
}
|
|
692
|
+
case "revoke": {
|
|
693
|
+
if (args.grantId === null) {
|
|
694
|
+
process.stderr.write("authz:revoke requires <grant-id>\n");
|
|
695
|
+
return 2;
|
|
696
|
+
}
|
|
697
|
+
{
|
|
698
|
+
const blocked = gateConfirm();
|
|
699
|
+
if (blocked !== null)
|
|
700
|
+
return blocked;
|
|
701
|
+
}
|
|
702
|
+
const revokedResult = revokeGrant({
|
|
703
|
+
projectRoot: args.projectRoot,
|
|
704
|
+
grantId: args.grantId,
|
|
705
|
+
});
|
|
706
|
+
if (!revokedResult.ok) {
|
|
707
|
+
process.stderr.write(`authz:revoke: ${revokedResult.reason}\n`);
|
|
708
|
+
return 2;
|
|
709
|
+
}
|
|
710
|
+
const revoked = revokedResult.grant;
|
|
711
|
+
if (revoked === null) {
|
|
712
|
+
process.stderr.write(`authz: grant not found: ${args.grantId}\n`);
|
|
713
|
+
return 1;
|
|
714
|
+
}
|
|
715
|
+
process.stdout.write(`✓ grant revoked id=${revoked.id} at ${revoked.semantics.revokedAt}\n`);
|
|
716
|
+
return 0;
|
|
717
|
+
}
|
|
718
|
+
default:
|
|
719
|
+
process.stderr.write(`${helpText()}\n`);
|
|
720
|
+
return 2;
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
catch (err) {
|
|
724
|
+
process.stderr.write(`authz: ${String(err)}\n`);
|
|
725
|
+
return 1;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
export default main;
|
|
729
|
+
if (import.meta.url === `file://${process.argv[1]?.replace(/\\/g, "/")}`) {
|
|
730
|
+
process.exitCode = main();
|
|
731
|
+
}
|
|
732
|
+
//# sourceMappingURL=authz.js.map
|