@matteeh/osq 0.2.1 → 0.2.2
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/README.md +234 -15
- package/dist/cli/approve.d.ts +7 -0
- package/dist/cli/approve.d.ts.map +1 -1
- package/dist/cli/approve.js +34 -0
- package/dist/cli/approve.js.map +1 -1
- package/dist/cli/bin.js +2 -3
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/check.d.ts +15 -0
- package/dist/cli/check.d.ts.map +1 -0
- package/dist/cli/check.js +65 -0
- package/dist/cli/check.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +10 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +6 -1
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/lint.d.ts +3 -0
- package/dist/cli/lint.d.ts.map +1 -1
- package/dist/cli/lint.js +33 -14
- package/dist/cli/lint.js.map +1 -1
- package/dist/cli/plan-queue.d.ts +10 -4
- package/dist/cli/plan-queue.d.ts.map +1 -1
- package/dist/cli/plan-queue.js +20 -19
- package/dist/cli/plan-queue.js.map +1 -1
- package/dist/cli/plan-sections.d.ts +15 -0
- package/dist/cli/plan-sections.d.ts.map +1 -0
- package/dist/cli/plan-sections.js +47 -0
- package/dist/cli/plan-sections.js.map +1 -0
- package/dist/cli/plan.d.ts +1 -0
- package/dist/cli/plan.d.ts.map +1 -1
- package/dist/cli/plan.js +14 -4
- package/dist/cli/plan.js.map +1 -1
- package/dist/cli/report.d.ts.map +1 -1
- package/dist/cli/report.js +73 -1
- package/dist/cli/report.js.map +1 -1
- package/dist/cli/run.d.ts +7 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +22 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/verified.d.ts +15 -0
- package/dist/cli/verified.d.ts.map +1 -0
- package/dist/cli/verified.js +34 -0
- package/dist/cli/verified.js.map +1 -0
- package/dist/core/foundation/config-agents.d.ts +16 -0
- package/dist/core/foundation/config-agents.d.ts.map +1 -0
- package/dist/core/foundation/config-agents.js +2 -0
- package/dist/core/foundation/config-agents.js.map +1 -0
- package/dist/core/foundation/config-claude.d.ts +48 -0
- package/dist/core/foundation/config-claude.d.ts.map +1 -0
- package/dist/core/foundation/config-claude.js +106 -0
- package/dist/core/foundation/config-claude.js.map +1 -0
- package/dist/core/foundation/config-codex-resolve.d.ts +10 -0
- package/dist/core/foundation/config-codex-resolve.d.ts.map +1 -0
- package/dist/core/foundation/config-codex-resolve.js +24 -0
- package/dist/core/foundation/config-codex-resolve.js.map +1 -0
- package/dist/core/foundation/config-file.d.ts +18 -0
- package/dist/core/foundation/config-file.d.ts.map +1 -0
- package/dist/core/foundation/config-file.js +46 -0
- package/dist/core/foundation/config-file.js.map +1 -0
- package/dist/core/foundation/config-gates.d.ts +2 -0
- package/dist/core/foundation/config-gates.d.ts.map +1 -1
- package/dist/core/foundation/config-gates.js +8 -0
- package/dist/core/foundation/config-gates.js.map +1 -1
- package/dist/core/foundation/config-opencode.d.ts +25 -0
- package/dist/core/foundation/config-opencode.d.ts.map +1 -0
- package/dist/core/foundation/config-opencode.js +55 -0
- package/dist/core/foundation/config-opencode.js.map +1 -0
- package/dist/core/foundation/config-pi.d.ts +10 -0
- package/dist/core/foundation/config-pi.d.ts.map +1 -1
- package/dist/core/foundation/config-pi.js +13 -0
- package/dist/core/foundation/config-pi.js.map +1 -1
- package/dist/core/foundation/config-planning.d.ts +12 -1
- package/dist/core/foundation/config-planning.d.ts.map +1 -1
- package/dist/core/foundation/config-planning.js +29 -1
- package/dist/core/foundation/config-planning.js.map +1 -1
- package/dist/core/foundation/config-traceability.d.ts +28 -0
- package/dist/core/foundation/config-traceability.d.ts.map +1 -0
- package/dist/core/foundation/config-traceability.js +63 -0
- package/dist/core/foundation/config-traceability.js.map +1 -0
- package/dist/core/foundation/config-user.d.ts +32 -0
- package/dist/core/foundation/config-user.d.ts.map +1 -0
- package/dist/core/foundation/config-user.js +2 -0
- package/dist/core/foundation/config-user.js.map +1 -0
- package/dist/core/foundation/config-vcs.d.ts +29 -0
- package/dist/core/foundation/config-vcs.d.ts.map +1 -0
- package/dist/core/foundation/config-vcs.js +57 -0
- package/dist/core/foundation/config-vcs.js.map +1 -0
- package/dist/core/foundation/config.d.ts +23 -24
- package/dist/core/foundation/config.d.ts.map +1 -1
- package/dist/core/foundation/config.js +29 -36
- package/dist/core/foundation/config.js.map +1 -1
- package/dist/core/foundation/decisions-validate.d.ts +16 -0
- package/dist/core/foundation/decisions-validate.d.ts.map +1 -0
- package/dist/core/foundation/decisions-validate.js +74 -0
- package/dist/core/foundation/decisions-validate.js.map +1 -0
- package/dist/core/foundation/decisions.d.ts +34 -0
- package/dist/core/foundation/decisions.d.ts.map +1 -0
- package/dist/core/foundation/decisions.js +152 -0
- package/dist/core/foundation/decisions.js.map +1 -0
- package/dist/core/foundation/doctor-decisions.d.ts +9 -0
- package/dist/core/foundation/doctor-decisions.d.ts.map +1 -0
- package/dist/core/foundation/doctor-decisions.js +49 -0
- package/dist/core/foundation/doctor-decisions.js.map +1 -0
- package/dist/core/foundation/doctor-managed.d.ts.map +1 -1
- package/dist/core/foundation/doctor-managed.js +3 -0
- package/dist/core/foundation/doctor-managed.js.map +1 -1
- package/dist/core/foundation/doctor-prices.d.ts +8 -0
- package/dist/core/foundation/doctor-prices.d.ts.map +1 -0
- package/dist/core/foundation/doctor-prices.js +25 -0
- package/dist/core/foundation/doctor-prices.js.map +1 -0
- package/dist/core/foundation/doctor.d.ts.map +1 -1
- package/dist/core/foundation/doctor.js +20 -30
- package/dist/core/foundation/doctor.js.map +1 -1
- package/dist/core/foundation/harness-catalog.d.ts +7 -8
- package/dist/core/foundation/harness-catalog.d.ts.map +1 -1
- package/dist/core/foundation/harness-catalog.js +26 -41
- package/dist/core/foundation/harness-catalog.js.map +1 -1
- package/dist/core/foundation/init-blocks.d.ts +1 -1
- package/dist/core/foundation/init-blocks.d.ts.map +1 -1
- package/dist/core/foundation/init-blocks.js +51 -14
- package/dist/core/foundation/init-blocks.js.map +1 -1
- package/dist/core/foundation/init.d.ts +4 -0
- package/dist/core/foundation/init.d.ts.map +1 -1
- package/dist/core/foundation/init.js +7 -0
- package/dist/core/foundation/init.js.map +1 -1
- package/dist/core/foundation/new.d.ts +4 -1
- package/dist/core/foundation/new.d.ts.map +1 -1
- package/dist/core/foundation/new.js +18 -8
- package/dist/core/foundation/new.js.map +1 -1
- package/dist/core/foundation/package-root.d.ts +6 -0
- package/dist/core/foundation/package-root.d.ts.map +1 -1
- package/dist/core/foundation/package-root.js +6 -0
- package/dist/core/foundation/package-root.js.map +1 -1
- package/dist/core/foundation/rules-block.d.ts +11 -0
- package/dist/core/foundation/rules-block.d.ts.map +1 -0
- package/dist/core/foundation/rules-block.js +90 -0
- package/dist/core/foundation/rules-block.js.map +1 -0
- package/dist/core/foundation/traceability-block.d.ts +13 -0
- package/dist/core/foundation/traceability-block.d.ts.map +1 -0
- package/dist/core/foundation/traceability-block.js +124 -0
- package/dist/core/foundation/traceability-block.js.map +1 -0
- package/dist/core/lifecycle/done.d.ts.map +1 -1
- package/dist/core/lifecycle/done.js +2 -4
- package/dist/core/lifecycle/done.js.map +1 -1
- package/dist/core/lifecycle/recertify.d.ts +9 -0
- package/dist/core/lifecycle/recertify.d.ts.map +1 -0
- package/dist/core/lifecycle/recertify.js +27 -0
- package/dist/core/lifecycle/recertify.js.map +1 -0
- package/dist/core/lifecycle/reject.d.ts.map +1 -1
- package/dist/core/lifecycle/reject.js +3 -4
- package/dist/core/lifecycle/reject.js.map +1 -1
- package/dist/core/lifecycle/retry.d.ts.map +1 -1
- package/dist/core/lifecycle/retry.js +6 -20
- package/dist/core/lifecycle/retry.js.map +1 -1
- package/dist/core/lifecycle/verification-record.d.ts +42 -0
- package/dist/core/lifecycle/verification-record.d.ts.map +1 -0
- package/dist/core/lifecycle/verification-record.js +76 -0
- package/dist/core/lifecycle/verification-record.js.map +1 -0
- package/dist/core/report/approval-flags.d.ts +16 -3
- package/dist/core/report/approval-flags.d.ts.map +1 -1
- package/dist/core/report/approval-flags.js +59 -22
- package/dist/core/report/approval-flags.js.map +1 -1
- package/dist/core/report/brief-to-approval.d.ts +7 -0
- package/dist/core/report/brief-to-approval.d.ts.map +1 -0
- package/dist/core/report/brief-to-approval.js +43 -0
- package/dist/core/report/brief-to-approval.js.map +1 -0
- package/dist/core/report/planning-price-gaps.d.ts +10 -0
- package/dist/core/report/planning-price-gaps.d.ts.map +1 -0
- package/dist/core/report/planning-price-gaps.js +37 -0
- package/dist/core/report/planning-price-gaps.js.map +1 -0
- package/dist/core/report/planning-slice-lookup.d.ts.map +1 -1
- package/dist/core/report/planning-slice-lookup.js +3 -9
- package/dist/core/report/planning-slice-lookup.js.map +1 -1
- package/dist/core/report/recent-disclosures.d.ts +18 -0
- package/dist/core/report/recent-disclosures.d.ts.map +1 -0
- package/dist/core/report/recent-disclosures.js +105 -0
- package/dist/core/report/recent-disclosures.js.map +1 -0
- package/dist/core/report/record-disclosures.d.ts +14 -0
- package/dist/core/report/record-disclosures.d.ts.map +1 -0
- package/dist/core/report/record-disclosures.js +30 -0
- package/dist/core/report/record-disclosures.js.map +1 -0
- package/dist/core/report/record-estimates.d.ts +25 -0
- package/dist/core/report/record-estimates.d.ts.map +1 -0
- package/dist/core/report/record-estimates.js +83 -0
- package/dist/core/report/record-estimates.js.map +1 -0
- package/dist/core/report/record-rework.d.ts +19 -0
- package/dist/core/report/record-rework.d.ts.map +1 -0
- package/dist/core/report/record-rework.js +50 -0
- package/dist/core/report/record-rework.js.map +1 -0
- package/dist/core/report/record-verification.d.ts +16 -0
- package/dist/core/report/record-verification.d.ts.map +1 -0
- package/dist/core/report/record-verification.js +33 -0
- package/dist/core/report/record-verification.js.map +1 -0
- package/dist/core/report/report-dependencies.d.ts +29 -0
- package/dist/core/report/report-dependencies.d.ts.map +1 -0
- package/dist/core/report/report-dependencies.js +92 -0
- package/dist/core/report/report-dependencies.js.map +1 -0
- package/dist/core/report/report-events.d.ts +1 -0
- package/dist/core/report/report-events.d.ts.map +1 -1
- package/dist/core/report/report-events.js +8 -26
- package/dist/core/report/report-events.js.map +1 -1
- package/dist/core/report/report-mutation.d.ts +34 -0
- package/dist/core/report/report-mutation.d.ts.map +1 -0
- package/dist/core/report/report-mutation.js +191 -0
- package/dist/core/report/report-mutation.js.map +1 -0
- package/dist/core/report/report-scope.d.ts +21 -0
- package/dist/core/report/report-scope.d.ts.map +1 -0
- package/dist/core/report/report-scope.js +61 -0
- package/dist/core/report/report-scope.js.map +1 -0
- package/dist/core/report/report-traceability.d.ts +29 -0
- package/dist/core/report/report-traceability.d.ts.map +1 -0
- package/dist/core/report/report-traceability.js +94 -0
- package/dist/core/report/report-traceability.js.map +1 -0
- package/dist/core/report/report.d.ts +35 -1
- package/dist/core/report/report.d.ts.map +1 -1
- package/dist/core/report/report.js +130 -111
- package/dist/core/report/report.js.map +1 -1
- package/dist/core/report/result-sections.d.ts +30 -0
- package/dist/core/report/result-sections.d.ts.map +1 -0
- package/dist/core/report/result-sections.js +125 -0
- package/dist/core/report/result-sections.js.map +1 -0
- package/dist/core/report/scope-size.d.ts +7 -0
- package/dist/core/report/scope-size.d.ts.map +1 -0
- package/dist/core/report/scope-size.js +22 -0
- package/dist/core/report/scope-size.js.map +1 -0
- package/dist/core/run/commit-message.d.ts +24 -0
- package/dist/core/run/commit-message.d.ts.map +1 -0
- package/dist/core/run/commit-message.js +76 -0
- package/dist/core/run/commit-message.js.map +1 -0
- package/dist/core/run/dead-commit.d.ts +10 -0
- package/dist/core/run/dead-commit.d.ts.map +1 -0
- package/dist/core/run/dead-commit.js +70 -0
- package/dist/core/run/dead-commit.js.map +1 -0
- package/dist/core/run/focused-tests.d.ts +43 -0
- package/dist/core/run/focused-tests.d.ts.map +1 -0
- package/dist/core/run/focused-tests.js +116 -0
- package/dist/core/run/focused-tests.js.map +1 -0
- package/dist/core/run/manifest-approval.d.ts +7 -0
- package/dist/core/run/manifest-approval.d.ts.map +1 -0
- package/dist/core/run/manifest-approval.js +30 -0
- package/dist/core/run/manifest-approval.js.map +1 -0
- package/dist/core/run/manifest.d.ts +11 -1
- package/dist/core/run/manifest.d.ts.map +1 -1
- package/dist/core/run/manifest.js +52 -11
- package/dist/core/run/manifest.js.map +1 -1
- package/dist/core/run/mutation-report.d.ts +29 -0
- package/dist/core/run/mutation-report.d.ts.map +1 -0
- package/dist/core/run/mutation-report.js +107 -0
- package/dist/core/run/mutation-report.js.map +1 -0
- package/dist/core/run/mutation-run.d.ts +32 -0
- package/dist/core/run/mutation-run.d.ts.map +1 -0
- package/dist/core/run/mutation-run.js +80 -0
- package/dist/core/run/mutation-run.js.map +1 -0
- package/dist/core/run/verification.d.ts +12 -1
- package/dist/core/run/verification.d.ts.map +1 -1
- package/dist/core/run/verification.js +24 -2
- package/dist/core/run/verification.js.map +1 -1
- package/dist/core/spec/approve-worktree-shared.d.ts +33 -0
- package/dist/core/spec/approve-worktree-shared.d.ts.map +1 -0
- package/dist/core/spec/approve-worktree-shared.js +59 -0
- package/dist/core/spec/approve-worktree-shared.js.map +1 -0
- package/dist/core/spec/approve-worktree.d.ts +21 -0
- package/dist/core/spec/approve-worktree.d.ts.map +1 -0
- package/dist/core/spec/approve-worktree.js +153 -0
- package/dist/core/spec/approve-worktree.js.map +1 -0
- package/dist/core/spec/approve.d.ts +20 -10
- package/dist/core/spec/approve.d.ts.map +1 -1
- package/dist/core/spec/approve.js +57 -54
- package/dist/core/spec/approve.js.map +1 -1
- package/dist/core/spec/capability-impact.d.ts +43 -0
- package/dist/core/spec/capability-impact.d.ts.map +1 -0
- package/dist/core/spec/capability-impact.js +85 -0
- package/dist/core/spec/capability-impact.js.map +1 -0
- package/dist/core/spec/decisions-lint.d.ts +18 -0
- package/dist/core/spec/decisions-lint.d.ts.map +1 -0
- package/dist/core/spec/decisions-lint.js +127 -0
- package/dist/core/spec/decisions-lint.js.map +1 -0
- package/dist/core/spec/delta.d.ts +6 -0
- package/dist/core/spec/delta.d.ts.map +1 -1
- package/dist/core/spec/delta.js +73 -5
- package/dist/core/spec/delta.js.map +1 -1
- package/dist/core/spec/digest-decisions.d.ts +27 -0
- package/dist/core/spec/digest-decisions.d.ts.map +1 -0
- package/dist/core/spec/digest-decisions.js +86 -0
- package/dist/core/spec/digest-decisions.js.map +1 -0
- package/dist/core/spec/digest-format.d.ts +4 -0
- package/dist/core/spec/digest-format.d.ts.map +1 -0
- package/dist/core/spec/digest-format.js +44 -0
- package/dist/core/spec/digest-format.js.map +1 -0
- package/dist/core/spec/digest.d.ts +5 -3
- package/dist/core/spec/digest.d.ts.map +1 -1
- package/dist/core/spec/digest.js +14 -33
- package/dist/core/spec/digest.js.map +1 -1
- package/dist/core/spec/human-steps.d.ts +20 -0
- package/dist/core/spec/human-steps.d.ts.map +1 -0
- package/dist/core/spec/human-steps.js +52 -0
- package/dist/core/spec/human-steps.js.map +1 -0
- package/dist/core/spec/impact-lint.d.ts +24 -0
- package/dist/core/spec/impact-lint.d.ts.map +1 -0
- package/dist/core/spec/impact-lint.js +39 -0
- package/dist/core/spec/impact-lint.js.map +1 -0
- package/dist/core/spec/import-graph.d.ts +35 -0
- package/dist/core/spec/import-graph.d.ts.map +1 -0
- package/dist/core/spec/import-graph.js +155 -0
- package/dist/core/spec/import-graph.js.map +1 -0
- package/dist/core/spec/lint-findings.d.ts +44 -0
- package/dist/core/spec/lint-findings.d.ts.map +1 -0
- package/dist/core/spec/lint-findings.js +56 -0
- package/dist/core/spec/lint-findings.js.map +1 -0
- package/dist/core/spec/lint-output.d.ts +53 -0
- package/dist/core/spec/lint-output.d.ts.map +1 -0
- package/dist/core/spec/lint-output.js +87 -0
- package/dist/core/spec/lint-output.js.map +1 -0
- package/dist/core/spec/linter.d.ts +14 -4
- package/dist/core/spec/linter.d.ts.map +1 -1
- package/dist/core/spec/linter.js +271 -111
- package/dist/core/spec/linter.js.map +1 -1
- package/dist/core/spec/merged-spec-check.d.ts +24 -0
- package/dist/core/spec/merged-spec-check.d.ts.map +1 -0
- package/dist/core/spec/merged-spec-check.js +95 -0
- package/dist/core/spec/merged-spec-check.js.map +1 -0
- package/dist/core/spec/openspec-issues.d.ts +58 -0
- package/dist/core/spec/openspec-issues.d.ts.map +1 -0
- package/dist/core/spec/openspec-issues.js +166 -0
- package/dist/core/spec/openspec-issues.js.map +1 -0
- package/dist/core/spec/parser.d.ts +1 -0
- package/dist/core/spec/parser.d.ts.map +1 -1
- package/dist/core/spec/parser.js +16 -6
- package/dist/core/spec/parser.js.map +1 -1
- package/dist/core/spec/scenario-impact.d.ts +47 -0
- package/dist/core/spec/scenario-impact.d.ts.map +1 -0
- package/dist/core/spec/scenario-impact.js +130 -0
- package/dist/core/spec/scenario-impact.js.map +1 -0
- package/dist/core/spec/test-impact.d.ts +28 -0
- package/dist/core/spec/test-impact.d.ts.map +1 -0
- package/dist/core/spec/test-impact.js +119 -0
- package/dist/core/spec/test-impact.js.map +1 -0
- package/dist/core/spec/traceability-links.d.ts +50 -0
- package/dist/core/spec/traceability-links.d.ts.map +1 -0
- package/dist/core/spec/traceability-links.js +120 -0
- package/dist/core/spec/traceability-links.js.map +1 -0
- package/dist/core/spec/traceability-lint.d.ts +29 -0
- package/dist/core/spec/traceability-lint.d.ts.map +1 -0
- package/dist/core/spec/traceability-lint.js +143 -0
- package/dist/core/spec/traceability-lint.js.map +1 -0
- package/dist/core/status/blocked-item.d.ts +8 -0
- package/dist/core/status/blocked-item.d.ts.map +1 -0
- package/dist/core/status/blocked-item.js +45 -0
- package/dist/core/status/blocked-item.js.map +1 -0
- package/dist/core/status/change-locations.d.ts +44 -0
- package/dist/core/status/change-locations.d.ts.map +1 -0
- package/dist/core/status/change-locations.js +138 -0
- package/dist/core/status/change-locations.js.map +1 -0
- package/dist/core/status/dependency-readiness.d.ts +11 -0
- package/dist/core/status/dependency-readiness.d.ts.map +1 -0
- package/dist/core/status/dependency-readiness.js +39 -0
- package/dist/core/status/dependency-readiness.js.map +1 -0
- package/dist/core/status/inbox-projection.d.ts.map +1 -1
- package/dist/core/status/inbox-projection.js +23 -4
- package/dist/core/status/inbox-projection.js.map +1 -1
- package/dist/core/status/inbox-text.d.ts.map +1 -1
- package/dist/core/status/inbox-text.js +34 -3
- package/dist/core/status/inbox-text.js.map +1 -1
- package/dist/core/status/inbox.d.ts +10 -1
- package/dist/core/status/inbox.d.ts.map +1 -1
- package/dist/core/status/inbox.js +19 -1
- package/dist/core/status/inbox.js.map +1 -1
- package/dist/core/status/layout.d.ts +6 -0
- package/dist/core/status/layout.d.ts.map +1 -1
- package/dist/core/status/layout.js +8 -0
- package/dist/core/status/layout.js.map +1 -1
- package/dist/core/status/next-step.d.ts +17 -0
- package/dist/core/status/next-step.d.ts.map +1 -0
- package/dist/core/status/next-step.js +85 -0
- package/dist/core/status/next-step.js.map +1 -0
- package/dist/core/status/pre-spawn-words.d.ts +13 -0
- package/dist/core/status/pre-spawn-words.d.ts.map +1 -0
- package/dist/core/status/pre-spawn-words.js +26 -0
- package/dist/core/status/pre-spawn-words.js.map +1 -0
- package/dist/core/status/queue-parser.d.ts +1 -0
- package/dist/core/status/queue-parser.d.ts.map +1 -1
- package/dist/core/status/queue-parser.js +41 -2
- package/dist/core/status/queue-parser.js.map +1 -1
- package/dist/core/status/queue-planning.d.ts +1 -0
- package/dist/core/status/queue-planning.d.ts.map +1 -1
- package/dist/core/status/queue-planning.js +24 -12
- package/dist/core/status/queue-planning.js.map +1 -1
- package/dist/core/status/queue-report-detail.d.ts.map +1 -1
- package/dist/core/status/queue-report-detail.js +5 -3
- package/dist/core/status/queue-report-detail.js.map +1 -1
- package/dist/core/status/queue-state.d.ts +1 -1
- package/dist/core/status/queue-state.d.ts.map +1 -1
- package/dist/core/status/queue-state.js +27 -41
- package/dist/core/status/queue-state.js.map +1 -1
- package/dist/core/status/show.d.ts +25 -0
- package/dist/core/status/show.d.ts.map +1 -1
- package/dist/core/status/show.js +354 -91
- package/dist/core/status/show.js.map +1 -1
- package/dist/core/status/state.d.ts.map +1 -1
- package/dist/core/status/state.js +1 -23
- package/dist/core/status/state.js.map +1 -1
- package/dist/core/status/status.d.ts +18 -0
- package/dist/core/status/status.d.ts.map +1 -1
- package/dist/core/status/status.js +59 -80
- package/dist/core/status/status.js.map +1 -1
- package/dist/core/status/verification.d.ts +27 -0
- package/dist/core/status/verification.d.ts.map +1 -0
- package/dist/core/status/verification.js +111 -0
- package/dist/core/status/verification.js.map +1 -0
- package/dist/core/trace/function-ranges.d.ts +30 -0
- package/dist/core/trace/function-ranges.d.ts.map +1 -0
- package/dist/core/trace/function-ranges.js +250 -0
- package/dist/core/trace/function-ranges.js.map +1 -0
- package/dist/core/trace/mutation-pick.d.ts +55 -0
- package/dist/core/trace/mutation-pick.d.ts.map +1 -0
- package/dist/core/trace/mutation-pick.js +96 -0
- package/dist/core/trace/mutation-pick.js.map +1 -0
- package/dist/core/trace/scenario-index.d.ts +27 -0
- package/dist/core/trace/scenario-index.d.ts.map +1 -0
- package/dist/core/trace/scenario-index.js +76 -0
- package/dist/core/trace/scenario-index.js.map +1 -0
- package/dist/core/trace/scenario-lookup.d.ts +14 -0
- package/dist/core/trace/scenario-lookup.d.ts.map +1 -0
- package/dist/core/trace/scenario-lookup.js +179 -0
- package/dist/core/trace/scenario-lookup.js.map +1 -0
- package/dist/core/trace/tag-scan.d.ts +44 -0
- package/dist/core/trace/tag-scan.d.ts.map +1 -0
- package/dist/core/trace/tag-scan.js +200 -0
- package/dist/core/trace/tag-scan.js.map +1 -0
- package/dist/core/vcs/doctor-git.d.ts +13 -0
- package/dist/core/vcs/doctor-git.d.ts.map +1 -0
- package/dist/core/vcs/doctor-git.js +114 -0
- package/dist/core/vcs/doctor-git.js.map +1 -0
- package/dist/core/vcs/git-vcs-write.d.ts +47 -0
- package/dist/core/vcs/git-vcs-write.d.ts.map +1 -0
- package/dist/core/vcs/git-vcs-write.js +210 -0
- package/dist/core/vcs/git-vcs-write.js.map +1 -0
- package/dist/core/vcs/git-vcs.d.ts +40 -0
- package/dist/core/vcs/git-vcs.d.ts.map +1 -0
- package/dist/core/vcs/git-vcs.js +170 -0
- package/dist/core/vcs/git-vcs.js.map +1 -0
- package/dist/core/vcs/no-vcs.d.ts +26 -0
- package/dist/core/vcs/no-vcs.d.ts.map +1 -0
- package/dist/core/vcs/no-vcs.js +62 -0
- package/dist/core/vcs/no-vcs.js.map +1 -0
- package/dist/core/vcs/select.d.ts +11 -0
- package/dist/core/vcs/select.d.ts.map +1 -0
- package/dist/core/vcs/select.js +33 -0
- package/dist/core/vcs/select.js.map +1 -0
- package/dist/core/vcs/snapshot.d.ts +34 -0
- package/dist/core/vcs/snapshot.d.ts.map +1 -0
- package/dist/core/vcs/snapshot.js +71 -0
- package/dist/core/vcs/snapshot.js.map +1 -0
- package/dist/core/vcs/vcs.d.ts +55 -0
- package/dist/core/vcs/vcs.d.ts.map +1 -0
- package/dist/core/vcs/vcs.js +2 -0
- package/dist/core/vcs/vcs.js.map +1 -0
- package/dist/core/vcs/worktree.d.ts +10 -0
- package/dist/core/vcs/worktree.d.ts.map +1 -0
- package/dist/core/vcs/worktree.js +25 -0
- package/dist/core/vcs/worktree.js.map +1 -0
- package/dist/core/web/web-data-folders.d.ts.map +1 -1
- package/dist/core/web/web-data-folders.js +18 -33
- package/dist/core/web/web-data-folders.js.map +1 -1
- package/dist/core/web/web-data-lifecycle.d.ts.map +1 -1
- package/dist/core/web/web-data-lifecycle.js +2 -1
- package/dist/core/web/web-data-lifecycle.js.map +1 -1
- package/dist/core/web/web-events.d.ts +8 -6
- package/dist/core/web/web-events.d.ts.map +1 -1
- package/dist/core/web/web-events.js +7 -31
- package/dist/core/web/web-events.js.map +1 -1
- package/dist/core/web/web-server.d.ts.map +1 -1
- package/dist/core/web/web-server.js +3 -0
- package/dist/core/web/web-server.js.map +1 -1
- package/dist/core/web/web-trees.d.ts +27 -0
- package/dist/core/web/web-trees.d.ts.map +1 -0
- package/dist/core/web/web-trees.js +82 -0
- package/dist/core/web/web-trees.js.map +1 -0
- package/dist/harness/claude/claude-exec-args.d.ts +13 -0
- package/dist/harness/claude/claude-exec-args.d.ts.map +1 -0
- package/dist/harness/claude/claude-exec-args.js +61 -0
- package/dist/harness/claude/claude-exec-args.js.map +1 -0
- package/dist/harness/claude/claude-exec.d.ts +12 -0
- package/dist/harness/claude/claude-exec.d.ts.map +1 -0
- package/dist/harness/claude/claude-exec.js +79 -0
- package/dist/harness/claude/claude-exec.js.map +1 -0
- package/dist/harness/claude/claude-stream.d.ts +31 -0
- package/dist/harness/claude/claude-stream.d.ts.map +1 -0
- package/dist/harness/claude/claude-stream.js +150 -0
- package/dist/harness/claude/claude-stream.js.map +1 -0
- package/dist/harness/claude/claude-tools.d.ts +5 -0
- package/dist/harness/claude/claude-tools.d.ts.map +1 -0
- package/dist/harness/claude/claude-tools.js +30 -0
- package/dist/harness/claude/claude-tools.js.map +1 -0
- package/dist/harness/index.d.ts +1 -0
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +3 -0
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/opencode/opencode-session.d.ts +42 -0
- package/dist/harness/opencode/opencode-session.d.ts.map +1 -0
- package/dist/harness/opencode/opencode-session.js +123 -0
- package/dist/harness/opencode/opencode-session.js.map +1 -0
- package/dist/harness/opencode/opencode.d.ts +2 -1
- package/dist/harness/opencode/opencode.d.ts.map +1 -1
- package/dist/harness/opencode/opencode.js +52 -28
- package/dist/harness/opencode/opencode.js.map +1 -1
- package/dist/harness/prompt.js +1 -1
- package/dist/harness/prompt.js.map +1 -1
- package/dist/harness/types.d.ts +112 -1
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/testing/index.d.ts +3 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +2 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/scenario.d.ts +29 -0
- package/dist/testing/scenario.d.ts.map +1 -0
- package/dist/testing/scenario.js +157 -0
- package/dist/testing/scenario.js.map +1 -0
- package/dist/watcher/archiver.d.ts +2 -1
- package/dist/watcher/archiver.d.ts.map +1 -1
- package/dist/watcher/archiver.js +27 -2
- package/dist/watcher/archiver.js.map +1 -1
- package/dist/watcher/auto-recertify.d.ts +27 -0
- package/dist/watcher/auto-recertify.d.ts.map +1 -0
- package/dist/watcher/auto-recertify.js +113 -0
- package/dist/watcher/auto-recertify.js.map +1 -0
- package/dist/watcher/auto-retry.d.ts +1 -1
- package/dist/watcher/auto-retry.d.ts.map +1 -1
- package/dist/watcher/auto-retry.js +3 -11
- package/dist/watcher/auto-retry.js.map +1 -1
- package/dist/watcher/baseline-key.d.ts +17 -0
- package/dist/watcher/baseline-key.d.ts.map +1 -0
- package/dist/watcher/baseline-key.js +31 -0
- package/dist/watcher/baseline-key.js.map +1 -0
- package/dist/watcher/baseline.d.ts +32 -0
- package/dist/watcher/baseline.d.ts.map +1 -0
- package/dist/watcher/baseline.js +166 -0
- package/dist/watcher/baseline.js.map +1 -0
- package/dist/watcher/blocked.d.ts +12 -0
- package/dist/watcher/blocked.d.ts.map +1 -0
- package/dist/watcher/blocked.js +24 -0
- package/dist/watcher/blocked.js.map +1 -0
- package/dist/watcher/dependencies.d.ts +28 -0
- package/dist/watcher/dependencies.d.ts.map +1 -0
- package/dist/watcher/dependencies.js +152 -0
- package/dist/watcher/dependencies.js.map +1 -0
- package/dist/watcher/done-metadata.d.ts +4 -0
- package/dist/watcher/done-metadata.d.ts.map +1 -0
- package/dist/watcher/done-metadata.js +20 -0
- package/dist/watcher/done-metadata.js.map +1 -0
- package/dist/watcher/failure-reason.d.ts +1 -1
- package/dist/watcher/failure-reason.d.ts.map +1 -1
- package/dist/watcher/focused-verify.d.ts +17 -0
- package/dist/watcher/focused-verify.d.ts.map +1 -0
- package/dist/watcher/focused-verify.js +54 -0
- package/dist/watcher/focused-verify.js.map +1 -0
- package/dist/watcher/git-guard.d.ts +24 -0
- package/dist/watcher/git-guard.d.ts.map +1 -0
- package/dist/watcher/git-guard.js +95 -0
- package/dist/watcher/git-guard.js.map +1 -0
- package/dist/watcher/instructions-drift.d.ts +21 -0
- package/dist/watcher/instructions-drift.d.ts.map +1 -0
- package/dist/watcher/instructions-drift.js +115 -0
- package/dist/watcher/instructions-drift.js.map +1 -0
- package/dist/watcher/loop.d.ts.map +1 -1
- package/dist/watcher/loop.js +36 -50
- package/dist/watcher/loop.js.map +1 -1
- package/dist/watcher/measures.d.ts.map +1 -1
- package/dist/watcher/measures.js +22 -39
- package/dist/watcher/measures.js.map +1 -1
- package/dist/watcher/mutation-check.d.ts +42 -0
- package/dist/watcher/mutation-check.d.ts.map +1 -0
- package/dist/watcher/mutation-check.js +147 -0
- package/dist/watcher/mutation-check.js.map +1 -0
- package/dist/watcher/regression.d.ts +10 -5
- package/dist/watcher/regression.d.ts.map +1 -1
- package/dist/watcher/regression.js +29 -22
- package/dist/watcher/regression.js.map +1 -1
- package/dist/watcher/runner.d.ts.map +1 -1
- package/dist/watcher/runner.js +12 -14
- package/dist/watcher/runner.js.map +1 -1
- package/dist/watcher/spawn.d.ts.map +1 -1
- package/dist/watcher/spawn.js +5 -0
- package/dist/watcher/spawn.js.map +1 -1
- package/dist/watcher/task-verify.d.ts +7 -2
- package/dist/watcher/task-verify.d.ts.map +1 -1
- package/dist/watcher/task-verify.js +33 -8
- package/dist/watcher/task-verify.js.map +1 -1
- package/dist/watcher/verify.d.ts +1 -5
- package/dist/watcher/verify.d.ts.map +1 -1
- package/dist/watcher/verify.js +2 -6
- package/dist/watcher/verify.js.map +1 -1
- package/package.json +5 -1
- package/templates/PLANNER.md +35 -9
- package/templates/openspec/config.yaml +1 -1
- package/templates/openspec/schemas/osq/schema.yaml +4 -2
- package/templates/openspec/schemas/osq/templates/proposal.md +9 -2
- package/templates/proposal.md +9 -2
- package/ui/dist/assets/{index-CZYeQ8la.js → index-D39uYbbL.js} +1 -1
- package/ui/dist/index.html +1 -1
package/README.md
CHANGED
|
@@ -22,6 +22,12 @@ Run `osq init --refresh-schema` to pick up a new OpenSpec schema. It overwrites
|
|
|
22
22
|
|
|
23
23
|
## Upgrading
|
|
24
24
|
|
|
25
|
+
To 0.2.2:
|
|
26
|
+
|
|
27
|
+
- The opencode adapter needs opencode 2. `osq doctor` and the watcher's preflight refuse opencode 1.
|
|
28
|
+
- A config file that exists but fails to import or validate now stops every command with `Error: Failed to load <path>: <message>` and exit 1. Earlier releases carried on with the defaults.
|
|
29
|
+
- The managed `AGENTS.md` and `PLANNER.md` blocks changed. Run `osq init` to refresh them; until you do, `osq doctor` reports the drift.
|
|
30
|
+
|
|
25
31
|
Resolver 2 changes the automated done-marker hashes for active changes. On the first watcher cycle after upgrading, a completed task in an active change whose `.run/done/<n>` lacks `scope_resolver: 2` is detected even when its recorded aggregate hash still matches. This is a one-time recertification wave: the watcher runs each affected task's `verify` at detection, writes one idempotent `.run/regressed/<n>.md` scope-regression marker carrying the recorded and current resolver versions, and halts the change. Review each marker and run `osq retry <id> <task>` to recertify that task explicitly; a passing verification refreshes the marker with resolver-2 hashes. Markers inside `openspec/changes/archive/` are not rewritten or audited by this migration.
|
|
26
32
|
|
|
27
33
|
## What it puts in your repo
|
|
@@ -41,7 +47,7 @@ openspec/
|
|
|
41
47
|
specs/ living capability specifications (e.g. cli-foundation/spec.md)
|
|
42
48
|
changes/
|
|
43
49
|
042-order-cancellation/
|
|
44
|
-
proposal.md parent spec: goal, verify, non-goals, contract, human steps, delta
|
|
50
|
+
proposal.md parent spec: goal, verify, non-goals, surface, decisions, contract, human steps, delta
|
|
45
51
|
plan-prompt.md the planning prompt `osq plan` writes; removed at archive
|
|
46
52
|
tasks.md task checklist, ticked by the watcher
|
|
47
53
|
tasks/1.md unit of work: acceptance, verify, scope, entry, tests.modify, verify_starts
|
|
@@ -73,13 +79,14 @@ Smart models author specs and never execute them. Cheap models execute specs and
|
|
|
73
79
|
## Gates and permissions
|
|
74
80
|
|
|
75
81
|
- **Approval gate.** Nothing runs until a human runs `osq approve`. It lints the change, hashes the folder, and writes `.run/approved` plus `.run/manifest.json`.
|
|
76
|
-
- **Approval digest.** Before sealing, `osq approve` prints a short digest: the goal, one line per task with its resolved-scope file count, and the requirements each delta adds, modifies, or removes. It then flags
|
|
82
|
+
- **Approval digest.** Before sealing, `osq approve` prints a short digest: the goal, one line per task with its resolved-scope file count, and the requirements each delta adds, modifies, or removes. It then flags eight things worth a human look: `shared_file` (a path two tasks share), `sensitive_path` (a package manifest, lockfile, CI workflow, osq or OpenSpec config, managed instruction file, or env file in scope), `verify_without_test` (a verify naming no test file or runner), `removed_requirement` (a delta that removes requirements), `unknown_capability` (a delta for a capability with no living spec that either has no `## Purpose` or has a name resembling a living capability, and the label names which; a deliberate new capability instead prints `(new capability)` on its digest heading), `verify_starts_conflict` (a task that declares `green` or `any` while its verify names a missing test its own scope creates), `adr_departure` (a `Departs from ADR <n>:` line in `## Decisions`), and `adr_check_modified` (a task that may change an ADR's check file; see Architecture decisions). Flags never block by default: they print last, as information, and the approval line names them (`Approved <id> with N flags: ...`). Add `--confirm` to stop and ask about them instead.
|
|
77
83
|
- **Verification gate.** The watcher never trusts the agent's claim. It runs each task's `verify` in its own process after the agent exits and writes `.run/done/<n>` only on exit 0; a non-zero exit becomes `.run/dead/<n>.md`.
|
|
78
84
|
- **Change verification after every task.** When the task's `verify` passes, the watcher also runs the proposal's change-level `verify` (`gates.changeVerifyAfterTask`, on by default). A red result kills the task with `change_verify_red`, so every task must leave the whole change green.
|
|
85
|
+
- **Baseline verify.** When `gates.baselineVerify` names a command, the watcher runs it once in the project root before a change's first task spawns, to prove the tree was green before the change started. A non-zero exit kills the first task with `baseline_red` and prints "tree was red before this change started"; no agent spawns and the reason waits for `osq retry`. Under git, when HEAD and every dirty file outside a `.run/` folder are unchanged since the latest green baseline in any active or archived change, the watcher reuses it and records `baseline_ran` with `outcome: reused` instead of running the command; outside git, or with no commit, the command always runs.
|
|
79
86
|
- **Pre-spawn verify check.** Before a task's first attempt, the watcher runs that task's `verify` once and expects it to fail: a verify already green before any agent work means the work is done or the verify does not exercise the task. A task declares its expected start with `verify_starts` — `red` by default, `green` for work like a refactor that should already pass, or `any` when either is fine. A mismatch warns by default and the task continues; `gates.preSpawnVerify: fail` kills the task with `verify_precondition` before the agent spawns, and `off` disables the check. A mismatch shows in the task's `verify_ran` event, `osq show`, and `osq report`. A named path the verify refers to that does not exist yet is recorded as `missingPaths` on that event and does not count as a mismatch for a `red` task. The check adds one extra verify per task, on its first attempt only.
|
|
80
|
-
- **Automatic retry.** When a task dies for a reason a fresh attempt could fix — `verify_red`, `change_verify_red`, `undeclared_test_change`, `verify_path_missing`, `no_result`, `crashed`, or `timeout` — the watcher retries it without asking. Every other reason (`spec_conflict`, `verify_precondition`, `already_running`) waits for you. `gates.autoRetries` caps how many automatic retries a task gets since its approval or its last manual retry; it defaults to 1, `0` turns automatic retries off entirely, and a manual `osq retry` grants one more. Each retry's prompt carries the previous dead marker's body, so the fresh agent sees exactly what failed.
|
|
87
|
+
- **Automatic retry.** When a task dies for a reason a fresh attempt could fix — `verify_red`, `change_verify_red`, `undeclared_test_change`, `verify_path_missing`, `denied_dependency`, `no_result`, `crashed`, or `timeout` — the watcher retries it without asking. Every other reason (`spec_conflict`, `verify_precondition`, `already_running`, `blocked`, `baseline_red`) waits for you. `gates.autoRetries` caps how many automatic retries a task gets since its approval or its last manual retry; it defaults to 1, `0` turns automatic retries off entirely, and a manual `osq retry` grants one more. Each retry's prompt carries the previous dead marker's body, so the fresh agent sees exactly what failed.
|
|
81
88
|
- **Stuck tasks.** Every dead marker records a `fingerprint` over its reason and body, ignoring details a rerun changes: ISO timestamps, durations, PIDs, ANSI codes, and absolute paths under the project root. When a task dies again with the same fingerprint as its most recent retained death, the watcher stops retrying and marks it stuck — `stuck: true` on the active marker, one `stuck` event, one line. The inbox shows the task as stuck and `osq --json` gives its `task-dead` item a `stuck` field carrying the fingerprint; `osq retry <id> <n>` still retries it after you fix the cause.
|
|
82
|
-
- **Scope recertification.** Before each task and again before archiving, the watcher re-hashes the resolved `scope` of every done task.
|
|
89
|
+
- **Scope recertification.** Before each task and again before archiving, the watcher re-hashes the resolved `scope` of every done task. When a later task whose `scope` covers a changed file changed it, the recorded hashes show nothing else did, and the task's `verify` still passes, the watcher recertifies that task by itself. Every other change halts the change until you run `osq retry <id> <n>`.
|
|
83
90
|
- **Archive verification.** Before archiving, the watcher re-runs every task's `verify` and the change-level `verify` against the final tree, halting with `.run/regressed/<n>.md` (or `.run/regressed/change.md`) if any fails.
|
|
84
91
|
- **State from disk.** The only authoritative state is which marker files exist under `.run/`: `running/<n>.pid`, `done/<n>`, `dead/<n>.md`, `regressed/<n>.md`, and `approved`. There is no in-memory state that matters, so the watcher can be killed and restarted at any time.
|
|
85
92
|
- **Executor permissions.** A coding agent may write only `.run/results/<n>.md` and files inside its task's `scope`. It may not edit living capability specs, `tasks.md`, or marker files. The watcher writes markers and checkboxes automatically; a human writes the rest through `osq approve`, `osq retry`, `osq reject`, and `osq done`.
|
|
@@ -101,12 +108,17 @@ features:
|
|
|
101
108
|
## Verify
|
|
102
109
|
## Non-goals
|
|
103
110
|
## Surface
|
|
111
|
+
## Decisions
|
|
104
112
|
## Contract
|
|
105
113
|
## Human steps
|
|
114
|
+
### Before approval
|
|
115
|
+
### After landing
|
|
106
116
|
## Delta
|
|
107
117
|
```
|
|
108
118
|
|
|
109
|
-
The frontmatter `verify` is the change-level command the watcher runs after every task and before archiving. Capability writes are not declared in frontmatter: the set of delta specs under `specs/<capability>/spec.md` is the authoritative declaration of what the change writes.
|
|
119
|
+
The frontmatter `verify` is the change-level command the watcher runs after every task and before archiving. An optional `fixes` list names the changes this one reworks; lint fails on an id that names no active, archived, or rejected change, and `fixes` never affects execution order. Capability writes are not declared in frontmatter: the set of delta specs under `specs/<capability>/spec.md` is the authoritative declaration of what the change writes.
|
|
120
|
+
|
|
121
|
+
`## Human steps` holds what osq cannot do. Steps under `### Before approval` show in the approval digest and on the inbox's approval item. Steps under `### After landing`, or a `check: <command>` in the frontmatter, leave the change **verification pending** once it archives: changes that depend on it wait until you run `osq check <id>` (for a `check` command) and record the outcome with `osq verified <id> --passed` or `--failed`. `osq status`, `osq show`, and the inbox list pending changes with their next command. Write `None` under a heading with no steps.
|
|
110
122
|
|
|
111
123
|
`## Surface` lists the user-facing names the change adds, changes, or removes — commands, flags, config keys, frontmatter fields, document sections, dead reasons, and event types; a change with none of those writes `None`.
|
|
112
124
|
|
|
@@ -146,7 +158,9 @@ skills: []
|
|
|
146
158
|
|
|
147
159
|
Tasks run in order. The agent reads its task, the parent `proposal.md`, the delta specs and capability docs it names, `AGENTS.md`, and a previous result file for that task if there is one. The runner also injects capability-specific constraints and code ownership rules extracted from living capability specs. The delta is applied by the watcher, so the agent never edits living specs under `openspec/specs/`.
|
|
148
160
|
|
|
149
|
-
|
|
161
|
+
Before exiting, the agent writes `.run/results/<n>.md` with these headings, leaving out any that would be empty: `## Changed`, `## Deviated` (for the reviewer), `## Missing context` (for the planner), `## Outside scope` (for the human), `## Blocked`, and `## Next`, ending with a `Touched: <paths>` line. A task that cannot finish within its scope writes what it needs under `## Blocked` and no code; the watcher records it dead with reason `blocked`, never retries it automatically, and the inbox shows the stated need. `osq show` prints each task's disclosures, and the plan prompt quotes those from recent archived changes, bounded by `planning.disclosures.recentChanges` (default 3) and `planning.disclosures.maxCharacters` (default 4000).
|
|
162
|
+
|
|
163
|
+
Lint, run by `osq approve` and `osq lint`. Limits come from `osq.config.ts`; defaults are shown. `osq lint` prints each finding as `<change>: <severity> <file> (<requirement or section>): <message>`, with repository-wide findings in their own group at the end, and `osq lint --json` prints them as JSON.
|
|
150
164
|
|
|
151
165
|
| Check | Result |
|
|
152
166
|
| --- | --- |
|
|
@@ -154,6 +168,7 @@ Lint, run by `osq approve` and `osq lint`. Limits come from `osq.config.ts`; def
|
|
|
154
168
|
| proposal declares `features.writes` | reject |
|
|
155
169
|
| more than one table under `## Contract` | reject |
|
|
156
170
|
| `depends_on` names a missing change | reject |
|
|
171
|
+
| `fixes` names a missing change | reject |
|
|
157
172
|
| task `scope` has more than 8 patterns (`limits.maxScopeFiles`) | reject |
|
|
158
173
|
| task acceptance longer than 7 lines (`limits.maxAcceptanceLines`), or two lines fused into one | reject |
|
|
159
174
|
| task scope names a preexisting test without `tests.modify: true` | reject |
|
|
@@ -162,14 +177,140 @@ Lint, run by `osq approve` and `osq lint`. Limits come from `osq.config.ts`; def
|
|
|
162
177
|
| `verify` names an absent package script | reject |
|
|
163
178
|
| `verify` names no existing path or package script | warn |
|
|
164
179
|
| a delta targets a requirement the living spec lacks, or is written as an instruction | reject |
|
|
180
|
+
| a project with ADRs has no usable `## Decisions` section (`None` with no governing ADR passes) | reject |
|
|
181
|
+
| `## Decisions` omits an accepted ADR that governs a capability the change writes | reject |
|
|
182
|
+
| the AGENTS.md project rules block is stale or exceeds `limits.maxProjectRules` | reject |
|
|
183
|
+
| `## Decisions` names an ADR that does not exist or is not accepted | warn |
|
|
165
184
|
| a file contains a prohibited control character | reject |
|
|
166
185
|
| OpenSpec schema or validator drift | reject |
|
|
167
186
|
| two tasks resolve the same scope file | warn |
|
|
187
|
+
| a task scope reaches a preexisting test no task may modify (`limits.importGraphDepth`) | warn |
|
|
188
|
+
| a scoped file imports code owned by a capability the proposal neither reads nor has a delta for | warn |
|
|
189
|
+
| a scoped file is owned by a capability with no delta in the change | warn |
|
|
190
|
+
| a task `verify` runs only tests that import nothing in the task's scope | warn |
|
|
168
191
|
|
|
169
192
|
`osq init` and `osq new` seed `verify: node -e "process.exit(0)"`. That is a planning sentinel, not trusted coverage: replace it before approval with a command that verifies the completed change's final tree. Checked-in fixtures use a local `node verify.cjs` verifier backed by files in their own execution root, never the sentinel, the network, a TTY, or this repository's full verification suite.
|
|
170
193
|
|
|
171
194
|
The rules lint can't check live in the managed `PLANNER.md` block: titles read "When X, Y"; every task leaves the change green on its own; a file belongs to one task; approve the task list before writing any task in full.
|
|
172
195
|
|
|
196
|
+
### Architecture decisions
|
|
197
|
+
|
|
198
|
+
Architecture decision records live under `paths.decisions` (default `decisions/`). A markdown file there is an ADR when its YAML frontmatter carries `status` (`proposed`, `accepted`, or `superseded`); its number is the leading digits of the file name, its title the first `# ` heading without that number prefix. Only accepted ADRs take effect. An accepted ADR states `applies_to`, either `all` or a list of capability names, and a one-line `rule`; a superseded ADR states `superseded_by`. `limits.maxRuleLength` (default 160) caps a rule's length. A file without frontmatter is ignored and reported.
|
|
199
|
+
|
|
200
|
+
`osq init` writes the rules block for every accepted system-wide ADR into `AGENTS.md` between `<!-- OSQ:RULES:START -->` and `<!-- OSQ:RULES:END -->`: a `## Project rules` heading and one `- <rule> ADR <number>` line per ADR, in number order. `limits.maxProjectRules` (default 10) caps how many lines the block may hold. The `decisions` check in `osq doctor` validates every ADR, fails on a stale or oversized rules block, and warns about ignored files and capability names with no living spec.
|
|
201
|
+
|
|
202
|
+
When the project has any ADR with osq frontmatter, every proposal needs a `## Decisions` section after `## Surface`. Name each accepted ADR that governs a capability the change writes, or write `None` when none does. A departure line begins `Departs from ADR <n>:` and gives the reason. `osq lint` and `osq approve` reject a missing or empty section, reject an unnamed governing ADR, and fail while the AGENTS.md rules block is out of date.
|
|
203
|
+
|
|
204
|
+
An accepted ADR may also name `checks`, the repository-relative test files that enforce it, and `denies`, the package names it forbids. A check path is trimmed, uses forward slashes, and drops a leading `./`; only accepted ADRs' checks and denials take effect. The `decisions` doctor check fails when an accepted ADR names a check file that does not exist. When a task declares `tests.modify: true` and its resolved scope covers an accepted ADR's check file, approval raises one `adr_check_modified` flag labelled `task <n> may modify a check of ADR <number>`, and `osq report` counts it in `approvalFlags.byFlag`.
|
|
205
|
+
|
|
206
|
+
After an agent exits, the watcher compares each scoped `package.json` against the baseline recorded on the attempt's `measures` start event. A new package appends one `dependencies_added` event; if an accepted ADR denies it, the task dies with `denied_dependency`, eligible for one automatic retry, and the marker names each package, file, ADR, and rule. `osq show` prints a `Dependencies added: <name> (<file>), ...` line under such a task, and `osq report` prints a `Dependencies added:` section with one `<change>: <name> (<file>), ...` line per change that added packages.
|
|
207
|
+
|
|
208
|
+
### Traceability
|
|
209
|
+
|
|
210
|
+
Opt a capability in through the `traceability` block in `osq.config.ts`:
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
export default defineConfig({
|
|
214
|
+
traceability: {
|
|
215
|
+
capabilities: ['pricing'], // or 'all'
|
|
216
|
+
mode: 'warn', // or 'require'
|
|
217
|
+
focusedTests: 'node --test --test-reporter=tap {files}', // optional
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
The resolved config always holds `traceability`, defaulting to `{ capabilities: [], mode: 'warn' }`. With no capability opted in, `osq init`, `osq lint`, `osq report`, and both managed blocks are exactly what they were, and a project that never imports the helper sees no change.
|
|
223
|
+
|
|
224
|
+
When at least one capability is opted in, `osq init` writes a `<!-- OSQ:TRACEABILITY:START -->` … `<!-- OSQ:TRACEABILITY:END -->` block directly after the managed block in `AGENTS.md` and `PLANNER.md`. Its scope is `every capability` for `'all'`, otherwise the opted-in names joined by `, `. Removing the opt-in removes the block and restores both files.
|
|
225
|
+
|
|
226
|
+
A test proves a scenario by importing from `@matteeh/osq/testing`:
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
import { scenario } from '@matteeh/osq/testing';
|
|
230
|
+
|
|
231
|
+
scenario('pricing', 'Volume pricing', { covers: quote }, ({ run, then, each }) => {
|
|
232
|
+
then('the subtotal is 1800.00', () => assert.equal(run(100).subtotal, 1800));
|
|
233
|
+
each('the unit price follows this table', (row) => assert.equal(quote(+row.quantity).unit, +row['unit price']));
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
`scenario(capability, name, { covers }, body)` registers one `node:test` test titled `Scenario: <name>`. It fails unless the covered function ran through `run`, every outcome was asserted by a `then` or `each` that completed, and every table row passed. `run` takes the covered function's parameters and returns its result, `then(outcome, check)` asserts one outcome, and `each(outcome, check)` calls the check once per table row, in order, with the row as an object keyed by the header cells. The helper's failure messages are exact: a missing name is `"<text>" is not a THEN of this scenario`; a `then` on a table is `THEN <text>: has a table, so check it with each`; an `each` on a non-table is `THEN <text>: has no table`; a failed check is `THEN <text>: failed` or `THEN <text>: failed at <column> <value>, ...`; a check before the function ran or settled is `THEN <text>: checked before <fn> ran` or `THEN <text>: checked before <fn> settled`; a body that never called `run` is `<fn> never ran`; and a missing assertion is `No assertion for: <text>; <text>`. A lookup failure is reported unchanged.
|
|
238
|
+
|
|
239
|
+
A scenario with more than one case puts a Markdown table directly under its THEN or AND line, with only blank lines between:
|
|
240
|
+
|
|
241
|
+
```
|
|
242
|
+
- **THEN** the unit price follows this table
|
|
243
|
+
|
|
244
|
+
| quantity | unit price |
|
|
245
|
+
| -------- | ---------- |
|
|
246
|
+
| 100 | 9.00 |
|
|
247
|
+
| 500 | 8.00 |
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
The first row names the columns, the dashes row is skipped, and later rows are keyed by the trimmed header cells with trimmed string values. Lint accepts a table under a THEN or AND line in a delta and in a living spec.
|
|
251
|
+
|
|
252
|
+
Lint reads tags only from a `/** ... */` doc comment directly above `export function`/`export async function`, or `export const <name>` bound to an arrow or function expression. A `@scenario <capability>: <scenario name>` line names a scenario the function serves; `@adr <number>` names a decision it follows. A file is a scenario test file when it imports from `@matteeh/osq/testing`, and its `scenario(` calls are read when capability and name are string literals and the third argument is `{ covers: <identifier> }`; anything else is reported as unreadable as `<file>:<line>: <reason>`.
|
|
253
|
+
|
|
254
|
+
A task lists the scenarios its tests prove under `## Scenarios`, one `- <capability>: <scenario name>` bullet each. A listed scenario counts as planned while the task's resolved scope holds a test path, so lint passes before the test exists; once a scoped test names it, only real `scenario(...)` calls count.
|
|
255
|
+
|
|
256
|
+
The watcher sets `OSQ_CHANGE` to the absolute change folder for every verify, so the helper resolves scenarios from the change's delta while it is still active. `osq check` on an archived change runs without it, because its deltas are already in the living spec.
|
|
257
|
+
|
|
258
|
+
For an opted-in capability, `osq lint` reports each scenario an ADDED or MODIFIED requirement holds that no scoped test names and that is not planned (`<capability>: no test names scenario "<name>"`), a `@scenario` tag naming a missing scenario (`<fn>: names a scenario the <capability> spec doesn't have: "<name>"`) or one no test covers (`<fn>: no test for "<name>" covers it`), a bad `@adr` tag (`<fn>: ADR <n> doesn't exist or isn't accepted`, `<fn>: ADR <n> doesn't apply to any capability it serves`), and a duplicate scenario name (`<capability>: two scenarios named "<name>"`). For every capability it also lists the tests naming a scenario a MODIFIED or REMOVED requirement changes and warns `<file> names changed scenario "<name>" but no task scopes it with tests.modify: true`. Every finding is a warning under `mode: 'warn'` and an error under `mode: 'require'`.
|
|
259
|
+
|
|
260
|
+
When a capability is opted in, `osq report` prints a `Traceability:` section with `<capability>: <n> untested scenarios, <m> unclaimed functions` and ` untested: <name>` / ` unclaimed: <file>#<name>` lines, also carried in JSON under `traceability`. `osq show` prints ` Scenarios: <capability>: <name>; ...` under a task whose scoped tests name scenarios.
|
|
261
|
+
|
|
262
|
+
Set the optional `traceability.focusedTests` to a command containing `{files}`, such as the reference `node --test --test-reporter=tap {files}`, to run a task's scenario tests before its full verify. When a task's resolved scope holds scenario test files naming opted-in scenarios, the watcher replaces `{files}` with every scenario test file in the repository that names one of those scenarios, each single-quoted and separated by spaces, and runs it through the verify's environment, `OSQ_CHANGE` included. The outcome is `passed` when the command succeeds, `failed` when the TAP output has a `not ok` line for a collected `Scenario: <name>`, and `problem` when it exits nonzero, times out, or cannot start and isn't `failed`. Only a `failed` outcome ends the attempt: the task dies with `verify_red` and its verify is skipped, so the next attempt receives the focused output; a `problem` or `passed` outcome goes on to the full verify, which alone decides the task. Each run appends one `focused_ran` event carrying the command, files, scenarios, outcome, exit code, duration, timeout state, and output. `osq show` prints ` Focused runs: <outcome> <duration>s, ...` under the task after its `Scenarios:` line, adding ` (attempt ended, verify skipped)` to each `failed` entry.
|
|
263
|
+
|
|
264
|
+
### Mutation checks
|
|
265
|
+
|
|
266
|
+
Set the optional `traceability.mutation` block to the project's mutation command
|
|
267
|
+
and an optional per-task budget in seconds (default `300`):
|
|
268
|
+
|
|
269
|
+
```ts
|
|
270
|
+
export default defineConfig({
|
|
271
|
+
traceability: {
|
|
272
|
+
capabilities: ['pricing'], // or 'all'
|
|
273
|
+
mode: 'warn',
|
|
274
|
+
mutation: {
|
|
275
|
+
command: 'npx stryker run', // or a command using {mutate}, {tests}, {report}
|
|
276
|
+
budgetSeconds: 300, // optional
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
After a task passes, osq picks the covered functions the task changed or newly tested. A covered function is an exported function carrying a `@scenario` tag naming an opted-in capability whose tagged scenario a scenario test file names. A function is picked when its file is in the task's resolved scope and its own range's hash differs from the task's last start `measures` event's `functionHashes` entry (a missing entry counts as different), or when a scenario test file the task changed covers it.
|
|
283
|
+
|
|
284
|
+
Each run gets that function's own range plus the range of every non-exported top-level function in the same file it calls, sorted by start line as `<file>:<start>-<end>`, and the sorted, distinct scenario test files naming its tagged scenarios. The command is run once per pick through the verify's environment, `OSQ_CHANGE` included, and receives:
|
|
285
|
+
|
|
286
|
+
- `{mutate}` and `OSQ_MUTATE`: the ranges, comma-joined for the placeholder and a JSON array for the variable
|
|
287
|
+
- `{tests}` and `OSQ_MUTATION_TESTS`: the tests, single-quoted and space-separated for the placeholder and a JSON array for the variable
|
|
288
|
+
- `{report}` and `OSQ_MUTATION_REPORT`: an absolute path in a fresh temporary folder, single-quoted for the placeholder
|
|
289
|
+
|
|
290
|
+
Each run's timeout is the budget left, and picks left once `budgetSeconds` of total wall time for the task is spent are not run. Each pick appends one `mutation_ran` event to the task's stream with `file`, `function`, `ranges`, `scenarios`, `tests`, `outcome`, `killed`, `survived`, `invalid`, `survivors`, `duration`, and `exitCode`. When a pick can't be measured the event says why: `range_unknown` (unknown ranges), `budget`, `timed_out`, `command_failed`, or `report_invalid`; a failed or timed-out run also carries the command's last 2,000 output characters. The check is observe only: it never fails, retries, or halts a task.
|
|
291
|
+
|
|
292
|
+
`osq show` prints, under a task whose stream holds `mutation_ran` events after its last `measures` start event, ` Mutation: <entry>; <entry>` with one entry per event in stream order. A measured entry is `<file>#<function> <killed> of <killed + survived> killed`, a not-measured one is `<file>#<function> not measured (<reason>)`, and each survivor adds a ` Survived: <file>:<line>:<column> <mutator> -> <replacement>` line. When a capability is opted in, `osq report` prints a `Mutation:` section with ` <capability>: <killed> of <killed + survived> killed (<percent>%), <n> survivors not yet reviewed`, the percent to one decimal, then a ` survived: ...` line per survivor, also carried under `mutation` in JSON. Every listed survivor counts as not yet reviewed.
|
|
293
|
+
|
|
294
|
+
The reference setup uses StrykerJS with its command test runner. Add `@stryker-mutator/core` as a dev dependency of the project, set `traceability.mutation.command` to `npx stryker run`, and add this `stryker.config.mjs`:
|
|
295
|
+
|
|
296
|
+
```js
|
|
297
|
+
const tests = JSON.parse(process.env.OSQ_MUTATION_TESTS ?? '[]')
|
|
298
|
+
.map((file) => `'build/${file.replace(/\.(m|c)?ts$/, (_, k) => `.${k ?? ''}js`)}'`)
|
|
299
|
+
.join(' ');
|
|
300
|
+
export default {
|
|
301
|
+
testRunner: 'command',
|
|
302
|
+
commandRunner: { command: `node --test ${tests}` },
|
|
303
|
+
buildCommand: 'npx tsc',
|
|
304
|
+
mutate: JSON.parse(process.env.OSQ_MUTATE ?? '[]'),
|
|
305
|
+
coverageAnalysis: 'off',
|
|
306
|
+
reporters: ['json'],
|
|
307
|
+
jsonReporter: { fileName: process.env.OSQ_MUTATION_REPORT },
|
|
308
|
+
tempDirName: '.stryker-tmp',
|
|
309
|
+
};
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
The config assumes `tsc` compiles `tests/` to `build/tests/`; follow the project's own layout if it differs. Leave `thresholds.break` unset so survivors never change the command's exit code, and add `.stryker-tmp` to `.gitignore`.
|
|
313
|
+
|
|
173
314
|
## What the watcher guarantees
|
|
174
315
|
|
|
175
316
|
- **Rebuilt from disk**: State is rebuilt from `openspec/` on every change. Kill it and restart it any time.
|
|
@@ -182,17 +323,40 @@ The rules lint can't check live in the managed `PLANNER.md` block: titles read "
|
|
|
182
323
|
- **Deterministic spec merges**: Capability specs are only ever changed by the watcher applying an approved delta merge (ADR 002). Agents never touch `openspec/specs/`.
|
|
183
324
|
- **Synthesized results**: An agent that exits without writing `.run/results/<n>.md` is not lost: if the adapter captured a final text message, the watcher synthesizes a result file (`synthesized: true`) from it and proceeds to verify. Only an exit with neither a result file nor final text is `dead` with `reason: no_result`. Nothing disappears silently.
|
|
184
325
|
|
|
185
|
-
Dead reasons: `verify_red` (with `timed_out: true` if verify exceeded its timeout), `change_verify_red`, `verify_precondition`, `undeclared_test_change`, `verify_path_missing` (a path the task's `verify` names did not exist after the agent exited), `no_result`, `crashed`, `timeout`, `spec_conflict`, and `already_running`. A done task whose scoped files changed afterwards is recorded under `.run/regressed/<n>.md` with `reason: scope_regression`, and a failed archive-time change verify under `.run/regressed/change.md`; either stops the run before the next task spawns. Every dead marker also carries a `fingerprint` of its reason and body, and a marker the watcher stopped retrying carries `stuck: true`.
|
|
326
|
+
Dead reasons: `verify_red` (with `timed_out: true` if verify exceeded its timeout), `change_verify_red`, `verify_precondition`, `baseline_red` (the configured baseline verify failed before the change's first task), `undeclared_test_change`, `verify_path_missing` (a path the task's `verify` names did not exist after the agent exited), `denied_dependency` (a scoped `package.json` gained a package an accepted ADR denies; retried automatically once), `blocked` (the agent wrote `## Blocked` in its result; never retried automatically), `no_result`, `crashed`, `timeout`, `spec_conflict`, and `already_running`. A done task whose scoped files changed afterwards is recorded under `.run/regressed/<n>.md` with `reason: scope_regression`, and a failed archive-time change verify under `.run/regressed/change.md`; either stops the run before the next task spawns. Every dead marker also carries a `fingerprint` of its reason and body, and a marker the watcher stopped retrying carries `stuck: true`.
|
|
327
|
+
|
|
328
|
+
## Version control
|
|
329
|
+
|
|
330
|
+
osq reads git when it is available: `osq doctor` reports it, baseline reuse compares HEAD, and the watcher records `scope_violation` and `vcs_violation` events. Agents never run git. osq makes no git writes unless `vcs.enabled` is true, and in this release that support is **unfinished**. Leave it off.
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
export default defineConfig({
|
|
334
|
+
vcs: {
|
|
335
|
+
enabled: false, // default; no git writes
|
|
336
|
+
author: 'osq <osq@example.com>', // required when enabled
|
|
337
|
+
// defaultBranch: 'main', // approval's base branch when origin has no HEAD; default main
|
|
338
|
+
// worktreeRoot: '~/.osq/worktrees',
|
|
339
|
+
// prepare: 'pnpm install', // run once in each new worktree
|
|
340
|
+
},
|
|
341
|
+
timeouts: {
|
|
342
|
+
gitSeconds: 10, // each git read
|
|
343
|
+
gitCommitSeconds: 120, // each commit
|
|
344
|
+
},
|
|
345
|
+
});
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
With `vcs.enabled`, `osq approve` creates branch `osq/<folder>` and a linked worktree under `vcs.worktreeRoot`, runs `vcs.prepare` there, writes the seal plus `.run/base` and `.run/approver` into the worktree's copy, commits `osq: <id> approved`, and prints `Worktree:` and `Branch:` lines. Your checkout is left untouched, and `osq status` warns when the checkout's copy of the change is edited afterwards. The watcher does not yet run changes in their worktrees, so a change approved this way does not run.
|
|
186
349
|
|
|
187
350
|
## Harnesses
|
|
188
351
|
|
|
189
|
-
`OSQ_HARNESS` picks an adapter. An adapter does two things: spawn an agent for a tier (`coding` or `smart`) and write its harness's config files (`osq setup`). Adapters translate the harness's own event stream into typed events (`started`, `tokens`, `tool`, `text`, `file_changed`, `result_written`, `exited`), and the watcher appends its own
|
|
352
|
+
`OSQ_HARNESS` picks an adapter. An adapter does two things: spawn an agent for a tier (`coding` or `smart`) and write its harness's config files (`osq setup`). Adapters translate the harness's own event stream into typed events (`started`, `tokens`, `tool`, `text`, `file_changed`, `result_written`, `exited`), and the watcher appends its own, among them `measures`, `verify_ran`, `baseline_ran`, `focused_ran`, `mutation_ran`, `dependencies_added`, `done`, `done_manual`, `dead`, `stuck`, `regressed`, `retry`, `recertification`, and `rejected`, to the task's `.run/events/<n>.jsonl`. Change-level events such as `archived`, `check_ran`, and `verification_recorded` go to `.run/events/change.jsonl`. Hooks are optional shims that append to the same file. The loop works without them.
|
|
190
353
|
|
|
191
354
|
Available adapters:
|
|
192
355
|
|
|
193
356
|
- `agy`: Antigravity harness adapter
|
|
357
|
+
- `claude`: Claude Code harness adapter running fresh headless `claude -p` tasks
|
|
194
358
|
- `codex`: Codex CLI harness adapter running tasks via `codex exec` and planning via the Codex TUI
|
|
195
|
-
- `opencode`: OpenCode harness adapter running tasks via `opencode run`
|
|
359
|
+
- `opencode`: OpenCode harness adapter running tasks via `opencode run` (requires opencode 2)
|
|
196
360
|
- `pi`: Pi coding agent harness adapter running fresh one-shot tasks in JSON mode
|
|
197
361
|
- `mock`: In-memory deterministic simulation for tests
|
|
198
362
|
|
|
@@ -207,11 +371,13 @@ export default defineConfig({
|
|
|
207
371
|
bin: 'opencode',
|
|
208
372
|
model: 'deepseek/deepseek-flash',
|
|
209
373
|
agent: 'osq-coder',
|
|
210
|
-
variant: 'thinking', // optional
|
|
374
|
+
variant: 'thinking', // optional; passed as <model>#<variant>
|
|
211
375
|
},
|
|
212
376
|
});
|
|
213
377
|
```
|
|
214
378
|
|
|
379
|
+
The adapter needs opencode 2; `osq doctor` reports a failing `harness-version` check for opencode 1 and a warning above the tested range. Tasks run with `opencode run --standalone` from the project root, and a configured `variant` is appended to the model as `<model>#<variant>`.
|
|
380
|
+
|
|
215
381
|
Running `osq setup` with the `opencode` harness scaffolds `.opencode/agent/osq-coder.md` with restricted permissions (denying `webfetch` and `websearch`) and the managed `AGENTS.md` execution procedure. Note that the `--auto` flag approves any action the agent file does not deny. The agent file must have mode `all` or `primary`; a subagent cannot be selected with --agent and OpenCode silently falls back to an unrestricted default. `webfetch` and `websearch` are denied at the tool level, but `bash` is allowed and unrestricted, so the agent can reach the network through the shell. Network isolation requires a sandbox, which osq does not provide.
|
|
216
382
|
|
|
217
383
|
### Codex CLI
|
|
@@ -306,6 +472,46 @@ As with every harness, scope is a protocol, not confinement: the prompt and the
|
|
|
306
472
|
|
|
307
473
|
Pi cannot plan: the adapter has no interactive session, so `osq plan --session` with Pi selected as the planner stops with the existing "does not support interactive sessions" error, and `planner.agent` is unsupported for Pi and rejected by configuration validation.
|
|
308
474
|
|
|
475
|
+
### Claude Code
|
|
476
|
+
|
|
477
|
+
Select Claude Code as the executor in `osq.config.ts`:
|
|
478
|
+
|
|
479
|
+
```ts
|
|
480
|
+
import { defineConfig } from '@matteeh/osq';
|
|
481
|
+
|
|
482
|
+
export default defineConfig({
|
|
483
|
+
harness: 'claude',
|
|
484
|
+
claude: {
|
|
485
|
+
// All fields are optional; omit any to use Claude Code's native value.
|
|
486
|
+
// bin: '/path/to/claude', // claude.bin -> `claude`
|
|
487
|
+
// model: '<your-model>', // claude.model -> OSQ_MODEL (Claude executor only) -> native
|
|
488
|
+
// sandbox: true, // confine Bash with Claude Code's OS sandbox (needs bubblewrap and socat)
|
|
489
|
+
},
|
|
490
|
+
});
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
Setting `OSQ_HARNESS=claude` in the environment or `.env` also selects Claude Code, but an explicit `harness` in `osq.config.ts` wins over that fallback. Binary precedence is `claude.bin`, then `claude` on `PATH`. Model precedence is `claude.model`, then `OSQ_MODEL` only when Claude Code is the executor, then Claude Code's native default; with no model configured, osq records `default` rather than guessing one. This release requires Claude Code `2.1.278` or newer, the version every flag below was verified on; `osq doctor`'s `harness-version` check and the watcher's preflight both fail under it.
|
|
494
|
+
|
|
495
|
+
Each task is a fresh `claude -p --output-format stream-json --verbose` process in the project root with stdin closed and `--no-session-persistence`, so there is no session to resume.
|
|
496
|
+
|
|
497
|
+
#### Claude Code setup and prerequisites
|
|
498
|
+
|
|
499
|
+
Install the Claude Code CLI and log in as usual: by default osq reuses your Claude Code login. When `ANTHROPIC_API_KEY` is set to a non-empty value, osq adds `--bare` and uses the key instead; `--bare` never reads your login, which is why it is tied to the key. The `started` event records which one ran through `harnessAuth`: `api_key` with a key and `login` otherwise.
|
|
500
|
+
|
|
501
|
+
`osq setup` writes no Claude Code files for execution; it only maintains the shared managed `AGENTS.md` block. Planning with Claude Code uses the tool-native `/osq-plan` command that `osq init` installs, not this adapter.
|
|
502
|
+
|
|
503
|
+
#### Claude Code stripped tool surface
|
|
504
|
+
|
|
505
|
+
Each task loads only six built-in tools: `Bash`, `Read`, `Edit`, `Write`, `Glob`, and `Grep`. osq passes `--tools Bash,Read,Edit,Write,Glob,Grep`, `--strict-mcp-config` with no `--mcp-config`, `--disable-slash-commands`, `--setting-sources ""`, `--no-session-persistence`, and `--settings '{"autoMemoryEnabled":false}'`. That strips MCP servers, skills, plugins, hooks, user, project and local settings, saved sessions, and auto-memory so the agent pays no tokens for harness features a coding task never uses: measured on a one-line prompt, input fell from about 29,500 to about 13,300 tokens per request. No configuration key re-enables any of them.
|
|
506
|
+
|
|
507
|
+
#### Claude Code permissions
|
|
508
|
+
|
|
509
|
+
Executor tasks run with `--permission-mode dontAsk`, so anything not allowed is denied rather than prompting. `Read`, `Glob`, and `Grep` are allowed; `Edit` and `Write` are confined to the project through `Edit(./**)` and `Write(./**)`; `Bash` is allowed but `git` is denied by `Bash(git:*)`, which still denies `git` inside compound commands such as `echo a && git status`.
|
|
510
|
+
|
|
511
|
+
Without `claude.sandbox`, Bash is not confined: a shell command can still write outside the project or reach the network. Set `claude.sandbox: true` to add Claude Code's Bash sandbox with no network. It fails at startup if the sandbox is unavailable instead of running unconfined, and on Linux and WSL2 it needs the OS packages `bubblewrap` and `socat` (`apt install bubblewrap socat`).
|
|
512
|
+
|
|
513
|
+
As with every harness, scope is a protocol, not confinement beyond what the harness itself enforces.
|
|
514
|
+
|
|
309
515
|
## Commands
|
|
310
516
|
|
|
311
517
|
```
|
|
@@ -317,11 +523,13 @@ osq setup write harness config for OSQ_HARNESS
|
|
|
317
523
|
osq new <name> new change folder from template in openspec/changes/
|
|
318
524
|
osq plan [name] create a change, write plan-prompt.md, and hand off to your planning tool
|
|
319
525
|
osq queue print the read-only brief queue from openspec/queue.md
|
|
320
|
-
osq lint [ids...] validate change folders and OpenSpec artifacts against constraints
|
|
526
|
+
osq lint [ids...] validate change folders and OpenSpec artifacts against constraints (--json for JSON)
|
|
321
527
|
osq approve <ids...> lint, print the digest, approve change; write .run/approved and .run/manifest.json
|
|
322
528
|
osq retry <id> <target> retry a dead or regressed task, or a change-level regression
|
|
323
529
|
osq reject <id> move an unapproved or failed change intact into rejected history
|
|
324
530
|
osq done <id> <task> mark a task done manually with required justification (--manual)
|
|
531
|
+
osq check <id> run an archived change's recorded check command
|
|
532
|
+
osq verified <id> record an after-landing outcome (--passed or --failed, optional --note <text>)
|
|
325
533
|
osq watch run the watcher loop
|
|
326
534
|
osq status overview of all changes, tasks, and runtime states
|
|
327
535
|
osq show <id> change details, tasks, results, dead markers, and event timeline (--json for JSON)
|
|
@@ -335,14 +543,19 @@ osq migrate openspec migrate a legacy osq layout to the canonical openspec/
|
|
|
335
543
|
### Approval
|
|
336
544
|
|
|
337
545
|
```sh
|
|
338
|
-
osq approve <id> --confirm
|
|
339
|
-
osq
|
|
546
|
+
osq approve <id> --confirm # show the digest, then ask about any flags before sealing
|
|
547
|
+
osq approve <id> --base-ok # approve even when HEAD is not the default branch
|
|
548
|
+
osq approve <id> --ignore-dirty # approve despite uncommitted changes in task scope
|
|
549
|
+
osq show <id> --json # details, tasks, events, and the digest as JSON
|
|
340
550
|
```
|
|
341
551
|
|
|
342
552
|
By default `osq approve` prints the digest and its flags, then approves without
|
|
343
553
|
asking; flags never block. `--confirm` asks only when flags fire, defaults to no,
|
|
344
554
|
and refuses without a terminal rather than waiting. A declined or refused approval
|
|
345
555
|
writes nothing, and `--confirm` on a flag-free change approves without a prompt.
|
|
556
|
+
With `vcs.enabled`, approve normally requires HEAD on the default branch and a
|
|
557
|
+
clean checkout in task scope; `--base-ok` and `--ignore-dirty` override those
|
|
558
|
+
two refusals.
|
|
346
559
|
`osq show <id> --json` prints the same details as JSON, with the digest and flags
|
|
347
560
|
for an unapproved change and a null digest once it is approved.
|
|
348
561
|
|
|
@@ -502,7 +715,13 @@ Run `osq doctor` to verify repository health:
|
|
|
502
715
|
|
|
503
716
|
- `config`: confirms `osq.config.ts` is valid and well-formed
|
|
504
717
|
- `harness`: checks that the configured harness binary (e.g. `opencode`, `agy`) exists and is executable
|
|
505
|
-
- `harness-version
|
|
718
|
+
- `harness-version`: the installed harness's version. Pi warns outside its tested range; Claude Code fails under `2.1.278`; opencode fails under 2 and warns from 3
|
|
719
|
+
- `harness-auth`: with Pi and `pi.provider` set, fails unless `pi auth check` reports `ready`
|
|
720
|
+
- `harness-containment`: with Claude Code, states what confines the agent's Bash
|
|
721
|
+
- `decisions`: validates every ADR, the AGENTS.md rules block, and each accepted ADR's check files
|
|
722
|
+
- `planning-prices`: warns, only when it applies, that a model with recorded planning tokens has no price in `planning.prices`
|
|
723
|
+
- `git`: git's version, or a warning saying why git is off. `git-env` warns when a variable such as `GIT_DIR` is set
|
|
724
|
+
- `vcs-prepare`, `git-hooks`, `git-signing`: with `vcs.enabled` only, warn about a lockfile without `vcs.prepare`, active commit hooks, and commit signing
|
|
506
725
|
- `managed-blocks`: verifies the `AGENTS.md`, `PLANNER.md`, and `.claude/commands/osq-plan.md` managed sections match the installed osq version (run `osq init` to repair drift)
|
|
507
726
|
- `locks`: checks for orphaned `.run/running/*.pid` locks and processes
|
|
508
727
|
- `archives`: validates integrity of archived change folders
|
|
@@ -515,7 +734,7 @@ To release a new version of `osq`:
|
|
|
515
734
|
|
|
516
735
|
1. Bump `"version"` in `package.json`.
|
|
517
736
|
2. Add a corresponding release section in `CHANGELOG.md`.
|
|
518
|
-
3. Commit the changes: `git commit -am "
|
|
737
|
+
3. Commit the changes: `git commit -am "chore: release <x.y.z>"`.
|
|
519
738
|
4. Create and push the release tag: `git tag v<x.y.z> && git push --tags`.
|
|
520
739
|
5. GitHub Actions (`release.yml`) verifies the build and publishes to npm with provenance via trusted publishing.
|
|
521
740
|
|
package/dist/cli/approve.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
1
2
|
import { type OsqConfig } from '../core/foundation/config.js';
|
|
2
3
|
import type { PlanningSessionReader } from '../core/report/planning-observed.js';
|
|
3
4
|
export interface ApproveCommandOptions {
|
|
@@ -7,10 +8,16 @@ export interface ApproveCommandOptions {
|
|
|
7
8
|
now?: Date | string;
|
|
8
9
|
/** Block on flagged approvals by asking before the seal is written. */
|
|
9
10
|
confirm?: boolean;
|
|
11
|
+
/** Approve from a branch other than the default branch. */
|
|
12
|
+
baseOk?: boolean;
|
|
13
|
+
/** Approve despite uncommitted changes covered by a task's scope. */
|
|
14
|
+
ignoreDirty?: boolean;
|
|
10
15
|
/** Injectable terminal check; defaults to both stdio streams being TTYs. */
|
|
11
16
|
isTerminal?: () => boolean;
|
|
12
17
|
/** Injectable prompt; defaults to a `node:readline/promises` question. */
|
|
13
18
|
ask?: (question: string) => Promise<string | null>;
|
|
14
19
|
}
|
|
15
20
|
export declare function approveCommand(specIds: string[], options?: ApproveCommandOptions): Promise<void>;
|
|
21
|
+
/** Register `osq approve` and its approval-only flags. */
|
|
22
|
+
export declare function registerApproveCommand(program: Command): void;
|
|
16
23
|
//# sourceMappingURL=approve.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approve.d.ts","sourceRoot":"","sources":["../../src/cli/approve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,8BAA8B,CAAC;AAE1E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"approve.d.ts","sourceRoot":"","sources":["../../src/cli/approve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,8BAA8B,CAAC;AAE1E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAgBjF,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,eAAe,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACnD,GAAG,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IACpB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qEAAqE;IACrE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;IAC3B,0EAA0E;IAC1E,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACpD;AA0BD,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,IAAI,CAAC,CAoEf;AAED,0DAA0D;AAC1D,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmB7D"}
|
package/dist/cli/approve.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { loadConfig } from '../core/foundation/config.js';
|
|
2
2
|
import { resolveHarnessExecutable } from '../core/foundation/harness-catalog.js';
|
|
3
|
+
import { formatPriceKey } from '../core/report/planning-price-gaps.js';
|
|
3
4
|
import { approveSpec } from '../core/spec/approve.js';
|
|
4
5
|
import { formatApprovalDigest, formatApprovalFlags, summarizeApprovalFlags, } from '../core/spec/digest.js';
|
|
6
|
+
import { findChange } from '../core/status/change-locations.js';
|
|
7
|
+
import { formatNextStep, readNextStep } from '../core/status/next-step.js';
|
|
5
8
|
import { readClaudePlanningSessions } from '../harness/claude/claude-usage.js';
|
|
6
9
|
import { readCodexPlanningSessions } from '../harness/codex/codex-observe-usage.js';
|
|
7
10
|
import { readOpencodePlanningSessions } from '../harness/opencode/opencode-observe-usage.js';
|
|
@@ -60,22 +63,53 @@ export async function approveCommand(specIds, options = {}) {
|
|
|
60
63
|
planningReaders,
|
|
61
64
|
now: options.now,
|
|
62
65
|
review,
|
|
66
|
+
baseOk: options.baseOk,
|
|
67
|
+
ignoreDirty: options.ignoreDirty,
|
|
63
68
|
});
|
|
64
69
|
const summary = summarizeApprovalFlags(result.digest.flags);
|
|
65
70
|
console.log(`Approved ${result.specId} (${result.folderName})${summary ? ` with ${summary}` : ''}`);
|
|
66
71
|
console.log(` Hash: ${result.hash}`);
|
|
72
|
+
if (result.worktreePath !== undefined && result.branch !== undefined) {
|
|
73
|
+
console.log(` Worktree: ${result.worktreePath}`);
|
|
74
|
+
console.log(` Branch: ${result.branch}`);
|
|
75
|
+
}
|
|
67
76
|
for (const warning of result.warnings) {
|
|
68
77
|
console.warn(` Warning: ${warning}`);
|
|
69
78
|
}
|
|
70
79
|
if (result.planningMatches === 0) {
|
|
71
80
|
console.log(`No planning record found for ${result.specId}.`);
|
|
72
81
|
}
|
|
82
|
+
for (const model of result.missingPrices) {
|
|
83
|
+
console.log(`Planning cost for ${model} stays unreported; add ${formatPriceKey(model)}.`);
|
|
84
|
+
}
|
|
73
85
|
}
|
|
74
86
|
catch (error) {
|
|
75
87
|
const message = error instanceof Error ? error.message : String(error);
|
|
76
88
|
console.error(`Error approving ${specId}:\n ${message}`);
|
|
89
|
+
try {
|
|
90
|
+
const { folderPath } = await findChange(cwd, config, specId);
|
|
91
|
+
const nextStep = await readNextStep(cwd, folderPath, config);
|
|
92
|
+
console.log(`Next: ${formatNextStep(nextStep)}`);
|
|
93
|
+
}
|
|
94
|
+
catch { }
|
|
77
95
|
process.exit(1);
|
|
78
96
|
}
|
|
79
97
|
}
|
|
80
98
|
}
|
|
99
|
+
/** Register `osq approve` and its approval-only flags. */
|
|
100
|
+
export function registerApproveCommand(program) {
|
|
101
|
+
program
|
|
102
|
+
.command('approve <ids...>')
|
|
103
|
+
.description('lint, hash, and approve change folders')
|
|
104
|
+
.option('--confirm', 'ask about approval flags before sealing')
|
|
105
|
+
.option('--base-ok', 'approve even when HEAD is not the default branch')
|
|
106
|
+
.option('--ignore-dirty', 'approve despite uncommitted changes in task scope')
|
|
107
|
+
.action(async (ids, options) => {
|
|
108
|
+
await approveCommand(ids, {
|
|
109
|
+
confirm: options.confirm,
|
|
110
|
+
baseOk: options.baseOk,
|
|
111
|
+
ignoreDirty: options.ignoreDirty,
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
81
115
|
//# sourceMappingURL=approve.js.map
|
package/dist/cli/approve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approve.js","sourceRoot":"","sources":["../../src/cli/approve.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"approve.js","sourceRoot":"","sources":["../../src/cli/approve.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/bin.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
await program.parseAsync(process.argv);
|
|
2
|
+
import { runCli } from './run.js';
|
|
3
|
+
await runCli(process.argv);
|
|
5
4
|
//# sourceMappingURL=bin.js.map
|
package/dist/cli/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import { type OsqConfig } from '../core/foundation/config.js';
|
|
3
|
+
export interface CheckCommandOptions {
|
|
4
|
+
cwd?: string;
|
|
5
|
+
config?: OsqConfig;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Run an archived change's recorded `check` command once, append one
|
|
9
|
+
* `check_ran` event, print the result and next step, and exit zero only when
|
|
10
|
+
* the check passed. A refusal writes nothing.
|
|
11
|
+
*/
|
|
12
|
+
export declare function checkCommand(specId: string, options?: CheckCommandOptions): Promise<void>;
|
|
13
|
+
/** Register `osq check` and `osq verified` on the root program. */
|
|
14
|
+
export declare function registerVerificationCommands(program: Command): void;
|
|
15
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/cli/check.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,8BAA8B,CAAC;AAK1E,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AA4BD;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,mEAAmE;AACnE,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiBnE"}
|