devrites 3.0.7 → 3.2.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/CHANGELOG.md +18 -0
- package/README.md +82 -50
- package/SECURITY.md +31 -29
- package/docs/adr/0001-go-engine-as-control-plane.md +1 -1
- package/docs/adr/0002-dual-host-harness.md +1 -1
- package/docs/adr/0004-state-schema-phases-sections.md +1 -2
- package/docs/adr/0006-clock-seam-and-engine-ci-gates.md +3 -4
- package/docs/adr/0009-prebuild-decision-coverage-and-readiness.md +67 -0
- package/docs/adr/0010-agent-first-fresh-context-orchestration.md +71 -0
- package/docs/adr/0011-define-plan-transition-rights.md +28 -0
- package/docs/adr/0012-semantic-workspace-upgrades.md +77 -0
- package/docs/adr/README.md +4 -0
- package/docs/agents/triage-labels.md +7 -7
- package/docs/architecture.md +179 -141
- package/docs/cli.md +47 -12
- package/docs/command-map.md +61 -38
- package/docs/engine/agent-contract.md +92 -15
- package/docs/engine/commands.md +248 -72
- package/docs/engine/state-schema.md +52 -23
- package/docs/engine/workspace-schema.md +103 -15
- package/docs/extensions.md +1 -1
- package/docs/flow.md +86 -51
- package/docs/harness-compliance.md +29 -5
- package/docs/orchestration.md +107 -79
- package/docs/quick-reference.md +11 -3
- package/docs/release.md +4 -3
- package/docs/skills.md +67 -38
- package/docs/usage.md +84 -39
- package/engine/cmd/releasepack/main.go +219 -0
- package/engine/cmd/releasepack/main_test.go +170 -0
- package/engine/commands.go +170 -23
- package/engine/git_guard.go +187 -0
- package/engine/git_guard_test.go +283 -0
- package/engine/hookpolicy.go +53 -55
- package/engine/hookpolicy_test.go +91 -1
- package/engine/hooks.go +296 -75
- package/engine/hooks_events_test.go +276 -6
- package/engine/hooks_workspace.go +640 -159
- package/engine/internal/devritespaths/paths.go +65 -10
- package/engine/internal/devritespaths/paths_test.go +110 -0
- package/engine/internal/doctor/doctor.go +153 -23
- package/engine/internal/doctor/doctor_test.go +74 -0
- package/engine/internal/forge/forge.go +940 -0
- package/engine/internal/forge/forge_test.go +576 -0
- package/engine/internal/forge/git.go +245 -0
- package/engine/internal/forge/liveness_unix.go +48 -0
- package/engine/internal/forge/liveness_windows.go +67 -0
- package/engine/internal/forge/manifest.go +402 -0
- package/engine/internal/gate/gate.go +90 -71
- package/engine/internal/gate/gate_test.go +71 -2
- package/engine/internal/harness/compliance.go +18 -24
- package/engine/internal/harness/harness.go +37 -44
- package/engine/internal/harness/harness_test.go +21 -5
- package/engine/internal/install/install.go +486 -38
- package/engine/internal/install/install_test.go +383 -10
- package/engine/internal/iohooks/iohooks.go +350 -59
- package/engine/internal/iohooks/iohooks_test.go +421 -1
- package/engine/internal/lib/buildreadiness.go +43 -18
- package/engine/internal/lib/clarifyreturn.go +91 -0
- package/engine/internal/lib/clarifyreturn_test.go +123 -0
- package/engine/internal/lib/context.go +54 -15
- package/engine/internal/lib/cursor_compat_test.go +8 -0
- package/engine/internal/lib/extensions.go +2 -3
- package/engine/internal/lib/gitauthority.go +601 -0
- package/engine/internal/lib/gitauthority_test.go +346 -0
- package/engine/internal/lib/jsonout.go +25 -11
- package/engine/internal/lib/jsonout_test.go +16 -0
- package/engine/internal/lib/lanes.go +14 -8
- package/engine/internal/lib/observability_test.go +358 -0
- package/engine/internal/lib/packageexistence.go +151 -35
- package/engine/internal/lib/packageexistence_test.go +163 -0
- package/engine/internal/lib/progress.go +11 -9
- package/engine/internal/lib/provenance.go +462 -0
- package/engine/internal/lib/provenance_test.go +154 -0
- package/engine/internal/lib/readiness_contract.json +118 -0
- package/engine/internal/lib/readinessartifact.go +533 -0
- package/engine/internal/lib/readinessartifact_test.go +422 -0
- package/engine/internal/lib/reconcile.go +712 -88
- package/engine/internal/lib/reconcile_test.go +335 -16
- package/engine/internal/lib/recoveryattempts.go +298 -0
- package/engine/internal/lib/recoveryattempts_test.go +215 -0
- package/engine/internal/lib/resolve.go +23 -19
- package/engine/internal/lib/runbook_context_test.go +20 -0
- package/engine/internal/lib/session.go +701 -9
- package/engine/internal/lib/session_test.go +80 -13
- package/engine/internal/lib/testintegrity.go +33 -37
- package/engine/internal/lib/testintegrity_test.go +63 -1
- package/engine/internal/migrate/migrate.go +81 -1
- package/engine/internal/migrate/migrate_test.go +22 -1
- package/engine/internal/reason/reason.go +180 -0
- package/engine/internal/reason/reason_test.go +35 -0
- package/engine/internal/rootfacts/facts.go +466 -0
- package/engine/internal/rootfacts/facts_test.go +306 -0
- package/engine/internal/safepath/safepath.go +55 -0
- package/engine/internal/safepath/safepath_test.go +69 -0
- package/engine/internal/safepath/safepath_windows_test.go +26 -0
- package/engine/internal/state/clarify_transition.go +165 -0
- package/engine/internal/state/clarify_transition_test.go +130 -0
- package/engine/internal/state/cmd/workflowmanifest/main.go +12 -8
- package/engine/internal/state/cursor.go +58 -0
- package/engine/internal/state/cursor_test.go +42 -1
- package/engine/internal/state/feature.go +35 -48
- package/engine/internal/state/schema.go +90 -37
- package/engine/internal/state/snapshot.go +18 -2
- package/engine/internal/state/state_test.go +187 -7
- package/engine/internal/state/status.go +48 -11
- package/engine/internal/state/workflow_manifest.json +231 -50
- package/engine/internal/toolpolicy/classifier.go +533 -0
- package/engine/internal/toolpolicy/classifier_test.go +424 -0
- package/engine/internal/toolpolicy/git.go +616 -0
- package/engine/internal/toolpolicy/scanner.go +382 -0
- package/engine/main.go +160 -77
- package/engine/observability_cli_test.go +52 -0
- package/engine/root_routing_test.go +277 -0
- package/engine/testdata/golden/TestParityBuildReadiness/arg=approved.golden +1 -1
- package/engine/testdata/golden/TestParityBuildReadiness/arg=emptystatus.golden +1 -1
- package/engine/testdata/golden/TestParityBuildReadiness/arg=legacycontract.golden +1 -0
- package/engine/testdata/golden/TestParityBuildReadiness/arg=noclarify.golden +1 -0
- package/engine/testdata/golden/TestParityBuildReadiness/arg=novet.golden +1 -0
- package/engine/testdata/golden/TestParityBuildReadiness/arg=stalevet.golden +1 -0
- package/engine/testdata/golden/TestParityBuildReadiness/arg=trailhash.golden +1 -1
- package/engine/testdata/golden/TestParityBuildReadiness/arg=trailpipe.golden +1 -1
- package/engine/testdata/golden/TestParityBuildReadiness/arg=vetnotready.golden +1 -0
- package/engine/testdata/golden/TestParityProgress/arg=allbuilt.golden +1 -1
- package/engine/testdata/golden/TestParityProgress/arg=done.golden +1 -1
- package/engine/testdata/golden/TestParityProgress/arg=mid.golden +1 -1
- package/engine/testdata/golden/TestParityProgress/arg=nophase.golden +1 -1
- package/engine/testdata/golden/TestParityProgress/arg=noslice.golden +1 -1
- package/engine/testdata/golden/TestParityProgress/arg=plan.golden +1 -1
- package/engine/testdata/golden/TestParityProgress/arg=seal.golden +1 -1
- package/engine/testdata/golden/TestParityReconcile/check-clean.golden +1 -1
- package/engine/testdata/golden/TestParityReconcile/inline-fallback.golden +1 -0
- package/engine/testdata/golden/TestParityReconcile/snapshot-no-allowlist.golden +1 -0
- package/engine/testdata/golden/TestParityWrightScope/devrites-edit-denied.golden +2 -0
- package/engine/testdata/golden/TestParityWrightScope/out-of-scope-enforce-denies.golden +1 -1
- package/engine/tests/adr_0011_define_plan_test.go +30 -0
- package/engine/tests/budget_test.go +19 -8
- package/engine/tests/concurrency_cli_test.go +7 -1
- package/engine/tests/doctor_cli_test.go +148 -2
- package/engine/tests/forge_cli_test.go +463 -0
- package/engine/tests/gate_test.go +63 -8
- package/engine/tests/hook_test.go +260 -8
- package/engine/tests/hooks_io_test.go +94 -3
- package/engine/tests/json_contract_test.go +127 -2
- package/engine/tests/migrate_cli_test.go +2 -2
- package/engine/tests/parity_buildreadiness_test.go +167 -10
- package/engine/tests/parity_learnings_test.go +16 -17
- package/engine/tests/parity_reconcile_test.go +20 -17
- package/engine/tests/parity_resolve_test.go +12 -11
- package/engine/tests/parity_test.go +21 -17
- package/pack/.claude/agents/devrites-code-reviewer.md +62 -48
- package/pack/.claude/agents/devrites-devex-reviewer.md +69 -53
- package/pack/.claude/agents/devrites-doubt-reviewer.md +29 -22
- package/pack/.claude/agents/devrites-evidence-scout.md +69 -0
- package/pack/.claude/agents/devrites-forge-judge.md +74 -61
- package/pack/.claude/agents/devrites-frontend-reviewer.md +48 -39
- package/pack/.claude/agents/devrites-performance-reviewer.md +49 -40
- package/pack/.claude/agents/devrites-plan-drafter.md +73 -0
- package/pack/.claude/agents/devrites-plan-reviewer.md +80 -47
- package/pack/.claude/agents/devrites-proof-runner.md +74 -0
- package/pack/.claude/agents/devrites-retrospector.md +48 -45
- package/pack/.claude/agents/devrites-security-auditor.md +46 -36
- package/pack/.claude/agents/devrites-simplifier-reviewer.md +50 -46
- package/pack/.claude/agents/devrites-slice-wright.md +153 -165
- package/pack/.claude/agents/devrites-spec-reviewer.md +34 -32
- package/pack/.claude/agents/devrites-strategy-reviewer.md +63 -34
- package/pack/.claude/agents/devrites-test-analyst.md +40 -30
- package/pack/.claude/agents/devrites-upgrade-planner.md +100 -0
- package/pack/.claude/settings.json +2 -1
- package/pack/.claude/skills/devrites-audit/SKILL.md +40 -61
- package/pack/.claude/skills/devrites-debug-recovery/SKILL.md +24 -13
- package/pack/.claude/skills/devrites-debug-recovery/reference/build-the-loop.md +24 -21
- package/pack/.claude/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +34 -6
- package/pack/.claude/skills/devrites-debug-recovery/reference/instrumentation.md +2 -2
- package/pack/.claude/skills/devrites-doubt/SKILL.md +25 -17
- package/pack/.claude/skills/devrites-interview/SKILL.md +53 -52
- package/pack/.claude/skills/devrites-lib/SKILL.md +12 -9
- package/pack/.claude/skills/devrites-lib/reference/intent-map.md +4 -2
- package/pack/.claude/skills/devrites-lib/reference/parallel-dispatch.md +82 -137
- package/pack/.claude/skills/devrites-lib/reference/reply-contract.md +8 -1
- package/pack/.claude/skills/devrites-lib/reference/standards/README.md +38 -55
- package/pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md +53 -27
- package/pack/.claude/skills/devrites-lib/reference/standards/agents.md +200 -190
- package/pack/.claude/skills/devrites-lib/reference/standards/anti-patterns.md +5 -15
- package/pack/.claude/skills/devrites-lib/reference/standards/ci-cd.md +27 -58
- package/pack/.claude/skills/devrites-lib/reference/standards/code-review.md +16 -52
- package/pack/.claude/skills/devrites-lib/reference/standards/coding-style.md +2 -10
- package/pack/.claude/skills/devrites-lib/reference/standards/context-hygiene.md +18 -61
- package/pack/.claude/skills/devrites-lib/reference/standards/core.md +23 -18
- package/pack/.claude/skills/devrites-lib/reference/standards/deprecation.md +17 -57
- package/pack/.claude/skills/devrites-lib/reference/standards/development-workflow.md +4 -33
- package/pack/.claude/skills/devrites-lib/reference/standards/git-workflow.md +4 -20
- package/pack/.claude/skills/devrites-lib/reference/standards/hooks.md +3 -14
- package/pack/.claude/skills/devrites-lib/reference/standards/patterns.md +9 -25
- package/pack/.claude/skills/devrites-lib/reference/standards/performance.md +0 -9
- package/pack/.claude/skills/devrites-lib/reference/standards/principles.md +1 -3
- package/pack/.claude/skills/devrites-lib/reference/standards/security.md +17 -7
- package/pack/.claude/skills/devrites-lib/reference/standards/testing.md +1 -27
- package/pack/.claude/skills/devrites-lib/reference/standards/tooling.md +46 -50
- package/pack/.claude/skills/devrites-lib/reference/workspace-artifact-schema.md +40 -10
- package/pack/.claude/skills/devrites-source-driven/SKILL.md +23 -22
- package/pack/.claude/skills/rite/SKILL.md +10 -6
- package/pack/.claude/skills/rite/reference/menu.md +13 -7
- package/pack/.claude/skills/rite-adopt/SKILL.md +33 -37
- package/pack/.claude/skills/rite-autocomplete/SKILL.md +33 -28
- package/pack/.claude/skills/rite-autocomplete/reference/loop.md +21 -21
- package/pack/.claude/skills/rite-autocomplete/reference/stop-conditions.md +15 -6
- package/pack/.claude/skills/rite-build/SKILL.md +35 -30
- package/pack/.claude/skills/rite-build/reference/afk-discipline.md +41 -39
- package/pack/.claude/skills/rite-build/reference/evidence-standard.md +10 -0
- package/pack/.claude/skills/rite-build/reference/forge.md +186 -156
- package/pack/.claude/skills/rite-build/reference/one-slice-cycle.md +4 -3
- package/pack/.claude/skills/rite-build/reference/phase-contract.md +96 -175
- package/pack/.claude/skills/rite-build/reference/spec-drift-guard.md +10 -4
- package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +129 -134
- package/pack/.claude/skills/rite-clarify/SKILL.md +90 -0
- package/pack/.claude/skills/rite-clarify/reference/decision-coverage.md +61 -0
- package/pack/.claude/skills/rite-converge/SKILL.md +35 -25
- package/pack/.claude/skills/rite-define/SKILL.md +58 -32
- package/pack/.claude/skills/rite-define/reference/gates.md +16 -15
- package/pack/.claude/skills/rite-define/reference/plan-template.md +18 -8
- package/pack/.claude/skills/rite-frame/reference/failure-modes.md +22 -24
- package/pack/.claude/skills/rite-plan/SKILL.md +47 -16
- package/pack/.claude/skills/rite-plan/reference/task-breakdown.md +4 -0
- package/pack/.claude/skills/rite-polish/SKILL.md +27 -23
- package/pack/.claude/skills/rite-prototype/SKILL.md +25 -26
- package/pack/.claude/skills/rite-prove/SKILL.md +27 -17
- package/pack/.claude/skills/rite-resolve/SKILL.md +12 -11
- package/pack/.claude/skills/rite-resolve/reference/answer-protocol.md +3 -0
- package/pack/.claude/skills/rite-review/SKILL.md +37 -28
- package/pack/.claude/skills/rite-seal/reference/phase-contract.md +27 -92
- package/pack/.claude/skills/rite-seal/reference/risk-and-rollback.md +13 -0
- package/pack/.claude/skills/rite-ship/reference/design-memory.md +31 -36
- package/pack/.claude/skills/rite-spec/SKILL.md +84 -135
- package/pack/.claude/skills/rite-spec/reference/investigation.md +37 -33
- package/pack/.claude/skills/rite-spec/reference/question-protocol.md +6 -2
- package/pack/.claude/skills/rite-spec/reference/spec-checklists.md +25 -24
- package/pack/.claude/skills/rite-spec/reference/spec-template.md +9 -2
- package/pack/.claude/skills/rite-spec/reference/state-workspace.md +13 -3
- package/pack/.claude/skills/rite-temper/SKILL.md +62 -47
- package/pack/.claude/skills/rite-temper/reference/review-dimensions.md +24 -22
- package/pack/.claude/skills/rite-upgrade/SKILL.md +125 -0
- package/pack/.claude/skills/rite-vet/SKILL.md +114 -113
- package/pack/.claude/skills/rite-vet/reference/artifacts.md +50 -9
- package/pack/.claude/skills/rite-vet/reference/review-axes.md +39 -37
- package/pack/generated/claude/agents/devrites-code-reviewer.md +62 -48
- package/pack/generated/claude/agents/devrites-devex-reviewer.md +69 -53
- package/pack/generated/claude/agents/devrites-doubt-reviewer.md +29 -22
- package/pack/generated/claude/agents/devrites-evidence-scout.md +69 -0
- package/pack/generated/claude/agents/devrites-forge-judge.md +74 -61
- package/pack/generated/claude/agents/devrites-frontend-reviewer.md +48 -39
- package/pack/generated/claude/agents/devrites-performance-reviewer.md +49 -40
- package/pack/generated/claude/agents/devrites-plan-drafter.md +73 -0
- package/pack/generated/claude/agents/devrites-plan-reviewer.md +80 -47
- package/pack/generated/claude/agents/devrites-proof-runner.md +74 -0
- package/pack/generated/claude/agents/devrites-retrospector.md +48 -45
- package/pack/generated/claude/agents/devrites-security-auditor.md +46 -36
- package/pack/generated/claude/agents/devrites-simplifier-reviewer.md +50 -46
- package/pack/generated/claude/agents/devrites-slice-wright.md +153 -165
- package/pack/generated/claude/agents/devrites-spec-reviewer.md +34 -32
- package/pack/generated/claude/agents/devrites-strategy-reviewer.md +63 -34
- package/pack/generated/claude/agents/devrites-test-analyst.md +40 -30
- package/pack/generated/claude/agents/devrites-upgrade-planner.md +100 -0
- package/pack/generated/claude/settings.json +2 -1
- package/pack/generated/claude/skills/devrites-audit/SKILL.md +40 -61
- package/pack/generated/claude/skills/devrites-debug-recovery/SKILL.md +24 -13
- package/pack/generated/claude/skills/devrites-debug-recovery/reference/build-the-loop.md +24 -21
- package/pack/generated/claude/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +34 -6
- package/pack/generated/claude/skills/devrites-debug-recovery/reference/instrumentation.md +2 -2
- package/pack/generated/claude/skills/devrites-doubt/SKILL.md +25 -17
- package/pack/generated/claude/skills/devrites-interview/SKILL.md +53 -52
- package/pack/generated/claude/skills/devrites-lib/SKILL.md +12 -9
- package/pack/generated/claude/skills/devrites-lib/reference/intent-map.md +4 -2
- package/pack/generated/claude/skills/devrites-lib/reference/parallel-dispatch.md +82 -137
- package/pack/generated/claude/skills/devrites-lib/reference/reply-contract.md +8 -1
- package/pack/generated/claude/skills/devrites-lib/reference/standards/README.md +38 -55
- package/pack/generated/claude/skills/devrites-lib/reference/standards/afk-hitl.md +53 -27
- package/pack/generated/claude/skills/devrites-lib/reference/standards/agents.md +200 -190
- package/pack/generated/claude/skills/devrites-lib/reference/standards/anti-patterns.md +5 -15
- package/pack/generated/claude/skills/devrites-lib/reference/standards/ci-cd.md +27 -58
- package/pack/generated/claude/skills/devrites-lib/reference/standards/code-review.md +16 -52
- package/pack/generated/claude/skills/devrites-lib/reference/standards/coding-style.md +2 -10
- package/pack/generated/claude/skills/devrites-lib/reference/standards/context-hygiene.md +18 -61
- package/pack/generated/claude/skills/devrites-lib/reference/standards/core.md +23 -18
- package/pack/generated/claude/skills/devrites-lib/reference/standards/deprecation.md +17 -57
- package/pack/generated/claude/skills/devrites-lib/reference/standards/development-workflow.md +4 -33
- package/pack/generated/claude/skills/devrites-lib/reference/standards/git-workflow.md +4 -20
- package/pack/generated/claude/skills/devrites-lib/reference/standards/hooks.md +3 -14
- package/pack/generated/claude/skills/devrites-lib/reference/standards/patterns.md +9 -25
- package/pack/generated/claude/skills/devrites-lib/reference/standards/performance.md +0 -9
- package/pack/generated/claude/skills/devrites-lib/reference/standards/principles.md +1 -3
- package/pack/generated/claude/skills/devrites-lib/reference/standards/security.md +17 -7
- package/pack/generated/claude/skills/devrites-lib/reference/standards/testing.md +1 -27
- package/pack/generated/claude/skills/devrites-lib/reference/standards/tooling.md +46 -50
- package/pack/generated/claude/skills/devrites-lib/reference/workspace-artifact-schema.md +40 -10
- package/pack/generated/claude/skills/devrites-source-driven/SKILL.md +23 -22
- package/pack/generated/claude/skills/rite/SKILL.md +10 -6
- package/pack/generated/claude/skills/rite/reference/menu.md +13 -7
- package/pack/generated/claude/skills/rite-adopt/SKILL.md +33 -37
- package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +33 -28
- package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +21 -21
- package/pack/generated/claude/skills/rite-autocomplete/reference/stop-conditions.md +15 -6
- package/pack/generated/claude/skills/rite-build/SKILL.md +35 -30
- package/pack/generated/claude/skills/rite-build/reference/afk-discipline.md +41 -39
- package/pack/generated/claude/skills/rite-build/reference/evidence-standard.md +10 -0
- package/pack/generated/claude/skills/rite-build/reference/forge.md +186 -156
- package/pack/generated/claude/skills/rite-build/reference/one-slice-cycle.md +4 -3
- package/pack/generated/claude/skills/rite-build/reference/phase-contract.md +96 -175
- package/pack/generated/claude/skills/rite-build/reference/spec-drift-guard.md +10 -4
- package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +129 -134
- package/pack/generated/claude/skills/rite-clarify/SKILL.md +90 -0
- package/pack/generated/claude/skills/rite-clarify/reference/decision-coverage.md +61 -0
- package/pack/generated/claude/skills/rite-converge/SKILL.md +35 -25
- package/pack/generated/claude/skills/rite-define/SKILL.md +58 -32
- package/pack/generated/claude/skills/rite-define/reference/gates.md +16 -15
- package/pack/generated/claude/skills/rite-define/reference/plan-template.md +18 -8
- package/pack/generated/claude/skills/rite-frame/reference/failure-modes.md +22 -24
- package/pack/generated/claude/skills/rite-plan/SKILL.md +47 -16
- package/pack/generated/claude/skills/rite-plan/reference/task-breakdown.md +4 -0
- package/pack/generated/claude/skills/rite-polish/SKILL.md +27 -23
- package/pack/generated/claude/skills/rite-prototype/SKILL.md +25 -26
- package/pack/generated/claude/skills/rite-prove/SKILL.md +27 -17
- package/pack/generated/claude/skills/rite-resolve/SKILL.md +12 -11
- package/pack/generated/claude/skills/rite-resolve/reference/answer-protocol.md +3 -0
- package/pack/generated/claude/skills/rite-review/SKILL.md +37 -28
- package/pack/generated/claude/skills/rite-seal/reference/phase-contract.md +27 -92
- package/pack/generated/claude/skills/rite-seal/reference/risk-and-rollback.md +13 -0
- package/pack/generated/claude/skills/rite-ship/reference/design-memory.md +31 -36
- package/pack/generated/claude/skills/rite-spec/SKILL.md +84 -135
- package/pack/generated/claude/skills/rite-spec/reference/investigation.md +37 -33
- package/pack/generated/claude/skills/rite-spec/reference/question-protocol.md +6 -2
- package/pack/generated/claude/skills/rite-spec/reference/spec-checklists.md +25 -24
- package/pack/generated/claude/skills/rite-spec/reference/spec-template.md +9 -2
- package/pack/generated/claude/skills/rite-spec/reference/state-workspace.md +13 -3
- package/pack/generated/claude/skills/rite-temper/SKILL.md +62 -47
- package/pack/generated/claude/skills/rite-temper/reference/review-dimensions.md +24 -22
- package/pack/generated/claude/skills/rite-upgrade/SKILL.md +125 -0
- package/pack/generated/claude/skills/rite-vet/SKILL.md +114 -113
- package/pack/generated/claude/skills/rite-vet/reference/artifacts.md +50 -9
- package/pack/generated/claude/skills/rite-vet/reference/review-axes.md +39 -37
- package/pack/generated/codex/AGENTS.md +5 -2
- package/pack/generated/codex/agents/devrites-code-reviewer.toml +69 -47
- package/pack/generated/codex/agents/devrites-devex-reviewer.toml +75 -51
- package/pack/generated/codex/agents/devrites-doubt-reviewer.toml +35 -20
- package/pack/generated/codex/agents/devrites-evidence-scout.toml +75 -0
- package/pack/generated/codex/agents/devrites-forge-judge.toml +80 -59
- package/pack/generated/codex/agents/devrites-frontend-reviewer.toml +54 -37
- package/pack/generated/codex/agents/devrites-performance-reviewer.toml +55 -38
- package/pack/generated/codex/agents/devrites-plan-drafter.toml +79 -0
- package/pack/generated/codex/agents/devrites-plan-reviewer.toml +82 -47
- package/pack/generated/codex/agents/devrites-proof-runner.toml +80 -0
- package/pack/generated/codex/agents/devrites-retrospector.toml +54 -43
- package/pack/generated/codex/agents/devrites-security-auditor.toml +53 -35
- package/pack/generated/codex/agents/devrites-simplifier-reviewer.toml +56 -44
- package/pack/generated/codex/agents/devrites-slice-wright.toml +159 -163
- package/pack/generated/codex/agents/devrites-spec-reviewer.toml +40 -30
- package/pack/generated/codex/agents/devrites-strategy-reviewer.toml +65 -34
- package/pack/generated/codex/agents/devrites-test-analyst.toml +46 -28
- package/pack/generated/codex/agents/devrites-upgrade-planner.toml +106 -0
- package/pack/generated/codex/hooks.json +4 -14
- package/pack/generated/codex/skills/devrites-api-interface/SKILL.md +7 -3
- package/pack/generated/codex/skills/devrites-audit/SKILL.md +47 -64
- package/pack/generated/codex/skills/devrites-browser-proof/SKILL.md +7 -3
- package/pack/generated/codex/skills/devrites-debug-recovery/SKILL.md +31 -16
- package/pack/generated/codex/skills/devrites-debug-recovery/reference/build-the-loop.md +24 -21
- package/pack/generated/codex/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +34 -6
- package/pack/generated/codex/skills/devrites-debug-recovery/reference/instrumentation.md +2 -2
- package/pack/generated/codex/skills/devrites-doubt/SKILL.md +32 -20
- package/pack/generated/codex/skills/devrites-frontend-craft/SKILL.md +7 -3
- package/pack/generated/codex/skills/devrites-interview/SKILL.md +60 -55
- package/pack/generated/codex/skills/devrites-lib/SKILL.md +19 -12
- package/pack/generated/codex/skills/devrites-lib/reference/intent-map.md +4 -2
- package/pack/generated/codex/skills/devrites-lib/reference/parallel-dispatch.md +82 -137
- package/pack/generated/codex/skills/devrites-lib/reference/reply-contract.md +8 -1
- package/pack/generated/codex/skills/devrites-lib/reference/standards/README.md +38 -55
- package/pack/generated/codex/skills/devrites-lib/reference/standards/afk-hitl.md +53 -27
- package/pack/generated/codex/skills/devrites-lib/reference/standards/agents.md +200 -190
- package/pack/generated/codex/skills/devrites-lib/reference/standards/anti-patterns.md +5 -15
- package/pack/generated/codex/skills/devrites-lib/reference/standards/ci-cd.md +27 -58
- package/pack/generated/codex/skills/devrites-lib/reference/standards/code-review.md +16 -52
- package/pack/generated/codex/skills/devrites-lib/reference/standards/coding-style.md +2 -10
- package/pack/generated/codex/skills/devrites-lib/reference/standards/context-hygiene.md +18 -61
- package/pack/generated/codex/skills/devrites-lib/reference/standards/core.md +23 -18
- package/pack/generated/codex/skills/devrites-lib/reference/standards/deprecation.md +17 -57
- package/pack/generated/codex/skills/devrites-lib/reference/standards/development-workflow.md +4 -33
- package/pack/generated/codex/skills/devrites-lib/reference/standards/git-workflow.md +4 -20
- package/pack/generated/codex/skills/devrites-lib/reference/standards/hooks.md +3 -14
- package/pack/generated/codex/skills/devrites-lib/reference/standards/patterns.md +9 -25
- package/pack/generated/codex/skills/devrites-lib/reference/standards/performance.md +0 -9
- package/pack/generated/codex/skills/devrites-lib/reference/standards/principles.md +1 -3
- package/pack/generated/codex/skills/devrites-lib/reference/standards/security.md +17 -7
- package/pack/generated/codex/skills/devrites-lib/reference/standards/testing.md +1 -27
- package/pack/generated/codex/skills/devrites-lib/reference/standards/tooling.md +46 -50
- package/pack/generated/codex/skills/devrites-lib/reference/workspace-artifact-schema.md +40 -10
- package/pack/generated/codex/skills/devrites-prose-craft/SKILL.md +7 -3
- package/pack/generated/codex/skills/devrites-refresh-indexes/SKILL.md +7 -3
- package/pack/generated/codex/skills/devrites-source-driven/SKILL.md +29 -24
- package/pack/generated/codex/skills/devrites-ux-shape/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite/SKILL.md +21 -13
- package/pack/generated/codex/skills/rite/reference/menu.md +13 -7
- package/pack/generated/codex/skills/rite-adopt/SKILL.md +40 -40
- package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +40 -31
- package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +21 -21
- package/pack/generated/codex/skills/rite-autocomplete/reference/stop-conditions.md +15 -6
- package/pack/generated/codex/skills/rite-build/SKILL.md +42 -33
- package/pack/generated/codex/skills/rite-build/reference/afk-discipline.md +41 -39
- package/pack/generated/codex/skills/rite-build/reference/evidence-standard.md +10 -0
- package/pack/generated/codex/skills/rite-build/reference/forge.md +186 -156
- package/pack/generated/codex/skills/rite-build/reference/one-slice-cycle.md +4 -3
- package/pack/generated/codex/skills/rite-build/reference/phase-contract.md +96 -175
- package/pack/generated/codex/skills/rite-build/reference/spec-drift-guard.md +10 -4
- package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +129 -134
- package/pack/generated/codex/skills/rite-clarify/SKILL.md +106 -0
- package/pack/generated/codex/skills/rite-clarify/reference/decision-coverage.md +61 -0
- package/pack/generated/codex/skills/rite-converge/SKILL.md +42 -28
- package/pack/generated/codex/skills/rite-customize/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-define/SKILL.md +65 -35
- package/pack/generated/codex/skills/rite-define/reference/gates.md +16 -15
- package/pack/generated/codex/skills/rite-define/reference/plan-template.md +18 -8
- package/pack/generated/codex/skills/rite-doctor/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-dogfood/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-explain/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-frame/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-frame/reference/failure-modes.md +22 -24
- package/pack/generated/codex/skills/rite-handoff/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-learn/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-plan/SKILL.md +54 -19
- package/pack/generated/codex/skills/rite-plan/reference/task-breakdown.md +5 -1
- package/pack/generated/codex/skills/rite-polish/SKILL.md +34 -26
- package/pack/generated/codex/skills/rite-pov/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-pr-feedback/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-pressure-test/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-prototype/SKILL.md +32 -29
- package/pack/generated/codex/skills/rite-prove/SKILL.md +34 -20
- package/pack/generated/codex/skills/rite-quick/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-resolve/SKILL.md +19 -14
- package/pack/generated/codex/skills/rite-resolve/reference/answer-protocol.md +3 -0
- package/pack/generated/codex/skills/rite-review/SKILL.md +44 -31
- package/pack/generated/codex/skills/rite-seal/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-seal/reference/phase-contract.md +27 -92
- package/pack/generated/codex/skills/rite-seal/reference/risk-and-rollback.md +13 -0
- package/pack/generated/codex/skills/rite-ship/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-ship/reference/design-memory.md +31 -36
- package/pack/generated/codex/skills/rite-spec/SKILL.md +91 -138
- package/pack/generated/codex/skills/rite-spec/reference/investigation.md +37 -33
- package/pack/generated/codex/skills/rite-spec/reference/question-protocol.md +6 -2
- package/pack/generated/codex/skills/rite-spec/reference/spec-checklists.md +25 -24
- package/pack/generated/codex/skills/rite-spec/reference/spec-template.md +9 -2
- package/pack/generated/codex/skills/rite-spec/reference/state-workspace.md +13 -3
- package/pack/generated/codex/skills/rite-status/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-temper/SKILL.md +69 -50
- package/pack/generated/codex/skills/rite-temper/reference/review-dimensions.md +24 -22
- package/pack/generated/codex/skills/rite-upgrade/SKILL.md +141 -0
- package/pack/generated/codex/skills/rite-upgrade/agents/openai.yaml +2 -0
- package/pack/generated/codex/skills/rite-vet/SKILL.md +121 -116
- package/pack/generated/codex/skills/rite-vet/reference/artifacts.md +50 -9
- package/pack/generated/codex/skills/rite-vet/reference/review-axes.md +40 -38
- package/pack/generated/codex/skills/rite-zoom-out/SKILL.md +7 -3
- package/package.json +1 -1
- package/scripts/build-release-tarball.sh +32 -15
- package/scripts/check-authority-drift.py +125 -0
- package/scripts/check-instruction-size-baseline.mjs +19 -11
- package/scripts/check-invocation-integrity.py +2 -0
- package/scripts/codex-generate.sh +69 -33
- package/scripts/grade-feature.sh +121 -40
- package/scripts/live-hosts/agent-result.schema.json +230 -0
- package/scripts/live-hosts/claude.sh +87 -0
- package/scripts/live-hosts/codex.sh +81 -0
- package/scripts/live-hosts/common.sh +113 -0
- package/scripts/live-hosts/fake-host.py +264 -0
- package/scripts/live-hosts/host-transport.py +287 -0
- package/scripts/release-check.sh +5 -1
- package/scripts/run-agent-contract-evals.py +1380 -0
- package/scripts/run-behavioral-evals.sh +24 -30
- package/scripts/run-evals.sh +1 -5
- package/scripts/run-live-behavioral-evals.py +1274 -144
- package/scripts/run-outcome-evals.sh +445 -88
- package/scripts/run-tests.mjs +30 -2
- package/scripts/skills-inventory.mjs +1 -1
- package/scripts/validate-workflow-security.py +39 -20
- package/scripts/validate-workspace-schema.py +362 -10
- package/scripts/validate.sh +21 -15
- package/engine/testdata/golden/TestParityWrightScope/devrites-edit-allowed.golden +0 -1
- /package/engine/testdata/golden/{TestParityReconcile/check-no-claimed.golden → TestParityBuildReadiness/arg=clarifyopen.golden} +0 -0
package/engine/main.go
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
// Command devrites-engine
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// Command dispatch is intentionally a small stdlib switch (no third-party deps)
|
|
7
|
-
// so the binary cross-compiles trivially with CGO_ENABLED=0; it can be swapped
|
|
8
|
-
// for Cobra later without changing the CLI contract.
|
|
1
|
+
// Command devrites-engine runs the DevRites control plane. It manages workflow
|
|
2
|
+
// phases, gates, and completeness under a project's .devrites directory without
|
|
3
|
+
// calling a model or the network. The pure-Go binary uses standard library
|
|
4
|
+
// dispatch so it can cross-compile with CGO_ENABLED=0.
|
|
9
5
|
package main
|
|
10
6
|
|
|
11
7
|
import (
|
|
@@ -13,13 +9,16 @@ import (
|
|
|
13
9
|
"fmt"
|
|
14
10
|
"io"
|
|
15
11
|
"os"
|
|
12
|
+
"path/filepath"
|
|
16
13
|
|
|
14
|
+
"github.com/devrites/devrites/internal/forge"
|
|
17
15
|
"github.com/devrites/devrites/internal/gate"
|
|
18
16
|
"github.com/devrites/devrites/internal/harness"
|
|
19
17
|
"github.com/devrites/devrites/internal/install"
|
|
20
18
|
"github.com/devrites/devrites/internal/iohooks"
|
|
21
19
|
"github.com/devrites/devrites/internal/lib"
|
|
22
20
|
"github.com/devrites/devrites/internal/profile"
|
|
21
|
+
"github.com/devrites/devrites/internal/reason"
|
|
23
22
|
"github.com/devrites/devrites/internal/state"
|
|
24
23
|
"github.com/devrites/devrites/internal/version"
|
|
25
24
|
)
|
|
@@ -42,28 +41,31 @@ Usage:
|
|
|
42
41
|
devrites-engine footprint <sub> <slug> Fan-out footprint: log|render|roster the dispatch log
|
|
43
42
|
devrites-engine evidence-fresh [slug] Gate: does the proof post-date every touched file?
|
|
44
43
|
devrites-engine coverage [slug] Render the AC → slice(s) → proven traceability matrix
|
|
45
|
-
devrites-engine doubt-coverage <slug>
|
|
44
|
+
devrites-engine doubt-coverage <slug> Check whether the build challenged its recorded decisions
|
|
46
45
|
devrites-engine budget [slug] Lint each workspace file against its context-size ceiling
|
|
47
46
|
devrites-engine preamble [slug] Print the active feature's workspace-state orientation
|
|
48
47
|
devrites-engine progress [slug] Render the active feature's phase/slice/flow footer
|
|
49
48
|
devrites-engine profile get|refresh Cache stable repo facts for grounding skills
|
|
50
49
|
devrites-engine stuck <sub> <slug> Unattended-build loop detector: log|check
|
|
50
|
+
devrites-engine recovery <sub> [...] Track up to three technical recovery attempts across runs
|
|
51
51
|
devrites-engine tick-afk <state.md> Decrement the AFK slice budget in a state.md
|
|
52
|
-
devrites-engine build-readiness [slug] Gate:
|
|
53
|
-
devrites-engine
|
|
52
|
+
devrites-engine build-readiness [slug] Gate: are plan approval, decision coverage, and implementation readiness build-ready?
|
|
53
|
+
devrites-engine readiness-digest <coverage|engineering> [slug] Render the canonical artifact input digest
|
|
54
|
+
devrites-engine clarify-return <enter|restore> [slug] Preserve/restore a later-phase clarification cursor
|
|
55
|
+
devrites-engine analyze [slug] Check coverage and consistency between the spec and tasks
|
|
54
56
|
devrites-engine mutation-gate [slug] Advisory: detect the mutation runner and scope it
|
|
55
57
|
devrites-engine test-integrity [slug] Gate: no test deleted, skipped, or de-asserted
|
|
56
58
|
devrites-engine review-integrity [slug] Gate: no adversarial review axis is silent (zero findings, no justification)
|
|
57
59
|
devrites-engine package-existence [slug] Gate: every new import is declared in a manifest
|
|
58
|
-
devrites-engine reconcile <sub> [slug] A1 gate: snapshot|check the wright's source writes
|
|
60
|
+
devrites-engine reconcile <sub> [slug] A1 gate: snapshot|check|close the wright's source writes
|
|
59
61
|
devrites-engine resolve <qid> "<ans>" Resolve an open question; keep state.md consistent
|
|
60
62
|
devrites-engine close-out <slug> Archive a shipped feature and clear ACTIVE
|
|
61
|
-
devrites-engine archive-search "<nouns>"
|
|
63
|
+
devrites-engine archive-search "<nouns>" Find prior shipped specs that overlap the query
|
|
62
64
|
devrites-engine decisions <sub> [...] Derived decision memory: index|search
|
|
63
65
|
devrites-engine ledger <sub> [...] Capability ledger (living specs/): sync|diff|validate|list|show
|
|
64
66
|
devrites-engine learnings <sub> [...] Cross-feature learning ledger: add|list|top|mine|nudge
|
|
65
|
-
devrites-engine timeline <sub> [...]
|
|
66
|
-
devrites-engine health [run|record|list]
|
|
67
|
+
devrites-engine timeline <sub> [...] Local typed trace: log|list|report|purge
|
|
68
|
+
devrites-engine health [run|record|list] Run the code health dashboard or view its history
|
|
67
69
|
devrites-engine config get <key> Read project config (outside_voice defaults auto)
|
|
68
70
|
devrites-engine reviewers list Validate/list configured reviewer aliases
|
|
69
71
|
devrites-engine outside-voice Detect outside-review availability
|
|
@@ -73,6 +75,7 @@ Usage:
|
|
|
73
75
|
devrites-engine reviewer-stats <sub> Reviewer dispatch outcomes: record <agent> <n> [slug] | report [--json]
|
|
74
76
|
devrites-engine conventions <sub> [...] Project convention ledger: band|read|orient|promote|contradict
|
|
75
77
|
devrites-engine lanes plan [slug] Advisory safe-parallelism/lane plan for slices
|
|
78
|
+
devrites-engine forge <sub> [...] Isolated candidate worktrees: plan|record|extract|merge|cleanup|reap
|
|
76
79
|
devrites-engine extensions <sub> Project extensions (.devrites/extensions/): list|validate|sync
|
|
77
80
|
devrites-engine overrides <sub> Reviewer-override linter (.devrites/overrides/): list|validate
|
|
78
81
|
devrites-engine context sync [file ...] Sync managed DevRites block into context files
|
|
@@ -80,7 +83,7 @@ Usage:
|
|
|
80
83
|
devrites-engine runbook <sub> [...] Local runbooks: list|validate|run|resume
|
|
81
84
|
devrites-engine doctor Report the binary / pack / state-schema version triangle
|
|
82
85
|
devrites-engine migrate Normalize .devrites workspaces to the current schema
|
|
83
|
-
devrites-engine validate-pack [dir]
|
|
86
|
+
devrites-engine validate-pack [dir] Check shipped hook wiring, frontmatter contracts, and command-map links
|
|
84
87
|
devrites-engine harness-matrix [--check F] Render (or drift-check) the harness adapter-compliance matrix
|
|
85
88
|
devrites-engine version Print the engine binary's version
|
|
86
89
|
devrites-engine hook <name> --harness=H Run hook <name> for harness H (claude|codex)
|
|
@@ -89,13 +92,14 @@ Hooks:
|
|
|
89
92
|
hook allow Auto-approve the read-only devrites orientation/gate subcommands
|
|
90
93
|
hook orient Emit SessionStart orientation for the active feature
|
|
91
94
|
hook stop-gate Refuse to end a turn at a provably inconsistent rest point
|
|
92
|
-
hook reviewer-readonly Deny
|
|
95
|
+
hook reviewer-readonly Deny every mutation/dispatch surface for read-only DevRites agents
|
|
93
96
|
hook subagent-orient Inject the DevRites discipline into a spawned devrites-* subagent
|
|
94
97
|
hook cursor Re-inject the active feature's cursor (UserPromptSubmit)
|
|
95
98
|
hook statusline One-line workspace HUD (settings.json statusLine)
|
|
96
99
|
hook redwatch Fail-on-red sentinel: set/clear .red after a test/build command
|
|
97
100
|
hook a1-guard Block the orchestrator editing source mid-build
|
|
98
|
-
hook
|
|
101
|
+
hook git-guard Require exact one-shot authority for destructive Git
|
|
102
|
+
hook wright-scope Fence the slice-wright to an exact orchestrator allowlist
|
|
99
103
|
hook source-cache-pre Serve a cached page reading on a 304 revalidation (WebFetch)
|
|
100
104
|
hook source-cache-post Store a WebFetch result keyed on its origin validators
|
|
101
105
|
hook refresh-indexes Refresh the code-intelligence indexes (detached) on Stop
|
|
@@ -114,13 +118,20 @@ Environment:
|
|
|
114
118
|
the nearest .devrites found walking up from the working directory.
|
|
115
119
|
DEVRITES_WORKSPACE Explicit feature workspace path for CI/agents; overrides
|
|
116
120
|
.devrites/ACTIVE when a command defaults to the active feature.
|
|
121
|
+
DEVRITES_AGENT_RUN=1 declares a DevRites leaf run when hook payloads omit identity.
|
|
122
|
+
DEVRITES_ACTIVE_AGENT=devrites-<role> supplies that exact leaf identity.
|
|
123
|
+
DEVRITES_WRIGHT_ALLOWLIST_FILE points to the wright's exact project-relative
|
|
124
|
+
path manifest; defaults to the active workspace's .wright-allowlist.
|
|
125
|
+
DEVRITES_FORGE_RUN_ID, DEVRITES_FORGE_CANDIDATE, DEVRITES_FORGE_WORKER_ID,
|
|
126
|
+
DEVRITES_FORGE_WORKER_PID, and DEVRITES_FORGE_PROCESS_START bind a candidate
|
|
127
|
+
wright to its root-owned manifest. All five are required.
|
|
117
128
|
|
|
118
129
|
Hook control plane:
|
|
119
130
|
DEVRITES_HOOK_PROFILE minimal | standard (default) | strict. minimal runs
|
|
120
131
|
orientation/approval hooks only; standard adds the
|
|
121
132
|
gates, guards and caches; strict also enables
|
|
122
|
-
every OBSERVE-default guard
|
|
123
|
-
|
|
133
|
+
every legacy OBSERVE-default guard to enforce at once.
|
|
134
|
+
Declared DevRites agents are always enforced.
|
|
124
135
|
DEVRITES_DISABLED_HOOKS Comma-separated hook ids to force off, e.g.
|
|
125
136
|
"stop-gate,redwatch". A disabled hook is a clean
|
|
126
137
|
fail-open no-op.
|
|
@@ -143,6 +154,11 @@ func run(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
|
|
143
154
|
fmt.Fprint(stderr, usage)
|
|
144
155
|
return exitUsage
|
|
145
156
|
}
|
|
157
|
+
root, rootExit, err := resolveRootFor(args[0], args[1:])
|
|
158
|
+
if err != nil {
|
|
159
|
+
fmt.Fprintf(stderr, "devrites: root selection: %v\n", err)
|
|
160
|
+
return rootExit
|
|
161
|
+
}
|
|
146
162
|
switch args[0] {
|
|
147
163
|
case "install":
|
|
148
164
|
return install.Run(args[1:], stdout, stderr, install.ModeInstall)
|
|
@@ -156,103 +172,121 @@ func run(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
|
|
156
172
|
case "snapshot":
|
|
157
173
|
return cmdSnapshot(args[1:], stdout, stderr)
|
|
158
174
|
case "first-task":
|
|
159
|
-
return lib.FirstTask(
|
|
175
|
+
return lib.FirstTask(root, args[1:], stdout, stderr)
|
|
160
176
|
case "readiness":
|
|
161
177
|
rest, j := extractFlag(args[1:], "--json")
|
|
162
|
-
return
|
|
178
|
+
return jsonWrapReason("readiness", j, stdout, stderr, func(code int) reason.ID {
|
|
179
|
+
if code == exitOK || code == exitBlocked {
|
|
180
|
+
return gate.ResultReasonID(gate.Readiness, code == exitBlocked)
|
|
181
|
+
}
|
|
182
|
+
return ""
|
|
183
|
+
}, func(o, e io.Writer) int { return cmdGate(gate.Readiness, rest, o, e) })
|
|
163
184
|
case "seal":
|
|
164
185
|
rest, j := extractFlag(args[1:], "--json")
|
|
165
|
-
return
|
|
186
|
+
return jsonWrapReason("seal", j, stdout, stderr, func(code int) reason.ID {
|
|
187
|
+
if code == exitOK || code == exitBlocked {
|
|
188
|
+
return gate.ResultReasonID(gate.Seal, code == exitBlocked)
|
|
189
|
+
}
|
|
190
|
+
return ""
|
|
191
|
+
}, func(o, e io.Writer) int { return cmdGate(gate.Seal, rest, o, e) })
|
|
166
192
|
case "spec-validate":
|
|
167
193
|
rest, j := extractFlag(args[1:], "--json")
|
|
168
194
|
return jsonWrap("spec-validate", j, stdout, stderr, func(o, e io.Writer) int { return cmdSpecValidate(rest, o, e) })
|
|
169
195
|
case "spec-skeleton":
|
|
170
196
|
return cmdSpecSkeleton(args[1:], stdout, stderr)
|
|
171
197
|
case "spec-dedupe":
|
|
172
|
-
return lib.SpecDedupe(
|
|
198
|
+
return lib.SpecDedupe(root, args[1:], stdout, stderr)
|
|
173
199
|
case "check-acceptance":
|
|
174
200
|
return cmdCheckAcceptance(args[1:], stdout, stderr)
|
|
175
201
|
case "footprint":
|
|
176
|
-
return cmdFootprint(args[1:], stdout, stderr)
|
|
202
|
+
return cmdFootprint(root, args[1:], stdout, stderr)
|
|
177
203
|
case "evidence-fresh":
|
|
178
204
|
rest, j := extractFlag(args[1:], "--json")
|
|
179
|
-
return jsonWrap("evidence-fresh", j, stdout, stderr, func(o, e io.Writer) int { return cmdEvidenceFresh(rest, o, e) })
|
|
205
|
+
return jsonWrap("evidence-fresh", j, stdout, stderr, func(o, e io.Writer) int { return cmdEvidenceFresh(root, rest, o, e) })
|
|
180
206
|
case "coverage":
|
|
181
207
|
rest, j := extractFlag(args[1:], "--json")
|
|
182
|
-
return jsonWrap("coverage", j, stdout, stderr, func(o, e io.Writer) int { return cmdCoverage(rest, o, e) })
|
|
208
|
+
return jsonWrap("coverage", j, stdout, stderr, func(o, e io.Writer) int { return cmdCoverage(root, rest, o, e) })
|
|
183
209
|
case "doubt-coverage":
|
|
184
|
-
return cmdDoubtCoverage(args[1:], stdout, stderr)
|
|
210
|
+
return cmdDoubtCoverage(root, args[1:], stdout, stderr)
|
|
185
211
|
case "budget":
|
|
186
|
-
return lib.Budget(
|
|
212
|
+
return lib.Budget(root, args[1:], stdout, stderr)
|
|
187
213
|
case "preamble":
|
|
188
214
|
rest, j := extractFlag(args[1:], "--json")
|
|
189
|
-
return jsonWrap("preamble", j, stdout, stderr, func(o, e io.Writer) int { return cmdPreamble(rest, o, e) })
|
|
215
|
+
return jsonWrap("preamble", j, stdout, stderr, func(o, e io.Writer) int { return cmdPreamble(root, rest, o, e) })
|
|
190
216
|
case "progress":
|
|
191
|
-
return cmdProgress(args[1:], stdout, stderr)
|
|
217
|
+
return cmdProgress(root, args[1:], stdout, stderr)
|
|
192
218
|
case "profile":
|
|
193
219
|
return profile.Run(args[1:], stdout, stderr)
|
|
194
220
|
case "stuck":
|
|
195
|
-
return cmdStuck(args[1:], stdout, stderr)
|
|
221
|
+
return cmdStuck(root, args[1:], stdout, stderr)
|
|
222
|
+
case "recovery":
|
|
223
|
+
return lib.RecoveryAttempts(root, args[1:], stdout, stderr)
|
|
196
224
|
case "tick-afk":
|
|
197
225
|
return lib.TickAfk(args[1:], stdout, stderr)
|
|
198
226
|
case "build-readiness":
|
|
199
|
-
return lib.BuildReadiness(
|
|
227
|
+
return lib.BuildReadiness(root, args[1:], stdout, stderr)
|
|
228
|
+
case "readiness-digest":
|
|
229
|
+
return lib.ReadinessDigest(root, args[1:], stdout, stderr)
|
|
230
|
+
case "clarify-return":
|
|
231
|
+
return lib.ClarifyReturn(root, args[1:], stdout, stderr)
|
|
200
232
|
case "analyze":
|
|
201
233
|
rest, j := extractFlag(args[1:], "--json")
|
|
202
|
-
return jsonWrap("analyze", j, stdout, stderr, func(o, e io.Writer) int { return lib.Analyze(
|
|
234
|
+
return jsonWrap("analyze", j, stdout, stderr, func(o, e io.Writer) int { return lib.Analyze(root, rest, o, e) })
|
|
203
235
|
case "mutation-gate":
|
|
204
|
-
return lib.MutationGate(
|
|
236
|
+
return lib.MutationGate(root, args[1:], stdout, stderr)
|
|
205
237
|
case "test-integrity":
|
|
206
|
-
return lib.TestIntegrity(
|
|
238
|
+
return lib.TestIntegrity(root, args[1:], stdout, stderr)
|
|
207
239
|
case "review-integrity":
|
|
208
|
-
return lib.ReviewIntegrity(
|
|
240
|
+
return lib.ReviewIntegrity(root, args[1:], stdout, stderr)
|
|
209
241
|
case "package-existence":
|
|
210
|
-
return lib.PackageExistence(
|
|
242
|
+
return lib.PackageExistence(root, args[1:], stdout, stderr)
|
|
211
243
|
case "reconcile":
|
|
212
|
-
return lib.Reconcile(
|
|
244
|
+
return lib.Reconcile(root, args[1:], stdout, stderr)
|
|
213
245
|
case "resolve":
|
|
214
|
-
return lib.Resolve(
|
|
246
|
+
return lib.Resolve(root, args[1:], stdout, stderr)
|
|
215
247
|
case "close-out":
|
|
216
|
-
return lib.CloseOut(
|
|
248
|
+
return lib.CloseOut(root, args[1:], stdout, stderr)
|
|
217
249
|
case "archive-search":
|
|
218
|
-
return lib.ArchiveSearch(
|
|
250
|
+
return lib.ArchiveSearch(root, args[1:], stdout, stderr)
|
|
219
251
|
case "decisions":
|
|
220
|
-
return lib.Decisions(
|
|
252
|
+
return lib.Decisions(root, args[1:], stdout, stderr)
|
|
221
253
|
case "ledger":
|
|
222
254
|
rest, j := extractFlag(args[1:], "--json")
|
|
223
|
-
return jsonWrap("ledger", j, stdout, stderr, func(o, e io.Writer) int { return lib.Ledger(
|
|
255
|
+
return jsonWrap("ledger", j, stdout, stderr, func(o, e io.Writer) int { return lib.Ledger(root, rest, o, e) })
|
|
224
256
|
case "learnings":
|
|
225
|
-
return lib.Learnings(
|
|
257
|
+
return lib.Learnings(root, args[1:], stdout, stderr)
|
|
226
258
|
case "timeline":
|
|
227
|
-
return lib.Timeline(
|
|
259
|
+
return lib.Timeline(root, args[1:], stdout, stderr)
|
|
228
260
|
case "health":
|
|
229
|
-
return lib.Health(
|
|
261
|
+
return lib.Health(root, args[1:], stdout, stderr)
|
|
230
262
|
case "config":
|
|
231
|
-
return lib.Config(
|
|
263
|
+
return lib.Config(root, args[1:], stdout, stderr)
|
|
232
264
|
case "reviewers":
|
|
233
|
-
return lib.Reviewers(
|
|
265
|
+
return lib.Reviewers(root, args[1:], stdout, stderr)
|
|
234
266
|
case "outside-voice":
|
|
235
|
-
return lib.OutsideVoice(
|
|
267
|
+
return lib.OutsideVoice(root, args[1:], stdout, stderr)
|
|
236
268
|
case "docs-stale":
|
|
237
|
-
return lib.DocsStale(
|
|
269
|
+
return lib.DocsStale(root, args[1:], stdout, stderr)
|
|
238
270
|
case "secret-scan":
|
|
239
|
-
return lib.SecretScan(
|
|
271
|
+
return lib.SecretScan(root, args[1:], stdout, stderr)
|
|
240
272
|
case "review-fingerprints":
|
|
241
|
-
return lib.ReviewFingerprints(
|
|
273
|
+
return lib.ReviewFingerprints(root, args[1:], stdout, stderr)
|
|
242
274
|
case "reviewer-stats":
|
|
243
|
-
return lib.ReviewerStats(
|
|
275
|
+
return lib.ReviewerStats(root, args[1:], stdout, stderr)
|
|
244
276
|
case "conventions":
|
|
245
277
|
return lib.Conventions(args[1:], stdout, stderr)
|
|
246
278
|
case "lanes":
|
|
247
|
-
return lib.Lanes(
|
|
279
|
+
return lib.Lanes(root, args[1:], stdout, stderr)
|
|
280
|
+
case "forge":
|
|
281
|
+
return forge.Run(filepath.Dir(root), args[1:], stdout, stderr)
|
|
248
282
|
case "extensions":
|
|
249
|
-
return lib.Extensions(
|
|
283
|
+
return lib.Extensions(root, args[1:], stdout, stderr)
|
|
250
284
|
case "overrides":
|
|
251
|
-
return lib.Overrides(
|
|
285
|
+
return lib.Overrides(root, args[1:], stdout, stderr)
|
|
252
286
|
case "context":
|
|
253
|
-
return lib.Context(
|
|
287
|
+
return lib.Context(root, args[1:], stdout, stderr)
|
|
254
288
|
case "runbook":
|
|
255
|
-
return lib.Runbook(
|
|
289
|
+
return lib.Runbook(root, args[1:], stdout, stderr)
|
|
256
290
|
case "doctor":
|
|
257
291
|
rest, j := extractFlag(args[1:], "--json")
|
|
258
292
|
return jsonWrap("doctor", j, stdout, stderr, func(o, e io.Writer) int { return cmdDoctor(rest, o, e) })
|
|
@@ -286,6 +320,7 @@ func cmdStatus(args []string, stdout, stderr io.Writer) int {
|
|
|
286
320
|
fmt.Fprintf(stderr, "devrites: %v\n", err)
|
|
287
321
|
return exitUsage
|
|
288
322
|
}
|
|
323
|
+
recordRootSelection(root, "status", stderr)
|
|
289
324
|
report, err := state.Status(root, args[0])
|
|
290
325
|
if err != nil {
|
|
291
326
|
fmt.Fprintf(stderr, "devrites: %v\n", err)
|
|
@@ -308,11 +343,29 @@ func cmdGate(kind gate.Kind, args []string, stdout, stderr io.Writer) int {
|
|
|
308
343
|
fmt.Fprintf(stderr, "devrites: %v\n", err)
|
|
309
344
|
return exitUsage
|
|
310
345
|
}
|
|
346
|
+
recordRootSelection(root, string(kind), stderr)
|
|
311
347
|
result, err := gate.Check(kind, root, args[0])
|
|
312
348
|
if err != nil {
|
|
313
349
|
fmt.Fprintf(stderr, "devrites: %v\n", err)
|
|
314
350
|
return exitUsage
|
|
315
351
|
}
|
|
352
|
+
evidence := append([]string(nil), result.MissingFiles...)
|
|
353
|
+
if result.LegacyLayout {
|
|
354
|
+
evidence = evidence[:0]
|
|
355
|
+
for _, section := range result.Missing {
|
|
356
|
+
evidence = append(evidence, string(section)+".md")
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
if ev, eventErr := lib.NewLifecycleGateEvent(
|
|
360
|
+
root, result.Slug, string(result.Kind), result.Phase,
|
|
361
|
+
result.Blocked, result.ReasonID, evidence,
|
|
362
|
+
); eventErr == nil {
|
|
363
|
+
if eventErr = lib.AppendEventV1(root, ev); eventErr != nil {
|
|
364
|
+
debugf(stderr, "lifecycle-gate event: %v", eventErr)
|
|
365
|
+
}
|
|
366
|
+
} else {
|
|
367
|
+
debugf(stderr, "lifecycle-gate event: %v", eventErr)
|
|
368
|
+
}
|
|
316
369
|
fmt.Fprint(stdout, result.Render())
|
|
317
370
|
if result.Blocked {
|
|
318
371
|
return exitBlocked
|
|
@@ -372,47 +425,47 @@ func cmdCheckAcceptance(args []string, stdout, stderr io.Writer) int {
|
|
|
372
425
|
return lib.CheckAcceptance(arg, stdout, stderr)
|
|
373
426
|
}
|
|
374
427
|
|
|
375
|
-
// cmdFootprint renders
|
|
376
|
-
// feature. Workspace state lives under <root>/work/<slug>, with features
|
|
428
|
+
// cmdFootprint renders, logs, or lists the fan-out dispatch footprint for a
|
|
429
|
+
// feature. Workspace state lives under <root>/work/<slug>, with features as an
|
|
377
430
|
// alias for older workspaces.
|
|
378
|
-
func cmdFootprint(args []string, stdout, stderr io.Writer) int {
|
|
379
|
-
return lib.Footprint(
|
|
431
|
+
func cmdFootprint(root string, args []string, stdout, stderr io.Writer) int {
|
|
432
|
+
return lib.Footprint(root, args, stdout, stderr)
|
|
380
433
|
}
|
|
381
434
|
|
|
382
435
|
// cmdEvidenceFresh runs the evidence-freshness gate (0 fresh · 3 stale · 5 no
|
|
383
436
|
// workspace/evidence).
|
|
384
|
-
func cmdEvidenceFresh(args []string, stdout, stderr io.Writer) int {
|
|
385
|
-
return lib.EvidenceFresh(
|
|
437
|
+
func cmdEvidenceFresh(root string, args []string, stdout, stderr io.Writer) int {
|
|
438
|
+
return lib.EvidenceFresh(root, args, stdout, stderr)
|
|
386
439
|
}
|
|
387
440
|
|
|
388
441
|
// cmdCoverage renders the AC → slice → proven traceability matrix (0 rendered ·
|
|
389
442
|
// 2 no workspace/spec).
|
|
390
|
-
func cmdCoverage(args []string, stdout, stderr io.Writer) int {
|
|
391
|
-
return lib.Coverage(
|
|
443
|
+
func cmdCoverage(root string, args []string, stdout, stderr io.Writer) int {
|
|
444
|
+
return lib.Coverage(root, args, stdout, stderr)
|
|
392
445
|
}
|
|
393
446
|
|
|
394
447
|
// cmdDoubtCoverage runs the doubt-coverage assessment (0 covered/n-a · 1 no doubt
|
|
395
448
|
// ran · 2 usage · 3 doubt: MISSING).
|
|
396
|
-
func cmdDoubtCoverage(args []string, stdout, stderr io.Writer) int {
|
|
397
|
-
return lib.DoubtCoverage(
|
|
449
|
+
func cmdDoubtCoverage(root string, args []string, stdout, stderr io.Writer) int {
|
|
450
|
+
return lib.DoubtCoverage(root, args, stdout, stderr)
|
|
398
451
|
}
|
|
399
452
|
|
|
400
453
|
// cmdPreamble prints the active feature's workspace-state orientation (always
|
|
401
454
|
// exit 0).
|
|
402
|
-
func cmdPreamble(args []string, stdout, stderr io.Writer) int {
|
|
403
|
-
return lib.Preamble(
|
|
455
|
+
func cmdPreamble(root string, args []string, stdout, stderr io.Writer) int {
|
|
456
|
+
return lib.Preamble(root, args, stdout, stderr)
|
|
404
457
|
}
|
|
405
458
|
|
|
406
459
|
// cmdProgress renders the active feature's phase/slice/flow footer (always exit 0,
|
|
407
460
|
// silent when no workspace).
|
|
408
|
-
func cmdProgress(args []string, stdout, stderr io.Writer) int {
|
|
409
|
-
return lib.Progress(
|
|
461
|
+
func cmdProgress(root string, args []string, stdout, stderr io.Writer) int {
|
|
462
|
+
return lib.Progress(root, args, stdout, stderr)
|
|
410
463
|
}
|
|
411
464
|
|
|
412
465
|
// cmdStuck is the unattended-build loop detector: `stuck log|check <slug>` (0 not
|
|
413
466
|
// stuck · 2 bad args · 3 STUCK).
|
|
414
|
-
func cmdStuck(args []string, stdout, stderr io.Writer) int {
|
|
415
|
-
return lib.Stuck(
|
|
467
|
+
func cmdStuck(root string, args []string, stdout, stderr io.Writer) int {
|
|
468
|
+
return lib.Stuck(root, args, stdout, stderr)
|
|
416
469
|
}
|
|
417
470
|
|
|
418
471
|
func cmdHook(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
|
@@ -425,6 +478,8 @@ func cmdHook(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
|
|
425
478
|
// in DEVRITES_DISABLED_HOOKS is a clean fail-open no-op, indistinguishable from
|
|
426
479
|
// an absent binary. Consulted before any work, including refresh-indexes.
|
|
427
480
|
if !hookActive(name) {
|
|
481
|
+
h, _ := harness.Parse(harnessFlag(args[1:]))
|
|
482
|
+
recordHookGuard(h, name, reason.HookDisabled, lib.GuardBypassed, lib.OutcomeBypassed)
|
|
428
483
|
return exitOK
|
|
429
484
|
}
|
|
430
485
|
// These hooks carry their own positional args and need no harness parsing, so
|
|
@@ -465,12 +520,19 @@ func cmdHook(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
|
|
465
520
|
return hookRedwatch(h, stdin, stdout, stderr)
|
|
466
521
|
case "a1-guard":
|
|
467
522
|
return hookA1Guard(h, stdin, stdout, stderr)
|
|
523
|
+
case "git-guard":
|
|
524
|
+
return hookGitGuard(h, stdin, stdout, stderr)
|
|
468
525
|
case "wright-scope":
|
|
469
526
|
return hookWrightScope(h, stdin, stdout, stderr)
|
|
470
527
|
case "source-cache-pre":
|
|
471
528
|
return iohooks.SourceCachePre(stdin, stdout, stderr)
|
|
472
529
|
case "source-cache-post":
|
|
473
|
-
|
|
530
|
+
var warning bytes.Buffer
|
|
531
|
+
code := iohooks.SourceCachePost(h, stdin, io.MultiWriter(stdout, &warning), stderr)
|
|
532
|
+
if warning.Len() > 0 {
|
|
533
|
+
recordHookGuard(h, "source-cache-post", reason.HookIngestWarning, lib.GuardObserved, lib.OutcomeWarning)
|
|
534
|
+
}
|
|
535
|
+
return code
|
|
474
536
|
default:
|
|
475
537
|
fmt.Fprintf(stderr, "devrites: unknown hook %q\n", name)
|
|
476
538
|
return exitUsage
|
|
@@ -520,11 +582,32 @@ func extractFlag(args []string, flag string) ([]string, bool) {
|
|
|
520
582
|
// otherwise. It is applied only to the AFK-parsed read commands (see the
|
|
521
583
|
// --json set in run()); other commands never accept --json.
|
|
522
584
|
func jsonWrap(command string, jsonMode bool, stdout, stderr io.Writer, thunk func(o, e io.Writer) int) int {
|
|
585
|
+
return jsonWrapReason(command, jsonMode, stdout, stderr, nil, thunk)
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
func jsonWrapReason(command string, jsonMode bool, stdout, stderr io.Writer, reasonFor func(int) reason.ID, thunk func(o, e io.Writer) int) int {
|
|
523
589
|
if !jsonMode {
|
|
524
590
|
return thunk(stdout, stderr)
|
|
525
591
|
}
|
|
526
592
|
var out, errb bytes.Buffer
|
|
527
593
|
code := thunk(&out, &errb)
|
|
528
|
-
|
|
594
|
+
env := lib.NewEnvelope(command, code, out.String(), errb.String())
|
|
595
|
+
if reasonFor != nil {
|
|
596
|
+
env = env.WithReason(reasonFor(code))
|
|
597
|
+
}
|
|
598
|
+
lib.WriteEnvelope(stdout, env)
|
|
529
599
|
return code
|
|
530
600
|
}
|
|
601
|
+
|
|
602
|
+
func recordRootSelection(root, command string, stderr io.Writer) {
|
|
603
|
+
if root == "" {
|
|
604
|
+
return
|
|
605
|
+
}
|
|
606
|
+
ev, err := lib.NewRootSelectionEvent(root, command)
|
|
607
|
+
if err == nil {
|
|
608
|
+
err = lib.AppendEventV1(root, ev)
|
|
609
|
+
}
|
|
610
|
+
if err != nil {
|
|
611
|
+
debugf(stderr, "root-selection event: %v", err)
|
|
612
|
+
}
|
|
613
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"os"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
|
|
10
|
+
"github.com/devrites/devrites/internal/lib"
|
|
11
|
+
"github.com/devrites/devrites/internal/reason"
|
|
12
|
+
"github.com/devrites/devrites/internal/state"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
func TestTimelineReportIgnoresItsOwnRootSelectionEvent(t *testing.T) {
|
|
16
|
+
project := t.TempDir()
|
|
17
|
+
initRootRoutingGitRepo(t, project)
|
|
18
|
+
root := filepath.Join(project, ".devrites")
|
|
19
|
+
work := filepath.Join(root, "work", "demo")
|
|
20
|
+
if err := os.MkdirAll(work, 0o755); err != nil {
|
|
21
|
+
t.Fatal(err)
|
|
22
|
+
}
|
|
23
|
+
if err := os.WriteFile(filepath.Join(root, "ACTIVE"), []byte("demo\n"), 0o644); err != nil {
|
|
24
|
+
t.Fatal(err)
|
|
25
|
+
}
|
|
26
|
+
if err := os.WriteFile(filepath.Join(work, "state.md"), []byte("| phase | build |\n"), 0o644); err != nil {
|
|
27
|
+
t.Fatal(err)
|
|
28
|
+
}
|
|
29
|
+
event := lib.NewEventV1(lib.BoundaryAgentDispatch, "run-started", reason.RootSelected)
|
|
30
|
+
event.TS = "2026-07-23T12:00:00Z"
|
|
31
|
+
event.RunID = "drv-run-v1:0123456789abcdef0123456789abcdef"
|
|
32
|
+
event.RootSource = lib.RootSourceExplicit
|
|
33
|
+
event.Workspace = ".devrites/work/demo"
|
|
34
|
+
event.PhaseBefore = state.PhaseBuild
|
|
35
|
+
event.PhaseAfter = state.PhaseBuild
|
|
36
|
+
event.Outcome = lib.OutcomeRecorded
|
|
37
|
+
if err := lib.AppendEventV1(root, event); err != nil {
|
|
38
|
+
t.Fatal(err)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
withRootRoutingCWD(t, project)
|
|
42
|
+
t.Setenv("DEVRITES_ROOT", root)
|
|
43
|
+
t.Setenv("DEVRITES_WORKSPACE", "")
|
|
44
|
+
var stdout, stderr bytes.Buffer
|
|
45
|
+
if code := run([]string{"timeline", "report"}, strings.NewReader(""), &stdout, &stderr); code != exitOK {
|
|
46
|
+
t.Fatalf("timeline report code=%d stdout=%q stderr=%q", code, stdout.String(), stderr.String())
|
|
47
|
+
}
|
|
48
|
+
if !strings.Contains(stdout.String(), event.RunID) ||
|
|
49
|
+
!strings.Contains(stdout.String(), "1 v1 events") {
|
|
50
|
+
t.Fatalf("report selected its own root-selection event instead of the trace: %s", stdout.String())
|
|
51
|
+
}
|
|
52
|
+
}
|