openplanr 1.25.2 → 2.0.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 +78 -0
- package/CONTRIBUTING.md +33 -0
- package/README.md +154 -131
- package/dist/cli/commands/artifact.d.ts.map +1 -1
- package/dist/cli/commands/artifact.js +214 -30
- package/dist/cli/commands/artifact.js.map +1 -1
- package/dist/cli/commands/backlog.d.ts +1 -21
- package/dist/cli/commands/backlog.d.ts.map +1 -1
- package/dist/cli/commands/backlog.js +1 -428
- package/dist/cli/commands/backlog.js.map +1 -1
- package/dist/cli/commands/company.d.ts +3 -0
- package/dist/cli/commands/company.d.ts.map +1 -0
- package/dist/cli/commands/company.js +173 -0
- package/dist/cli/commands/company.js.map +1 -0
- package/dist/cli/commands/config-deterministic.d.ts +3 -0
- package/dist/cli/commands/config-deterministic.d.ts.map +1 -0
- package/dist/cli/commands/config-deterministic.js +88 -0
- package/dist/cli/commands/config-deterministic.js.map +1 -0
- package/dist/cli/commands/dashboard.d.ts +3 -0
- package/dist/cli/commands/dashboard.d.ts.map +1 -0
- package/dist/cli/commands/dashboard.js +36 -0
- package/dist/cli/commands/dashboard.js.map +1 -0
- package/dist/cli/commands/diagram/index.d.ts +3 -0
- package/dist/cli/commands/diagram/index.d.ts.map +1 -0
- package/dist/cli/commands/diagram/index.js +73 -0
- package/dist/cli/commands/diagram/index.js.map +1 -0
- package/dist/cli/commands/diagram/presentation.d.ts +4 -0
- package/dist/cli/commands/diagram/presentation.d.ts.map +1 -0
- package/dist/cli/commands/diagram/presentation.js +38 -0
- package/dist/cli/commands/diagram/presentation.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +1 -11
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/epic.d.ts +1 -9
- package/dist/cli/commands/epic.d.ts.map +1 -1
- package/dist/cli/commands/epic.js +1 -259
- package/dist/cli/commands/epic.js.map +1 -1
- package/dist/cli/commands/feature.d.ts +1 -8
- package/dist/cli/commands/feature.d.ts.map +1 -1
- package/dist/cli/commands/feature.js +1 -220
- package/dist/cli/commands/feature.js.map +1 -1
- package/dist/cli/commands/groups/delivery.d.ts +3 -0
- package/dist/cli/commands/groups/delivery.d.ts.map +1 -0
- package/dist/cli/commands/groups/delivery.js +13 -0
- package/dist/cli/commands/groups/delivery.js.map +1 -0
- package/dist/cli/commands/groups/foundation.d.ts +3 -0
- package/dist/cli/commands/groups/foundation.d.ts.map +1 -0
- package/dist/cli/commands/groups/foundation.js +11 -0
- package/dist/cli/commands/groups/foundation.js.map +1 -0
- package/dist/cli/commands/groups/intelligence.d.ts +3 -0
- package/dist/cli/commands/groups/intelligence.d.ts.map +1 -0
- package/dist/cli/commands/groups/intelligence.js +19 -0
- package/dist/cli/commands/groups/intelligence.js.map +1 -0
- package/dist/cli/commands/groups/operations.d.ts +3 -0
- package/dist/cli/commands/groups/operations.d.ts.map +1 -0
- package/dist/cli/commands/groups/operations.js +17 -0
- package/dist/cli/commands/groups/operations.js.map +1 -0
- package/dist/cli/commands/groups/planning.d.ts +3 -0
- package/dist/cli/commands/groups/planning.d.ts.map +1 -0
- package/dist/cli/commands/groups/planning.js +25 -0
- package/dist/cli/commands/groups/planning.js.map +1 -0
- package/dist/cli/commands/index.d.ts +4 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +14 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/init-deterministic.d.ts +3 -0
- package/dist/cli/commands/init-deterministic.d.ts.map +1 -0
- package/dist/cli/commands/init-deterministic.js +40 -0
- package/dist/cli/commands/init-deterministic.js.map +1 -0
- package/dist/cli/commands/land.d.ts +15 -0
- package/dist/cli/commands/land.d.ts.map +1 -0
- package/dist/cli/commands/land.js +176 -0
- package/dist/cli/commands/land.js.map +1 -0
- package/dist/cli/commands/operate/input.d.ts +54 -0
- package/dist/cli/commands/operate/input.d.ts.map +1 -0
- package/dist/cli/commands/operate/input.js +98 -0
- package/dist/cli/commands/operate/input.js.map +1 -0
- package/dist/cli/commands/operate/registrars/assignments.d.ts +5 -0
- package/dist/cli/commands/operate/registrars/assignments.d.ts.map +1 -0
- package/dist/cli/commands/operate/registrars/assignments.js +167 -0
- package/dist/cli/commands/operate/registrars/assignments.js.map +1 -0
- package/dist/cli/commands/operate/registrars/catalog.d.ts +4 -0
- package/dist/cli/commands/operate/registrars/catalog.d.ts.map +1 -0
- package/dist/cli/commands/operate/registrars/catalog.js +12 -0
- package/dist/cli/commands/operate/registrars/catalog.js.map +1 -0
- package/dist/cli/commands/operate/registrars/contracts.d.ts +41 -0
- package/dist/cli/commands/operate/registrars/contracts.d.ts.map +1 -0
- package/dist/cli/commands/operate/registrars/contracts.js +2 -0
- package/dist/cli/commands/operate/registrars/contracts.js.map +1 -0
- package/dist/cli/commands/operate/registrars/dashboard.d.ts +4 -0
- package/dist/cli/commands/operate/registrars/dashboard.d.ts.map +1 -0
- package/dist/cli/commands/operate/registrars/dashboard.js +26 -0
- package/dist/cli/commands/operate/registrars/dashboard.js.map +1 -0
- package/dist/cli/commands/operate/registrars/dispatch.d.ts +7 -0
- package/dist/cli/commands/operate/registrars/dispatch.d.ts.map +1 -0
- package/dist/cli/commands/operate/registrars/dispatch.js +55 -0
- package/dist/cli/commands/operate/registrars/dispatch.js.map +1 -0
- package/dist/cli/commands/operate/registrars/experience.d.ts +4 -0
- package/dist/cli/commands/operate/registrars/experience.d.ts.map +1 -0
- package/dist/cli/commands/operate/registrars/experience.js +93 -0
- package/dist/cli/commands/operate/registrars/experience.js.map +1 -0
- package/dist/cli/commands/operate/registrars/index.d.ts +5 -0
- package/dist/cli/commands/operate/registrars/index.d.ts.map +1 -0
- package/dist/cli/commands/operate/registrars/index.js +28 -0
- package/dist/cli/commands/operate/registrars/index.js.map +1 -0
- package/dist/cli/commands/operate/registrars/lifecycle.d.ts +4 -0
- package/dist/cli/commands/operate/registrars/lifecycle.d.ts.map +1 -0
- package/dist/cli/commands/operate/registrars/lifecycle.js +46 -0
- package/dist/cli/commands/operate/registrars/lifecycle.js.map +1 -0
- package/dist/cli/commands/operate/registrars/measurement.d.ts +4 -0
- package/dist/cli/commands/operate/registrars/measurement.d.ts.map +1 -0
- package/dist/cli/commands/operate/registrars/measurement.js +122 -0
- package/dist/cli/commands/operate/registrars/measurement.js.map +1 -0
- package/dist/cli/commands/operate/registrars/note-validation.d.ts +6 -0
- package/dist/cli/commands/operate/registrars/note-validation.d.ts.map +1 -0
- package/dist/cli/commands/operate/registrars/note-validation.js +103 -0
- package/dist/cli/commands/operate/registrars/note-validation.js.map +1 -0
- package/dist/cli/commands/operate/registrars/planning.d.ts +4 -0
- package/dist/cli/commands/operate/registrars/planning.d.ts.map +1 -0
- package/dist/cli/commands/operate/registrars/planning.js +41 -0
- package/dist/cli/commands/operate/registrars/planning.js.map +1 -0
- package/dist/cli/commands/operate/registrars/recovery.d.ts +4 -0
- package/dist/cli/commands/operate/registrars/recovery.d.ts.map +1 -0
- package/dist/cli/commands/operate/registrars/recovery.js +65 -0
- package/dist/cli/commands/operate/registrars/recovery.js.map +1 -0
- package/dist/cli/commands/operate/registrars/reviews.d.ts +4 -0
- package/dist/cli/commands/operate/registrars/reviews.d.ts.map +1 -0
- package/dist/cli/commands/operate/registrars/reviews.js +83 -0
- package/dist/cli/commands/operate/registrars/reviews.js.map +1 -0
- package/dist/cli/commands/operate/registration.d.ts +4 -0
- package/dist/cli/commands/operate/registration.d.ts.map +1 -0
- package/dist/cli/commands/operate/registration.js +3 -0
- package/dist/cli/commands/operate/registration.js.map +1 -0
- package/dist/cli/commands/operate/render.d.ts +19 -0
- package/dist/cli/commands/operate/render.d.ts.map +1 -0
- package/dist/cli/commands/operate/render.js +201 -0
- package/dist/cli/commands/operate/render.js.map +1 -0
- package/dist/cli/commands/operate.d.ts +58 -13
- package/dist/cli/commands/operate.d.ts.map +1 -1
- package/dist/cli/commands/operate.js +169 -984
- package/dist/cli/commands/operate.js.map +1 -1
- package/dist/cli/commands/planning-artifacts.d.ts +10 -0
- package/dist/cli/commands/planning-artifacts.d.ts.map +1 -0
- package/dist/cli/commands/planning-artifacts.js +350 -0
- package/dist/cli/commands/planning-artifacts.js.map +1 -0
- package/dist/cli/commands/quick/interaction.d.ts +8 -0
- package/dist/cli/commands/quick/interaction.d.ts.map +1 -0
- package/dist/cli/commands/quick/interaction.js +8 -0
- package/dist/cli/commands/quick/interaction.js.map +1 -0
- package/dist/cli/commands/quick/project.d.ts +8 -0
- package/dist/cli/commands/quick/project.d.ts.map +1 -0
- package/dist/cli/commands/quick/project.js +8 -0
- package/dist/cli/commands/quick/project.js.map +1 -0
- package/dist/cli/commands/quick.d.ts +1 -29
- package/dist/cli/commands/quick.d.ts.map +1 -1
- package/dist/cli/commands/quick.js +1 -337
- package/dist/cli/commands/quick.js.map +1 -1
- package/dist/cli/commands/rules.js +1 -1
- package/dist/cli/commands/rules.js.map +1 -1
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +40 -18
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/spec.d.ts +6 -4
- package/dist/cli/commands/spec.d.ts.map +1 -1
- package/dist/cli/commands/spec.js +166 -174
- package/dist/cli/commands/spec.js.map +1 -1
- package/dist/cli/commands/sprint.d.ts +1 -8
- package/dist/cli/commands/sprint.d.ts.map +1 -1
- package/dist/cli/commands/sprint.js +1 -522
- package/dist/cli/commands/sprint.js.map +1 -1
- package/dist/cli/commands/story/interaction.d.ts +7 -0
- package/dist/cli/commands/story/interaction.d.ts.map +1 -0
- package/dist/cli/commands/story/interaction.js +7 -0
- package/dist/cli/commands/story/interaction.js.map +1 -0
- package/dist/cli/commands/story/project.d.ts +10 -0
- package/dist/cli/commands/story/project.d.ts.map +1 -0
- package/dist/cli/commands/story/project.js +10 -0
- package/dist/cli/commands/story/project.js.map +1 -0
- package/dist/cli/commands/story.d.ts +1 -8
- package/dist/cli/commands/story.d.ts.map +1 -1
- package/dist/cli/commands/story.js +1 -358
- package/dist/cli/commands/story.js.map +1 -1
- package/dist/cli/commands/task.d.ts +1 -9
- package/dist/cli/commands/task.d.ts.map +1 -1
- package/dist/cli/commands/task.js +1 -351
- package/dist/cli/commands/task.js.map +1 -1
- package/dist/cli/error-boundary.d.ts +29 -0
- package/dist/cli/error-boundary.d.ts.map +1 -0
- package/dist/cli/error-boundary.js +103 -0
- package/dist/cli/error-boundary.js.map +1 -0
- package/dist/cli/helpers/bulk-checkbox-update.d.ts +1 -1
- package/dist/cli/helpers/bulk-checkbox-update.js +1 -1
- package/dist/cli/index.js +38 -113
- package/dist/cli/index.js.map +1 -1
- package/dist/dashboard/.vite/manifest.json +68 -0
- package/dist/dashboard/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dist/dashboard/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dist/dashboard/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dist/dashboard/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dist/dashboard/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
- package/dist/dashboard/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
- package/dist/dashboard/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
- package/dist/dashboard/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/dashboard/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
- package/dist/dashboard/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
- package/dist/dashboard/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dist/dashboard/assets/index-Bk8DyO_2.css +1 -0
- package/dist/dashboard/assets/index-zeygL5iu.js +557 -0
- package/dist/dashboard/assets/index-zeygL5iu.js.map +1 -0
- package/dist/dashboard/dashboard-manifest.json +84 -0
- package/dist/dashboard/index.html +13 -0
- package/dist/generators/base-generator.d.ts +2 -0
- package/dist/generators/base-generator.d.ts.map +1 -1
- package/dist/generators/base-generator.js +8 -0
- package/dist/generators/base-generator.js.map +1 -1
- package/dist/generators/claude-generator.d.ts.map +1 -1
- package/dist/generators/claude-generator.js +12 -14
- package/dist/generators/claude-generator.js.map +1 -1
- package/dist/generators/codex-generator.d.ts.map +1 -1
- package/dist/generators/codex-generator.js +7 -7
- package/dist/generators/codex-generator.js.map +1 -1
- package/dist/generators/cursor-generator.d.ts.map +1 -1
- package/dist/generators/cursor-generator.js +11 -30
- package/dist/generators/cursor-generator.js.map +1 -1
- package/dist/models/schema.d.ts +0 -23
- package/dist/models/schema.d.ts.map +1 -1
- package/dist/models/schema.js +0 -7
- package/dist/models/schema.js.map +1 -1
- package/dist/models/types.d.ts +3 -14
- package/dist/models/types.d.ts.map +1 -1
- package/dist/services/artifact-pipeline-service.d.ts +99 -1
- package/dist/services/artifact-pipeline-service.d.ts.map +1 -1
- package/dist/services/artifact-pipeline-service.js +681 -4
- package/dist/services/artifact-pipeline-service.js.map +1 -1
- package/dist/services/canonical-json.d.ts +3 -0
- package/dist/services/canonical-json.d.ts.map +1 -0
- package/dist/services/canonical-json.js +71 -0
- package/dist/services/canonical-json.js.map +1 -0
- package/dist/services/claude-plugin-service.d.ts +6 -1
- package/dist/services/claude-plugin-service.d.ts.map +1 -1
- package/dist/services/claude-plugin-service.js +184 -12
- package/dist/services/claude-plugin-service.js.map +1 -1
- package/dist/services/codex-plugin-service.d.ts +30 -0
- package/dist/services/codex-plugin-service.d.ts.map +1 -0
- package/dist/services/codex-plugin-service.js +195 -0
- package/dist/services/codex-plugin-service.js.map +1 -0
- package/dist/services/company-auth-service.d.ts +70 -0
- package/dist/services/company-auth-service.d.ts.map +1 -0
- package/dist/services/company-auth-service.js +720 -0
- package/dist/services/company-auth-service.js.map +1 -0
- package/dist/services/company-auth-store.d.ts +22 -0
- package/dist/services/company-auth-store.d.ts.map +1 -0
- package/dist/services/company-auth-store.js +158 -0
- package/dist/services/company-auth-store.js.map +1 -0
- package/dist/services/company-common.d.ts +9 -0
- package/dist/services/company-common.d.ts.map +1 -0
- package/dist/services/company-common.js +35 -0
- package/dist/services/company-common.js.map +1 -0
- package/dist/services/company-sync-service.d.ts +214 -0
- package/dist/services/company-sync-service.d.ts.map +1 -0
- package/dist/services/company-sync-service.js +1299 -0
- package/dist/services/company-sync-service.js.map +1 -0
- package/dist/services/connectors/adapters/business-metrics.d.ts +5 -0
- package/dist/services/connectors/adapters/business-metrics.d.ts.map +1 -0
- package/dist/services/connectors/adapters/business-metrics.js +41 -0
- package/dist/services/connectors/adapters/business-metrics.js.map +1 -0
- package/dist/services/connectors/adapters/deployment-health.d.ts +18 -0
- package/dist/services/connectors/adapters/deployment-health.d.ts.map +1 -0
- package/dist/services/connectors/adapters/deployment-health.js +67 -0
- package/dist/services/connectors/adapters/deployment-health.js.map +1 -0
- package/dist/services/connectors/adapters/github.d.ts +5 -0
- package/dist/services/connectors/adapters/github.d.ts.map +1 -0
- package/dist/services/connectors/adapters/github.js +31 -0
- package/dist/services/connectors/adapters/github.js.map +1 -0
- package/dist/services/connectors/adapters/linear-jira.d.ts +5 -0
- package/dist/services/connectors/adapters/linear-jira.d.ts.map +1 -0
- package/dist/services/connectors/adapters/linear-jira.js +26 -0
- package/dist/services/connectors/adapters/linear-jira.js.map +1 -0
- package/dist/services/connectors/adapters/posthog.d.ts +5 -0
- package/dist/services/connectors/adapters/posthog.d.ts.map +1 -0
- package/dist/services/connectors/adapters/posthog.js +31 -0
- package/dist/services/connectors/adapters/posthog.js.map +1 -0
- package/dist/services/connectors/adapters/sentry.d.ts +5 -0
- package/dist/services/connectors/adapters/sentry.d.ts.map +1 -0
- package/dist/services/connectors/adapters/sentry.js +31 -0
- package/dist/services/connectors/adapters/sentry.js.map +1 -0
- package/dist/services/connectors/checkpoint-custody.d.ts +45 -0
- package/dist/services/connectors/checkpoint-custody.d.ts.map +1 -0
- package/dist/services/connectors/checkpoint-custody.js +496 -0
- package/dist/services/connectors/checkpoint-custody.js.map +1 -0
- package/dist/services/connectors/connector-registry.d.ts +144 -0
- package/dist/services/connectors/connector-registry.d.ts.map +1 -0
- package/dist/services/connectors/connector-registry.js +423 -0
- package/dist/services/connectors/connector-registry.js.map +1 -0
- package/dist/services/connectors/connector-runtime.d.ts +200 -0
- package/dist/services/connectors/connector-runtime.d.ts.map +1 -0
- package/dist/services/connectors/connector-runtime.js +1297 -0
- package/dist/services/connectors/connector-runtime.js.map +1 -0
- package/dist/services/connectors/credential-custody.d.ts +96 -0
- package/dist/services/connectors/credential-custody.d.ts.map +1 -0
- package/dist/services/connectors/credential-custody.js +390 -0
- package/dist/services/connectors/credential-custody.js.map +1 -0
- package/dist/services/credential-backends.d.ts +11 -1
- package/dist/services/credential-backends.d.ts.map +1 -1
- package/dist/services/credential-backends.js +104 -21
- package/dist/services/credential-backends.js.map +1 -1
- package/dist/services/credential-write-lock.d.ts +8 -0
- package/dist/services/credential-write-lock.d.ts.map +1 -0
- package/dist/services/credential-write-lock.js +104 -0
- package/dist/services/credential-write-lock.js.map +1 -0
- package/dist/services/credentials-service.d.ts +8 -2
- package/dist/services/credentials-service.d.ts.map +1 -1
- package/dist/services/credentials-service.js +66 -21
- package/dist/services/credentials-service.js.map +1 -1
- package/dist/services/deprecation-notices.d.ts +2 -2
- package/dist/services/deprecation-notices.d.ts.map +1 -1
- package/dist/services/deprecation-notices.js +2 -2
- package/dist/services/deprecation-notices.js.map +1 -1
- package/dist/services/design-artifact-service.d.ts +37 -0
- package/dist/services/design-artifact-service.d.ts.map +1 -0
- package/dist/services/design-artifact-service.js +94 -0
- package/dist/services/design-artifact-service.js.map +1 -0
- package/dist/services/diagram-artifact-service.d.ts +12 -0
- package/dist/services/diagram-artifact-service.d.ts.map +1 -0
- package/dist/services/diagram-artifact-service.js +41 -0
- package/dist/services/diagram-artifact-service.js.map +1 -0
- package/dist/services/diagram-pipeline-service.d.ts +125 -0
- package/dist/services/diagram-pipeline-service.d.ts.map +1 -0
- package/dist/services/diagram-pipeline-service.js +329 -0
- package/dist/services/diagram-pipeline-service.js.map +1 -0
- package/dist/services/gherkin-service.d.ts +3 -0
- package/dist/services/gherkin-service.d.ts.map +1 -0
- package/dist/services/gherkin-service.js +9 -0
- package/dist/services/gherkin-service.js.map +1 -0
- package/dist/services/graph-service.d.ts.map +1 -1
- package/dist/services/graph-service.js +6 -4
- package/dist/services/graph-service.js.map +1 -1
- package/dist/services/landing/landing-service.d.ts +42 -0
- package/dist/services/landing/landing-service.d.ts.map +1 -0
- package/dist/services/landing/landing-service.js +197 -0
- package/dist/services/landing/landing-service.js.map +1 -0
- package/dist/services/landing/operation-registry.d.ts +56 -0
- package/dist/services/landing/operation-registry.d.ts.map +1 -0
- package/dist/services/landing/operation-registry.js +165 -0
- package/dist/services/landing/operation-registry.js.map +1 -0
- package/dist/services/landing/receipt-custody.d.ts +48 -0
- package/dist/services/landing/receipt-custody.d.ts.map +1 -0
- package/dist/services/landing/receipt-custody.js +375 -0
- package/dist/services/landing/receipt-custody.js.map +1 -0
- package/dist/services/linear/constants.d.ts.map +1 -1
- package/dist/services/linear/constants.js +2 -6
- package/dist/services/linear/constants.js.map +1 -1
- package/dist/services/linear/task-status-aggregation.d.ts +1 -1
- package/dist/services/linear/task-status-aggregation.js +1 -1
- package/dist/services/linear-pull-service.d.ts.map +1 -1
- package/dist/services/linear-pull-service.js +7 -30
- package/dist/services/linear-pull-service.js.map +1 -1
- package/dist/services/linear-push-service.d.ts.map +1 -1
- package/dist/services/linear-push-service.js +4 -5
- package/dist/services/linear-push-service.js.map +1 -1
- package/dist/services/migration-registry.d.ts +0 -19
- package/dist/services/migration-registry.d.ts.map +1 -1
- package/dist/services/migration-registry.js +18 -32
- package/dist/services/migration-registry.js.map +1 -1
- package/dist/services/operate/assignment-lifecycle-service.d.ts +135 -0
- package/dist/services/operate/assignment-lifecycle-service.d.ts.map +1 -0
- package/dist/services/operate/assignment-lifecycle-service.js +113 -0
- package/dist/services/operate/assignment-lifecycle-service.js.map +1 -0
- package/dist/services/operate/assignment-packet-service.d.ts +79 -0
- package/dist/services/operate/assignment-packet-service.d.ts.map +1 -0
- package/dist/services/operate/assignment-packet-service.js +1030 -0
- package/dist/services/operate/assignment-packet-service.js.map +1 -0
- package/dist/services/operate/client/governance.d.ts +4 -0
- package/dist/services/operate/client/governance.d.ts.map +1 -0
- package/dist/services/operate/client/governance.js +3 -0
- package/dist/services/operate/client/governance.js.map +1 -0
- package/dist/services/operate/client/lifecycle.d.ts +18 -0
- package/dist/services/operate/client/lifecycle.d.ts.map +1 -0
- package/dist/services/operate/client/lifecycle.js +15 -0
- package/dist/services/operate/client/lifecycle.js.map +1 -0
- package/dist/services/operate/client/runtime.d.ts +13 -0
- package/dist/services/operate/client/runtime.d.ts.map +1 -0
- package/dist/services/operate/client/runtime.js +11 -0
- package/dist/services/operate/client/runtime.js.map +1 -0
- package/dist/services/operate/client-error.d.ts +9 -0
- package/dist/services/operate/client-error.d.ts.map +1 -0
- package/dist/services/operate/client-error.js +14 -0
- package/dist/services/operate/client-error.js.map +1 -0
- package/dist/services/operate/client.d.ts +415 -0
- package/dist/services/operate/client.d.ts.map +1 -0
- package/dist/services/operate/client.js +2432 -0
- package/dist/services/operate/client.js.map +1 -0
- package/dist/services/operate/command-gateway.d.ts +152 -0
- package/dist/services/operate/command-gateway.d.ts.map +1 -0
- package/dist/services/operate/command-gateway.js +883 -0
- package/dist/services/operate/command-gateway.js.map +1 -0
- package/dist/services/operate/composition.d.ts +421 -0
- package/dist/services/operate/composition.d.ts.map +1 -0
- package/dist/services/operate/composition.js +394 -0
- package/dist/services/operate/composition.js.map +1 -0
- package/dist/services/operate/cycle-lifecycle-service.d.ts +35 -0
- package/dist/services/operate/cycle-lifecycle-service.d.ts.map +1 -0
- package/dist/services/operate/cycle-lifecycle-service.js +427 -0
- package/dist/services/operate/cycle-lifecycle-service.js.map +1 -0
- package/dist/services/operate/delivery-evidence.d.ts +34 -0
- package/dist/services/operate/delivery-evidence.d.ts.map +1 -0
- package/dist/services/operate/delivery-evidence.js +666 -0
- package/dist/services/operate/delivery-evidence.js.map +1 -0
- package/dist/services/operate/domain-catalog-service.d.ts +24 -0
- package/dist/services/operate/domain-catalog-service.d.ts.map +1 -0
- package/dist/services/operate/domain-catalog-service.js +99 -0
- package/dist/services/operate/domain-catalog-service.js.map +1 -0
- package/dist/services/operate/experience-read-service.d.ts +64 -0
- package/dist/services/operate/experience-read-service.d.ts.map +1 -0
- package/dist/services/operate/experience-read-service.js +109 -0
- package/dist/services/operate/experience-read-service.js.map +1 -0
- package/dist/services/operate/governed-action-service.d.ts +80 -0
- package/dist/services/operate/governed-action-service.d.ts.map +1 -0
- package/dist/services/operate/governed-action-service.js +497 -0
- package/dist/services/operate/governed-action-service.js.map +1 -0
- package/dist/services/operate/identity-contract.d.ts +3 -0
- package/dist/services/operate/identity-contract.d.ts.map +1 -0
- package/dist/services/operate/identity-contract.js +6 -0
- package/dist/services/operate/identity-contract.js.map +1 -0
- package/dist/services/operate/measurement-schedule-service.d.ts +81 -0
- package/dist/services/operate/measurement-schedule-service.d.ts.map +1 -0
- package/dist/services/operate/measurement-schedule-service.js +461 -0
- package/dist/services/operate/measurement-schedule-service.js.map +1 -0
- package/dist/services/operate/path-custody.d.ts +16 -0
- package/dist/services/operate/path-custody.d.ts.map +1 -0
- package/dist/services/operate/path-custody.js +120 -0
- package/dist/services/operate/path-custody.js.map +1 -0
- package/dist/services/operate/pinned-legacy-replay-runner.d.ts +9 -0
- package/dist/services/operate/pinned-legacy-replay-runner.d.ts.map +1 -0
- package/dist/services/operate/pinned-legacy-replay-runner.js +441 -0
- package/dist/services/operate/pinned-legacy-replay-runner.js.map +1 -0
- package/dist/services/operate/planning-bridge.d.ts +28 -0
- package/dist/services/operate/planning-bridge.d.ts.map +1 -0
- package/dist/services/operate/planning-bridge.js +341 -0
- package/dist/services/operate/planning-bridge.js.map +1 -0
- package/dist/services/operate/planning-handoff-gateway.d.ts +47 -0
- package/dist/services/operate/planning-handoff-gateway.d.ts.map +1 -0
- package/dist/services/operate/planning-handoff-gateway.js +169 -0
- package/dist/services/operate/planning-handoff-gateway.js.map +1 -0
- package/dist/services/operate/planning-handoff-service.d.ts +38 -0
- package/dist/services/operate/planning-handoff-service.d.ts.map +1 -0
- package/dist/services/operate/planning-handoff-service.js +304 -0
- package/dist/services/operate/planning-handoff-service.js.map +1 -0
- package/dist/services/operate/project-transaction-lock.d.ts +6 -0
- package/dist/services/operate/project-transaction-lock.d.ts.map +1 -0
- package/dist/services/operate/project-transaction-lock.js +146 -0
- package/dist/services/operate/project-transaction-lock.js.map +1 -0
- package/dist/services/operate/recovery-service.d.ts +16 -0
- package/dist/services/operate/recovery-service.d.ts.map +1 -0
- package/dist/services/operate/recovery-service.js +59 -0
- package/dist/services/operate/recovery-service.js.map +1 -0
- package/dist/services/operate/replay-safe-retry-service.d.ts +21 -0
- package/dist/services/operate/replay-safe-retry-service.d.ts.map +1 -0
- package/dist/services/operate/replay-safe-retry-service.js +66 -0
- package/dist/services/operate/replay-safe-retry-service.js.map +1 -0
- package/dist/services/operate/repository-read-service.d.ts +13 -0
- package/dist/services/operate/repository-read-service.d.ts.map +1 -0
- package/dist/services/operate/repository-read-service.js +153 -0
- package/dist/services/operate/repository-read-service.js.map +1 -0
- package/dist/services/operate/review-lifecycle-service.d.ts +50 -0
- package/dist/services/operate/review-lifecycle-service.d.ts.map +1 -0
- package/dist/services/operate/review-lifecycle-service.js +63 -0
- package/dist/services/operate/review-lifecycle-service.js.map +1 -0
- package/dist/services/operate/review-read-gateway.d.ts +21 -0
- package/dist/services/operate/review-read-gateway.d.ts.map +1 -0
- package/dist/services/operate/review-read-gateway.js +119 -0
- package/dist/services/operate/review-read-gateway.js.map +1 -0
- package/dist/services/operate/screened-evidence-service.d.ts +24 -0
- package/dist/services/operate/screened-evidence-service.d.ts.map +1 -0
- package/dist/services/operate/screened-evidence-service.js +186 -0
- package/dist/services/operate/screened-evidence-service.js.map +1 -0
- package/dist/services/operate/search-hit-contract.d.ts +11 -0
- package/dist/services/operate/search-hit-contract.d.ts.map +1 -0
- package/dist/services/operate/search-hit-contract.js +29 -0
- package/dist/services/operate/search-hit-contract.js.map +1 -0
- package/dist/services/operate/session-capability.d.ts +61 -0
- package/dist/services/operate/session-capability.d.ts.map +1 -0
- package/dist/services/operate/session-capability.js +124 -0
- package/dist/services/operate/session-capability.js.map +1 -0
- package/dist/services/operate/spec-operating-origin-service.d.ts +60 -0
- package/dist/services/operate/spec-operating-origin-service.d.ts.map +1 -0
- package/dist/services/operate/spec-operating-origin-service.js +401 -0
- package/dist/services/operate/spec-operating-origin-service.js.map +1 -0
- package/dist/services/operate/storage-layout.d.ts +82 -0
- package/dist/services/operate/storage-layout.d.ts.map +1 -0
- package/dist/services/operate/storage-layout.js +1244 -0
- package/dist/services/operate/storage-layout.js.map +1 -0
- package/dist/services/operate/storage-migration-service.d.ts +15 -0
- package/dist/services/operate/storage-migration-service.d.ts.map +1 -0
- package/dist/services/operate/storage-migration-service.js +27 -0
- package/dist/services/operate/storage-migration-service.js.map +1 -0
- package/dist/services/operate/store.d.ts +132 -0
- package/dist/services/operate/store.d.ts.map +1 -0
- package/dist/services/operate/store.js +1344 -0
- package/dist/services/operate/store.js.map +1 -0
- package/dist/services/pipeline-package-service.d.ts +93 -2
- package/dist/services/pipeline-package-service.d.ts.map +1 -1
- package/dist/services/pipeline-package-service.js +867 -7
- package/dist/services/pipeline-package-service.js.map +1 -1
- package/dist/services/planning-id-service.d.ts +8 -0
- package/dist/services/planning-id-service.d.ts.map +1 -0
- package/dist/services/planning-id-service.js +114 -0
- package/dist/services/planning-id-service.js.map +1 -0
- package/dist/services/provenance-service.d.ts +33 -1
- package/dist/services/provenance-service.d.ts.map +1 -1
- package/dist/services/provenance-service.js +104 -8
- package/dist/services/provenance-service.js.map +1 -1
- package/dist/services/runtime-manager/doctor.d.ts +22 -0
- package/dist/services/runtime-manager/doctor.d.ts.map +1 -0
- package/dist/services/runtime-manager/doctor.js +74 -0
- package/dist/services/runtime-manager/doctor.js.map +1 -0
- package/dist/services/runtime-manager/global-state.d.ts +47 -0
- package/dist/services/runtime-manager/global-state.d.ts.map +1 -0
- package/dist/services/runtime-manager/global-state.js +59 -0
- package/dist/services/runtime-manager/global-state.js.map +1 -0
- package/dist/services/runtime-manager/install-plan.d.ts +37 -0
- package/dist/services/runtime-manager/install-plan.d.ts.map +1 -0
- package/dist/services/runtime-manager/install-plan.js +91 -0
- package/dist/services/runtime-manager/install-plan.js.map +1 -0
- package/dist/services/runtime-manager/inventory.d.ts +29 -0
- package/dist/services/runtime-manager/inventory.d.ts.map +1 -0
- package/dist/services/runtime-manager/inventory.js +46 -0
- package/dist/services/runtime-manager/inventory.js.map +1 -0
- package/dist/services/runtime-manager-service.d.ts +16 -71
- package/dist/services/runtime-manager-service.d.ts.map +1 -1
- package/dist/services/runtime-manager-service.js +1288 -505
- package/dist/services/runtime-manager-service.js.map +1 -1
- package/dist/services/spec-service.d.ts +213 -39
- package/dist/services/spec-service.d.ts.map +1 -1
- package/dist/services/spec-service.js +938 -171
- package/dist/services/spec-service.js.map +1 -1
- package/dist/services/template-service.d.ts.map +1 -1
- package/dist/services/template-service.js +1 -0
- package/dist/services/template-service.js.map +1 -1
- package/dist/templates/quick/quick-task.md.hbs +6 -0
- package/dist/templates/rules/claude/CLAUDE.md.hbs +3 -111
- package/dist/templates/rules/codex/AGENTS.md.hbs +2 -92
- package/dist/templates/rules/cursor/create-task-list.mdc.hbs +1 -1
- package/dist/templates/rules/cursor/implement-task-list.mdc.hbs +5 -83
- package/dist/templates/rules/cursor/openplanr.mdc.hbs +12 -0
- package/dist/templates/rules/shared/host-native-guidance.md.hbs +12 -0
- package/dist/templates/rules/shared/implementation-guidance.md.hbs +44 -0
- package/dist/templates/spec/spec-shaped.md.hbs +66 -22
- package/dist/templates/spec/spec.md.hbs +46 -23
- package/dist/templates/spec/story.md.hbs +15 -4
- package/dist/templates/spec/task.md.hbs +53 -5
- package/dist/utils/constants.d.ts +1 -1
- package/dist/utils/constants.js +1 -1
- package/dist/utils/logger.d.ts +0 -3
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +0 -6
- package/dist/utils/logger.js.map +1 -1
- package/docs/ARTIFACT_REVIEW.md +110 -0
- package/docs/CLI.md +1216 -0
- package/docs/CROSS_RUNTIME_SETUP.md +168 -0
- package/docs/TROUBLESHOOTING.md +227 -0
- package/lib/dashboard-verifier.d.mts +29 -0
- package/lib/dashboard-verifier.mjs +307 -0
- package/lib/host-packages/adapter-registry.json +44 -0
- package/lib/host-packages/claude/.claude-plugin/marketplace.json +20 -0
- package/lib/host-packages/claude/openplanr/.claude-plugin/plugin.json +9 -0
- package/lib/host-packages/claude/openplanr/.openplanr-content.json +1179 -0
- package/lib/host-packages/claude/openplanr/agents/planr-backend.md +66 -0
- package/lib/host-packages/claude/openplanr/agents/planr-database.md +165 -0
- package/lib/host-packages/claude/openplanr/agents/planr-designer.md +57 -0
- package/lib/host-packages/claude/openplanr/agents/planr-devops.md +57 -0
- package/lib/host-packages/claude/openplanr/agents/planr-documentation.md +63 -0
- package/lib/host-packages/claude/openplanr/agents/planr-entity-scaffold.md +29 -0
- package/lib/host-packages/claude/openplanr/agents/planr-frontend.md +69 -0
- package/lib/host-packages/claude/openplanr/agents/planr-qa.md +162 -0
- package/lib/host-packages/claude/openplanr/agents/planr-specification.md +124 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/default/backend.md +93 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/default/designer.md +90 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/default/devops.md +55 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/default/doc-gen.md +67 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/default/frontend.md +94 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/default/qa.md +17 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/default/specification.md +111 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/shared/contract-create-modify-preserve.md +17 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/shared/design-craft-rubric.md +51 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/shared/design-principles.md +43 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/shared/design-spec-template.md +88 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/shared/task-context-resolution.md +60 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/shared/verification-and-recovery-backend.md +26 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/shared/verification-and-recovery-frontend.md +27 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/spec-driven/backend.md +96 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/spec-driven/designer.md +83 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/spec-driven/devops.md +55 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/spec-driven/doc-gen.md +67 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/spec-driven/frontend.md +96 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/spec-driven/qa.md +17 -0
- package/lib/host-packages/claude/openplanr/references/agents/shared/modes/spec-driven/specification.md +112 -0
- package/lib/host-packages/claude/openplanr/references/pipeline/stacks/backend/nestjs.md +130 -0
- package/lib/host-packages/claude/openplanr/references/pipeline/stacks/database/mongodb.md +122 -0
- package/lib/host-packages/claude/openplanr/references/pipeline/stacks/database/prisma.md +155 -0
- package/lib/host-packages/claude/openplanr/references/pipeline/stacks/devops/docker-compose.md +140 -0
- package/lib/host-packages/claude/openplanr/references/pipeline/stacks/frontend/nextjs.md +123 -0
- package/lib/host-packages/claude/openplanr/skills/artifact/SKILL.md +54 -0
- package/lib/host-packages/claude/openplanr/skills/artifact/openplanr.skill.json +48 -0
- package/lib/host-packages/claude/openplanr/skills/artifact/references/company-review.md +18 -0
- package/lib/host-packages/claude/openplanr/skills/artifact/references/design-sharing.md +51 -0
- package/lib/host-packages/claude/openplanr/skills/browser-qa/SKILL.md +34 -0
- package/lib/host-packages/claude/openplanr/skills/browser-qa/openplanr.skill.json +26 -0
- package/lib/host-packages/claude/openplanr/skills/ceo-review/SKILL.md +47 -0
- package/lib/host-packages/claude/openplanr/skills/ceo-review/openplanr.skill.json +81 -0
- package/lib/host-packages/claude/openplanr/skills/ceo-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/claude/openplanr/skills/ceo-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/claude/openplanr/skills/ceo-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/claude/openplanr/skills/ceo-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/claude/openplanr/skills/ceo-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/claude/openplanr/skills/chair-review/SKILL.md +101 -0
- package/lib/host-packages/claude/openplanr/skills/chair-review/openplanr.skill.json +70 -0
- package/lib/host-packages/claude/openplanr/skills/chair-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/claude/openplanr/skills/chair-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/claude/openplanr/skills/chair-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/claude/openplanr/skills/chair-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/claude/openplanr/skills/challenger-review/SKILL.md +86 -0
- package/lib/host-packages/claude/openplanr/skills/challenger-review/openplanr.skill.json +70 -0
- package/lib/host-packages/claude/openplanr/skills/challenger-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/claude/openplanr/skills/challenger-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/claude/openplanr/skills/challenger-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/claude/openplanr/skills/challenger-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/claude/openplanr/skills/cmo-review/SKILL.md +46 -0
- package/lib/host-packages/claude/openplanr/skills/cmo-review/openplanr.skill.json +81 -0
- package/lib/host-packages/claude/openplanr/skills/cmo-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/claude/openplanr/skills/cmo-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/claude/openplanr/skills/cmo-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/claude/openplanr/skills/cmo-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/claude/openplanr/skills/cmo-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/claude/openplanr/skills/coo-review/SKILL.md +45 -0
- package/lib/host-packages/claude/openplanr/skills/coo-review/openplanr.skill.json +81 -0
- package/lib/host-packages/claude/openplanr/skills/coo-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/claude/openplanr/skills/coo-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/claude/openplanr/skills/coo-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/claude/openplanr/skills/coo-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/claude/openplanr/skills/coo-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/claude/openplanr/skills/cpo-review/SKILL.md +48 -0
- package/lib/host-packages/claude/openplanr/skills/cpo-review/openplanr.skill.json +81 -0
- package/lib/host-packages/claude/openplanr/skills/cpo-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/claude/openplanr/skills/cpo-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/claude/openplanr/skills/cpo-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/claude/openplanr/skills/cpo-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/claude/openplanr/skills/cpo-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/claude/openplanr/skills/cto-review/SKILL.md +47 -0
- package/lib/host-packages/claude/openplanr/skills/cto-review/openplanr.skill.json +81 -0
- package/lib/host-packages/claude/openplanr/skills/cto-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/claude/openplanr/skills/cto-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/claude/openplanr/skills/cto-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/claude/openplanr/skills/cto-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/claude/openplanr/skills/cto-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/claude/openplanr/skills/dashboard/SKILL.md +20 -0
- package/lib/host-packages/claude/openplanr/skills/dashboard/openplanr.skill.json +26 -0
- package/lib/host-packages/claude/openplanr/skills/design/SKILL.md +73 -0
- package/lib/host-packages/claude/openplanr/skills/design/openplanr.skill.json +466 -0
- package/lib/host-packages/claude/openplanr/skills/design/references/craft.md +68 -0
- package/lib/host-packages/claude/openplanr/skills/design/references/design-spec-template.md +88 -0
- package/lib/host-packages/claude/openplanr/skills/design/references/design-system.md +33 -0
- package/lib/host-packages/claude/openplanr/skills/design/references/discovery.md +53 -0
- package/lib/host-packages/claude/openplanr/skills/design/references/generation.md +105 -0
- package/lib/host-packages/claude/openplanr/skills/design/references/handoff.md +47 -0
- package/lib/host-packages/claude/openplanr/skills/design/references/review.md +88 -0
- package/lib/host-packages/claude/openplanr/skills/design/references/team-review.md +131 -0
- package/lib/host-packages/claude/openplanr/skills/design/references/utilities.md +93 -0
- package/lib/host-packages/claude/openplanr/skills/design/schemas/design-document.schema.json +306 -0
- package/lib/host-packages/claude/openplanr/skills/design/schemas/design-review-context.schema.json +191 -0
- package/lib/host-packages/claude/openplanr/skills/design/schemas/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/design.mjs +17323 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/notices/entities.txt +13 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/notices/parse5.txt +21 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +3994 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/design/templates/studio/enhancements.css +378 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/design/templates/studio/enhancements.js +805 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/design/templates/studio/share.css +1 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/design/templates/studio/share.js +132 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/design/templates/studio/studio.css +1103 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/design/templates/studio/studio.js +1775 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/package.json +115 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/registry/artifact-theme.json +60 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.0.0/design-manifest.schema.json +90 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-envelope.schema.json +142 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +49 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-review.schema.json +97 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-theme.schema.json +139 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-bundle.schema.json +584 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-context.schema.json +191 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-metadata-payload.schema.json +106 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.11.0/design-review-metadata-payload.schema.json +107 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-document.schema.json +306 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-bundle.schema.json +346 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +108 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +170 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +97 -0
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +56 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/SKILL.md +58 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/openplanr.skill.json +466 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/craft.md +68 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/design-spec-template.md +88 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/design-system.md +33 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/discovery.md +53 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/generation.md +105 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/handoff.md +47 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/review.md +88 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/team-review.md +131 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/utilities.md +93 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/schemas/design-document.schema.json +306 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/schemas/design-review-context.schema.json +191 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/schemas/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/design.mjs +17323 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/notices/entities.txt +13 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/notices/parse5.txt +21 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +3994 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/design/templates/studio/enhancements.css +378 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/design/templates/studio/enhancements.js +805 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/design/templates/studio/share.css +1 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/design/templates/studio/share.js +132 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/design/templates/studio/studio.css +1103 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/design/templates/studio/studio.js +1775 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/package.json +115 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/registry/artifact-theme.json +60 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.0.0/design-manifest.schema.json +90 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-envelope.schema.json +142 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +49 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-review.schema.json +97 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-theme.schema.json +139 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-bundle.schema.json +584 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-context.schema.json +191 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-metadata-payload.schema.json +106 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.11.0/design-review-metadata-payload.schema.json +107 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-document.schema.json +306 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-bundle.schema.json +346 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +108 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +170 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +97 -0
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +56 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/SKILL.md +54 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/openplanr.skill.json +466 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/references/craft.md +68 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/references/design-spec-template.md +88 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/references/design-system.md +33 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/references/discovery.md +53 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/references/generation.md +105 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/references/handoff.md +47 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/references/review.md +88 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/references/team-review.md +131 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/references/utilities.md +93 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/schemas/design-document.schema.json +306 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/schemas/design-review-context.schema.json +191 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/schemas/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/design.mjs +17323 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/notices/entities.txt +13 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/notices/parse5.txt +21 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +3994 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/design/templates/studio/enhancements.css +378 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/design/templates/studio/enhancements.js +805 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/design/templates/studio/share.css +1 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/design/templates/studio/share.js +132 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/design/templates/studio/studio.css +1103 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/design/templates/studio/studio.js +1775 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/package.json +115 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/registry/artifact-theme.json +60 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.0.0/design-manifest.schema.json +90 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-envelope.schema.json +142 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +49 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-review.schema.json +97 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-theme.schema.json +139 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-bundle.schema.json +584 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-context.schema.json +191 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-metadata-payload.schema.json +106 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.11.0/design-review-metadata-payload.schema.json +107 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-document.schema.json +306 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-bundle.schema.json +346 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +108 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +170 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +97 -0
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +56 -0
- package/lib/host-packages/claude/openplanr/skills/diagram/SKILL.md +65 -0
- package/lib/host-packages/claude/openplanr/skills/diagram/openplanr.skill.json +59 -0
- package/lib/host-packages/claude/openplanr/skills/diagram/references/diagram-document.md +86 -0
- package/lib/host-packages/claude/openplanr/skills/diagram/references/diagram-fidelity.md +19 -0
- package/lib/host-packages/claude/openplanr/skills/diagram/references/diagram-intent-to-ir.md +22 -0
- package/lib/host-packages/claude/openplanr/skills/doctor/SKILL.md +40 -0
- package/lib/host-packages/claude/openplanr/skills/doctor/openplanr.skill.json +37 -0
- package/lib/host-packages/claude/openplanr/skills/doctor/references/upgrade.md +106 -0
- package/lib/host-packages/claude/openplanr/skills/investigate/SKILL.md +31 -0
- package/lib/host-packages/claude/openplanr/skills/investigate/openplanr.skill.json +26 -0
- package/lib/host-packages/claude/openplanr/skills/land/SKILL.md +33 -0
- package/lib/host-packages/claude/openplanr/skills/land/openplanr.skill.json +26 -0
- package/lib/host-packages/claude/openplanr/skills/operate/SKILL.md +181 -0
- package/lib/host-packages/claude/openplanr/skills/operate/openplanr.skill.json +70 -0
- package/lib/host-packages/claude/openplanr/skills/operate/scripts/errors.mjs +8 -0
- package/lib/host-packages/claude/openplanr/skills/operate/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/claude/openplanr/skills/operate/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/claude/openplanr/skills/operate/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/claude/openplanr/skills/plan/SKILL.md +106 -0
- package/lib/host-packages/claude/openplanr/skills/plan/openplanr.skill.json +389 -0
- package/lib/host-packages/claude/openplanr/skills/plan/references/artifact-contract.md +39 -0
- package/lib/host-packages/claude/openplanr/skills/plan/schemas/design-document.schema.json +306 -0
- package/lib/host-packages/claude/openplanr/skills/plan/schemas/design-review-context.schema.json +191 -0
- package/lib/host-packages/claude/openplanr/skills/plan/schemas/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/design.mjs +17323 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/planning-ids.mjs +120 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/notices/entities.txt +13 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/notices/parse5.txt +21 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +3994 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/design/templates/studio/enhancements.css +378 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/design/templates/studio/enhancements.js +805 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/design/templates/studio/share.css +1 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/design/templates/studio/share.js +132 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/design/templates/studio/studio.css +1103 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/design/templates/studio/studio.js +1775 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/package.json +115 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/registry/artifact-theme.json +60 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.0.0/design-manifest.schema.json +90 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-envelope.schema.json +142 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +49 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-review.schema.json +97 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-theme.schema.json +139 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-bundle.schema.json +584 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-context.schema.json +191 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-metadata-payload.schema.json +106 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.11.0/design-review-metadata-payload.schema.json +107 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-document.schema.json +306 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-bundle.schema.json +346 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +108 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +170 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +97 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +56 -0
- package/lib/host-packages/claude/openplanr/skills/plan-review/SKILL.md +39 -0
- package/lib/host-packages/claude/openplanr/skills/plan-review/openplanr.skill.json +26 -0
- package/lib/host-packages/claude/openplanr/skills/release/SKILL.md +180 -0
- package/lib/host-packages/claude/openplanr/skills/release/assets/changelog-template.md +18 -0
- package/lib/host-packages/claude/openplanr/skills/release/assets/profile-template.md +45 -0
- package/lib/host-packages/claude/openplanr/skills/release/openplanr.skill.json +92 -0
- package/lib/host-packages/claude/openplanr/skills/release/references/cadence.md +92 -0
- package/lib/host-packages/claude/openplanr/skills/release/references/release-notes.md +127 -0
- package/lib/host-packages/claude/openplanr/skills/release/references/schemes.md +103 -0
- package/lib/host-packages/claude/openplanr/skills/release/scripts/collect_changes.sh +85 -0
- package/lib/host-packages/claude/openplanr/skills/ship/SKILL.md +80 -0
- package/lib/host-packages/claude/openplanr/skills/ship/openplanr.skill.json +48 -0
- package/lib/host-packages/claude/openplanr/skills/ship/references/result-contract.md +14 -0
- package/lib/host-packages/claude/openplanr/skills/ship/scripts/discover-verification.mjs +107 -0
- package/lib/host-packages/claude/openplanr/skills/spec/SKILL.md +53 -0
- package/lib/host-packages/claude/openplanr/skills/spec/openplanr.skill.json +37 -0
- package/lib/host-packages/claude/openplanr/skills/spec/references/specification-contract.md +32 -0
- package/lib/host-packages/claude/openplanr/skills/status/SKILL.md +21 -0
- package/lib/host-packages/claude/openplanr/skills/status/openplanr.skill.json +26 -0
- package/lib/host-packages/claude/openplanr/skills/sync/SKILL.md +30 -0
- package/lib/host-packages/claude/openplanr/skills/sync/openplanr.skill.json +37 -0
- package/lib/host-packages/claude/openplanr/skills/sync/scripts/sync.mjs +230 -0
- package/lib/host-packages/cursor/openplanr/.openplanr-content.json +939 -0
- package/lib/host-packages/cursor/openplanr/manifest.json +32 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-artifact/references/company-review.md +18 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-artifact/references/design-sharing.md +51 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-artifact.mdc +53 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-browser-qa.mdc +34 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-ceo-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-ceo-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-ceo-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-ceo-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-ceo-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-ceo-review.mdc +45 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-chair-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-chair-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-chair-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-chair-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-chair-review.mdc +99 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-challenger-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-challenger-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-challenger-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-challenger-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-challenger-review.mdc +84 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cmo-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cmo-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cmo-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cmo-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cmo-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cmo-review.mdc +44 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-coo-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-coo-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-coo-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-coo-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-coo-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-coo-review.mdc +43 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cpo-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cpo-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cpo-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cpo-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cpo-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cpo-review.mdc +46 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cto-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cto-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cto-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cto-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cto-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-cto-review.mdc +45 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-dashboard.mdc +19 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/craft.md +68 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/design-spec-template.md +88 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/design-system.md +33 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/discovery.md +53 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/generation.md +105 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/handoff.md +47 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/review.md +88 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/team-review.md +131 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/utilities.md +93 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/schemas/design-document.schema.json +306 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/schemas/design-review-context.schema.json +191 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/schemas/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/design.mjs +17323 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/notices/entities.txt +13 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/notices/parse5.txt +21 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +3994 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/design/templates/studio/enhancements.css +378 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/design/templates/studio/enhancements.js +805 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/design/templates/studio/share.css +1 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/design/templates/studio/share.js +132 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/design/templates/studio/studio.css +1103 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/design/templates/studio/studio.js +1775 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/package.json +115 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/registry/artifact-theme.json +60 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.0.0/design-manifest.schema.json +90 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-envelope.schema.json +142 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +49 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-review.schema.json +97 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-theme.schema.json +139 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-bundle.schema.json +584 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-context.schema.json +191 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-metadata-payload.schema.json +106 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.11.0/design-review-metadata-payload.schema.json +107 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-document.schema.json +306 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-bundle.schema.json +346 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +108 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +170 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +97 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +56 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/craft.md +68 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/design-spec-template.md +88 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/design-system.md +33 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/discovery.md +53 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/generation.md +105 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/handoff.md +47 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/review.md +88 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/team-review.md +131 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/utilities.md +93 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/schemas/design-document.schema.json +306 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/schemas/design-review-context.schema.json +191 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/schemas/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/design.mjs +17323 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/notices/entities.txt +13 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/notices/parse5.txt +21 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +3994 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/design/templates/studio/enhancements.css +378 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/design/templates/studio/enhancements.js +805 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/design/templates/studio/share.css +1 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/design/templates/studio/share.js +132 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/design/templates/studio/studio.css +1103 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/design/templates/studio/studio.js +1775 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/package.json +115 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/registry/artifact-theme.json +60 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.0.0/design-manifest.schema.json +90 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-envelope.schema.json +142 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +49 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-review.schema.json +97 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-theme.schema.json +139 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-bundle.schema.json +584 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-context.schema.json +191 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-metadata-payload.schema.json +106 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.11.0/design-review-metadata-payload.schema.json +107 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-document.schema.json +306 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-bundle.schema.json +346 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +108 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +170 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +97 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +56 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop.mdc +57 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/craft.md +68 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/design-spec-template.md +88 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/design-system.md +33 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/discovery.md +53 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/generation.md +105 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/handoff.md +47 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/review.md +88 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/team-review.md +131 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/utilities.md +93 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/schemas/design-document.schema.json +306 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/schemas/design-review-context.schema.json +191 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/schemas/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/design.mjs +17323 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/notices/entities.txt +13 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/notices/parse5.txt +21 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +3994 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/design/templates/studio/enhancements.css +378 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/design/templates/studio/enhancements.js +805 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/design/templates/studio/share.css +1 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/design/templates/studio/share.js +132 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/design/templates/studio/studio.css +1103 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/design/templates/studio/studio.js +1775 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/package.json +115 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/registry/artifact-theme.json +60 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.0.0/design-manifest.schema.json +90 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-envelope.schema.json +142 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +49 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-review.schema.json +97 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-theme.schema.json +139 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-bundle.schema.json +584 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-context.schema.json +191 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-metadata-payload.schema.json +106 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.11.0/design-review-metadata-payload.schema.json +107 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-document.schema.json +306 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-bundle.schema.json +346 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +108 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +170 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +97 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +56 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review.mdc +53 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design.mdc +72 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-diagram/references/diagram-document.md +86 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-diagram/references/diagram-fidelity.md +19 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-diagram/references/diagram-intent-to-ir.md +22 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-diagram.mdc +64 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-doctor/references/upgrade.md +106 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-doctor.mdc +39 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-investigate.mdc +31 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-land.mdc +32 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-operate/scripts/errors.mjs +8 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-operate/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-operate/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-operate/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-operate.mdc +180 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/references/artifact-contract.md +39 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/schemas/design-document.schema.json +306 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/schemas/design-review-context.schema.json +191 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/schemas/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/design.mjs +17323 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/planning-ids.mjs +120 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/notices/entities.txt +13 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/notices/parse5.txt +21 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +3994 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/design/templates/studio/enhancements.css +378 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/design/templates/studio/enhancements.js +805 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/design/templates/studio/share.css +1 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/design/templates/studio/share.js +132 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/design/templates/studio/studio.css +1103 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/design/templates/studio/studio.js +1775 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/package.json +115 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/registry/artifact-theme.json +60 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.0.0/design-manifest.schema.json +90 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-envelope.schema.json +142 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +49 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-review.schema.json +97 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-theme.schema.json +139 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-bundle.schema.json +584 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-context.schema.json +191 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-metadata-payload.schema.json +106 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.11.0/design-review-metadata-payload.schema.json +107 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-document.schema.json +306 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-bundle.schema.json +346 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +108 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +170 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +97 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +56 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan-review.mdc +38 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan.mdc +105 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-release/assets/changelog-template.md +18 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-release/assets/profile-template.md +45 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-release/references/cadence.md +92 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-release/references/release-notes.md +127 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-release/references/schemes.md +103 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-release/scripts/collect_changes.sh +85 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-release.mdc +179 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-ship/references/result-contract.md +14 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-ship/scripts/discover-verification.mjs +107 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-ship.mdc +79 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-spec/references/specification-contract.md +32 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-spec.mdc +52 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-status.mdc +20 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-sync/scripts/sync.mjs +230 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-sync.mdc +29 -0
- package/lib/host-packages/openai/.claude-plugin/marketplace.json +19 -0
- package/lib/host-packages/openai/openplanr/.codex-plugin/plugin.json +10 -0
- package/lib/host-packages/openai/openplanr/.openplanr-content.json +1139 -0
- package/lib/host-packages/openai/openplanr/skills/artifact/SKILL.md +54 -0
- package/lib/host-packages/openai/openplanr/skills/artifact/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/artifact/openplanr.skill.json +48 -0
- package/lib/host-packages/openai/openplanr/skills/artifact/references/company-review.md +18 -0
- package/lib/host-packages/openai/openplanr/skills/artifact/references/design-sharing.md +51 -0
- package/lib/host-packages/openai/openplanr/skills/browser-qa/SKILL.md +34 -0
- package/lib/host-packages/openai/openplanr/skills/browser-qa/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/browser-qa/openplanr.skill.json +26 -0
- package/lib/host-packages/openai/openplanr/skills/ceo-review/SKILL.md +47 -0
- package/lib/host-packages/openai/openplanr/skills/ceo-review/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/ceo-review/openplanr.skill.json +81 -0
- package/lib/host-packages/openai/openplanr/skills/ceo-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/openai/openplanr/skills/ceo-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/openai/openplanr/skills/ceo-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/openai/openplanr/skills/ceo-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/openai/openplanr/skills/ceo-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/openai/openplanr/skills/chair-review/SKILL.md +101 -0
- package/lib/host-packages/openai/openplanr/skills/chair-review/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/chair-review/openplanr.skill.json +70 -0
- package/lib/host-packages/openai/openplanr/skills/chair-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/openai/openplanr/skills/chair-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/openai/openplanr/skills/chair-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/openai/openplanr/skills/chair-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/openai/openplanr/skills/challenger-review/SKILL.md +86 -0
- package/lib/host-packages/openai/openplanr/skills/challenger-review/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/challenger-review/openplanr.skill.json +70 -0
- package/lib/host-packages/openai/openplanr/skills/challenger-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/openai/openplanr/skills/challenger-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/openai/openplanr/skills/challenger-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/openai/openplanr/skills/challenger-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/openai/openplanr/skills/cmo-review/SKILL.md +46 -0
- package/lib/host-packages/openai/openplanr/skills/cmo-review/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/cmo-review/openplanr.skill.json +81 -0
- package/lib/host-packages/openai/openplanr/skills/cmo-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/openai/openplanr/skills/cmo-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/openai/openplanr/skills/cmo-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/openai/openplanr/skills/cmo-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/openai/openplanr/skills/cmo-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/openai/openplanr/skills/coo-review/SKILL.md +45 -0
- package/lib/host-packages/openai/openplanr/skills/coo-review/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/coo-review/openplanr.skill.json +81 -0
- package/lib/host-packages/openai/openplanr/skills/coo-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/openai/openplanr/skills/coo-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/openai/openplanr/skills/coo-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/openai/openplanr/skills/coo-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/openai/openplanr/skills/coo-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/openai/openplanr/skills/cpo-review/SKILL.md +48 -0
- package/lib/host-packages/openai/openplanr/skills/cpo-review/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/cpo-review/openplanr.skill.json +81 -0
- package/lib/host-packages/openai/openplanr/skills/cpo-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/openai/openplanr/skills/cpo-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/openai/openplanr/skills/cpo-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/openai/openplanr/skills/cpo-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/openai/openplanr/skills/cpo-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/openai/openplanr/skills/cto-review/SKILL.md +47 -0
- package/lib/host-packages/openai/openplanr/skills/cto-review/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/cto-review/openplanr.skill.json +81 -0
- package/lib/host-packages/openai/openplanr/skills/cto-review/references/operate-advisor-contract.md +111 -0
- package/lib/host-packages/openai/openplanr/skills/cto-review/scripts/errors.mjs +8 -0
- package/lib/host-packages/openai/openplanr/skills/cto-review/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/openai/openplanr/skills/cto-review/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/openai/openplanr/skills/cto-review/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/openai/openplanr/skills/dashboard/SKILL.md +20 -0
- package/lib/host-packages/openai/openplanr/skills/dashboard/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/dashboard/openplanr.skill.json +26 -0
- package/lib/host-packages/openai/openplanr/skills/design/SKILL.md +73 -0
- package/lib/host-packages/openai/openplanr/skills/design/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/design/openplanr.skill.json +466 -0
- package/lib/host-packages/openai/openplanr/skills/design/references/craft.md +68 -0
- package/lib/host-packages/openai/openplanr/skills/design/references/design-spec-template.md +88 -0
- package/lib/host-packages/openai/openplanr/skills/design/references/design-system.md +33 -0
- package/lib/host-packages/openai/openplanr/skills/design/references/discovery.md +53 -0
- package/lib/host-packages/openai/openplanr/skills/design/references/generation.md +105 -0
- package/lib/host-packages/openai/openplanr/skills/design/references/handoff.md +47 -0
- package/lib/host-packages/openai/openplanr/skills/design/references/review.md +88 -0
- package/lib/host-packages/openai/openplanr/skills/design/references/team-review.md +131 -0
- package/lib/host-packages/openai/openplanr/skills/design/references/utilities.md +93 -0
- package/lib/host-packages/openai/openplanr/skills/design/schemas/design-document.schema.json +306 -0
- package/lib/host-packages/openai/openplanr/skills/design/schemas/design-review-context.schema.json +191 -0
- package/lib/host-packages/openai/openplanr/skills/design/schemas/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/design.mjs +17323 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/notices/entities.txt +13 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/notices/parse5.txt +21 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +3994 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/design/templates/studio/enhancements.css +378 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/design/templates/studio/enhancements.js +805 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/design/templates/studio/share.css +1 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/design/templates/studio/share.js +132 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/design/templates/studio/studio.css +1103 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/design/templates/studio/studio.js +1775 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/package.json +115 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/registry/artifact-theme.json +60 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.0.0/design-manifest.schema.json +90 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-envelope.schema.json +142 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +49 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-review.schema.json +97 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-theme.schema.json +139 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-bundle.schema.json +584 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-context.schema.json +191 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-metadata-payload.schema.json +106 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.11.0/design-review-metadata-payload.schema.json +107 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-document.schema.json +306 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-bundle.schema.json +346 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +108 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +170 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +97 -0
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +56 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/SKILL.md +58 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/openplanr.skill.json +466 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/craft.md +68 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/design-spec-template.md +88 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/design-system.md +33 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/discovery.md +53 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/generation.md +105 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/handoff.md +47 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/review.md +88 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/team-review.md +131 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/utilities.md +93 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/schemas/design-document.schema.json +306 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/schemas/design-review-context.schema.json +191 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/schemas/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/design.mjs +17323 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/notices/entities.txt +13 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/notices/parse5.txt +21 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +3994 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/design/templates/studio/enhancements.css +378 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/design/templates/studio/enhancements.js +805 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/design/templates/studio/share.css +1 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/design/templates/studio/share.js +132 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/design/templates/studio/studio.css +1103 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/design/templates/studio/studio.js +1775 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/package.json +115 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/registry/artifact-theme.json +60 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.0.0/design-manifest.schema.json +90 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-envelope.schema.json +142 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +49 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-review.schema.json +97 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-theme.schema.json +139 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-bundle.schema.json +584 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-context.schema.json +191 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-metadata-payload.schema.json +106 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.11.0/design-review-metadata-payload.schema.json +107 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-document.schema.json +306 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-bundle.schema.json +346 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +108 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +170 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +97 -0
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +56 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/SKILL.md +54 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/openplanr.skill.json +466 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/references/craft.md +68 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/references/design-spec-template.md +88 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/references/design-system.md +33 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/references/discovery.md +53 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/references/generation.md +105 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/references/handoff.md +47 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/references/review.md +88 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/references/team-review.md +131 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/references/utilities.md +93 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/schemas/design-document.schema.json +306 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/schemas/design-review-context.schema.json +191 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/schemas/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/design.mjs +17323 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/notices/entities.txt +13 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/notices/parse5.txt +21 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +3994 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/design/templates/studio/enhancements.css +378 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/design/templates/studio/enhancements.js +805 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/design/templates/studio/share.css +1 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/design/templates/studio/share.js +132 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/design/templates/studio/studio.css +1103 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/design/templates/studio/studio.js +1775 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/package.json +115 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/registry/artifact-theme.json +60 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.0.0/design-manifest.schema.json +90 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-envelope.schema.json +142 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +49 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-review.schema.json +97 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-theme.schema.json +139 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-bundle.schema.json +584 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-context.schema.json +191 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-metadata-payload.schema.json +106 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.11.0/design-review-metadata-payload.schema.json +107 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-document.schema.json +306 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-bundle.schema.json +346 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +108 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +170 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +97 -0
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +56 -0
- package/lib/host-packages/openai/openplanr/skills/diagram/SKILL.md +65 -0
- package/lib/host-packages/openai/openplanr/skills/diagram/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/diagram/openplanr.skill.json +59 -0
- package/lib/host-packages/openai/openplanr/skills/diagram/references/diagram-document.md +86 -0
- package/lib/host-packages/openai/openplanr/skills/diagram/references/diagram-fidelity.md +19 -0
- package/lib/host-packages/openai/openplanr/skills/diagram/references/diagram-intent-to-ir.md +22 -0
- package/lib/host-packages/openai/openplanr/skills/doctor/SKILL.md +40 -0
- package/lib/host-packages/openai/openplanr/skills/doctor/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/doctor/openplanr.skill.json +37 -0
- package/lib/host-packages/openai/openplanr/skills/doctor/references/upgrade.md +106 -0
- package/lib/host-packages/openai/openplanr/skills/investigate/SKILL.md +31 -0
- package/lib/host-packages/openai/openplanr/skills/investigate/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/investigate/openplanr.skill.json +26 -0
- package/lib/host-packages/openai/openplanr/skills/land/SKILL.md +33 -0
- package/lib/host-packages/openai/openplanr/skills/land/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/land/openplanr.skill.json +26 -0
- package/lib/host-packages/openai/openplanr/skills/operate/SKILL.md +181 -0
- package/lib/host-packages/openai/openplanr/skills/operate/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/operate/openplanr.skill.json +70 -0
- package/lib/host-packages/openai/openplanr/skills/operate/scripts/errors.mjs +8 -0
- package/lib/host-packages/openai/openplanr/skills/operate/scripts/operate-review-contract.mjs +438 -0
- package/lib/host-packages/openai/openplanr/skills/operate/scripts/operate-review-note.mjs +595 -0
- package/lib/host-packages/openai/openplanr/skills/operate/scripts/validate-note.mjs +31 -0
- package/lib/host-packages/openai/openplanr/skills/plan/SKILL.md +106 -0
- package/lib/host-packages/openai/openplanr/skills/plan/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/plan/openplanr.skill.json +389 -0
- package/lib/host-packages/openai/openplanr/skills/plan/references/artifact-contract.md +39 -0
- package/lib/host-packages/openai/openplanr/skills/plan/schemas/design-document.schema.json +306 -0
- package/lib/host-packages/openai/openplanr/skills/plan/schemas/design-review-context.schema.json +191 -0
- package/lib/host-packages/openai/openplanr/skills/plan/schemas/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/design.mjs +17323 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/planning-ids.mjs +120 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/notices/entities.txt +13 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/notices/parse5.txt +21 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +3994 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/design/templates/studio/enhancements.css +378 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/design/templates/studio/enhancements.js +805 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/design/templates/studio/share.css +1 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/design/templates/studio/share.js +132 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/design/templates/studio/studio.css +1103 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/design/templates/studio/studio.js +1775 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/package.json +115 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/registry/artifact-theme.json +60 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.0.0/design-manifest.schema.json +90 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-envelope.schema.json +142 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +49 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-review.schema.json +97 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-theme.schema.json +139 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-bundle.schema.json +584 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-context.schema.json +191 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-handoff.schema.json +407 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.10.0/design-review-metadata-payload.schema.json +106 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.11.0/design-review-metadata-payload.schema.json +107 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-document.schema.json +306 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-bundle.schema.json +346 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +108 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +170 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +97 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +56 -0
- package/lib/host-packages/openai/openplanr/skills/plan-review/SKILL.md +39 -0
- package/lib/host-packages/openai/openplanr/skills/plan-review/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/plan-review/openplanr.skill.json +26 -0
- package/lib/host-packages/openai/openplanr/skills/release/SKILL.md +180 -0
- package/lib/host-packages/openai/openplanr/skills/release/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/release/assets/changelog-template.md +18 -0
- package/lib/host-packages/openai/openplanr/skills/release/assets/profile-template.md +45 -0
- package/lib/host-packages/openai/openplanr/skills/release/openplanr.skill.json +92 -0
- package/lib/host-packages/openai/openplanr/skills/release/references/cadence.md +92 -0
- package/lib/host-packages/openai/openplanr/skills/release/references/release-notes.md +127 -0
- package/lib/host-packages/openai/openplanr/skills/release/references/schemes.md +103 -0
- package/lib/host-packages/openai/openplanr/skills/release/scripts/collect_changes.sh +85 -0
- package/lib/host-packages/openai/openplanr/skills/ship/SKILL.md +80 -0
- package/lib/host-packages/openai/openplanr/skills/ship/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/ship/openplanr.skill.json +48 -0
- package/lib/host-packages/openai/openplanr/skills/ship/references/result-contract.md +14 -0
- package/lib/host-packages/openai/openplanr/skills/ship/scripts/discover-verification.mjs +107 -0
- package/lib/host-packages/openai/openplanr/skills/spec/SKILL.md +53 -0
- package/lib/host-packages/openai/openplanr/skills/spec/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/spec/openplanr.skill.json +37 -0
- package/lib/host-packages/openai/openplanr/skills/spec/references/specification-contract.md +32 -0
- package/lib/host-packages/openai/openplanr/skills/status/SKILL.md +21 -0
- package/lib/host-packages/openai/openplanr/skills/status/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/status/openplanr.skill.json +26 -0
- package/lib/host-packages/openai/openplanr/skills/sync/SKILL.md +30 -0
- package/lib/host-packages/openai/openplanr/skills/sync/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/sync/openplanr.skill.json +37 -0
- package/lib/host-packages/openai/openplanr/skills/sync/scripts/sync.mjs +230 -0
- package/lib/integrations.d.mts +43 -0
- package/lib/integrations.mjs +230 -0
- package/lib/skill-runtime/errors.mjs +8 -0
- package/lib/skill-runtime/operate-review-contract.mjs +438 -0
- package/lib/skill-runtime/operate-review-note.mjs +595 -0
- package/package.json +56 -18
- package/dist/ai/codebase/context-builder.d.ts +0 -50
- package/dist/ai/codebase/context-builder.d.ts.map +0 -1
- package/dist/ai/codebase/context-builder.js +0 -281
- package/dist/ai/codebase/context-builder.js.map +0 -1
- package/dist/ai/codebase/file-reader.d.ts +0 -22
- package/dist/ai/codebase/file-reader.d.ts.map +0 -1
- package/dist/ai/codebase/file-reader.js +0 -144
- package/dist/ai/codebase/file-reader.js.map +0 -1
- package/dist/ai/codebase/index.d.ts +0 -7
- package/dist/ai/codebase/index.d.ts.map +0 -1
- package/dist/ai/codebase/index.js +0 -7
- package/dist/ai/codebase/index.js.map +0 -1
- package/dist/ai/codebase/pattern-rules.d.ts +0 -28
- package/dist/ai/codebase/pattern-rules.d.ts.map +0 -1
- package/dist/ai/codebase/pattern-rules.js +0 -186
- package/dist/ai/codebase/pattern-rules.js.map +0 -1
- package/dist/ai/codebase/rules-reader.d.ts +0 -14
- package/dist/ai/codebase/rules-reader.d.ts.map +0 -1
- package/dist/ai/codebase/rules-reader.js +0 -25
- package/dist/ai/codebase/rules-reader.js.map +0 -1
- package/dist/ai/codebase/stack-detector.d.ts +0 -18
- package/dist/ai/codebase/stack-detector.d.ts.map +0 -1
- package/dist/ai/codebase/stack-detector.js +0 -173
- package/dist/ai/codebase/stack-detector.js.map +0 -1
- package/dist/ai/codebase/tree-generator.d.ts +0 -8
- package/dist/ai/codebase/tree-generator.d.ts.map +0 -1
- package/dist/ai/codebase/tree-generator.js +0 -84
- package/dist/ai/codebase/tree-generator.js.map +0 -1
- package/dist/ai/errors.d.ts +0 -22
- package/dist/ai/errors.d.ts.map +0 -1
- package/dist/ai/errors.js +0 -72
- package/dist/ai/errors.js.map +0 -1
- package/dist/ai/index.d.ts +0 -11
- package/dist/ai/index.d.ts.map +0 -1
- package/dist/ai/index.js +0 -10
- package/dist/ai/index.js.map +0 -1
- package/dist/ai/prompts/prompt-builder.d.ts +0 -134
- package/dist/ai/prompts/prompt-builder.d.ts.map +0 -1
- package/dist/ai/prompts/prompt-builder.js +0 -295
- package/dist/ai/prompts/prompt-builder.js.map +0 -1
- package/dist/ai/prompts/system-prompts.d.ts +0 -41
- package/dist/ai/prompts/system-prompts.d.ts.map +0 -1
- package/dist/ai/prompts/system-prompts.js +0 -512
- package/dist/ai/prompts/system-prompts.js.map +0 -1
- package/dist/ai/provider-factory.d.ts +0 -10
- package/dist/ai/provider-factory.d.ts.map +0 -1
- package/dist/ai/provider-factory.js +0 -49
- package/dist/ai/provider-factory.js.map +0 -1
- package/dist/ai/providers/anthropic-provider.d.ts +0 -24
- package/dist/ai/providers/anthropic-provider.d.ts.map +0 -1
- package/dist/ai/providers/anthropic-provider.js +0 -97
- package/dist/ai/providers/anthropic-provider.js.map +0 -1
- package/dist/ai/providers/ollama-provider.d.ts +0 -13
- package/dist/ai/providers/ollama-provider.d.ts.map +0 -1
- package/dist/ai/providers/ollama-provider.js +0 -16
- package/dist/ai/providers/ollama-provider.js.map +0 -1
- package/dist/ai/providers/openai-provider.d.ts +0 -19
- package/dist/ai/providers/openai-provider.d.ts.map +0 -1
- package/dist/ai/providers/openai-provider.js +0 -84
- package/dist/ai/providers/openai-provider.js.map +0 -1
- package/dist/ai/schemas/ai-response-schemas.d.ts +0 -340
- package/dist/ai/schemas/ai-response-schemas.d.ts.map +0 -1
- package/dist/ai/schemas/ai-response-schemas.js +0 -278
- package/dist/ai/schemas/ai-response-schemas.js.map +0 -1
- package/dist/ai/types.d.ts +0 -76
- package/dist/ai/types.d.ts.map +0 -1
- package/dist/ai/types.js +0 -49
- package/dist/ai/types.js.map +0 -1
- package/dist/ai/validation/index.d.ts +0 -2
- package/dist/ai/validation/index.d.ts.map +0 -1
- package/dist/ai/validation/index.js +0 -2
- package/dist/ai/validation/index.js.map +0 -1
- package/dist/ai/validation/task-validator.d.ts +0 -37
- package/dist/ai/validation/task-validator.d.ts.map +0 -1
- package/dist/ai/validation/task-validator.js +0 -81
- package/dist/ai/validation/task-validator.js.map +0 -1
- package/dist/cli/commands/config.d.ts +0 -8
- package/dist/cli/commands/config.d.ts.map +0 -1
- package/dist/cli/commands/config.js +0 -224
- package/dist/cli/commands/config.js.map +0 -1
- package/dist/cli/commands/estimate.d.ts +0 -3
- package/dist/cli/commands/estimate.d.ts.map +0 -1
- package/dist/cli/commands/estimate.js +0 -368
- package/dist/cli/commands/estimate.js.map +0 -1
- package/dist/cli/commands/init.d.ts +0 -9
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/init.js +0 -166
- package/dist/cli/commands/init.js.map +0 -1
- package/dist/cli/commands/pipeline.d.ts +0 -3
- package/dist/cli/commands/pipeline.d.ts.map +0 -1
- package/dist/cli/commands/pipeline.js +0 -59
- package/dist/cli/commands/pipeline.js.map +0 -1
- package/dist/cli/commands/plan.d.ts +0 -15
- package/dist/cli/commands/plan.d.ts.map +0 -1
- package/dist/cli/commands/plan.js +0 -444
- package/dist/cli/commands/plan.js.map +0 -1
- package/dist/cli/commands/refine.d.ts +0 -10
- package/dist/cli/commands/refine.d.ts.map +0 -1
- package/dist/cli/commands/refine.js +0 -226
- package/dist/cli/commands/refine.js.map +0 -1
- package/dist/cli/commands/revise.d.ts +0 -24
- package/dist/cli/commands/revise.d.ts.map +0 -1
- package/dist/cli/commands/revise.js +0 -572
- package/dist/cli/commands/revise.js.map +0 -1
- package/dist/cli/helpers/task-creation.d.ts +0 -89
- package/dist/cli/helpers/task-creation.d.ts.map +0 -1
- package/dist/cli/helpers/task-creation.js +0 -139
- package/dist/cli/helpers/task-creation.js.map +0 -1
- package/dist/services/ai-service.d.ts +0 -77
- package/dist/services/ai-service.d.ts.map +0 -1
- package/dist/services/ai-service.js +0 -241
- package/dist/services/ai-service.js.map +0 -1
- package/dist/services/artifact-gathering.d.ts +0 -55
- package/dist/services/artifact-gathering.d.ts.map +0 -1
- package/dist/services/artifact-gathering.js +0 -147
- package/dist/services/artifact-gathering.js.map +0 -1
- package/dist/services/operate/advisors.d.ts +0 -625
- package/dist/services/operate/advisors.d.ts.map +0 -1
- package/dist/services/operate/advisors.js +0 -1545
- package/dist/services/operate/advisors.js.map +0 -1
- package/dist/services/operate/artifact-route-generation.d.ts +0 -111
- package/dist/services/operate/artifact-route-generation.d.ts.map +0 -1
- package/dist/services/operate/artifact-route-generation.js +0 -460
- package/dist/services/operate/artifact-route-generation.js.map +0 -1
- package/dist/services/operate/artifacts.d.ts +0 -66
- package/dist/services/operate/artifacts.d.ts.map +0 -1
- package/dist/services/operate/artifacts.js +0 -336
- package/dist/services/operate/artifacts.js.map +0 -1
- package/dist/services/operate/cadence.d.ts +0 -50
- package/dist/services/operate/cadence.d.ts.map +0 -1
- package/dist/services/operate/cadence.js +0 -56
- package/dist/services/operate/cadence.js.map +0 -1
- package/dist/services/operate/canonical.d.ts +0 -18
- package/dist/services/operate/canonical.d.ts.map +0 -1
- package/dist/services/operate/canonical.js +0 -157
- package/dist/services/operate/canonical.js.map +0 -1
- package/dist/services/operate/citation-resolution.d.ts +0 -161
- package/dist/services/operate/citation-resolution.d.ts.map +0 -1
- package/dist/services/operate/citation-resolution.js +0 -593
- package/dist/services/operate/citation-resolution.js.map +0 -1
- package/dist/services/operate/completion.d.ts +0 -80
- package/dist/services/operate/completion.d.ts.map +0 -1
- package/dist/services/operate/completion.js +0 -279
- package/dist/services/operate/completion.js.map +0 -1
- package/dist/services/operate/config.d.ts +0 -154
- package/dist/services/operate/config.d.ts.map +0 -1
- package/dist/services/operate/config.js +0 -791
- package/dist/services/operate/config.js.map +0 -1
- package/dist/services/operate/consolidation.d.ts +0 -18
- package/dist/services/operate/consolidation.d.ts.map +0 -1
- package/dist/services/operate/consolidation.js +0 -539
- package/dist/services/operate/consolidation.js.map +0 -1
- package/dist/services/operate/context-research.d.ts +0 -84
- package/dist/services/operate/context-research.d.ts.map +0 -1
- package/dist/services/operate/context-research.js +0 -448
- package/dist/services/operate/context-research.js.map +0 -1
- package/dist/services/operate/decision-brief.d.ts +0 -237
- package/dist/services/operate/decision-brief.d.ts.map +0 -1
- package/dist/services/operate/decision-brief.js +0 -368
- package/dist/services/operate/decision-brief.js.map +0 -1
- package/dist/services/operate/doctor.d.ts +0 -85
- package/dist/services/operate/doctor.d.ts.map +0 -1
- package/dist/services/operate/doctor.js +0 -1070
- package/dist/services/operate/doctor.js.map +0 -1
- package/dist/services/operate/drafts.d.ts +0 -48
- package/dist/services/operate/drafts.d.ts.map +0 -1
- package/dist/services/operate/drafts.js +0 -398
- package/dist/services/operate/drafts.js.map +0 -1
- package/dist/services/operate/engine.d.ts +0 -151
- package/dist/services/operate/engine.d.ts.map +0 -1
- package/dist/services/operate/engine.js +0 -1896
- package/dist/services/operate/engine.js.map +0 -1
- package/dist/services/operate/event-store.d.ts +0 -113
- package/dist/services/operate/event-store.d.ts.map +0 -1
- package/dist/services/operate/event-store.js +0 -384
- package/dist/services/operate/event-store.js.map +0 -1
- package/dist/services/operate/evidence-cache.d.ts +0 -41
- package/dist/services/operate/evidence-cache.d.ts.map +0 -1
- package/dist/services/operate/evidence-cache.js +0 -193
- package/dist/services/operate/evidence-cache.js.map +0 -1
- package/dist/services/operate/evidence-import.d.ts +0 -40
- package/dist/services/operate/evidence-import.d.ts.map +0 -1
- package/dist/services/operate/evidence-import.js +0 -340
- package/dist/services/operate/evidence-import.js.map +0 -1
- package/dist/services/operate/evidence.d.ts +0 -21
- package/dist/services/operate/evidence.d.ts.map +0 -1
- package/dist/services/operate/evidence.js +0 -20
- package/dist/services/operate/evidence.js.map +0 -1
- package/dist/services/operate/ids.d.ts +0 -7
- package/dist/services/operate/ids.d.ts.map +0 -1
- package/dist/services/operate/ids.js +0 -23
- package/dist/services/operate/ids.js.map +0 -1
- package/dist/services/operate/index.d.ts +0 -16
- package/dist/services/operate/index.d.ts.map +0 -1
- package/dist/services/operate/index.js +0 -1864
- package/dist/services/operate/index.js.map +0 -1
- package/dist/services/operate/integrity.d.ts +0 -81
- package/dist/services/operate/integrity.d.ts.map +0 -1
- package/dist/services/operate/integrity.js +0 -152
- package/dist/services/operate/integrity.js.map +0 -1
- package/dist/services/operate/interaction/action-service.d.ts +0 -34
- package/dist/services/operate/interaction/action-service.d.ts.map +0 -1
- package/dist/services/operate/interaction/action-service.js +0 -103
- package/dist/services/operate/interaction/action-service.js.map +0 -1
- package/dist/services/operate/interaction/answer-service.d.ts +0 -40
- package/dist/services/operate/interaction/answer-service.d.ts.map +0 -1
- package/dist/services/operate/interaction/answer-service.js +0 -317
- package/dist/services/operate/interaction/answer-service.js.map +0 -1
- package/dist/services/operate/interaction/charter-suggestions.d.ts +0 -29
- package/dist/services/operate/interaction/charter-suggestions.d.ts.map +0 -1
- package/dist/services/operate/interaction/charter-suggestions.js +0 -104
- package/dist/services/operate/interaction/charter-suggestions.js.map +0 -1
- package/dist/services/operate/interaction/confirmation-service.d.ts +0 -30
- package/dist/services/operate/interaction/confirmation-service.d.ts.map +0 -1
- package/dist/services/operate/interaction/confirmation-service.js +0 -78
- package/dist/services/operate/interaction/confirmation-service.js.map +0 -1
- package/dist/services/operate/interaction/initialization-replay.d.ts +0 -9
- package/dist/services/operate/interaction/initialization-replay.d.ts.map +0 -1
- package/dist/services/operate/interaction/initialization-replay.js +0 -64
- package/dist/services/operate/interaction/initialization-replay.js.map +0 -1
- package/dist/services/operate/interaction/question-engine.d.ts +0 -41
- package/dist/services/operate/interaction/question-engine.d.ts.map +0 -1
- package/dist/services/operate/interaction/question-engine.js +0 -434
- package/dist/services/operate/interaction/question-engine.js.map +0 -1
- package/dist/services/operate/interaction/question-registry.d.ts +0 -52
- package/dist/services/operate/interaction/question-registry.d.ts.map +0 -1
- package/dist/services/operate/interaction/question-registry.js +0 -305
- package/dist/services/operate/interaction/question-registry.js.map +0 -1
- package/dist/services/operate/interaction/session-service.d.ts +0 -55
- package/dist/services/operate/interaction/session-service.d.ts.map +0 -1
- package/dist/services/operate/interaction/session-service.js +0 -304
- package/dist/services/operate/interaction/session-service.js.map +0 -1
- package/dist/services/operate/interaction/terminal-renderer.d.ts +0 -19
- package/dist/services/operate/interaction/terminal-renderer.d.ts.map +0 -1
- package/dist/services/operate/interaction/terminal-renderer.js +0 -124
- package/dist/services/operate/interaction/terminal-renderer.js.map +0 -1
- package/dist/services/operate/journal.d.ts +0 -34
- package/dist/services/operate/journal.d.ts.map +0 -1
- package/dist/services/operate/journal.js +0 -235
- package/dist/services/operate/journal.js.map +0 -1
- package/dist/services/operate/legacy-import-service.d.ts +0 -58
- package/dist/services/operate/legacy-import-service.d.ts.map +0 -1
- package/dist/services/operate/legacy-import-service.js +0 -922
- package/dist/services/operate/legacy-import-service.js.map +0 -1
- package/dist/services/operate/lifecycle-driver.d.ts +0 -309
- package/dist/services/operate/lifecycle-driver.d.ts.map +0 -1
- package/dist/services/operate/lifecycle-driver.js +0 -434
- package/dist/services/operate/lifecycle-driver.js.map +0 -1
- package/dist/services/operate/lifecycle.d.ts +0 -96
- package/dist/services/operate/lifecycle.d.ts.map +0 -1
- package/dist/services/operate/lifecycle.js +0 -596
- package/dist/services/operate/lifecycle.js.map +0 -1
- package/dist/services/operate/lock-service.d.ts +0 -37
- package/dist/services/operate/lock-service.d.ts.map +0 -1
- package/dist/services/operate/lock-service.js +0 -215
- package/dist/services/operate/lock-service.js.map +0 -1
- package/dist/services/operate/maintenance.d.ts +0 -139
- package/dist/services/operate/maintenance.d.ts.map +0 -1
- package/dist/services/operate/maintenance.js +0 -2200
- package/dist/services/operate/maintenance.js.map +0 -1
- package/dist/services/operate/migration.d.ts +0 -68
- package/dist/services/operate/migration.d.ts.map +0 -1
- package/dist/services/operate/migration.js +0 -243
- package/dist/services/operate/migration.js.map +0 -1
- package/dist/services/operate/mission-dispatch.d.ts +0 -271
- package/dist/services/operate/mission-dispatch.d.ts.map +0 -1
- package/dist/services/operate/mission-dispatch.js +0 -590
- package/dist/services/operate/mission-dispatch.js.map +0 -1
- package/dist/services/operate/outcomes.d.ts +0 -48
- package/dist/services/operate/outcomes.d.ts.map +0 -1
- package/dist/services/operate/outcomes.js +0 -312
- package/dist/services/operate/outcomes.js.map +0 -1
- package/dist/services/operate/pipeline-handoff.d.ts +0 -138
- package/dist/services/operate/pipeline-handoff.d.ts.map +0 -1
- package/dist/services/operate/pipeline-handoff.js +0 -175
- package/dist/services/operate/pipeline-handoff.js.map +0 -1
- package/dist/services/operate/profile-migration.d.ts +0 -69
- package/dist/services/operate/profile-migration.d.ts.map +0 -1
- package/dist/services/operate/profile-migration.js +0 -462
- package/dist/services/operate/profile-migration.js.map +0 -1
- package/dist/services/operate/projection-persistence.d.ts +0 -126
- package/dist/services/operate/projection-persistence.d.ts.map +0 -1
- package/dist/services/operate/projection-persistence.js +0 -752
- package/dist/services/operate/projection-persistence.js.map +0 -1
- package/dist/services/operate/projection.d.ts +0 -37
- package/dist/services/operate/projection.d.ts.map +0 -1
- package/dist/services/operate/projection.js +0 -209
- package/dist/services/operate/projection.js.map +0 -1
- package/dist/services/operate/protocol.d.ts +0 -86
- package/dist/services/operate/protocol.d.ts.map +0 -1
- package/dist/services/operate/protocol.js +0 -76
- package/dist/services/operate/protocol.js.map +0 -1
- package/dist/services/operate/read-only-providers.d.ts +0 -76
- package/dist/services/operate/read-only-providers.d.ts.map +0 -1
- package/dist/services/operate/read-only-providers.js +0 -421
- package/dist/services/operate/read-only-providers.js.map +0 -1
- package/dist/services/operate/redaction.d.ts +0 -74
- package/dist/services/operate/redaction.d.ts.map +0 -1
- package/dist/services/operate/redaction.js +0 -406
- package/dist/services/operate/redaction.js.map +0 -1
- package/dist/services/operate/reducer.d.ts +0 -10
- package/dist/services/operate/reducer.d.ts.map +0 -1
- package/dist/services/operate/reducer.js +0 -11
- package/dist/services/operate/reducer.js.map +0 -1
- package/dist/services/operate/report-html.d.ts +0 -32
- package/dist/services/operate/report-html.d.ts.map +0 -1
- package/dist/services/operate/report-html.js +0 -289
- package/dist/services/operate/report-html.js.map +0 -1
- package/dist/services/operate/reports.d.ts +0 -72
- package/dist/services/operate/reports.d.ts.map +0 -1
- package/dist/services/operate/reports.js +0 -481
- package/dist/services/operate/reports.js.map +0 -1
- package/dist/services/operate/routes.d.ts +0 -133
- package/dist/services/operate/routes.d.ts.map +0 -1
- package/dist/services/operate/routes.js +0 -1577
- package/dist/services/operate/routes.js.map +0 -1
- package/dist/services/operate/scratch.d.ts +0 -81
- package/dist/services/operate/scratch.d.ts.map +0 -1
- package/dist/services/operate/scratch.js +0 -190
- package/dist/services/operate/scratch.js.map +0 -1
- package/dist/services/operate/shipment-observer.d.ts +0 -14
- package/dist/services/operate/shipment-observer.d.ts.map +0 -1
- package/dist/services/operate/shipment-observer.js +0 -320
- package/dist/services/operate/shipment-observer.js.map +0 -1
- package/dist/services/operate/stalled-item-service.d.ts +0 -18
- package/dist/services/operate/stalled-item-service.d.ts.map +0 -1
- package/dist/services/operate/stalled-item-service.js +0 -121
- package/dist/services/operate/stalled-item-service.js.map +0 -1
- package/dist/services/operate/subprocess-env.d.ts +0 -4
- package/dist/services/operate/subprocess-env.d.ts.map +0 -1
- package/dist/services/operate/subprocess-env.js +0 -45
- package/dist/services/operate/subprocess-env.js.map +0 -1
- package/dist/services/operate/types.d.ts +0 -1064
- package/dist/services/operate/types.d.ts.map +0 -1
- package/dist/services/operate/types.js +0 -27
- package/dist/services/operate/types.js.map +0 -1
- package/dist/services/operate/workspace.d.ts +0 -76
- package/dist/services/operate/workspace.d.ts.map +0 -1
- package/dist/services/operate/workspace.js +0 -350
- package/dist/services/operate/workspace.js.map +0 -1
- package/dist/services/revise-service.d.ts +0 -115
- package/dist/services/revise-service.d.ts.map +0 -1
- package/dist/services/revise-service.js +0 -294
- package/dist/services/revise-service.js.map +0 -1
- package/dist/templates/rules/claude/planr-pipeline.md.hbs +0 -69
- package/dist/templates/rules/codex/_pipeline-section.md.hbs +0 -154
- package/dist/templates/rules/cursor/agents/backend-agent.md +0 -299
- package/dist/templates/rules/cursor/agents/db-agent.md +0 -163
- package/dist/templates/rules/cursor/agents/designer-agent.md +0 -219
- package/dist/templates/rules/cursor/agents/devops-agent.md +0 -197
- package/dist/templates/rules/cursor/agents/doc-gen-agent.md +0 -203
- package/dist/templates/rules/cursor/agents/frontend-agent.md +0 -220
- package/dist/templates/rules/cursor/agents/qa-agent.md +0 -170
- package/dist/templates/rules/cursor/agents/specification-agent.md +0 -282
- package/dist/templates/rules/cursor/planr-pipeline-plan.mdc.hbs +0 -196
- package/dist/templates/rules/cursor/planr-pipeline-ship.mdc.hbs +0 -246
- package/dist/templates/rules/cursor/planr-pipeline.mdc.hbs +0 -134
|
@@ -1,2200 +0,0 @@
|
|
|
1
|
-
import { createHmac, randomBytes, randomUUID, timingSafeEqual } from 'node:crypto';
|
|
2
|
-
import { mkdir, open, readdir, readFile, rename, rm, stat, unlink, writeFile, } from 'node:fs/promises';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { advisorResponseContractDetails, assertAdvisorOutputMatchesBrief, attachMandateResponseContract, buildOperatingMandate, collectAdvisorResponseContractIssues, createNativeMissionOperatingRoleResult, createRegistryReconciledAdvisorBrief, DEFAULT_OPERATING_ROLE_RESEARCH_BUDGET_MS, } from './advisors.js';
|
|
5
|
-
import { canonicalDigest, canonicalize, sha256Digest } from './canonical.js';
|
|
6
|
-
import { citationComponentsFromWorkspace } from './citation-resolution.js';
|
|
7
|
-
import { operatingProjectKey, readOperatingAdapterLeaseDurationMs } from './config.js';
|
|
8
|
-
import { buildOperatingBootstrapMap } from './context-research.js';
|
|
9
|
-
import { gateRecordedProposalCitations } from './engine.js';
|
|
10
|
-
import { OperatingEventStore, toPersistedDataGap } from './event-store.js';
|
|
11
|
-
import { OperatingEvidenceCache } from './evidence-cache.js';
|
|
12
|
-
import { guidedSessionStatus, purgeGuidedSessions } from './interaction/session-service.js';
|
|
13
|
-
import { assertCommittedOperatingView, recoverOperatingTransactions } from './journal.js';
|
|
14
|
-
import { withOperatingLock } from './lock-service.js';
|
|
15
|
-
import { assertOperatingArtifact, loadOperatingProtocol } from './protocol.js';
|
|
16
|
-
import { containsSecret, hardBlockedSecretDetections, redactSensitiveText, } from './redaction.js';
|
|
17
|
-
import { cleanOperatingScratch, listAbandonedOperatingScratch } from './scratch.js';
|
|
18
|
-
import { OPERATE_MISSION_PROTOCOL_VERSION, OPERATE_PROTOCOL_VERSION, OPERATE_SCHEMA_VERSION, OperateError, } from './types.js';
|
|
19
|
-
import { readOperatingConfig, readOperatingWorkspaceRoots, refreshOperatingWorkspaceManifest, resolveContainedPath, resolveOperatingPaths, } from './workspace.js';
|
|
20
|
-
function adapterSessionSummary(session) {
|
|
21
|
-
const { roleBriefs: _roleBriefs, roleMandates: _roleMandates, ...summary } = session;
|
|
22
|
-
return summary;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* The response-facing `session` view every harness handoff embeds (FR2 / DevEx
|
|
26
|
-
* T4). It is the machine-local session summary (heavy `roleBriefs`/`roleMandates`
|
|
27
|
-
* stripped) plus `leaseTtlSeconds` — the size of ONE lease window in whole
|
|
28
|
-
* seconds. Together with `session.expiresAt` (the absolute deadline) this lets a
|
|
29
|
-
* caller schedule heartbeats against a real deadline: renew before `expiresAt`,
|
|
30
|
-
* and know each renew/record buys another `leaseTtlSeconds`. Surfaced identically
|
|
31
|
-
* on `prepare`, `record`, `heartbeat`, and `resume` so no handoff kind leaves the
|
|
32
|
-
* lease window invisible.
|
|
33
|
-
*/
|
|
34
|
-
function sessionView(session, leaseDurationMs) {
|
|
35
|
-
return {
|
|
36
|
-
...adapterSessionSummary(session),
|
|
37
|
-
leaseTtlSeconds: Math.floor(leaseDurationMs / 1_000),
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
async function adapterHandoff(session) {
|
|
41
|
-
const recorded = new Set(session.recordedRoles);
|
|
42
|
-
const notEvaluated = session.notEvaluatedRoles ?? {};
|
|
43
|
-
// T-020: a role is terminal once it has recorded a result OR was governed
|
|
44
|
-
// terminal `not-evaluated`. Only in-flight (pending) roles keep the board in
|
|
45
|
-
// `record-required`; an all-terminal board is `finalize-required`, exactly the
|
|
46
|
-
// T-001 wire contract the pipeline handoff validator enforces.
|
|
47
|
-
const isTerminal = (role) => recorded.has(role) || role in notEvaluated;
|
|
48
|
-
const state = session.state === 'cancelled'
|
|
49
|
-
? 'cancelled'
|
|
50
|
-
: session.state === 'finalized'
|
|
51
|
-
? 'continue-required'
|
|
52
|
-
: session.roles.some((role) => !isTerminal(role))
|
|
53
|
-
? 'record-required'
|
|
54
|
-
: 'finalize-required';
|
|
55
|
-
const protocol = await loadOperatingProtocol();
|
|
56
|
-
const handoff = protocol.createOperatingAdapterHandoff({
|
|
57
|
-
protocolVersion: session.protocolVersion ?? '1.3.0',
|
|
58
|
-
phase: session.phase,
|
|
59
|
-
state,
|
|
60
|
-
cycleId: session.cycleId,
|
|
61
|
-
evidenceDigest: session.evidenceDigest,
|
|
62
|
-
runtime: session.runtime,
|
|
63
|
-
idempotencyKey: session.idempotencyKey,
|
|
64
|
-
lease: session.lease,
|
|
65
|
-
expiresAt: session.expiresAt,
|
|
66
|
-
roles: session.roles.map((role) => ({
|
|
67
|
-
roleId: role,
|
|
68
|
-
status: recorded.has(role) ? 'recorded' : role in notEvaluated ? 'not-evaluated' : 'pending',
|
|
69
|
-
// A governed not-evaluated role carries its reason through the handoff;
|
|
70
|
-
// recorded/pending roles omit the field so existing roles stay byte-identical.
|
|
71
|
-
...(role in notEvaluated ? { statusReason: notEvaluated[role] } : {}),
|
|
72
|
-
inputDigest: session.roleInputDigests[role],
|
|
73
|
-
})),
|
|
74
|
-
});
|
|
75
|
-
return protocol.validateOperatingAdapterHandoffBindings(handoff);
|
|
76
|
-
}
|
|
77
|
-
function adapterPhase(roles) {
|
|
78
|
-
return roles.length === 1 && roles[0] === 'chair' ? 'chair' : 'advisors';
|
|
79
|
-
}
|
|
80
|
-
function sameRoleSet(left, right) {
|
|
81
|
-
return (left.length === right.length &&
|
|
82
|
-
[...left].sort().every((role, index) => role === [...right].sort()[index]));
|
|
83
|
-
}
|
|
84
|
-
function sessionExpired(session, nowMs = Date.now()) {
|
|
85
|
-
return Date.parse(session.expiresAt) <= nowMs;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* FR4: the board's identity is the hash of its event-chain genesis event (the
|
|
89
|
-
* event whose `previousEventHash` is null). It is immutable for a board
|
|
90
|
-
* generation — appending events never rewrites the genesis — and a board
|
|
91
|
-
* re-inited at the same path re-genesises the chain, so the identity changes.
|
|
92
|
-
* Machine-local adapter sessions are bound to it so a session from a superseded
|
|
93
|
-
* generation is never matched or reused by the current board. Returns '' when
|
|
94
|
-
* no committed chain exists yet, or if the chain cannot be read/verified (that
|
|
95
|
-
* failure is surfaced by the dedicated event-replay diagnostics, not here).
|
|
96
|
-
*/
|
|
97
|
-
async function committedBoardIdentity(store) {
|
|
98
|
-
try {
|
|
99
|
-
const { events } = await store.replay();
|
|
100
|
-
const genesis = events.find((event) => event.previousEventHash === null) ?? events[0];
|
|
101
|
-
return genesis?.eventHash ?? '';
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
return '';
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
async function removeMachineLocalCacheDir(target) {
|
|
108
|
-
const entries = await readdir(target, { withFileTypes: true }).catch(() => []);
|
|
109
|
-
const removed = entries.filter((entry) => entry.isFile() && entry.name.endsWith('.json')).length;
|
|
110
|
-
await rm(target, { recursive: true, force: true });
|
|
111
|
-
return removed;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* FR4: purge the board's machine-local advisor sessions (`<localRoot>/advisors/`)
|
|
115
|
-
* and incremental evidence baselines (`<localRoot>/evidence/incremental/`). A
|
|
116
|
-
* committed `operate init` apply calls this so a board re-inited at the same path
|
|
117
|
-
* never inherits a prior generation's sessions or cached baselines, and
|
|
118
|
-
* `operate cache purge` calls it so the doctor's staleness diagnostics have a
|
|
119
|
-
* scoped fix command. Both surfaces are rebuildable machine-local caches, never
|
|
120
|
-
* committed protocol artifacts.
|
|
121
|
-
*/
|
|
122
|
-
export async function purgeBoardMachineLocalCaches(input) {
|
|
123
|
-
const paths = resolveOperatingPaths(input.projectRoot, { localRoot: input.localRoot });
|
|
124
|
-
const removedAdvisorSessions = await removeMachineLocalCacheDir(paths.advisors);
|
|
125
|
-
const removedIncrementalBaselines = await removeMachineLocalCacheDir(path.join(paths.evidence, 'incremental'));
|
|
126
|
-
return { removedAdvisorSessions, removedIncrementalBaselines };
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* FR7 (T-006): sibling machine-local cleanup for OpenPlanr-owned scratch left
|
|
130
|
-
* behind by a session that never finalized. Deliberately NOT folded into
|
|
131
|
-
* `purgeBoardMachineLocalCaches` — scratch has its own narrower per-cycle
|
|
132
|
-
* lifecycle. Removes ONLY scratch a valid `openplanr-operate-scratch` manifest
|
|
133
|
-
* confirms this project wrote and whose lease window has lapsed; it never touches
|
|
134
|
-
* an unowned file found under the scratch root, nor any other machine-local
|
|
135
|
-
* cache. This is the owned-only removal the doctor's abandoned-scratch diagnostic
|
|
136
|
-
* points at, and the sibling `operate cache purge` invokes.
|
|
137
|
-
*/
|
|
138
|
-
export async function purgeAbandonedOperatingScratch(input) {
|
|
139
|
-
const paths = resolveOperatingPaths(input.projectRoot, { localRoot: input.localRoot });
|
|
140
|
-
const abandoned = await listAbandonedOperatingScratch(paths, input.now ? { now: input.now } : {});
|
|
141
|
-
let removed = 0;
|
|
142
|
-
const cycles = [];
|
|
143
|
-
for (const entry of abandoned) {
|
|
144
|
-
const result = await cleanOperatingScratch(paths, entry.cycleId);
|
|
145
|
-
removed += result.removed;
|
|
146
|
-
cycles.push(entry.cycleId);
|
|
147
|
-
}
|
|
148
|
-
return { removed, cycles: cycles.sort() };
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Surface the adapter session lease ergonomically (FR10 / T-008): the absolute
|
|
152
|
-
* `expiresAt` plus the remaining time relative to the resolved clock. Included in
|
|
153
|
-
* every adapter lifecycle response so a native runtime can see, at a glance, how
|
|
154
|
-
* long its prepared session is still valid and when it must resume or re-run —
|
|
155
|
-
* rather than parsing `expiresAt` against wall-clock itself. `remainingMs` is
|
|
156
|
-
* floored at zero so an already-lapsed lease reads as `expired`, never negative.
|
|
157
|
-
*/
|
|
158
|
-
function adapterLeaseStatus(session, nowMs) {
|
|
159
|
-
const remainingMs = Math.max(0, Date.parse(session.expiresAt) - nowMs);
|
|
160
|
-
return {
|
|
161
|
-
expiresAt: session.expiresAt,
|
|
162
|
-
remainingMs,
|
|
163
|
-
remainingSeconds: Math.floor(remainingMs / 1_000),
|
|
164
|
-
expired: remainingMs <= 0,
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
function retryRunCommand(session) {
|
|
168
|
-
return `planr operate run --cycle-id ${session.cycleId} --runtime ${session.runtime} --json`;
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* The command that actually escapes a blocked second binding.
|
|
172
|
-
*
|
|
173
|
-
* A prepare rejected because another session is still open used to be handed
|
|
174
|
-
* `planr operate run …` as its recovery — but that command's prepare
|
|
175
|
-
* continuation re-enters this same branch and returns the identical error with
|
|
176
|
-
* the identical suggestion. An agent following the CLI's own guidance loops
|
|
177
|
-
* forever. The way out is to close the OPEN session, so that is what is named.
|
|
178
|
-
*
|
|
179
|
-
* The open session's lease is deliberately NOT interpolated: it belongs to the
|
|
180
|
-
* holder of that session, and echoing a live credential into an error payload a
|
|
181
|
-
* different caller receives would leak it. The placeholder says where it comes
|
|
182
|
-
* from instead.
|
|
183
|
-
*/
|
|
184
|
-
function closeOpenSessionCommand(session, action = 'cancel') {
|
|
185
|
-
return (`planr operate harness ${action} --cycle-id ${session.cycleId} ` +
|
|
186
|
-
'--evidence-digest <open-session-evidence-digest> --lease <open-session-lease> ' +
|
|
187
|
-
'--idempotency-key <open-session-idempotency-key> --json');
|
|
188
|
-
}
|
|
189
|
-
async function atomicPrivateWrite(target, value) {
|
|
190
|
-
await mkdir(path.dirname(target), { recursive: true, mode: 0o700 });
|
|
191
|
-
const temporary = `${target}.${process.pid}.${randomUUID()}.tmp`;
|
|
192
|
-
await writeFile(temporary, `${canonicalize(value)}\n`, { mode: 0o600 });
|
|
193
|
-
await rename(temporary, target);
|
|
194
|
-
}
|
|
195
|
-
async function atomicBytesWrite(target, value) {
|
|
196
|
-
await mkdir(path.dirname(target), { recursive: true, mode: 0o700 });
|
|
197
|
-
const temporary = `${target}.${process.pid}.${randomUUID()}.tmp`;
|
|
198
|
-
await writeFile(temporary, value, { mode: 0o600 });
|
|
199
|
-
await rename(temporary, target);
|
|
200
|
-
}
|
|
201
|
-
// FR1 (SPEC-005 T-002): `harness record` and `harness heartbeat` both mutate ONE
|
|
202
|
-
// shared, lease-bound session file. T-001 widened the handoff so every pending
|
|
203
|
-
// role is authorized to record the instant it returns; that removed the batch
|
|
204
|
-
// barrier but, on the write side, two records returning together would each read
|
|
205
|
-
// the same `recordedRoles` snapshot and — last writer wins — silently drop the
|
|
206
|
-
// other already-recorded role. That trades lost-work-from-a-barrier for a
|
|
207
|
-
// nondeterministic lost-work-from-a-race, which is worse. T-001 states plainly
|
|
208
|
-
// that this handoff "never schedules concurrent session writes", so preventing
|
|
209
|
-
// the race is a write-side property owned here: serialize the session write per
|
|
210
|
-
// cycle and re-read the freshest snapshot inside the critical section before
|
|
211
|
-
// merging. The in-process chain serializes async writers in this process; the
|
|
212
|
-
// O_EXCL lockfile serializes concurrently spawned `planr operate harness record`
|
|
213
|
-
// processes. The per-role result file (`<cycle>.<role>.json`) is the durable
|
|
214
|
-
// cross-process record — re-adopted on prepare/resume — so a stolen stale lock
|
|
215
|
-
// never loses committed work.
|
|
216
|
-
const sessionCommitTails = new Map();
|
|
217
|
-
async function withInProcessSessionLock(key, operation) {
|
|
218
|
-
const previous = sessionCommitTails.get(key) ?? Promise.resolve();
|
|
219
|
-
let openGate;
|
|
220
|
-
const gate = new Promise((resolve) => {
|
|
221
|
-
openGate = resolve;
|
|
222
|
-
});
|
|
223
|
-
// `tail` resolves (never rejects) only once our gate opens, so the next writer
|
|
224
|
-
// in the chain waits for us regardless of whether our operation threw.
|
|
225
|
-
const tail = previous.then(() => gate);
|
|
226
|
-
sessionCommitTails.set(key, tail);
|
|
227
|
-
await previous;
|
|
228
|
-
try {
|
|
229
|
-
return await operation();
|
|
230
|
-
}
|
|
231
|
-
finally {
|
|
232
|
-
openGate();
|
|
233
|
-
if (sessionCommitTails.get(key) === tail)
|
|
234
|
-
sessionCommitTails.delete(key);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
async function withCrossProcessSessionLock(sessionPath, operation) {
|
|
238
|
-
const lockPath = `${sessionPath}.commit.lock`;
|
|
239
|
-
await mkdir(path.dirname(lockPath), { recursive: true, mode: 0o700 });
|
|
240
|
-
const deadline = Date.now() + 10_000;
|
|
241
|
-
let handle;
|
|
242
|
-
for (;;) {
|
|
243
|
-
try {
|
|
244
|
-
handle = await open(lockPath, 'wx', 0o600);
|
|
245
|
-
break;
|
|
246
|
-
}
|
|
247
|
-
catch (error) {
|
|
248
|
-
if (error.code !== 'EEXIST')
|
|
249
|
-
throw error;
|
|
250
|
-
// Steal only a demonstrably abandoned lock (a crashed record process must
|
|
251
|
-
// never deadlock the session). The per-role result files own committed
|
|
252
|
-
// work, so stealing this mutex risks nothing durable.
|
|
253
|
-
const age = await stat(lockPath)
|
|
254
|
-
.then((info) => Date.now() - info.mtimeMs)
|
|
255
|
-
.catch(() => 0);
|
|
256
|
-
if (age > 30_000) {
|
|
257
|
-
await unlink(lockPath).catch(() => undefined);
|
|
258
|
-
continue;
|
|
259
|
-
}
|
|
260
|
-
if (Date.now() > deadline) {
|
|
261
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', 'Timed out serializing the adapter session write.');
|
|
262
|
-
}
|
|
263
|
-
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
try {
|
|
267
|
-
return await operation();
|
|
268
|
-
}
|
|
269
|
-
finally {
|
|
270
|
-
await handle.close().catch(() => undefined);
|
|
271
|
-
await unlink(lockPath).catch(() => undefined);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* Apply a mutation to the shared adapter session under the cross-process lock,
|
|
276
|
-
* re-reading the freshest on-disk snapshot first so a sibling record committed
|
|
277
|
-
* between the caller's snapshot and now is merged forward rather than clobbered
|
|
278
|
-
* (FR1). The lease/idempotency binding and a recordable (`prepared`/`recording`)
|
|
279
|
-
* state are re-asserted inside the critical section, so a concurrent cancel or
|
|
280
|
-
* expiry cannot be silently overwritten. Callers must already hold the
|
|
281
|
-
* in-process session lock for the same `target`.
|
|
282
|
-
*/
|
|
283
|
-
async function commitSessionWrite(target, input) {
|
|
284
|
-
return withCrossProcessSessionLock(target, async () => {
|
|
285
|
-
const current = await readAdapterSession(input.projectRoot, input.cycleId, input.localRoot, input.nowMs);
|
|
286
|
-
assertAdapterBinding(current, input.lease, input.idempotencyKey, input.evidenceDigest);
|
|
287
|
-
if (!['prepared', 'recording'].includes(current.state)) {
|
|
288
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', `Adapter session is ${current.state}; its lease-bound write is no longer valid.`, { recoveryCommand: retryRunCommand(current) });
|
|
289
|
-
}
|
|
290
|
-
const next = input.apply(current);
|
|
291
|
-
await atomicPrivateWrite(target, next);
|
|
292
|
-
return next;
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* FR4/FR5: commit a just-recorded role's canonical `advisory.recorded` event and
|
|
297
|
-
* materialize the readable partial projection immediately, so `planr operate
|
|
298
|
-
* report`/`status` and `.planr/operate/cycles/<id>/` reflect every validated
|
|
299
|
-
* lens BEFORE Chair runs — not only at finalize. The commit is idempotent (a
|
|
300
|
-
* role already committed by a prior record or a finalize reconciliation is
|
|
301
|
-
* skipped; a different digest for the same role is the same isolation error
|
|
302
|
-
* finalize raises) and best-effort under concurrency: if another writer holds the
|
|
303
|
-
* project lock or advanced the event head between replay and append, the role's
|
|
304
|
-
* validated result is already durable in its machine-local file and session
|
|
305
|
-
* entry, and finalize reconciles the canonical event, so the record defers rather
|
|
306
|
-
* than fails.
|
|
307
|
-
*/
|
|
308
|
-
async function materializeRecordedRole(input) {
|
|
309
|
-
const store = new OperatingEventStore(input.projectRoot, { localRoot: input.localRoot });
|
|
310
|
-
try {
|
|
311
|
-
const alreadyCommitted = new Map((await readPersistedOperatingRoleResults(store, input.cycleId)).map((result) => [
|
|
312
|
-
result.roleId,
|
|
313
|
-
result,
|
|
314
|
-
]));
|
|
315
|
-
const prior = alreadyCommitted.get(input.result.roleId);
|
|
316
|
-
if (prior) {
|
|
317
|
-
if (prior.resultDigest !== input.result.resultDigest) {
|
|
318
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', `Cycle ${input.cycleId} already committed a different ${input.result.roleId} result.`);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
else {
|
|
322
|
-
const initial = await store.replay();
|
|
323
|
-
await withOperatingLock(input.projectRoot, {
|
|
324
|
-
projectKey: operatingProjectKey(input.projectRoot),
|
|
325
|
-
expectedEventHead: initial.eventHead,
|
|
326
|
-
currentEventHead: initial.eventHead,
|
|
327
|
-
localRoot: input.localRoot,
|
|
328
|
-
}, async (lock) => {
|
|
329
|
-
// Re-check under the lock: a concurrent writer may have committed this
|
|
330
|
-
// role between our replay and lock acquisition.
|
|
331
|
-
const committed = new Map((await readPersistedOperatingRoleResults(store, input.cycleId)).map((result) => [
|
|
332
|
-
result.roleId,
|
|
333
|
-
result,
|
|
334
|
-
]));
|
|
335
|
-
if (committed.has(input.result.roleId))
|
|
336
|
-
return;
|
|
337
|
-
const record = await store.putRecord('advisor-result', input.result, { correlationId: input.session.idempotencyKey });
|
|
338
|
-
const advisorReportRecord = input.session.protocolVersion === '1.4.0' && input.advisorReport
|
|
339
|
-
? await store.putRecord('advisor-report', input.advisorReport, {
|
|
340
|
-
correlationId: input.session.idempotencyKey,
|
|
341
|
-
})
|
|
342
|
-
: null;
|
|
343
|
-
const runtimeBinding = (await adapterHandoff(input.session)).binding;
|
|
344
|
-
const event = await store.append({
|
|
345
|
-
type: 'advisory.recorded',
|
|
346
|
-
cycleId: input.cycleId,
|
|
347
|
-
entityId: `${input.cycleId}-${input.result.roleId}`,
|
|
348
|
-
correlationId: input.session.idempotencyKey,
|
|
349
|
-
evidenceRefs: input.result.proposals.flatMap((proposal) => proposal.evidenceRefs),
|
|
350
|
-
payload: {
|
|
351
|
-
recordDigest: record.digest,
|
|
352
|
-
...(advisorReportRecord ? { advisorReportDigest: advisorReportRecord.digest } : {}),
|
|
353
|
-
roleId: input.result.roleId,
|
|
354
|
-
runtimeBinding: {
|
|
355
|
-
runtime: runtimeBinding.runtime,
|
|
356
|
-
runtimeBinding: runtimeBinding.runtimeBinding,
|
|
357
|
-
crossRuntimeFallback: runtimeBinding.crossRuntimeFallback,
|
|
358
|
-
executionMode: runtimeBinding.executionMode,
|
|
359
|
-
assurance: runtimeBinding.assurance,
|
|
360
|
-
toolIsolation: runtimeBinding.toolIsolation,
|
|
361
|
-
},
|
|
362
|
-
},
|
|
363
|
-
...(input.session.protocolVersion === '1.4.0'
|
|
364
|
-
? { protocolVersion: '1.4.0' }
|
|
365
|
-
: {}),
|
|
366
|
-
expectedHead: initial.eventHead.hash,
|
|
367
|
-
actor: { kind: 'runtime', id: 'operate-adapter' },
|
|
368
|
-
});
|
|
369
|
-
await lock.advanceEventHead(initial.eventHead, {
|
|
370
|
-
sequence: event.sequence,
|
|
371
|
-
hash: event.eventHash,
|
|
372
|
-
});
|
|
373
|
-
await store.writeCheckpoint(await store.state());
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
// Refresh the readable projection from the freshest committed state so the
|
|
377
|
-
// recorded lens' Markdown lands under `.planr/operate/cycles/<id>/` at once.
|
|
378
|
-
const { persistOperatingProjections } = await import('./projection-persistence.js');
|
|
379
|
-
await persistOperatingProjections({
|
|
380
|
-
projectRoot: input.projectRoot,
|
|
381
|
-
localRoot: input.localRoot,
|
|
382
|
-
state: await store.state(),
|
|
383
|
-
revalidateEventHead: async () => (await store.replay()).eventHead,
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
catch (error) {
|
|
387
|
-
if (error instanceof OperateError &&
|
|
388
|
-
['E_OPERATE_CYCLE_ACTIVE', 'E_OPERATE_ROUTE_DRIFT'].includes(error.code)) {
|
|
389
|
-
// A concurrent writer holds the project lock or advanced the head between
|
|
390
|
-
// our replay and commit. The validated result is already durable in its
|
|
391
|
-
// machine-local file and session entry; finalize reconciles the canonical
|
|
392
|
-
// event idempotently. Defer rather than fail the record.
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
|
-
throw error;
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
function maximumOperatingOrdinal(records, prefix) {
|
|
399
|
-
return records.reduce((maximum, record) => {
|
|
400
|
-
const match = String(record.id ?? '').match(new RegExp(`^${prefix}-(\\d+)$`));
|
|
401
|
-
return Math.max(maximum, match ? Number(match[1]) : 0);
|
|
402
|
-
}, 0);
|
|
403
|
-
}
|
|
404
|
-
/**
|
|
405
|
-
* SPEC-005 T-019 — persist the citation gate's governed gaps on the agent-native
|
|
406
|
-
* adapter-lifecycle `record` path, exactly as the inline consolidation loop
|
|
407
|
-
* (`engine.ts`) persists its dispatch gaps.
|
|
408
|
-
*
|
|
409
|
-
* A lens whose every proposal is citation-rejected records a schema-legal `quiet`
|
|
410
|
-
* result; the `unresolvable-citation` / `missing-evidence` gaps that record WHY it
|
|
411
|
-
* grounded nothing were previously only echoed transiently in the record response
|
|
412
|
-
* (`citationGaps`) and never reached the event store. So the Chair board —
|
|
413
|
-
* assembled by a later `run` continuation, after this role is already recorded and
|
|
414
|
-
* is never re-dispatched — saw no citation signal in committed state and rendered
|
|
415
|
-
* the lens a false-clean `recorded-quiet` (reason `null`, gapId `null`): the exact
|
|
416
|
-
* dishonest surface SPEC-005 exists to eliminate, on the path real runtimes use.
|
|
417
|
-
* Persisting the governed gap here makes it durable, readable back from the event
|
|
418
|
-
* store, and reconstructible into the `citation-rejected` classification at
|
|
419
|
-
* consolidation (see `engine.ts`).
|
|
420
|
-
*
|
|
421
|
-
* This reuses T-017's landed `toPersistedDataGap` v1.2 projection verbatim — the
|
|
422
|
-
* SAME projection the inline path relies on (category/citations dropped, canonical
|
|
423
|
-
* `GAP-NNN` id) — so the gap validates against the append log / `operating-record`
|
|
424
|
-
* schemas instead of throwing `E_OPERATE_STATE_INVALID` (`$ matched 0/11
|
|
425
|
-
* branches`). It is NOT a second, forked persistence path; it carries T-017's
|
|
426
|
-
* signal across the record→consolidation boundary the inline path never crosses.
|
|
427
|
-
*
|
|
428
|
-
* Idempotent: the citation gate names every gap it opens for a role in that gap's
|
|
429
|
-
* `affectedRoles`, so a role already gap-named in committed state is a no-op —
|
|
430
|
-
* a resume, retry, or idempotent re-record never mints a duplicate under a fresh
|
|
431
|
-
* `GAP-NNN` id.
|
|
432
|
-
*/
|
|
433
|
-
async function persistRecordedRoleGaps(input) {
|
|
434
|
-
if (input.gaps.length === 0)
|
|
435
|
-
return;
|
|
436
|
-
const store = new OperatingEventStore(input.projectRoot, { localRoot: input.localRoot });
|
|
437
|
-
const namesRole = (gap) => (gap.cycleId === undefined || gap.cycleId === input.cycleId) &&
|
|
438
|
-
Array.isArray(gap.affectedRoles) &&
|
|
439
|
-
gap.affectedRoles.includes(input.roleId);
|
|
440
|
-
if ((await store.state()).dataGaps.some(namesRole))
|
|
441
|
-
return;
|
|
442
|
-
try {
|
|
443
|
-
const initial = await store.replay();
|
|
444
|
-
await withOperatingLock(input.projectRoot, {
|
|
445
|
-
projectKey: operatingProjectKey(input.projectRoot),
|
|
446
|
-
expectedEventHead: initial.eventHead,
|
|
447
|
-
currentEventHead: initial.eventHead,
|
|
448
|
-
localRoot: input.localRoot,
|
|
449
|
-
}, async (lock) => {
|
|
450
|
-
// Re-check under the lock: a concurrent writer may have persisted this
|
|
451
|
-
// role's gaps between our replay and lock acquisition.
|
|
452
|
-
const current = await store.state();
|
|
453
|
-
if (current.dataGaps.some(namesRole))
|
|
454
|
-
return;
|
|
455
|
-
let head = initial.eventHead;
|
|
456
|
-
let gapOrdinal = maximumOperatingOrdinal(current.dataGaps, 'GAP');
|
|
457
|
-
for (const rawGap of input.gaps) {
|
|
458
|
-
const gap = toPersistedDataGap(rawGap, () => `GAP-${String(++gapOrdinal).padStart(3, '0')}`);
|
|
459
|
-
await assertOperatingArtifact('operating-data-gap', gap);
|
|
460
|
-
await store.putRecord('data-gap', structuredClone(gap), { correlationId: input.correlationId });
|
|
461
|
-
const event = await store.append({
|
|
462
|
-
type: 'gap.open',
|
|
463
|
-
cycleId: input.cycleId,
|
|
464
|
-
entityId: gap.id,
|
|
465
|
-
correlationId: input.correlationId,
|
|
466
|
-
evidenceRefs: gap.evidenceRefs,
|
|
467
|
-
payload: { record: gap },
|
|
468
|
-
expectedHead: head.hash,
|
|
469
|
-
actor: { kind: 'runtime', id: 'operate-adapter' },
|
|
470
|
-
});
|
|
471
|
-
const next = { sequence: event.sequence, hash: event.eventHash };
|
|
472
|
-
await lock.advanceEventHead(head, next);
|
|
473
|
-
head = next;
|
|
474
|
-
}
|
|
475
|
-
await store.writeCheckpoint(await store.state());
|
|
476
|
-
});
|
|
477
|
-
}
|
|
478
|
-
catch (error) {
|
|
479
|
-
if (error instanceof OperateError &&
|
|
480
|
-
['E_OPERATE_CYCLE_ACTIVE', 'E_OPERATE_ROUTE_DRIFT'].includes(error.code)) {
|
|
481
|
-
// A concurrent writer holds the project lock or advanced the head between our
|
|
482
|
-
// replay and commit. The governed gap is idempotent and content-addressed;
|
|
483
|
-
// the next record/finalize reconciles it. Defer rather than fail the record.
|
|
484
|
-
return;
|
|
485
|
-
}
|
|
486
|
-
throw error;
|
|
487
|
-
}
|
|
488
|
-
const { persistOperatingProjections } = await import('./projection-persistence.js');
|
|
489
|
-
await persistOperatingProjections({
|
|
490
|
-
projectRoot: input.projectRoot,
|
|
491
|
-
localRoot: input.localRoot,
|
|
492
|
-
state: await store.state(),
|
|
493
|
-
revalidateEventHead: async () => (await store.replay()).eventHead,
|
|
494
|
-
});
|
|
495
|
-
}
|
|
496
|
-
/**
|
|
497
|
-
* SPEC-005 T-020 (FR13): the governed gap recording a lens terminal
|
|
498
|
-
* `not_evaluated` because it was dispatched but never returned a result — a true
|
|
499
|
-
* stall on the agent-native adapter-lifecycle path, distinct from T-019's
|
|
500
|
-
* citation-rejected case (a lens that DID return a result grounding zero
|
|
501
|
-
* evidence). Shaped `missing-evidence` in memory so `toPersistedDataGap` mints its
|
|
502
|
-
* canonical `GAP-NNN` id and strips `category` for the v1.2 committed projection —
|
|
503
|
-
* the same projection T-017/T-019 rely on. This gap, in committed state, IS the
|
|
504
|
-
* durable terminal signal: a role with NO committed result but named by such a
|
|
505
|
-
* cycle gap is reconstructed `not_evaluated` at consolidation (`engine.ts`), keyed
|
|
506
|
-
* on that committed-state fact, never the gap prose.
|
|
507
|
-
*/
|
|
508
|
-
function buildTerminalNotEvaluatedGap(input) {
|
|
509
|
-
return {
|
|
510
|
-
kind: 'operating-data-gap',
|
|
511
|
-
schemaVersion: OPERATE_SCHEMA_VERSION,
|
|
512
|
-
protocolVersion: OPERATE_MISSION_PROTOCOL_VERSION,
|
|
513
|
-
id: `GAP-${canonicalDigest({
|
|
514
|
-
roleId: input.roleId,
|
|
515
|
-
cycleId: input.cycleId,
|
|
516
|
-
reason: 'stalled-not-evaluated',
|
|
517
|
-
}).slice('sha256:'.length)}`,
|
|
518
|
-
cycleId: input.cycleId,
|
|
519
|
-
category: 'missing-evidence',
|
|
520
|
-
question: `Why did ${input.roleId} not evaluate this cycle? It was dispatched but never recorded a result.`,
|
|
521
|
-
reason: input.reason,
|
|
522
|
-
unblocks: [],
|
|
523
|
-
affectedRoles: [input.roleId],
|
|
524
|
-
status: 'open',
|
|
525
|
-
owner: input.owner && input.owner.length > 0 ? input.owner : 'chair',
|
|
526
|
-
evidenceRefs: [],
|
|
527
|
-
createdAt: input.now,
|
|
528
|
-
updatedAt: input.now,
|
|
529
|
-
};
|
|
530
|
-
}
|
|
531
|
-
/**
|
|
532
|
-
* SPEC-005 T-020 — terminally govern one dispatched-but-unrecorded lens
|
|
533
|
-
* `not_evaluated` with a reason, in committed state. Shared by the runtime
|
|
534
|
-
* `harness abandon` action (lease-bound) and the operator escape
|
|
535
|
-
* (`reapStalledOperatingRoles`, keyed on a lapsed lease). It persists the governed
|
|
536
|
-
* gap through the SAME durable path T-019's citation gaps use
|
|
537
|
-
* (`persistRecordedRoleGaps` → `gap.open` event), so a terminal transition is
|
|
538
|
-
* always a governed event carrying its reason. Idempotent per role: a role already
|
|
539
|
-
* named by a committed gap is a no-op. Never fabricates a result — the lens
|
|
540
|
-
* contributes zero grounded proposals by construction (it recorded none).
|
|
541
|
-
*/
|
|
542
|
-
async function governTerminalNotEvaluated(input) {
|
|
543
|
-
const config = await readOperatingConfig(input.projectRoot, {
|
|
544
|
-
localRoot: input.localRoot,
|
|
545
|
-
}).catch(() => null);
|
|
546
|
-
const gap = buildTerminalNotEvaluatedGap({
|
|
547
|
-
cycleId: input.cycleId,
|
|
548
|
-
roleId: input.roleId,
|
|
549
|
-
reason: input.reason,
|
|
550
|
-
owner: config?.decisionOwner ?? 'chair',
|
|
551
|
-
now: new Date().toISOString(),
|
|
552
|
-
});
|
|
553
|
-
await persistRecordedRoleGaps({
|
|
554
|
-
projectRoot: input.projectRoot,
|
|
555
|
-
localRoot: input.localRoot,
|
|
556
|
-
cycleId: input.cycleId,
|
|
557
|
-
roleId: input.roleId,
|
|
558
|
-
gaps: [gap],
|
|
559
|
-
correlationId: input.correlationId,
|
|
560
|
-
});
|
|
561
|
-
}
|
|
562
|
-
async function regularFiles(root) {
|
|
563
|
-
const files = [];
|
|
564
|
-
async function visit(directory) {
|
|
565
|
-
for (const entry of await readdir(directory, { withFileTypes: true }).catch(() => [])) {
|
|
566
|
-
const target = path.join(directory, entry.name);
|
|
567
|
-
if (entry.isDirectory())
|
|
568
|
-
await visit(target);
|
|
569
|
-
else if (entry.isFile())
|
|
570
|
-
files.push(target);
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
await visit(root);
|
|
574
|
-
return files.sort();
|
|
575
|
-
}
|
|
576
|
-
function isInside(root, target) {
|
|
577
|
-
const relative = path.relative(path.resolve(root), path.resolve(target));
|
|
578
|
-
return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
|
|
579
|
-
}
|
|
580
|
-
function metadataPath(relativePath) {
|
|
581
|
-
const normalized = relativePath.split(path.sep).join('/');
|
|
582
|
-
return redactSensitiveText(normalized).value;
|
|
583
|
-
}
|
|
584
|
-
async function fileMetadata(target, root, scope, affected) {
|
|
585
|
-
const bytes = await readFile(target);
|
|
586
|
-
return {
|
|
587
|
-
scope,
|
|
588
|
-
path: metadataPath(path.relative(root, target)),
|
|
589
|
-
digest: sha256Digest(bytes),
|
|
590
|
-
size: bytes.byteLength,
|
|
591
|
-
affected,
|
|
592
|
-
};
|
|
593
|
-
}
|
|
594
|
-
export async function operatingCacheAction(input) {
|
|
595
|
-
const paths = resolveOperatingPaths(input.projectRoot, {
|
|
596
|
-
localRoot: input.localRoot,
|
|
597
|
-
});
|
|
598
|
-
const preferences = await readFile(path.join(paths.localRoot, 'preferences.json'), 'utf8')
|
|
599
|
-
.then((raw) => JSON.parse(raw))
|
|
600
|
-
.catch(() => ({ sensitivityCeiling: 'internal' }));
|
|
601
|
-
const cache = new OperatingEvidenceCache(paths.evidence, preferences.sensitivityCeiling ?? 'internal');
|
|
602
|
-
if (input.action === 'status') {
|
|
603
|
-
return {
|
|
604
|
-
evidence: await cache.status(),
|
|
605
|
-
sessions: await guidedSessionStatus({
|
|
606
|
-
projectRoot: input.projectRoot,
|
|
607
|
-
localRoot: input.localRoot,
|
|
608
|
-
}),
|
|
609
|
-
};
|
|
610
|
-
}
|
|
611
|
-
if (!input.confirmed) {
|
|
612
|
-
throw new OperateError('E_OPERATE_AUTHORITY_REQUIRED', 'Purging machine-local evidence requires explicit confirmation.');
|
|
613
|
-
}
|
|
614
|
-
const removed = await cache.purgeExpired(new Date(), { all: true });
|
|
615
|
-
const sessions = await purgeGuidedSessions({
|
|
616
|
-
projectRoot: input.projectRoot,
|
|
617
|
-
localRoot: input.localRoot,
|
|
618
|
-
});
|
|
619
|
-
// FR4/FR11: clearing machine-local caches also drops board-bound adapter
|
|
620
|
-
// sessions and incremental evidence baselines, so this is the scoped fix the
|
|
621
|
-
// doctor names for stale adapter sessions and stale incremental baselines.
|
|
622
|
-
const board = await purgeBoardMachineLocalCaches({
|
|
623
|
-
projectRoot: input.projectRoot,
|
|
624
|
-
localRoot: input.localRoot,
|
|
625
|
-
});
|
|
626
|
-
// FR7: sibling to the board purge — clear only confirmed OpenPlanr-owned stale
|
|
627
|
-
// scratch (its own per-cycle lifecycle, kept out of purgeBoardMachineLocalCaches).
|
|
628
|
-
const scratch = await purgeAbandonedOperatingScratch({
|
|
629
|
-
projectRoot: input.projectRoot,
|
|
630
|
-
localRoot: input.localRoot,
|
|
631
|
-
});
|
|
632
|
-
return {
|
|
633
|
-
removed: removed.length +
|
|
634
|
-
sessions.removed +
|
|
635
|
-
board.removedAdvisorSessions +
|
|
636
|
-
board.removedIncrementalBaselines +
|
|
637
|
-
scratch.removed,
|
|
638
|
-
evidence: { removed: removed.length, entries: removed },
|
|
639
|
-
sessions,
|
|
640
|
-
adapterSessions: { removed: board.removedAdvisorSessions },
|
|
641
|
-
incrementalBaselines: { removed: board.removedIncrementalBaselines },
|
|
642
|
-
scratch: { removed: scratch.removed, cycles: scratch.cycles },
|
|
643
|
-
};
|
|
644
|
-
}
|
|
645
|
-
function integrityKeyPath(projectRoot, localRoot) {
|
|
646
|
-
return path.join(resolveOperatingPaths(projectRoot, { localRoot }).localRoot, 'integrity.key');
|
|
647
|
-
}
|
|
648
|
-
// The committed checkpoint moved under `.state/` in Protocol v1.3; derive its
|
|
649
|
-
// project-relative display path from the resolver so these results never drift
|
|
650
|
-
// from the on-disk layout again.
|
|
651
|
-
function operatingCheckpointRelativePath(projectRoot, localRoot) {
|
|
652
|
-
const paths = resolveOperatingPaths(projectRoot, { localRoot });
|
|
653
|
-
return path.relative(projectRoot, paths.checkpoint).split(path.sep).join('/');
|
|
654
|
-
}
|
|
655
|
-
async function loadIntegrityKey(projectRoot, localRoot) {
|
|
656
|
-
return readFile(integrityKeyPath(projectRoot, localRoot)).catch(() => null);
|
|
657
|
-
}
|
|
658
|
-
function checkpointSigner(key) {
|
|
659
|
-
const keyId = `local:${sha256Digest(key).slice(7, 23)}`;
|
|
660
|
-
return (payload) => ({
|
|
661
|
-
algorithm: 'hmac-sha256',
|
|
662
|
-
keyId,
|
|
663
|
-
value: createHmac('sha256', key).update(payload).digest('base64url'),
|
|
664
|
-
});
|
|
665
|
-
}
|
|
666
|
-
function checkpointKeyFingerprint(keyId) {
|
|
667
|
-
return `digest:${sha256Digest(Buffer.from(keyId)).slice('sha256:'.length)}`;
|
|
668
|
-
}
|
|
669
|
-
export async function operatingIntegrityAction(input) {
|
|
670
|
-
const store = new OperatingEventStore(input.projectRoot, {
|
|
671
|
-
localRoot: input.localRoot,
|
|
672
|
-
});
|
|
673
|
-
const replay = await store.replay();
|
|
674
|
-
if (input.action === 'enable') {
|
|
675
|
-
if (!input.confirmed) {
|
|
676
|
-
throw new OperateError('E_OPERATE_AUTHORITY_REQUIRED', 'Enabling signed checkpoints requires explicit confirmation.');
|
|
677
|
-
}
|
|
678
|
-
const initial = replay.eventHead;
|
|
679
|
-
return withOperatingLock(input.projectRoot, {
|
|
680
|
-
projectKey: operatingProjectKey(input.projectRoot),
|
|
681
|
-
expectedEventHead: initial,
|
|
682
|
-
currentEventHead: initial,
|
|
683
|
-
localRoot: input.localRoot,
|
|
684
|
-
}, async () => {
|
|
685
|
-
const target = integrityKeyPath(input.projectRoot, input.localRoot);
|
|
686
|
-
let key = await loadIntegrityKey(input.projectRoot, input.localRoot);
|
|
687
|
-
if (!key) {
|
|
688
|
-
key = randomBytes(32);
|
|
689
|
-
await mkdir(path.dirname(target), { recursive: true, mode: 0o700 });
|
|
690
|
-
await writeFile(target, key, { mode: 0o600, flag: 'wx' });
|
|
691
|
-
}
|
|
692
|
-
const checkpoint = await store.writeCheckpoint(await store.state(), {
|
|
693
|
-
signer: checkpointSigner(key),
|
|
694
|
-
});
|
|
695
|
-
return {
|
|
696
|
-
status: checkpoint.integrity.status,
|
|
697
|
-
keyId: checkpoint.integrity.status === 'signed' ? checkpoint.integrity.signature.keyId : null,
|
|
698
|
-
checkpoint: operatingCheckpointRelativePath(input.projectRoot, input.localRoot),
|
|
699
|
-
};
|
|
700
|
-
});
|
|
701
|
-
}
|
|
702
|
-
const key = await loadIntegrityKey(input.projectRoot, input.localRoot);
|
|
703
|
-
const checkpoint = await store.readCheckpoint(key
|
|
704
|
-
? {
|
|
705
|
-
requireSignatureVerification: true,
|
|
706
|
-
verifySignature(payload, signature) {
|
|
707
|
-
if (signature.algorithm !== 'hmac-sha256')
|
|
708
|
-
return false;
|
|
709
|
-
const actual = checkpointSigner(key)(payload);
|
|
710
|
-
const left = Buffer.from(actual.value);
|
|
711
|
-
const right = Buffer.from(signature.value);
|
|
712
|
-
return left.length === right.length && timingSafeEqual(left, right);
|
|
713
|
-
},
|
|
714
|
-
}
|
|
715
|
-
: {});
|
|
716
|
-
return {
|
|
717
|
-
eventHead: replay.eventHead,
|
|
718
|
-
checkpoint: checkpoint
|
|
719
|
-
? {
|
|
720
|
-
eventHead: checkpoint.eventHead,
|
|
721
|
-
stateHash: checkpoint.stateHash,
|
|
722
|
-
integrity: checkpoint.integrity,
|
|
723
|
-
verified: checkpoint.integrity.status === 'hash' ||
|
|
724
|
-
(checkpoint.integrity.status === 'signed' && Boolean(key)),
|
|
725
|
-
}
|
|
726
|
-
: null,
|
|
727
|
-
};
|
|
728
|
-
}
|
|
729
|
-
export async function exportOperatingDiagnostics(input) {
|
|
730
|
-
await assertCommittedOperatingView(input.projectRoot, {
|
|
731
|
-
localRoot: input.localRoot,
|
|
732
|
-
});
|
|
733
|
-
const store = new OperatingEventStore(input.projectRoot, {
|
|
734
|
-
localRoot: input.localRoot,
|
|
735
|
-
});
|
|
736
|
-
const state = await store.state();
|
|
737
|
-
const replay = await store.replay();
|
|
738
|
-
const checkpoint = await store.readCheckpoint();
|
|
739
|
-
const output = input.output ?? '.planr/operate/diagnostics.json';
|
|
740
|
-
const target = await resolveContainedPath(input.projectRoot, output);
|
|
741
|
-
const diagnostic = {
|
|
742
|
-
schemaVersion: '1.0.0',
|
|
743
|
-
protocolVersion: OPERATE_PROTOCOL_VERSION,
|
|
744
|
-
generatedAt: new Date().toISOString(),
|
|
745
|
-
eventHead: replay.eventHead,
|
|
746
|
-
checkpoint: checkpoint
|
|
747
|
-
? {
|
|
748
|
-
eventHead: checkpoint.eventHead,
|
|
749
|
-
stateHash: checkpoint.stateHash,
|
|
750
|
-
integrity: checkpoint.integrity,
|
|
751
|
-
}
|
|
752
|
-
: null,
|
|
753
|
-
summary: state.summary,
|
|
754
|
-
paths: {
|
|
755
|
-
commitSafe: '.planr/operate',
|
|
756
|
-
local: '~/.planr/operate/<project-hash>',
|
|
757
|
-
},
|
|
758
|
-
};
|
|
759
|
-
await mkdir(path.dirname(target), { recursive: true, mode: 0o700 });
|
|
760
|
-
await writeFile(target, `${canonicalize(diagnostic)}\n`, { mode: 0o600 });
|
|
761
|
-
return { path: output, digest: canonicalDigest(diagnostic) };
|
|
762
|
-
}
|
|
763
|
-
export async function repairOperatingSecurity(input) {
|
|
764
|
-
const paths = resolveOperatingPaths(input.projectRoot, {
|
|
765
|
-
localRoot: input.localRoot,
|
|
766
|
-
});
|
|
767
|
-
const affected = [];
|
|
768
|
-
for (const target of await regularFiles(paths.root)) {
|
|
769
|
-
const relative = metadataPath(path.relative(input.projectRoot, target));
|
|
770
|
-
const raw = await readFile(target, 'utf8').catch(() => '');
|
|
771
|
-
if (containsSecret(raw))
|
|
772
|
-
affected.push(relative);
|
|
773
|
-
}
|
|
774
|
-
const pendingTransactions = await assertCommittedOperatingView(input.projectRoot, {
|
|
775
|
-
localRoot: input.localRoot,
|
|
776
|
-
}).then(() => false, () => true);
|
|
777
|
-
const preview = {
|
|
778
|
-
affected,
|
|
779
|
-
pendingTransactions,
|
|
780
|
-
actions: [
|
|
781
|
-
'recover incomplete local journals',
|
|
782
|
-
'hold the project writer lock for the complete repair',
|
|
783
|
-
'purge machine-local evidence, advisor, cache, journal, transaction, and prior quarantine data',
|
|
784
|
-
...(affected.length
|
|
785
|
-
? [
|
|
786
|
-
'record metadata-only quarantine evidence, purge affected records, and require explicit Git-history remediation',
|
|
787
|
-
]
|
|
788
|
-
: []),
|
|
789
|
-
],
|
|
790
|
-
};
|
|
791
|
-
if (!input.confirmed)
|
|
792
|
-
return preview;
|
|
793
|
-
const store = new OperatingEventStore(input.projectRoot, {
|
|
794
|
-
localRoot: input.localRoot,
|
|
795
|
-
});
|
|
796
|
-
const initial = await store.replay();
|
|
797
|
-
return withOperatingLock(input.projectRoot, {
|
|
798
|
-
projectKey: operatingProjectKey(input.projectRoot),
|
|
799
|
-
expectedEventHead: initial.eventHead,
|
|
800
|
-
currentEventHead: initial.eventHead,
|
|
801
|
-
localRoot: input.localRoot,
|
|
802
|
-
}, async (lock) => {
|
|
803
|
-
// The project writer lock is held before journal recovery or any purge.
|
|
804
|
-
// If another operating mutation starts while repair is active, it fails
|
|
805
|
-
// with E_OPERATE_CYCLE_ACTIVE instead of racing the discontinuity.
|
|
806
|
-
const lockedReplay = await store.replay();
|
|
807
|
-
lock.assertEventHead(lockedReplay.eventHead);
|
|
808
|
-
const recovered = await recoverOperatingTransactions(input.projectRoot, {
|
|
809
|
-
localRoot: input.localRoot,
|
|
810
|
-
});
|
|
811
|
-
const oldCheckpoint = await store.readCheckpoint().catch(() => null);
|
|
812
|
-
const operatingFiles = await regularFiles(paths.root);
|
|
813
|
-
const freshAffectedTargets = [];
|
|
814
|
-
for (const target of operatingFiles) {
|
|
815
|
-
const raw = await readFile(target, 'utf8').catch(() => '');
|
|
816
|
-
if (containsSecret(raw))
|
|
817
|
-
freshAffectedTargets.push(target);
|
|
818
|
-
}
|
|
819
|
-
const freshAffected = freshAffectedTargets
|
|
820
|
-
.map((target) => metadataPath(path.relative(input.projectRoot, target)))
|
|
821
|
-
.sort();
|
|
822
|
-
const purgeRoots = [
|
|
823
|
-
paths.cache,
|
|
824
|
-
paths.evidence,
|
|
825
|
-
paths.advisors,
|
|
826
|
-
paths.journals,
|
|
827
|
-
paths.transactions,
|
|
828
|
-
paths.quarantine,
|
|
829
|
-
];
|
|
830
|
-
const localFiles = await regularFiles(paths.localRoot);
|
|
831
|
-
const localPurgeTargets = new Set(localFiles.filter((target) => purgeRoots.some((root) => isInside(root, target))));
|
|
832
|
-
for (const target of localFiles) {
|
|
833
|
-
if (isInside(paths.locks, target) ||
|
|
834
|
-
target === integrityKeyPath(input.projectRoot, input.localRoot)) {
|
|
835
|
-
continue;
|
|
836
|
-
}
|
|
837
|
-
const raw = await readFile(target, 'utf8').catch(() => '');
|
|
838
|
-
if (containsSecret(raw))
|
|
839
|
-
localPurgeTargets.add(target);
|
|
840
|
-
}
|
|
841
|
-
if (freshAffected.length > 0) {
|
|
842
|
-
const recoveryId = `RCV-${randomUUID()}`;
|
|
843
|
-
const confirmedAt = new Date().toISOString();
|
|
844
|
-
const quarantineRoot = path.join(paths.quarantine, recoveryId);
|
|
845
|
-
const commitSafeMetadata = await Promise.all(operatingFiles.map((target) => fileMetadata(target, input.projectRoot, 'commit-safe', freshAffectedTargets.includes(target))));
|
|
846
|
-
const localMetadata = await Promise.all([...localPurgeTargets]
|
|
847
|
-
.sort()
|
|
848
|
-
.map((target) => fileMetadata(target, paths.localRoot, 'machine-local', true)));
|
|
849
|
-
for (const root of purgeRoots) {
|
|
850
|
-
await rm(root, { recursive: true, force: true });
|
|
851
|
-
}
|
|
852
|
-
for (const target of localPurgeTargets) {
|
|
853
|
-
await unlink(target).catch(() => undefined);
|
|
854
|
-
}
|
|
855
|
-
const quarantineManifest = {
|
|
856
|
-
implementation: 'openplanr-operate-security-quarantine',
|
|
857
|
-
state: 'quarantined',
|
|
858
|
-
recoveryId,
|
|
859
|
-
createdAt: confirmedAt,
|
|
860
|
-
oldHead: initial.eventHead,
|
|
861
|
-
affectedPaths: freshAffected,
|
|
862
|
-
files: [...commitSafeMetadata, ...localMetadata].sort((left, right) => left.scope.localeCompare(right.scope) || left.path.localeCompare(right.path)),
|
|
863
|
-
};
|
|
864
|
-
const quarantineManifestDigest = canonicalDigest(quarantineManifest);
|
|
865
|
-
await atomicPrivateWrite(path.join(quarantineRoot, 'manifest.json'), quarantineManifest);
|
|
866
|
-
await input.faultInjector?.('project-quarantined');
|
|
867
|
-
const preserved = new Set([paths.config, paths.charter, paths.workspace]);
|
|
868
|
-
for (const target of operatingFiles) {
|
|
869
|
-
if (preserved.has(target)) {
|
|
870
|
-
const raw = await readFile(target, 'utf8');
|
|
871
|
-
if (containsSecret(raw)) {
|
|
872
|
-
await atomicBytesWrite(target, redactSensitiveText(raw).value);
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
else {
|
|
876
|
-
await unlink(target).catch(() => undefined);
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
await mkdir(path.dirname(paths.events), {
|
|
880
|
-
recursive: true,
|
|
881
|
-
mode: 0o700,
|
|
882
|
-
});
|
|
883
|
-
await atomicBytesWrite(paths.events, '');
|
|
884
|
-
const reason = 'Explicit authority confirmed sensitive-state quarantine and event-chain re-genesis.';
|
|
885
|
-
const guidance = [
|
|
886
|
-
'Rotate every exposed credential immediately.',
|
|
887
|
-
'Remove affected bytes from Git history with an approved history-rewrite procedure.',
|
|
888
|
-
'Notify repository collaborators before force-updating protected branches.',
|
|
889
|
-
'Run `planr operate integrity status` and a fresh deep operating cycle.',
|
|
890
|
-
].join(' ');
|
|
891
|
-
const record = {
|
|
892
|
-
kind: 'operating-recovery-record',
|
|
893
|
-
schemaVersion: OPERATE_SCHEMA_VERSION,
|
|
894
|
-
protocolVersion: OPERATE_PROTOCOL_VERSION,
|
|
895
|
-
id: recoveryId,
|
|
896
|
-
transactionId: null,
|
|
897
|
-
action: 'restore-backup',
|
|
898
|
-
reason,
|
|
899
|
-
previewDigest: canonicalDigest(preview),
|
|
900
|
-
fromHead: initial.eventHead,
|
|
901
|
-
toHead: { sequence: 1, hash: null },
|
|
902
|
-
outcome: 'recovered',
|
|
903
|
-
confirmedBy: 'operate-cli',
|
|
904
|
-
createdAt: confirmedAt,
|
|
905
|
-
};
|
|
906
|
-
await assertOperatingArtifact('operating-recovery-record', record);
|
|
907
|
-
const saved = await store.putRecord('recovery', record, { correlationId: recoveryId, createdAt: confirmedAt });
|
|
908
|
-
const oldCheckpointSummary = oldCheckpoint
|
|
909
|
-
? {
|
|
910
|
-
stateHash: oldCheckpoint.stateHash,
|
|
911
|
-
integrityStatus: oldCheckpoint.integrity.status,
|
|
912
|
-
keyId: oldCheckpoint.integrity.status === 'signed'
|
|
913
|
-
? checkpointKeyFingerprint(oldCheckpoint.integrity.signature.keyId)
|
|
914
|
-
: null,
|
|
915
|
-
}
|
|
916
|
-
: null;
|
|
917
|
-
const event = await store.append({
|
|
918
|
-
type: 'security.discontinuity',
|
|
919
|
-
cycleId: 'CYCLE-000',
|
|
920
|
-
entityId: recoveryId,
|
|
921
|
-
timestamp: confirmedAt,
|
|
922
|
-
actor: { kind: 'human', id: 'operate-cli' },
|
|
923
|
-
correlationId: recoveryId,
|
|
924
|
-
expectedHead: null,
|
|
925
|
-
payload: {
|
|
926
|
-
oldHead: initial.eventHead,
|
|
927
|
-
oldCheckpoint: oldCheckpointSummary,
|
|
928
|
-
authority: {
|
|
929
|
-
kind: 'human',
|
|
930
|
-
id: 'operate-cli',
|
|
931
|
-
confirmedAt,
|
|
932
|
-
},
|
|
933
|
-
remediation: {
|
|
934
|
-
reasonDigest: canonicalDigest(reason),
|
|
935
|
-
guidanceDigest: canonicalDigest(guidance),
|
|
936
|
-
affectedPathsDigest: canonicalDigest(freshAffected),
|
|
937
|
-
quarantineManifestDigest,
|
|
938
|
-
},
|
|
939
|
-
recoveryRecordDigest: saved.digest,
|
|
940
|
-
requiresSignedCheckpoint: true,
|
|
941
|
-
},
|
|
942
|
-
});
|
|
943
|
-
const next = { sequence: event.sequence, hash: event.eventHash };
|
|
944
|
-
await lock.advanceEventHead(initial.eventHead, next);
|
|
945
|
-
let key = await loadIntegrityKey(input.projectRoot, input.localRoot);
|
|
946
|
-
if (!key) {
|
|
947
|
-
key = randomBytes(32);
|
|
948
|
-
await atomicBytesWrite(integrityKeyPath(input.projectRoot, input.localRoot), key);
|
|
949
|
-
}
|
|
950
|
-
const checkpoint = await store.writeCheckpoint(await store.state(), {
|
|
951
|
-
signer: checkpointSigner(key),
|
|
952
|
-
});
|
|
953
|
-
return {
|
|
954
|
-
recoveredTransactions: recovered,
|
|
955
|
-
purgedEntries: localPurgeTargets.size,
|
|
956
|
-
record,
|
|
957
|
-
quarantine: {
|
|
958
|
-
root: quarantineRoot,
|
|
959
|
-
manifestDigest: quarantineManifestDigest,
|
|
960
|
-
fileCount: quarantineManifest.files.length,
|
|
961
|
-
},
|
|
962
|
-
checkpoint: {
|
|
963
|
-
integrity: checkpoint.integrity,
|
|
964
|
-
path: operatingCheckpointRelativePath(input.projectRoot, input.localRoot),
|
|
965
|
-
},
|
|
966
|
-
guidance,
|
|
967
|
-
};
|
|
968
|
-
}
|
|
969
|
-
for (const root of purgeRoots) {
|
|
970
|
-
await rm(root, { recursive: true, force: true });
|
|
971
|
-
}
|
|
972
|
-
for (const target of localPurgeTargets) {
|
|
973
|
-
await unlink(target).catch(() => undefined);
|
|
974
|
-
}
|
|
975
|
-
const record = {
|
|
976
|
-
kind: 'operating-recovery-record',
|
|
977
|
-
schemaVersion: OPERATE_SCHEMA_VERSION,
|
|
978
|
-
protocolVersion: OPERATE_PROTOCOL_VERSION,
|
|
979
|
-
id: `RCV-${randomUUID()}`,
|
|
980
|
-
transactionId: null,
|
|
981
|
-
action: 'recover-journal',
|
|
982
|
-
reason: 'Explicit security repair recovered local journals and purged local evidence.',
|
|
983
|
-
previewDigest: canonicalDigest(preview),
|
|
984
|
-
fromHead: initial.eventHead,
|
|
985
|
-
toHead: initial.eventHead,
|
|
986
|
-
outcome: 'recovered',
|
|
987
|
-
confirmedBy: 'operate-cli',
|
|
988
|
-
createdAt: new Date().toISOString(),
|
|
989
|
-
};
|
|
990
|
-
await assertOperatingArtifact('operating-recovery-record', record);
|
|
991
|
-
const saved = await store.putRecord('recovery', record, {
|
|
992
|
-
correlationId: record.id,
|
|
993
|
-
});
|
|
994
|
-
const event = await store.append({
|
|
995
|
-
type: 'recovery.performed',
|
|
996
|
-
cycleId: (await store.state()).summary.currentCycleId ?? 'CYCLE-000',
|
|
997
|
-
entityId: record.id,
|
|
998
|
-
payload: { recordDigest: saved.digest },
|
|
999
|
-
expectedHead: initial.eventHead.hash,
|
|
1000
|
-
actor: { kind: 'human', id: 'operate-cli' },
|
|
1001
|
-
});
|
|
1002
|
-
const next = { sequence: event.sequence, hash: event.eventHash };
|
|
1003
|
-
await lock.advanceEventHead(initial.eventHead, next);
|
|
1004
|
-
await store.writeCheckpoint(await store.state());
|
|
1005
|
-
return {
|
|
1006
|
-
recoveredTransactions: recovered,
|
|
1007
|
-
purgedEntries: localPurgeTargets.size,
|
|
1008
|
-
record,
|
|
1009
|
-
};
|
|
1010
|
-
});
|
|
1011
|
-
}
|
|
1012
|
-
function adapterSessionPath(projectRoot, cycleId, localRoot) {
|
|
1013
|
-
return path.join(resolveOperatingPaths(projectRoot, { localRoot }).advisors, `${cycleId}.json`);
|
|
1014
|
-
}
|
|
1015
|
-
async function persistedAdapterEvidence(store, cycleId) {
|
|
1016
|
-
const replay = await store.replay();
|
|
1017
|
-
const event = [...replay.events]
|
|
1018
|
-
.reverse()
|
|
1019
|
-
.find((candidate) => candidate.cycleId === cycleId &&
|
|
1020
|
-
candidate.type === 'evidence.collected' &&
|
|
1021
|
-
typeof candidate.payload.recordDigest === 'string');
|
|
1022
|
-
if (!event) {
|
|
1023
|
-
throw new OperateError('E_OPERATE_EVIDENCE_NOT_READY', `Cycle ${cycleId} has no committed evidence snapshot for native dispatch.`);
|
|
1024
|
-
}
|
|
1025
|
-
const record = await store.readRecord(event.payload.recordDigest);
|
|
1026
|
-
if (record.recordType !== 'evidence-metadata') {
|
|
1027
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', `Cycle ${cycleId} evidence references an unexpected record type.`);
|
|
1028
|
-
}
|
|
1029
|
-
return assertOperatingArtifact('operating-evidence', record.content);
|
|
1030
|
-
}
|
|
1031
|
-
export async function readPersistedOperatingRoleResults(store, cycleId) {
|
|
1032
|
-
const replay = await store.replay();
|
|
1033
|
-
const byRole = new Map();
|
|
1034
|
-
for (const event of replay.events) {
|
|
1035
|
-
if (event.cycleId !== cycleId ||
|
|
1036
|
-
event.type !== 'advisory.recorded' ||
|
|
1037
|
-
typeof event.payload.recordDigest !== 'string') {
|
|
1038
|
-
continue;
|
|
1039
|
-
}
|
|
1040
|
-
const record = await store.readRecord(event.payload.recordDigest);
|
|
1041
|
-
if (record.recordType !== 'advisor-result') {
|
|
1042
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', `Cycle ${cycleId} advisor event references an unexpected record type.`);
|
|
1043
|
-
}
|
|
1044
|
-
const result = await assertOperatingArtifact('operating-role-result', record.content);
|
|
1045
|
-
byRole.set(result.roleId, result);
|
|
1046
|
-
}
|
|
1047
|
-
return [...byRole.values()].sort((left, right) => left.roleId.localeCompare(right.roleId));
|
|
1048
|
-
}
|
|
1049
|
-
/** Read the rich Protocol v1.4 analysis sidecars associated with advisor events. */
|
|
1050
|
-
export async function readPersistedOperatingAdvisorReports(store, cycleId) {
|
|
1051
|
-
const protocol = await loadOperatingProtocol();
|
|
1052
|
-
const reports = new Map();
|
|
1053
|
-
for (const event of (await store.replay()).events) {
|
|
1054
|
-
if (event.cycleId !== cycleId ||
|
|
1055
|
-
event.type !== 'advisory.recorded' ||
|
|
1056
|
-
typeof event.payload.advisorReportDigest !== 'string' ||
|
|
1057
|
-
typeof event.payload.roleId !== 'string') {
|
|
1058
|
-
continue;
|
|
1059
|
-
}
|
|
1060
|
-
const record = await store.readRecord(event.payload.advisorReportDigest);
|
|
1061
|
-
if (record.recordType !== 'advisor-report')
|
|
1062
|
-
continue;
|
|
1063
|
-
const issues = protocol.validateProtocolArtifact('operating-advisor-response', record.content, {
|
|
1064
|
-
protocolVersion: '1.4.0',
|
|
1065
|
-
});
|
|
1066
|
-
if (issues.length > 0) {
|
|
1067
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', `Cycle ${cycleId} contains an invalid agent-native advisor report.`, { roleId: event.payload.roleId, issues: issues.slice(0, 8) });
|
|
1068
|
-
}
|
|
1069
|
-
reports.set(event.payload.roleId, record.content);
|
|
1070
|
-
}
|
|
1071
|
-
return reports;
|
|
1072
|
-
}
|
|
1073
|
-
async function readAdapterSession(projectRoot, cycleId, localRoot, nowMs = Date.now()) {
|
|
1074
|
-
const parsed = JSON.parse(await readFile(adapterSessionPath(projectRoot, cycleId, localRoot), 'utf8'));
|
|
1075
|
-
const session = {
|
|
1076
|
-
...parsed,
|
|
1077
|
-
phase: parsed.phase ?? adapterPhase(parsed.roles ?? []),
|
|
1078
|
-
runtime: parsed.runtime ?? 'auto',
|
|
1079
|
-
};
|
|
1080
|
-
if (!['openplanr-operate-adapter', 'openplanr-operate-harness'].includes(session.implementation)) {
|
|
1081
|
-
throw new OperateError('E_OPERATE_ADVISOR_FAILED', 'Operate harness session is invalid.');
|
|
1082
|
-
}
|
|
1083
|
-
// Expiry is evaluated against the resolved clock (an injected clock in tests,
|
|
1084
|
-
// wall-clock in production) so a lease that lapsed after its refresh window is
|
|
1085
|
-
// still rejected here even when the caller supplies a deterministic clock.
|
|
1086
|
-
if (sessionExpired(session, nowMs)) {
|
|
1087
|
-
throw new OperateError('E_OPERATE_ADVISOR_FAILED', 'Adapter session expired.', {
|
|
1088
|
-
cycleId,
|
|
1089
|
-
recoveryCommand: retryRunCommand(session),
|
|
1090
|
-
});
|
|
1091
|
-
}
|
|
1092
|
-
return session;
|
|
1093
|
-
}
|
|
1094
|
-
function assertAdapterBinding(session, lease, idempotencyKey, evidenceDigest) {
|
|
1095
|
-
if (session.lease !== lease ||
|
|
1096
|
-
session.idempotencyKey !== idempotencyKey ||
|
|
1097
|
-
session.evidenceDigest !== evidenceDigest) {
|
|
1098
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', 'Adapter evidence, lease, or idempotency binding does not match the prepared session.');
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1101
|
-
async function assertAdapterCycleBinding(input, session) {
|
|
1102
|
-
const store = new OperatingEventStore(input.projectRoot, { localRoot: input.localRoot });
|
|
1103
|
-
const state = await store.state();
|
|
1104
|
-
const cycle = state.cycles.find((record) => record.id === input.cycleId);
|
|
1105
|
-
if (!cycle || !['advising', 'blocked'].includes(cycle.state)) {
|
|
1106
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', `Adapter session requires cycle ${input.cycleId} to remain advising or blocked.`);
|
|
1107
|
-
}
|
|
1108
|
-
const cycleManifest = cycle;
|
|
1109
|
-
if (cycleManifest.producer.runtime !== session.runtime) {
|
|
1110
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', 'Adapter runtime no longer matches the immutable cycle runtime.');
|
|
1111
|
-
}
|
|
1112
|
-
const evidence = await persistedAdapterEvidence(store, input.cycleId);
|
|
1113
|
-
if (evidence.fingerprint !== session.evidenceDigest) {
|
|
1114
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', 'Adapter evidence no longer matches the committed cycle snapshot.');
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
/**
|
|
1118
|
-
* The machine-local sensitivity ceiling (default `internal`), read the same way
|
|
1119
|
-
* the evidence cache and cycle engine read it. Mission packets and their tool
|
|
1120
|
-
* grants are narrowed to this ceiling.
|
|
1121
|
-
*/
|
|
1122
|
-
async function readAdapterSensitivityCeiling(projectRoot, localRoot) {
|
|
1123
|
-
const paths = resolveOperatingPaths(projectRoot, { localRoot });
|
|
1124
|
-
return readFile(path.join(paths.localRoot, 'preferences.json'), 'utf8')
|
|
1125
|
-
.then((raw) => JSON.parse(raw).sensitivityCeiling ??
|
|
1126
|
-
'internal')
|
|
1127
|
-
.catch(() => 'internal');
|
|
1128
|
-
}
|
|
1129
|
-
// The mandate `boundaries.roots` items must satisfy this pattern (leading dot
|
|
1130
|
-
// permitted, no `..` traversal), so `.planr` is a valid declared root.
|
|
1131
|
-
const MANDATE_ROOT_PATTERN = /^(?!.*\.\.)[A-Za-z0-9._][A-Za-z0-9._/-]*$/;
|
|
1132
|
-
/**
|
|
1133
|
-
* FR1/FR2: derive a mandate's declared read roots directly from the project
|
|
1134
|
-
* working tree — every top-level directory the agent may traverse — rather than
|
|
1135
|
-
* from a collected evidence index. `.planr/` is ALWAYS declared, whether or not
|
|
1136
|
-
* it exists yet and REGARDLESS of git tracking, because the mission tool surface
|
|
1137
|
-
* (`mission-dispatch.ts`) walks the filesystem directly rather than `git
|
|
1138
|
-
* ls-files`, so a gitignored `.planr/` tree is fully readable (finding 2's
|
|
1139
|
-
* tracked-file gap cannot reproduce here). `.git`/`node_modules` are never
|
|
1140
|
-
* declared, and every root is filtered to the mandate's schema pattern.
|
|
1141
|
-
*/
|
|
1142
|
-
async function deriveOperatingMandateRoots(projectRoot) {
|
|
1143
|
-
const entries = await readdir(projectRoot, { withFileTypes: true }).catch(() => []);
|
|
1144
|
-
const roots = new Set(['.planr']);
|
|
1145
|
-
for (const entry of entries) {
|
|
1146
|
-
if (!entry.isDirectory())
|
|
1147
|
-
continue;
|
|
1148
|
-
if (entry.name === '.git' || entry.name === 'node_modules')
|
|
1149
|
-
continue;
|
|
1150
|
-
if (MANDATE_ROOT_PATTERN.test(entry.name))
|
|
1151
|
-
roots.add(entry.name);
|
|
1152
|
-
}
|
|
1153
|
-
return [...roots].sort();
|
|
1154
|
-
}
|
|
1155
|
-
/**
|
|
1156
|
-
* Refuse advisor text ONLY for a hard-blocked secret category — a known token, an
|
|
1157
|
-
* authorization header, a private key, a JWT, or a credential URL — exactly as the
|
|
1158
|
-
* citation resolver does.
|
|
1159
|
-
*
|
|
1160
|
-
* The soft categories are secret-SHAPED, not secret: a public `token: write`
|
|
1161
|
-
* workflow permission quoted inside an analysis matches `structured-secret`.
|
|
1162
|
-
* Rejecting the whole submission over one of those destroys legitimate work for
|
|
1163
|
-
* content the redaction path already handles — the result body's free text is
|
|
1164
|
-
* redacted inside `createNativeMissionOperatingRoleResult`, and the v1.4 rich
|
|
1165
|
-
* fields are redacted here before they are persisted.
|
|
1166
|
-
*
|
|
1167
|
-
* EVERY offending field is reported in one error, with its detection category, so
|
|
1168
|
-
* a runtime learns the complete list from a single rejection instead of one field
|
|
1169
|
-
* per resubmission. Only locations and categories are disclosed, never the value.
|
|
1170
|
-
*/
|
|
1171
|
-
function assertNoHardBlockedSecrets(fields, context) {
|
|
1172
|
-
const detected = fields.flatMap((field) => typeof field.value === 'string'
|
|
1173
|
-
? hardBlockedSecretDetections(field.value).map((detection) => ({
|
|
1174
|
-
field: field.location,
|
|
1175
|
-
category: detection.category,
|
|
1176
|
-
ruleId: detection.ruleId,
|
|
1177
|
-
line: detection.line,
|
|
1178
|
-
}))
|
|
1179
|
-
: []);
|
|
1180
|
-
if (detected.length === 0)
|
|
1181
|
-
return;
|
|
1182
|
-
const locations = detected.map((entry) => `${entry.field} (${entry.category})`).join(', ');
|
|
1183
|
-
throw new OperateError('E_OPERATE_SECRET_DETECTED', `${context.subject} contains ${detected.length} secret${detected.length === 1 ? '' : 's'} at ${locations}; nothing was persisted.`, { roleId: context.roleId, fields: detected });
|
|
1184
|
-
}
|
|
1185
|
-
/**
|
|
1186
|
-
* Redact the soft (non-hard-blocking) secret shapes out of a v1.4 advisor report
|
|
1187
|
-
* before it is persisted.
|
|
1188
|
-
*
|
|
1189
|
-
* The committed result's free text is already redacted inside
|
|
1190
|
-
* `createNativeMissionOperatingRoleResult`; the report's rich fields
|
|
1191
|
-
* (`analysisMarkdown`, claims, actions) are the only advisor text that reaches the
|
|
1192
|
-
* `advisor-report` record and the committed board Markdown verbatim, so the same
|
|
1193
|
-
* redaction has to run over them here. PII redaction stays off: this is the secret
|
|
1194
|
-
* boundary, not the PII one.
|
|
1195
|
-
*/
|
|
1196
|
-
function redactAdvisorReportText(value) {
|
|
1197
|
-
if (typeof value === 'string')
|
|
1198
|
-
return redactSensitiveText(value, { redactPii: false }).value;
|
|
1199
|
-
if (Array.isArray(value))
|
|
1200
|
-
return value.map(redactAdvisorReportText);
|
|
1201
|
-
if (value && typeof value === 'object') {
|
|
1202
|
-
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
|
|
1203
|
-
key,
|
|
1204
|
-
redactAdvisorReportText(entry),
|
|
1205
|
-
]));
|
|
1206
|
-
}
|
|
1207
|
-
return value;
|
|
1208
|
-
}
|
|
1209
|
-
export async function createOperatingAdapterStartHandoff(input) {
|
|
1210
|
-
const target = adapterSessionPath(input.projectRoot, input.cycleId, input.localRoot);
|
|
1211
|
-
const existing = await readFile(target, 'utf8')
|
|
1212
|
-
.then((raw) => JSON.parse(raw))
|
|
1213
|
-
.catch(() => null);
|
|
1214
|
-
if (existing) {
|
|
1215
|
-
const normalized = {
|
|
1216
|
-
...existing,
|
|
1217
|
-
phase: existing.phase ?? adapterPhase(existing.roles ?? []),
|
|
1218
|
-
runtime: existing.runtime ?? 'auto',
|
|
1219
|
-
};
|
|
1220
|
-
const exact = normalized.evidenceDigest === input.evidenceDigest &&
|
|
1221
|
-
normalized.runtime === input.runtime &&
|
|
1222
|
-
normalized.phase === input.phase &&
|
|
1223
|
-
sameRoleSet(normalized.roles, input.roles);
|
|
1224
|
-
if (!sessionExpired(normalized) && normalized.state !== 'cancelled' && exact) {
|
|
1225
|
-
return adapterHandoff(normalized);
|
|
1226
|
-
}
|
|
1227
|
-
if (!sessionExpired(normalized) &&
|
|
1228
|
-
['prepared', 'recording'].includes(normalized.state) &&
|
|
1229
|
-
!exact) {
|
|
1230
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', `Cycle ${input.cycleId} already has a different active adapter session.`, { recoveryCommand: retryRunCommand(normalized) });
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
const protocol = await loadOperatingProtocol();
|
|
1234
|
-
const handoff = protocol.createOperatingAdapterHandoff({
|
|
1235
|
-
protocolVersion: '1.4.0',
|
|
1236
|
-
phase: input.phase,
|
|
1237
|
-
state: 'prepare-required',
|
|
1238
|
-
cycleId: input.cycleId,
|
|
1239
|
-
evidenceDigest: input.evidenceDigest,
|
|
1240
|
-
runtime: input.runtime,
|
|
1241
|
-
idempotencyKey: `native-${input.cycleId}-${input.phase}-${randomBytes(12).toString('hex')}`,
|
|
1242
|
-
lease: null,
|
|
1243
|
-
expiresAt: null,
|
|
1244
|
-
roles: [...new Set(input.roles)].sort().map((roleId) => ({
|
|
1245
|
-
roleId,
|
|
1246
|
-
status: 'awaiting-prepare',
|
|
1247
|
-
inputDigest: null,
|
|
1248
|
-
})),
|
|
1249
|
-
});
|
|
1250
|
-
return protocol.validateOperatingAdapterHandoffBindings(handoff);
|
|
1251
|
-
}
|
|
1252
|
-
export async function operateAdapterLifecycle(input) {
|
|
1253
|
-
// US-T1 dry-run: `harness validate` checks a draft advisor response against the
|
|
1254
|
-
// EXACT contract `record` enforces, but is read-only — it reads the prepared
|
|
1255
|
-
// session to reuse that role's brief + protocol version, takes NO lease, consumes
|
|
1256
|
-
// NO idempotency key, and mutates nothing. Handled before the record-path guards
|
|
1257
|
-
// (which require an idempotency key and, below, a lease) so a runtime can iterate
|
|
1258
|
-
// on its response with zero state cost. It shares collectAdvisorResponseContract-
|
|
1259
|
-
// Issues with the record path, so the dry-run and the real rejection never diverge.
|
|
1260
|
-
if (input.action === 'validate') {
|
|
1261
|
-
if (!input.cycleId) {
|
|
1262
|
-
throw new OperateError('E_OPERATE_CONFIG_INVALID', 'Adapter validate requires --cycle-id.');
|
|
1263
|
-
}
|
|
1264
|
-
if (!input.role || !input.stdin) {
|
|
1265
|
-
throw new OperateError('E_OPERATE_CONFIG_INVALID', 'Adapter validate requires --role and JSON on stdin.');
|
|
1266
|
-
}
|
|
1267
|
-
const validateNowMs = (input.now?.() ?? new Date()).getTime();
|
|
1268
|
-
// Read-only: `readAdapterSession` reads the prepared session and checks expiry
|
|
1269
|
-
// only — it never asserts or refreshes the lease (that is `assertAdapterBinding`,
|
|
1270
|
-
// deliberately skipped here). Nothing below writes.
|
|
1271
|
-
const session = await readAdapterSession(input.projectRoot, input.cycleId, input.localRoot, validateNowMs);
|
|
1272
|
-
if (!session.roles.includes(input.role)) {
|
|
1273
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', `Role ${input.role} was not bound by adapter prepare.`);
|
|
1274
|
-
}
|
|
1275
|
-
const brief = session.roleBriefs[input.role];
|
|
1276
|
-
let submitted;
|
|
1277
|
-
try {
|
|
1278
|
-
submitted = JSON.parse(input.stdin);
|
|
1279
|
-
}
|
|
1280
|
-
catch {
|
|
1281
|
-
throw new OperateError('E_OPERATE_ADVISOR_FAILED', 'Native advisor response must be one valid JSON document.', { ...advisorResponseContractDetails(brief) });
|
|
1282
|
-
}
|
|
1283
|
-
const issues = await collectAdvisorResponseContractIssues({
|
|
1284
|
-
brief,
|
|
1285
|
-
response: submitted,
|
|
1286
|
-
protocolVersion: session.roleMandates[input.role].protocolVersion,
|
|
1287
|
-
});
|
|
1288
|
-
// Same complete-issues output as a `record` rejection: when the draft fails, it
|
|
1289
|
-
// is one E_OPERATE_ADVISOR_FAILED whose `data.issues` array spans every category
|
|
1290
|
-
// at once — so a runtime's error handling is identical to the record path — but
|
|
1291
|
-
// it consumed no lease and wrote nothing.
|
|
1292
|
-
if (issues.length > 0) {
|
|
1293
|
-
throw new OperateError('E_OPERATE_ADVISOR_FAILED', `Native ${input.role} response does not satisfy the disclosed advisor contract (${issues.length} issue${issues.length === 1 ? '' : 's'}).`, { issues, ...advisorResponseContractDetails(brief) });
|
|
1294
|
-
}
|
|
1295
|
-
return {
|
|
1296
|
-
validated: input.role,
|
|
1297
|
-
valid: true,
|
|
1298
|
-
issues,
|
|
1299
|
-
...advisorResponseContractDetails(brief),
|
|
1300
|
-
};
|
|
1301
|
-
}
|
|
1302
|
-
if (!input.cycleId || !input.idempotencyKey) {
|
|
1303
|
-
throw new OperateError('E_OPERATE_CONFIG_INVALID', 'Adapter calls require --cycle-id and --idempotency-key.');
|
|
1304
|
-
}
|
|
1305
|
-
const nowMs = (input.now?.() ?? new Date()).getTime();
|
|
1306
|
-
// The lease window is a machine-local preference (default 30 minutes, or the
|
|
1307
|
-
// `OPENPLANR_ADAPTER_LEASE_MS` seam). Resolved once so both the fresh `prepare`
|
|
1308
|
-
// expiry and the per-`record` refresh use the same configured duration, and so
|
|
1309
|
-
// every handoff response can echo it as `session.leaseTtlSeconds`.
|
|
1310
|
-
const leaseDurationMs = await readOperatingAdapterLeaseDurationMs(input.projectRoot, {
|
|
1311
|
-
localRoot: input.localRoot,
|
|
1312
|
-
});
|
|
1313
|
-
const target = adapterSessionPath(input.projectRoot, input.cycleId, input.localRoot);
|
|
1314
|
-
if (input.action === 'prepare') {
|
|
1315
|
-
if (!input.evidenceDigest?.startsWith('sha256:')) {
|
|
1316
|
-
throw new OperateError('E_OPERATE_CONFIG_INVALID', 'Adapter prepare requires --evidence-digest.');
|
|
1317
|
-
}
|
|
1318
|
-
const store = new OperatingEventStore(input.projectRoot, {
|
|
1319
|
-
localRoot: input.localRoot,
|
|
1320
|
-
});
|
|
1321
|
-
const state = await store.state();
|
|
1322
|
-
// FR4: the identity of the board that owns this prepare. A machine-local
|
|
1323
|
-
// session bound to any other genesis belongs to a superseded generation.
|
|
1324
|
-
const boardIdentity = await committedBoardIdentity(store);
|
|
1325
|
-
const cycle = state.cycles.find((record) => record.id === input.cycleId);
|
|
1326
|
-
if (!cycle || !['advising', 'blocked'].includes(cycle.state)) {
|
|
1327
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', 'Adapter prepare requires an advising or blocked cycle.');
|
|
1328
|
-
}
|
|
1329
|
-
const protocol = await loadOperatingProtocol();
|
|
1330
|
-
const knownRoles = new Set(protocol.listOperatingRoles().map((role) => role.id));
|
|
1331
|
-
const enabledRoles = (Array.isArray(cycle.enabledRoles) ? cycle.enabledRoles.map(String) : []).filter((role) => knownRoles.has(role));
|
|
1332
|
-
const requestedRoles = input.role
|
|
1333
|
-
? input.role
|
|
1334
|
-
.split(',')
|
|
1335
|
-
.map((role) => role.trim())
|
|
1336
|
-
.filter(Boolean)
|
|
1337
|
-
: enabledRoles.filter((role) => role !== 'chair');
|
|
1338
|
-
const unknownRoles = requestedRoles.filter((role) => !knownRoles.has(role));
|
|
1339
|
-
if (unknownRoles.length > 0) {
|
|
1340
|
-
throw new OperateError('E_OPERATE_CONFIG_INVALID', `Adapter prepare contains unknown roles: ${unknownRoles.sort().join(', ')}.`);
|
|
1341
|
-
}
|
|
1342
|
-
const roles = [...new Set(requestedRoles)]
|
|
1343
|
-
.filter((role) => knownRoles.has(role))
|
|
1344
|
-
.sort();
|
|
1345
|
-
if (roles.length === 0) {
|
|
1346
|
-
throw new OperateError('E_OPERATE_CONFIG_INVALID', 'Adapter prepare requires at least one bound advisor role.');
|
|
1347
|
-
}
|
|
1348
|
-
if (roles.some((role) => !enabledRoles.includes(role))) {
|
|
1349
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', 'Adapter prepare cannot widen the cycle enabled-role set.');
|
|
1350
|
-
}
|
|
1351
|
-
if (roles.includes('chair') && roles.length !== 1) {
|
|
1352
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', 'Chair dispatch must be prepared separately after independent advisor results.');
|
|
1353
|
-
}
|
|
1354
|
-
const baseEvidence = await persistedAdapterEvidence(store, input.cycleId);
|
|
1355
|
-
if (baseEvidence.fingerprint !== input.evidenceDigest) {
|
|
1356
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', 'Adapter evidence digest does not match the committed cycle snapshot.');
|
|
1357
|
-
}
|
|
1358
|
-
const phase = adapterPhase(roles);
|
|
1359
|
-
const runtime = cycle.producer.runtime;
|
|
1360
|
-
const existing = await readFile(target, 'utf8')
|
|
1361
|
-
.then((raw) => JSON.parse(raw))
|
|
1362
|
-
.catch(() => null);
|
|
1363
|
-
// Recovery semantics (FR10 / T-008, behavior unchanged — documented here so
|
|
1364
|
-
// the lease ergonomics read coherently): when a prior session for this cycle
|
|
1365
|
-
// exists and its binding is an *exact* match (same cycle, evidence digest,
|
|
1366
|
-
// runtime, phase, and role set) but it has lapsed or was cancelled, its
|
|
1367
|
-
// deterministic role packs are reused rather than rebuilt. The reused packs
|
|
1368
|
-
// carry the same per-role `inputDigest`, so any machine-local role result that
|
|
1369
|
-
// still matches that digest is re-adopted below as already-recorded work — the
|
|
1370
|
-
// lease is reissued fresh (new token + refreshed `expiresAt`) while the proven,
|
|
1371
|
-
// digest-bound advisory output is preserved. A non-exact prior binding is never
|
|
1372
|
-
// recovered; it fails closed above with `E_OPERATE_ADVISOR_ISOLATION`.
|
|
1373
|
-
let recoverableSession = null;
|
|
1374
|
-
if (existing) {
|
|
1375
|
-
const normalized = {
|
|
1376
|
-
...existing,
|
|
1377
|
-
phase: existing.phase ?? adapterPhase(existing.roles ?? []),
|
|
1378
|
-
runtime: existing.runtime ?? 'auto',
|
|
1379
|
-
boardIdentity: existing.boardIdentity ?? '',
|
|
1380
|
-
};
|
|
1381
|
-
// FR4: a session bound to a superseded board generation (its genesis no
|
|
1382
|
-
// longer matches the committed event chain) never blocks, matches, or is
|
|
1383
|
-
// reused by the current board — it is silently superseded by the fresh
|
|
1384
|
-
// session written below. This is what lets a board re-inited at the same
|
|
1385
|
-
// path — whose CYCLE-NNN ordinal collides with a prior generation's
|
|
1386
|
-
// finalized session — prepare cleanly instead of dead-ending on
|
|
1387
|
-
// `E_OPERATE_ADVISOR_ISOLATION` / a whole-cycle cancel.
|
|
1388
|
-
const sessionMatchesBoard = normalized.boardIdentity === boardIdentity;
|
|
1389
|
-
if (sessionMatchesBoard) {
|
|
1390
|
-
const exact = normalized.cycleId === input.cycleId &&
|
|
1391
|
-
normalized.evidenceDigest === input.evidenceDigest &&
|
|
1392
|
-
normalized.runtime === runtime &&
|
|
1393
|
-
normalized.phase === phase &&
|
|
1394
|
-
sameRoleSet(normalized.roles, roles);
|
|
1395
|
-
if (normalized.idempotencyKey === input.idempotencyKey) {
|
|
1396
|
-
if (!exact) {
|
|
1397
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', 'Idempotent adapter prepare does not match its original cycle, evidence, runtime, phase, or role binding.');
|
|
1398
|
-
}
|
|
1399
|
-
if (sessionExpired(normalized) || normalized.state === 'cancelled') {
|
|
1400
|
-
throw new OperateError('E_OPERATE_ADVISOR_FAILED', 'The prepared adapter session is expired or cancelled; request a fresh CLI-owned handoff.', { recoveryCommand: retryRunCommand(normalized) });
|
|
1401
|
-
}
|
|
1402
|
-
return {
|
|
1403
|
-
...normalized,
|
|
1404
|
-
session: sessionView(normalized, leaseDurationMs),
|
|
1405
|
-
leaseStatus: adapterLeaseStatus(normalized, nowMs),
|
|
1406
|
-
handoff: await adapterHandoff(normalized),
|
|
1407
|
-
};
|
|
1408
|
-
}
|
|
1409
|
-
if (!sessionExpired(normalized) && ['prepared', 'recording'].includes(normalized.state)) {
|
|
1410
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', `Cycle ${input.cycleId} already has an active adapter session with another binding. ` +
|
|
1411
|
-
'Close that session before preparing a new one.', {
|
|
1412
|
-
// Names the escape, not the command that just failed.
|
|
1413
|
-
recoveryCommand: closeOpenSessionCommand(normalized),
|
|
1414
|
-
alternateRecoveryCommand: closeOpenSessionCommand(normalized, 'finalize'),
|
|
1415
|
-
});
|
|
1416
|
-
}
|
|
1417
|
-
// FR4: a finalized/expired/cancelled same-board session no longer forces
|
|
1418
|
-
// a whole-cycle-cancelling error on a new compatible prepare. The
|
|
1419
|
-
// advisors→chair continuation and a same-phase re-prepare both fall
|
|
1420
|
-
// through and supersede the dead session; an exact dead session reuses
|
|
1421
|
-
// its already-built mandates so recorded advisory work is not recomputed.
|
|
1422
|
-
if (exact && (sessionExpired(normalized) || normalized.state === 'cancelled')) {
|
|
1423
|
-
recoverableSession = normalized;
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
|
-
}
|
|
1427
|
-
// FR1/FR2: every requested role — the Chair included — dispatches an operating
|
|
1428
|
-
// MANDATE. The role-dependent pack/mission split is retired, so there is no
|
|
1429
|
-
// pre-dispatch readiness gate against collected evidence and no v1.2 role pack
|
|
1430
|
-
// is built. A mandate carries the lens question, the investigation mandate, the
|
|
1431
|
-
// declared read boundaries (the granted workspace roots — including a
|
|
1432
|
-
// gitignored `.planr/` tree — the registry sensitivity ceiling, and any
|
|
1433
|
-
// forbidden paths), the response schema, and the citation requirement. It
|
|
1434
|
-
// carries NO evidence body and NO evidence index: nothing is collected,
|
|
1435
|
-
// budgeted, packed, or pre-filtered. A response that grounds nothing is
|
|
1436
|
-
// post-gated at record time by the universal citation gate
|
|
1437
|
-
// (`gateRecordedProposalCitations`). A recovered dead-but-exact session reuses
|
|
1438
|
-
// its stored mandates verbatim.
|
|
1439
|
-
const roleMandates = recoverableSession?.roleMandates && Object.keys(recoverableSession.roleMandates).length > 0
|
|
1440
|
-
? recoverableSession.roleMandates
|
|
1441
|
-
: await (async () => {
|
|
1442
|
-
const roots = await deriveOperatingMandateRoots(input.projectRoot);
|
|
1443
|
-
// FR12 (SPEC-005 T-003): the native harness prepare path is the one real
|
|
1444
|
-
// runs use, so it must thread the SAME shared research guidance the inline
|
|
1445
|
-
// dispatch path does — otherwise native-runtime agents receive no FR12
|
|
1446
|
-
// targeting at all. Build the ONE shared, citation-bearing bootstrap map
|
|
1447
|
-
// once per cycle here (cached per project+head) and reference it from every
|
|
1448
|
-
// advisor role's mandate below, alongside the graceful per-role research
|
|
1449
|
-
// budget. The Chair is prepared alone (`['chair']`), never mixed with
|
|
1450
|
-
// advisors, so it derives an empty advisor set, builds no map, and its
|
|
1451
|
-
// mandate stays byte-identical. The map is body-free targeting layered over
|
|
1452
|
-
// the immutable mandate — never an evidence-pack input, never a size ceiling,
|
|
1453
|
-
// never a cap on what a lens may examine.
|
|
1454
|
-
const advisorRoles = roles.filter((roleId) => roleId !== 'chair');
|
|
1455
|
-
const bootstrapMap = advisorRoles.length > 0 ? await buildOperatingBootstrapMap(input.projectRoot) : null;
|
|
1456
|
-
const built = await Promise.all(roles.map(async (roleId) => [
|
|
1457
|
-
roleId,
|
|
1458
|
-
await buildOperatingMandate({
|
|
1459
|
-
roleId,
|
|
1460
|
-
roots,
|
|
1461
|
-
runtime,
|
|
1462
|
-
...(roleId !== 'chair' && bootstrapMap ? { bootstrapMap } : {}),
|
|
1463
|
-
...(roleId !== 'chair'
|
|
1464
|
-
? { researchBudgetMs: DEFAULT_OPERATING_ROLE_RESEARCH_BUDGET_MS }
|
|
1465
|
-
: {}),
|
|
1466
|
-
}),
|
|
1467
|
-
]));
|
|
1468
|
-
return Object.fromEntries(built);
|
|
1469
|
-
})();
|
|
1470
|
-
// Every requested role dispatches; the bound role set is exactly `roles`.
|
|
1471
|
-
const dispatchedRoles = roles;
|
|
1472
|
-
const roleBriefs = Object.fromEntries(Object.keys(roleMandates).map((role) => [
|
|
1473
|
-
role,
|
|
1474
|
-
createRegistryReconciledAdvisorBrief(protocol, role),
|
|
1475
|
-
]));
|
|
1476
|
-
// US-T1: ship the disclosed response contract INSIDE every dispatched mandate.
|
|
1477
|
-
// Serialize each role brief's already-computed output facet onto its mandate's
|
|
1478
|
-
// `output` block so the runtime that must satisfy the contract can dereference
|
|
1479
|
-
// it, instead of only a `responseSchema` name it cannot resolve. Layered on
|
|
1480
|
-
// AFTER the pipeline signed each `mandateDigest` — exactly like the FR12
|
|
1481
|
-
// research guidance — so it never alters the signed digest or the immutable
|
|
1482
|
-
// mandate the digest pins (`roleInputDigests` below still equals it verbatim).
|
|
1483
|
-
const dispatchedMandates = Object.fromEntries(Object.entries(roleMandates).map(([role, mandate]) => [
|
|
1484
|
-
role,
|
|
1485
|
-
attachMandateResponseContract(mandate, roleBriefs[role]),
|
|
1486
|
-
]));
|
|
1487
|
-
// A role's committed input digest is its mandate digest. The record path
|
|
1488
|
-
// binds a recorded result to exactly this value.
|
|
1489
|
-
const roleInputDigests = Object.fromEntries(dispatchedRoles.map((role) => [role, roleMandates[role].mandateDigest]));
|
|
1490
|
-
const validRecordedRoles = [];
|
|
1491
|
-
for (const role of dispatchedRoles) {
|
|
1492
|
-
const prior = await readFile(path.join(path.dirname(target), `${input.cycleId}.${role}.json`), 'utf8')
|
|
1493
|
-
.then((raw) => JSON.parse(raw))
|
|
1494
|
-
.catch(() => null);
|
|
1495
|
-
if (prior &&
|
|
1496
|
-
prior.cycleId === input.cycleId &&
|
|
1497
|
-
prior.roleId === role &&
|
|
1498
|
-
prior.inputDigest === roleInputDigests[role]) {
|
|
1499
|
-
try {
|
|
1500
|
-
await assertOperatingArtifact('operating-role-result', prior);
|
|
1501
|
-
protocol.validateOperatingRoleResultDigest(prior);
|
|
1502
|
-
validRecordedRoles.push(role);
|
|
1503
|
-
}
|
|
1504
|
-
catch {
|
|
1505
|
-
// A stale or invalid machine-local role file is never trusted as a
|
|
1506
|
-
// recovered result; the new session will request that role again.
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
1509
|
-
}
|
|
1510
|
-
const pinnedRevision = baseEvidence.items.find((item) => item.repository?.revision)?.repository
|
|
1511
|
-
?.revision;
|
|
1512
|
-
const session = {
|
|
1513
|
-
implementation: 'openplanr-operate-harness',
|
|
1514
|
-
boardIdentity,
|
|
1515
|
-
cycleId: input.cycleId,
|
|
1516
|
-
evidenceDigest: input.evidenceDigest,
|
|
1517
|
-
phase,
|
|
1518
|
-
runtime,
|
|
1519
|
-
protocolVersion: '1.4.0',
|
|
1520
|
-
...(pinnedRevision ? { pinnedRevision } : {}),
|
|
1521
|
-
lease: randomBytes(32).toString('base64url'),
|
|
1522
|
-
idempotencyKey: input.idempotencyKey,
|
|
1523
|
-
state: validRecordedRoles.length > 0 ? 'recording' : 'prepared',
|
|
1524
|
-
expiresAt: new Date(nowMs + leaseDurationMs).toISOString(),
|
|
1525
|
-
roles: dispatchedRoles,
|
|
1526
|
-
recordedRoles: validRecordedRoles.sort(),
|
|
1527
|
-
roleBriefs,
|
|
1528
|
-
roleMandates: dispatchedMandates,
|
|
1529
|
-
roleInputDigests,
|
|
1530
|
-
};
|
|
1531
|
-
await atomicPrivateWrite(target, session);
|
|
1532
|
-
return {
|
|
1533
|
-
...session,
|
|
1534
|
-
mandates: dispatchedMandates,
|
|
1535
|
-
session: sessionView(session, leaseDurationMs),
|
|
1536
|
-
leaseStatus: adapterLeaseStatus(session, nowMs),
|
|
1537
|
-
handoff: await adapterHandoff(session),
|
|
1538
|
-
};
|
|
1539
|
-
}
|
|
1540
|
-
if (!input.lease) {
|
|
1541
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', 'Adapter lease is required.');
|
|
1542
|
-
}
|
|
1543
|
-
const session = await readAdapterSession(input.projectRoot, input.cycleId, input.localRoot, nowMs);
|
|
1544
|
-
assertAdapterBinding(session, input.lease, input.idempotencyKey, input.evidenceDigest);
|
|
1545
|
-
await assertAdapterCycleBinding({
|
|
1546
|
-
projectRoot: input.projectRoot,
|
|
1547
|
-
cycleId: input.cycleId,
|
|
1548
|
-
localRoot: input.localRoot,
|
|
1549
|
-
}, session);
|
|
1550
|
-
if (input.action === 'heartbeat') {
|
|
1551
|
-
// FR2: renew the cycle session's lease WITHOUT recording a role result. A
|
|
1552
|
-
// slow lens can hold the session open — extending `expiresAt` by the same
|
|
1553
|
-
// configured lease duration — while siblings keep their already-recorded work
|
|
1554
|
-
// instead of the shared lease lapsing and stranding it. This is the sanctioned
|
|
1555
|
-
// renewal path; raising `adapterLeaseDurationMs` is explicitly not (SPEC-005).
|
|
1556
|
-
// It carries no `--role`/stdin, changes no role's recorded/pending status, and
|
|
1557
|
-
// is safe to call concurrently by any coordinator holding the current lease:
|
|
1558
|
-
// it goes through the same per-cycle session serialization as `record`, so it
|
|
1559
|
-
// can never clobber a concurrent record's `recordedRoles`.
|
|
1560
|
-
if (!['prepared', 'recording'].includes(session.state)) {
|
|
1561
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', `Adapter heartbeat is not valid after the session is ${session.state}.`, { recoveryCommand: retryRunCommand(session) });
|
|
1562
|
-
}
|
|
1563
|
-
const renewed = await withInProcessSessionLock(target, () => commitSessionWrite(target, {
|
|
1564
|
-
projectRoot: input.projectRoot,
|
|
1565
|
-
cycleId: input.cycleId,
|
|
1566
|
-
localRoot: input.localRoot,
|
|
1567
|
-
lease: input.lease,
|
|
1568
|
-
idempotencyKey: input.idempotencyKey,
|
|
1569
|
-
evidenceDigest: input.evidenceDigest,
|
|
1570
|
-
nowMs,
|
|
1571
|
-
apply: (current) => ({
|
|
1572
|
-
...current,
|
|
1573
|
-
expiresAt: new Date(nowMs + leaseDurationMs).toISOString(),
|
|
1574
|
-
}),
|
|
1575
|
-
}));
|
|
1576
|
-
return {
|
|
1577
|
-
session: sessionView(renewed, leaseDurationMs),
|
|
1578
|
-
leaseStatus: adapterLeaseStatus(renewed, nowMs),
|
|
1579
|
-
handoff: await adapterHandoff(renewed),
|
|
1580
|
-
};
|
|
1581
|
-
}
|
|
1582
|
-
if (input.action === 'abandon') {
|
|
1583
|
-
// SPEC-005 T-020 (FR13) — the runtime-side governed terminal path. The
|
|
1584
|
-
// orchestrating runtime, which dispatched this lens and holds the session
|
|
1585
|
-
// lease, invokes this when a dispatched lens exceeded its budget and never
|
|
1586
|
-
// returned (see the skill/command runtime workflow). The engine never spawned
|
|
1587
|
-
// the agent, so it cannot time it out unilaterally; this explicit governed
|
|
1588
|
-
// action, with a required reason, is the smallest honest substitute. It marks
|
|
1589
|
-
// ONE still-pending lens terminal `not_evaluated`, persists the governed gap
|
|
1590
|
-
// (a `gap.open` event carrying the reason), and lets the board consolidate
|
|
1591
|
-
// without it — its recorded siblings are untouched and the Chair names it as a
|
|
1592
|
-
// gap it must not synthesize around.
|
|
1593
|
-
if (!['prepared', 'recording'].includes(session.state)) {
|
|
1594
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', `Adapter abandon is not valid after the session is ${session.state}.`, { recoveryCommand: retryRunCommand(session) });
|
|
1595
|
-
}
|
|
1596
|
-
if (!input.role) {
|
|
1597
|
-
throw new OperateError('E_OPERATE_CONFIG_INVALID', 'Adapter abandon requires --role naming the stalled lens.');
|
|
1598
|
-
}
|
|
1599
|
-
const reason = input.reason?.trim();
|
|
1600
|
-
if (!reason) {
|
|
1601
|
-
throw new OperateError('E_OPERATE_CONFIG_INVALID', 'Adapter abandon requires --reason recording why the lens is not_evaluated.');
|
|
1602
|
-
}
|
|
1603
|
-
if (!session.roles.includes(input.role)) {
|
|
1604
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', `Role ${input.role} was not bound by adapter prepare.`);
|
|
1605
|
-
}
|
|
1606
|
-
if (session.recordedRoles.includes(input.role)) {
|
|
1607
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', `Role ${input.role} already recorded a result and cannot be abandoned.`, { recoveryCommand: retryRunCommand(session) });
|
|
1608
|
-
}
|
|
1609
|
-
// Persist the governed terminal gap first (committed state is the source of
|
|
1610
|
-
// truth the later `run` continuation reconstructs from), then mark the role
|
|
1611
|
-
// terminal in the lease-bound session so finalize no longer waits on it and
|
|
1612
|
-
// the handoff renders it `not-evaluated`. Idempotent: re-abandoning a role
|
|
1613
|
-
// already governed is a no-op that returns the same terminal handoff.
|
|
1614
|
-
await governTerminalNotEvaluated({
|
|
1615
|
-
projectRoot: input.projectRoot,
|
|
1616
|
-
localRoot: input.localRoot,
|
|
1617
|
-
cycleId: input.cycleId,
|
|
1618
|
-
roleId: input.role,
|
|
1619
|
-
reason,
|
|
1620
|
-
correlationId: input.idempotencyKey,
|
|
1621
|
-
});
|
|
1622
|
-
const updated = await withInProcessSessionLock(target, () => commitSessionWrite(target, {
|
|
1623
|
-
projectRoot: input.projectRoot,
|
|
1624
|
-
cycleId: input.cycleId,
|
|
1625
|
-
localRoot: input.localRoot,
|
|
1626
|
-
lease: input.lease,
|
|
1627
|
-
idempotencyKey: input.idempotencyKey,
|
|
1628
|
-
evidenceDigest: input.evidenceDigest,
|
|
1629
|
-
nowMs,
|
|
1630
|
-
apply: (current) => ({
|
|
1631
|
-
...current,
|
|
1632
|
-
state: 'recording',
|
|
1633
|
-
notEvaluatedRoles: {
|
|
1634
|
-
...(current.notEvaluatedRoles ?? {}),
|
|
1635
|
-
[input.role]: reason,
|
|
1636
|
-
},
|
|
1637
|
-
}),
|
|
1638
|
-
}));
|
|
1639
|
-
return {
|
|
1640
|
-
abandoned: input.role,
|
|
1641
|
-
notEvaluated: true,
|
|
1642
|
-
reason,
|
|
1643
|
-
session: sessionView(updated, leaseDurationMs),
|
|
1644
|
-
leaseStatus: adapterLeaseStatus(updated, nowMs),
|
|
1645
|
-
handoff: await adapterHandoff(updated),
|
|
1646
|
-
};
|
|
1647
|
-
}
|
|
1648
|
-
if (input.action === 'resume') {
|
|
1649
|
-
if (!['prepared', 'recording'].includes(session.state)) {
|
|
1650
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', `Adapter resume is not valid after the session is ${session.state}.`, { recoveryCommand: retryRunCommand(session) });
|
|
1651
|
-
}
|
|
1652
|
-
return {
|
|
1653
|
-
...session,
|
|
1654
|
-
session: sessionView(session, leaseDurationMs),
|
|
1655
|
-
leaseStatus: adapterLeaseStatus(session, nowMs),
|
|
1656
|
-
handoff: await adapterHandoff(session),
|
|
1657
|
-
};
|
|
1658
|
-
}
|
|
1659
|
-
if (input.action === 'cancel') {
|
|
1660
|
-
if (session.state === 'finalized') {
|
|
1661
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', 'A finalized adapter session cannot be cancelled.', { recoveryCommand: retryRunCommand(session) });
|
|
1662
|
-
}
|
|
1663
|
-
if (session.state === 'cancelled') {
|
|
1664
|
-
return {
|
|
1665
|
-
session: sessionView(session, leaseDurationMs),
|
|
1666
|
-
leaseStatus: adapterLeaseStatus(session, nowMs),
|
|
1667
|
-
handoff: await adapterHandoff(session),
|
|
1668
|
-
};
|
|
1669
|
-
}
|
|
1670
|
-
const cancelled = { ...session, state: 'cancelled' };
|
|
1671
|
-
await atomicPrivateWrite(target, cancelled);
|
|
1672
|
-
return {
|
|
1673
|
-
session: sessionView(cancelled, leaseDurationMs),
|
|
1674
|
-
leaseStatus: adapterLeaseStatus(cancelled, nowMs),
|
|
1675
|
-
handoff: await adapterHandoff(cancelled),
|
|
1676
|
-
};
|
|
1677
|
-
}
|
|
1678
|
-
if (input.action === 'record') {
|
|
1679
|
-
if (!['prepared', 'recording'].includes(session.state)) {
|
|
1680
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', `Adapter record is not valid after the session is ${session.state}.`, { recoveryCommand: retryRunCommand(session) });
|
|
1681
|
-
}
|
|
1682
|
-
if (!input.role || !input.stdin) {
|
|
1683
|
-
throw new OperateError('E_OPERATE_CONFIG_INVALID', 'Adapter record requires --role and JSON on stdin.');
|
|
1684
|
-
}
|
|
1685
|
-
if (!session.roles.includes(input.role)) {
|
|
1686
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', `Role ${input.role} was not bound by adapter prepare.`);
|
|
1687
|
-
}
|
|
1688
|
-
// T-001 widened `record-required.next` to one record action per PENDING role,
|
|
1689
|
-
// so authorization is keyed by role, not by position: any pending role may
|
|
1690
|
-
// record the instant it returns, regardless of sibling order or completion
|
|
1691
|
-
// state (FR1). A role that is already recorded is not pending (so it has no
|
|
1692
|
-
// record action in `next`) but is still a legal idempotent replay target —
|
|
1693
|
-
// its identical-bytes no-op is enforced downstream by the resultDigest guard.
|
|
1694
|
-
// Only a role that is neither pending nor already recorded (e.g. a session
|
|
1695
|
-
// with no pending roles left) is rejected here, pointed at recovery.
|
|
1696
|
-
const currentHandoff = await adapterHandoff(session);
|
|
1697
|
-
const authorizedRecord = currentHandoff.next.find((action) => ['adapter.record', 'harness.record'].includes(action.action) && action.role === input.role);
|
|
1698
|
-
const alreadyRecorded = session.recordedRoles.includes(input.role);
|
|
1699
|
-
if (!authorizedRecord && !alreadyRecorded) {
|
|
1700
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', `Role ${input.role} has no pending adapter record action.`, {
|
|
1701
|
-
expectedRole: currentHandoff.next.find((action) => ['adapter.record', 'harness.record'].includes(action.action))?.role ?? null,
|
|
1702
|
-
recoveryCommand: currentHandoff.recovery
|
|
1703
|
-
.find((action) => ['adapter.resume', 'harness.resume'].includes(action.action))
|
|
1704
|
-
?.argv.join(' '),
|
|
1705
|
-
});
|
|
1706
|
-
}
|
|
1707
|
-
const outputLimit = Math.min(session.protocolVersion === '1.4.0' ? 262_144 : 32_768, session.roleBriefs[input.role].output.maximumOutputBytes);
|
|
1708
|
-
if (Buffer.byteLength(input.stdin, 'utf8') > outputLimit) {
|
|
1709
|
-
throw new OperateError('E_OPERATE_ADVISOR_FAILED', `Native advisor response exceeds the ${outputLimit}-byte bound.`, {
|
|
1710
|
-
...advisorResponseContractDetails(session.roleBriefs[input.role]),
|
|
1711
|
-
recoveryCommand: retryRunCommand(session),
|
|
1712
|
-
});
|
|
1713
|
-
}
|
|
1714
|
-
let submitted;
|
|
1715
|
-
try {
|
|
1716
|
-
submitted = JSON.parse(input.stdin);
|
|
1717
|
-
}
|
|
1718
|
-
catch {
|
|
1719
|
-
throw new OperateError('E_OPERATE_ADVISOR_FAILED', 'Native advisor response must be one valid JSON document.', {
|
|
1720
|
-
...advisorResponseContractDetails(session.roleBriefs[input.role]),
|
|
1721
|
-
recoveryCommand: retryRunCommand(session),
|
|
1722
|
-
});
|
|
1723
|
-
}
|
|
1724
|
-
const submittedRecord = submitted && typeof submitted === 'object' ? submitted : {};
|
|
1725
|
-
let result;
|
|
1726
|
-
// FR1/FR2: unresolvable-citation and empty-grounding gaps opened while
|
|
1727
|
-
// resolving a mandate response's citations, surfaced in the record response
|
|
1728
|
-
// for observability. `recordNotEvaluated` marks a role whose citations
|
|
1729
|
-
// grounded zero evidence (committed as a quiet result plus the governed gap).
|
|
1730
|
-
let recordGaps = [];
|
|
1731
|
-
let recordNotEvaluated = false;
|
|
1732
|
-
if (submittedRecord.kind === 'operating-role-result') {
|
|
1733
|
-
throw new OperateError('E_OPERATE_ADVISOR_FAILED', 'Native advisors must submit only the compact response contract; OpenPlanr owns canonical result metadata.', {
|
|
1734
|
-
...advisorResponseContractDetails(session.roleBriefs[input.role]),
|
|
1735
|
-
recoveryCommand: retryRunCommand(session),
|
|
1736
|
-
});
|
|
1737
|
-
}
|
|
1738
|
-
else {
|
|
1739
|
-
const submittedProposals = Array.isArray(submittedRecord.proposals)
|
|
1740
|
-
? submittedRecord.proposals
|
|
1741
|
-
: [];
|
|
1742
|
-
const submittedText = [
|
|
1743
|
-
...(typeof submittedRecord.analysisMarkdown === 'string'
|
|
1744
|
-
? [{ location: 'analysisMarkdown', value: submittedRecord.analysisMarkdown }]
|
|
1745
|
-
: []),
|
|
1746
|
-
...(Array.isArray(submittedRecord.claims) ? submittedRecord.claims : []).flatMap((claim, index) => claim && typeof claim === 'object' && !Array.isArray(claim)
|
|
1747
|
-
? [
|
|
1748
|
-
{
|
|
1749
|
-
location: `claims.${index}.statement`,
|
|
1750
|
-
value: claim.statement,
|
|
1751
|
-
},
|
|
1752
|
-
]
|
|
1753
|
-
: []),
|
|
1754
|
-
...(Array.isArray(submittedRecord.actions) ? submittedRecord.actions : []).flatMap((action, index) => action && typeof action === 'object' && !Array.isArray(action)
|
|
1755
|
-
? ['title', 'summary'].map((field) => ({
|
|
1756
|
-
location: `actions.${index}.${field}`,
|
|
1757
|
-
value: action[field],
|
|
1758
|
-
}))
|
|
1759
|
-
: []),
|
|
1760
|
-
...submittedProposals.flatMap((proposal, index) => {
|
|
1761
|
-
if (!proposal || typeof proposal !== 'object' || Array.isArray(proposal))
|
|
1762
|
-
return [];
|
|
1763
|
-
const record = proposal;
|
|
1764
|
-
return ['title', 'problem', 'proposal'].map((field) => ({
|
|
1765
|
-
location: `proposals.${index}.${field}`,
|
|
1766
|
-
value: record[field],
|
|
1767
|
-
}));
|
|
1768
|
-
}),
|
|
1769
|
-
...(Array.isArray(submittedRecord.gaps) ? submittedRecord.gaps : []).map((value, index) => ({ location: `gaps.${index}`, value })),
|
|
1770
|
-
...(Array.isArray(submittedRecord.conflicts) ? submittedRecord.conflicts : []).map((value, index) => ({ location: `conflicts.${index}`, value })),
|
|
1771
|
-
];
|
|
1772
|
-
assertNoHardBlockedSecrets(submittedText, {
|
|
1773
|
-
roleId: input.role,
|
|
1774
|
-
subject: 'Native advisor response',
|
|
1775
|
-
});
|
|
1776
|
-
const mandate = session.roleMandates[input.role];
|
|
1777
|
-
// US-T1 batch validation: collect EVERY advisor-contract violation (response
|
|
1778
|
-
// schema issues, the per-role proposal cap, disallowed proposal types) in one
|
|
1779
|
-
// pass and reject with ALL of them, so a runtime never learns one category per
|
|
1780
|
-
// rejected resubmission. Shared verbatim with `harness validate` via
|
|
1781
|
-
// collectAdvisorResponseContractIssues so the record path and the dry-run can
|
|
1782
|
-
// never disagree. Runs after the secret scan (never echo a secret in an issue)
|
|
1783
|
-
// and before the citation gate mutates anything.
|
|
1784
|
-
const contractIssues = await collectAdvisorResponseContractIssues({
|
|
1785
|
-
brief: session.roleBriefs[input.role],
|
|
1786
|
-
response: submitted,
|
|
1787
|
-
protocolVersion: mandate.protocolVersion,
|
|
1788
|
-
});
|
|
1789
|
-
if (contractIssues.length > 0) {
|
|
1790
|
-
throw new OperateError('E_OPERATE_ADVISOR_FAILED', `Native ${input.role} response does not satisfy the disclosed advisor contract (${contractIssues.length} issue${contractIssues.length === 1 ? '' : 's'}).`, {
|
|
1791
|
-
issues: contractIssues,
|
|
1792
|
-
...advisorResponseContractDetails(session.roleBriefs[input.role]),
|
|
1793
|
-
recoveryCommand: retryRunCommand(session),
|
|
1794
|
-
});
|
|
1795
|
-
}
|
|
1796
|
-
try {
|
|
1797
|
-
const gated = await createNativeMissionOperatingRoleResult({
|
|
1798
|
-
mandate,
|
|
1799
|
-
cycleId: input.cycleId,
|
|
1800
|
-
response: submitted,
|
|
1801
|
-
runtime: session.runtime,
|
|
1802
|
-
pinnedRevision: session.pinnedRevision,
|
|
1803
|
-
resolveCitations: async (roleResults) => {
|
|
1804
|
-
const [workspace, sensitivityCeiling, config, workspaceRoots] = await Promise.all([
|
|
1805
|
-
refreshOperatingWorkspaceManifest(input.projectRoot, {
|
|
1806
|
-
localRoot: input.localRoot,
|
|
1807
|
-
}),
|
|
1808
|
-
readAdapterSensitivityCeiling(input.projectRoot, input.localRoot),
|
|
1809
|
-
readOperatingConfig(input.projectRoot, { localRoot: input.localRoot }).catch(() => null),
|
|
1810
|
-
readOperatingWorkspaceRoots(input.projectRoot, { localRoot: input.localRoot }),
|
|
1811
|
-
]);
|
|
1812
|
-
return gateRecordedProposalCitations({
|
|
1813
|
-
roleResults,
|
|
1814
|
-
context: {
|
|
1815
|
-
projectRoot: input.projectRoot,
|
|
1816
|
-
cycleId: input.cycleId,
|
|
1817
|
-
descriptor: workspace.controlRepository,
|
|
1818
|
-
cache: new OperatingEvidenceCache(resolveOperatingPaths(input.projectRoot, {
|
|
1819
|
-
localRoot: input.localRoot,
|
|
1820
|
-
}).evidence, sensitivityCeiling),
|
|
1821
|
-
owner: config?.decisionOwner,
|
|
1822
|
-
components: citationComponentsFromWorkspace(workspace, workspaceRoots),
|
|
1823
|
-
},
|
|
1824
|
-
});
|
|
1825
|
-
},
|
|
1826
|
-
});
|
|
1827
|
-
result = gated.result;
|
|
1828
|
-
recordGaps = gated.gaps;
|
|
1829
|
-
recordNotEvaluated = gated.notEvaluated;
|
|
1830
|
-
}
|
|
1831
|
-
catch (error) {
|
|
1832
|
-
if (error instanceof OperateError && error.code === 'E_OPERATE_ADVISOR_FAILED') {
|
|
1833
|
-
throw new OperateError(error.code, error.message, {
|
|
1834
|
-
...error.details,
|
|
1835
|
-
recoveryCommand: retryRunCommand(session),
|
|
1836
|
-
});
|
|
1837
|
-
}
|
|
1838
|
-
throw error;
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
await assertOperatingArtifact('operating-role-result', result);
|
|
1842
|
-
// The structured provider path runs every proposal's free text through
|
|
1843
|
-
// sanitizeGeneratedPlainText before it is persisted. Native runtimes hand
|
|
1844
|
-
// their output in here instead, so the same post-output secret scan has to
|
|
1845
|
-
// happen on this path — otherwise a token in a proposal title reaches the
|
|
1846
|
-
// commit-safe records and the brief projection unredacted.
|
|
1847
|
-
//
|
|
1848
|
-
// A hard-blocked category rejects rather than redacts: the result is bound by
|
|
1849
|
-
// resultDigest, so rewriting the content in place would invalidate the binding
|
|
1850
|
-
// that proves the runtime returned exactly this. A runtime that emits a real
|
|
1851
|
-
// secret must produce a clean result, not have one silently edited underneath
|
|
1852
|
-
// it. Soft, secret-SHAPED matches were already redacted by
|
|
1853
|
-
// sanitizeGeneratedPlainText inside the result builder, so they never reach
|
|
1854
|
-
// here as a reason to discard the result.
|
|
1855
|
-
const generatedText = [
|
|
1856
|
-
...(result.proposals ?? []).flatMap((proposal) => ['title', 'problem', 'proposal'].map((field) => ({
|
|
1857
|
-
location: `proposal.${proposal.proposalKey}.${field}`,
|
|
1858
|
-
value: proposal[field],
|
|
1859
|
-
}))),
|
|
1860
|
-
...(result.gaps ?? []).map((value, index) => ({
|
|
1861
|
-
location: `gaps.${index}`,
|
|
1862
|
-
value,
|
|
1863
|
-
})),
|
|
1864
|
-
...(result.conflicts ?? []).map((value, index) => ({
|
|
1865
|
-
location: `conflicts.${index}`,
|
|
1866
|
-
value,
|
|
1867
|
-
})),
|
|
1868
|
-
];
|
|
1869
|
-
assertNoHardBlockedSecrets(generatedText, {
|
|
1870
|
-
roleId: input.role,
|
|
1871
|
-
subject: 'Recorded advisor output',
|
|
1872
|
-
});
|
|
1873
|
-
if (result.cycleId !== input.cycleId || result.roleId !== input.role) {
|
|
1874
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', 'Recorded advisor output does not match its cycle and role binding.');
|
|
1875
|
-
}
|
|
1876
|
-
assertAdvisorOutputMatchesBrief(session.roleBriefs[input.role], result);
|
|
1877
|
-
if (result.inputDigest !== session.roleInputDigests[input.role]) {
|
|
1878
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', 'Recorded advisor output does not match its role/evidence input digest.');
|
|
1879
|
-
}
|
|
1880
|
-
try {
|
|
1881
|
-
(await loadOperatingProtocol()).validateOperatingRoleResultDigest(result);
|
|
1882
|
-
}
|
|
1883
|
-
catch {
|
|
1884
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', 'Recorded advisor output resultDigest does not match its canonical content.');
|
|
1885
|
-
}
|
|
1886
|
-
const existingResult = await readFile(path.join(path.dirname(target), `${input.cycleId}.${input.role}.json`), 'utf8')
|
|
1887
|
-
.then((raw) => JSON.parse(raw))
|
|
1888
|
-
.catch(() => null);
|
|
1889
|
-
if (existingResult && existingResult.resultDigest !== result.resultDigest) {
|
|
1890
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', `Role ${input.role} already recorded a different result.`);
|
|
1891
|
-
}
|
|
1892
|
-
await atomicPrivateWrite(path.join(path.dirname(target), `${input.cycleId}.${input.role}.json`), result);
|
|
1893
|
-
// The v1.4 report is the ONLY advisor text persisted verbatim (response.json →
|
|
1894
|
-
// the `advisor-report` record → the committed board Markdown), so its soft,
|
|
1895
|
-
// secret-SHAPED matches are redacted here rather than rejected — the same
|
|
1896
|
-
// treatment the result body's text already received. The identical object is
|
|
1897
|
-
// written to disk and committed as the record, so finalize (which re-reads
|
|
1898
|
-
// response.json) can never disagree with this record.
|
|
1899
|
-
const advisorReport = session.protocolVersion === '1.4.0' &&
|
|
1900
|
-
submitted &&
|
|
1901
|
-
typeof submitted === 'object' &&
|
|
1902
|
-
!Array.isArray(submitted)
|
|
1903
|
-
? redactAdvisorReportText(submitted)
|
|
1904
|
-
: null;
|
|
1905
|
-
if (session.protocolVersion === '1.4.0') {
|
|
1906
|
-
await atomicPrivateWrite(path.join(path.dirname(target), `${input.cycleId}.${input.role}.response.json`), advisorReport ?? submitted);
|
|
1907
|
-
}
|
|
1908
|
-
// The role's validated result is now durable in its own machine-local file
|
|
1909
|
-
// (survives a sibling stalling, restart, lease expiry, and resume). Merging it
|
|
1910
|
-
// into the shared session's `recordedRoles`, committing its canonical event,
|
|
1911
|
-
// and materializing its projection all mutate cycle-shared state, so they run
|
|
1912
|
-
// inside the per-cycle in-process serialization — a concurrent record of a
|
|
1913
|
-
// DIFFERENT role can never lose this one (FR1). A successful record also
|
|
1914
|
-
// refreshes the lease forward from now (T-008): steady progress across a
|
|
1915
|
-
// multi-role dispatch keeps the session alive without a separate keep-alive
|
|
1916
|
-
// call, while an idle session past the refreshed window still lapses.
|
|
1917
|
-
const target2 = target;
|
|
1918
|
-
const updated = await withInProcessSessionLock(target2, async () => {
|
|
1919
|
-
const merged = await commitSessionWrite(target2, {
|
|
1920
|
-
projectRoot: input.projectRoot,
|
|
1921
|
-
cycleId: input.cycleId,
|
|
1922
|
-
localRoot: input.localRoot,
|
|
1923
|
-
lease: input.lease,
|
|
1924
|
-
idempotencyKey: input.idempotencyKey,
|
|
1925
|
-
evidenceDigest: input.evidenceDigest,
|
|
1926
|
-
nowMs,
|
|
1927
|
-
apply: (current) => ({
|
|
1928
|
-
...current,
|
|
1929
|
-
state: 'recording',
|
|
1930
|
-
recordedRoles: [...new Set([...current.recordedRoles, input.role])].sort(),
|
|
1931
|
-
expiresAt: new Date(nowMs + leaseDurationMs).toISOString(),
|
|
1932
|
-
}),
|
|
1933
|
-
});
|
|
1934
|
-
// FR4/FR5: commit the canonical `advisory.recorded` event and refresh the
|
|
1935
|
-
// readable projection now, so `planr operate report`/`status` and
|
|
1936
|
-
// `.planr/operate/cycles/<id>/` reflect this lens' real analysis before
|
|
1937
|
-
// Chair runs — not only at finalize.
|
|
1938
|
-
await materializeRecordedRole({
|
|
1939
|
-
projectRoot: input.projectRoot,
|
|
1940
|
-
localRoot: input.localRoot,
|
|
1941
|
-
cycleId: input.cycleId,
|
|
1942
|
-
session: merged,
|
|
1943
|
-
result,
|
|
1944
|
-
advisorReport,
|
|
1945
|
-
});
|
|
1946
|
-
return merged;
|
|
1947
|
-
});
|
|
1948
|
-
// SPEC-005 T-019 (FR5/FR13): a citation-rejected lens commits a quiet result;
|
|
1949
|
-
// persist the governed gaps the citation gate opened so the Chair board — built
|
|
1950
|
-
// by a later `run` continuation, after this role is recorded and never
|
|
1951
|
-
// re-dispatched — can reconstruct the `citation-rejected` outcome from committed
|
|
1952
|
-
// state instead of rendering a false-clean `recorded-quiet`. Runs after the role
|
|
1953
|
-
// is materialized (its `advisory.recorded` event committed), acquiring the
|
|
1954
|
-
// event-store lock itself and idempotent per role, so a resume/retry never
|
|
1955
|
-
// duplicates. Empty on the normal healthy path (no citation rejection → no gaps).
|
|
1956
|
-
await persistRecordedRoleGaps({
|
|
1957
|
-
projectRoot: input.projectRoot,
|
|
1958
|
-
localRoot: input.localRoot,
|
|
1959
|
-
cycleId: input.cycleId,
|
|
1960
|
-
roleId: input.role,
|
|
1961
|
-
gaps: recordGaps,
|
|
1962
|
-
correlationId: input.idempotencyKey,
|
|
1963
|
-
});
|
|
1964
|
-
// FR7: the per-role result is now durably committed, so any OpenPlanr-owned
|
|
1965
|
-
// scratch this cycle used as a handoff is redundant. Clean only confirmed
|
|
1966
|
-
// owned scratch (a no-op on the normal stdin path, which writes none).
|
|
1967
|
-
await cleanOperatingScratch(resolveOperatingPaths(input.projectRoot, { localRoot: input.localRoot }), input.cycleId);
|
|
1968
|
-
return {
|
|
1969
|
-
recorded: input.role,
|
|
1970
|
-
result,
|
|
1971
|
-
...(recordGaps.length > 0 ? { citationGaps: recordGaps } : {}),
|
|
1972
|
-
...(recordNotEvaluated ? { notEvaluated: true } : {}),
|
|
1973
|
-
session: sessionView(updated, leaseDurationMs),
|
|
1974
|
-
leaseStatus: adapterLeaseStatus(updated, nowMs),
|
|
1975
|
-
handoff: await adapterHandoff(updated),
|
|
1976
|
-
};
|
|
1977
|
-
}
|
|
1978
|
-
if (session.state === 'cancelled') {
|
|
1979
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', 'A cancelled adapter session cannot be finalized.', { recoveryCommand: retryRunCommand(session) });
|
|
1980
|
-
}
|
|
1981
|
-
if (session.state === 'finalized') {
|
|
1982
|
-
const summaries = await Promise.all(session.recordedRoles.map((role) => readFile(path.join(path.dirname(target), `${input.cycleId}.${role}.json`), 'utf8').then((raw) => {
|
|
1983
|
-
const result = JSON.parse(raw);
|
|
1984
|
-
return {
|
|
1985
|
-
roleId: result.roleId,
|
|
1986
|
-
outcome: result.outcome,
|
|
1987
|
-
inputDigest: result.inputDigest,
|
|
1988
|
-
resultDigest: result.resultDigest,
|
|
1989
|
-
};
|
|
1990
|
-
})));
|
|
1991
|
-
return {
|
|
1992
|
-
session: sessionView(session, leaseDurationMs),
|
|
1993
|
-
results: summaries,
|
|
1994
|
-
leaseStatus: adapterLeaseStatus(session, nowMs),
|
|
1995
|
-
handoff: await adapterHandoff(session),
|
|
1996
|
-
};
|
|
1997
|
-
}
|
|
1998
|
-
// T-020: a role is terminal for finalize once it recorded a result OR was
|
|
1999
|
-
// governed terminal `not_evaluated` (a lens abandoned after a genuine stall).
|
|
2000
|
-
// Only an in-flight lens — never dispatched to a terminal outcome — blocks
|
|
2001
|
-
// finalize, matching the T-001 wire contract that accepts an all-terminal board.
|
|
2002
|
-
const notEvaluatedRoles = session.notEvaluatedRoles ?? {};
|
|
2003
|
-
const missingRoles = session.roles.filter((role) => !session.recordedRoles.includes(role) && !(role in notEvaluatedRoles));
|
|
2004
|
-
if (missingRoles.length > 0) {
|
|
2005
|
-
throw new OperateError('E_OPERATE_ADVISOR_FAILED', `Adapter finalize is incomplete; missing roles: ${missingRoles.join(', ')}.`);
|
|
2006
|
-
}
|
|
2007
|
-
const results = await Promise.all(session.recordedRoles.map((role) => readFile(path.join(path.dirname(target), `${input.cycleId}.${role}.json`), 'utf8').then((raw) => JSON.parse(raw))));
|
|
2008
|
-
for (const result of results) {
|
|
2009
|
-
await assertOperatingArtifact('operating-role-result', result);
|
|
2010
|
-
let digestValid = true;
|
|
2011
|
-
try {
|
|
2012
|
-
(await loadOperatingProtocol()).validateOperatingRoleResultDigest(result);
|
|
2013
|
-
}
|
|
2014
|
-
catch {
|
|
2015
|
-
digestValid = false;
|
|
2016
|
-
}
|
|
2017
|
-
if (result.inputDigest !== session.roleInputDigests[result.roleId] || !digestValid) {
|
|
2018
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', `Finalized result for ${result.roleId} failed digest binding.`);
|
|
2019
|
-
}
|
|
2020
|
-
}
|
|
2021
|
-
const store = new OperatingEventStore(input.projectRoot, { localRoot: input.localRoot });
|
|
2022
|
-
const initial = await store.replay();
|
|
2023
|
-
await withOperatingLock(input.projectRoot, {
|
|
2024
|
-
projectKey: operatingProjectKey(input.projectRoot),
|
|
2025
|
-
expectedEventHead: initial.eventHead,
|
|
2026
|
-
currentEventHead: initial.eventHead,
|
|
2027
|
-
localRoot: input.localRoot,
|
|
2028
|
-
}, async (lock) => {
|
|
2029
|
-
let head = initial.eventHead;
|
|
2030
|
-
const existing = new Map((await readPersistedOperatingRoleResults(store, input.cycleId)).map((result) => [
|
|
2031
|
-
result.roleId,
|
|
2032
|
-
result,
|
|
2033
|
-
]));
|
|
2034
|
-
for (const result of [...results].sort((left, right) => left.roleId.localeCompare(right.roleId))) {
|
|
2035
|
-
const prior = existing.get(result.roleId);
|
|
2036
|
-
if (prior) {
|
|
2037
|
-
if (prior.resultDigest !== result.resultDigest) {
|
|
2038
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', `Cycle ${input.cycleId} already committed a different ${result.roleId} result.`);
|
|
2039
|
-
}
|
|
2040
|
-
continue;
|
|
2041
|
-
}
|
|
2042
|
-
const record = await store.putRecord('advisor-result', result, {
|
|
2043
|
-
correlationId: session.idempotencyKey,
|
|
2044
|
-
});
|
|
2045
|
-
const advisorReport = session.protocolVersion === '1.4.0'
|
|
2046
|
-
? await readFile(path.join(path.dirname(target), `${input.cycleId}.${result.roleId}.response.json`), 'utf8')
|
|
2047
|
-
.then((raw) => JSON.parse(raw))
|
|
2048
|
-
.catch(() => null)
|
|
2049
|
-
: null;
|
|
2050
|
-
const advisorReportRecord = advisorReport
|
|
2051
|
-
? await store.putRecord('advisor-report', advisorReport, {
|
|
2052
|
-
correlationId: session.idempotencyKey,
|
|
2053
|
-
})
|
|
2054
|
-
: null;
|
|
2055
|
-
const runtimeBinding = (await adapterHandoff(session)).binding;
|
|
2056
|
-
const event = await store.append({
|
|
2057
|
-
type: 'advisory.recorded',
|
|
2058
|
-
cycleId: input.cycleId,
|
|
2059
|
-
entityId: `${input.cycleId}-${result.roleId}`,
|
|
2060
|
-
correlationId: session.idempotencyKey,
|
|
2061
|
-
evidenceRefs: result.proposals.flatMap((proposal) => proposal.evidenceRefs),
|
|
2062
|
-
payload: {
|
|
2063
|
-
recordDigest: record.digest,
|
|
2064
|
-
...(advisorReportRecord ? { advisorReportDigest: advisorReportRecord.digest } : {}),
|
|
2065
|
-
roleId: result.roleId,
|
|
2066
|
-
runtimeBinding: {
|
|
2067
|
-
runtime: runtimeBinding.runtime,
|
|
2068
|
-
runtimeBinding: runtimeBinding.runtimeBinding,
|
|
2069
|
-
crossRuntimeFallback: runtimeBinding.crossRuntimeFallback,
|
|
2070
|
-
executionMode: runtimeBinding.executionMode,
|
|
2071
|
-
assurance: runtimeBinding.assurance,
|
|
2072
|
-
toolIsolation: runtimeBinding.toolIsolation,
|
|
2073
|
-
},
|
|
2074
|
-
},
|
|
2075
|
-
...(session.protocolVersion === '1.4.0' ? { protocolVersion: '1.4.0' } : {}),
|
|
2076
|
-
expectedHead: head.hash,
|
|
2077
|
-
actor: { kind: 'runtime', id: 'operate-adapter' },
|
|
2078
|
-
});
|
|
2079
|
-
const next = { sequence: event.sequence, hash: event.eventHash };
|
|
2080
|
-
await lock.advanceEventHead(head, next);
|
|
2081
|
-
head = next;
|
|
2082
|
-
}
|
|
2083
|
-
await store.writeCheckpoint(await store.state());
|
|
2084
|
-
});
|
|
2085
|
-
const finalized = { ...session, state: 'finalized' };
|
|
2086
|
-
await atomicPrivateWrite(target, finalized);
|
|
2087
|
-
// FR7: the cycle's advisory work is fully committed; clear any confirmed
|
|
2088
|
-
// OpenPlanr-owned scratch this cycle used as a handoff.
|
|
2089
|
-
await cleanOperatingScratch(resolveOperatingPaths(input.projectRoot, { localRoot: input.localRoot }), input.cycleId);
|
|
2090
|
-
return {
|
|
2091
|
-
session: sessionView(finalized, leaseDurationMs),
|
|
2092
|
-
results: results.map((result) => ({
|
|
2093
|
-
roleId: result.roleId,
|
|
2094
|
-
outcome: result.outcome,
|
|
2095
|
-
inputDigest: result.inputDigest,
|
|
2096
|
-
resultDigest: result.resultDigest,
|
|
2097
|
-
})),
|
|
2098
|
-
leaseStatus: adapterLeaseStatus(finalized, nowMs),
|
|
2099
|
-
handoff: await adapterHandoff(finalized),
|
|
2100
|
-
};
|
|
2101
|
-
}
|
|
2102
|
-
/**
|
|
2103
|
-
* SPEC-005 T-020 (FR13) — the OPERATOR escape, independent of a well-behaved
|
|
2104
|
-
* runtime. When a runtime dispatched a lens and then reported nothing at all — it
|
|
2105
|
-
* crashed, or does not implement `harness abandon` — the cycle is stranded at
|
|
2106
|
-
* `phase: advisors` on every continuation: the stalled lens is never recorded, so
|
|
2107
|
-
* it stays runnable-and-required and Chair is never assembled. The only prior
|
|
2108
|
-
* recourse was `cycles cancel`, which discards the whole cycle including the
|
|
2109
|
-
* siblings that DID record.
|
|
2110
|
-
*
|
|
2111
|
-
* This governed escape reaches a reviewable cycle without discarding it. It is
|
|
2112
|
-
* gated on a LAPSED lease — the legitimate signal that no runtime is actively
|
|
2113
|
-
* working the session — and an explicit operator confirmation. It never touches
|
|
2114
|
-
* the runtime lifecycle (`harness abandon`/`record`/`finalize`), so it works when
|
|
2115
|
-
* the runtime is gone. For each still-unrecorded advisor lens it commits the SAME
|
|
2116
|
-
* governed terminal `not_evaluated` gap the runtime path commits
|
|
2117
|
-
* (`governTerminalNotEvaluated`), so the next `run` continuation reconstructs the
|
|
2118
|
-
* lens `not_evaluated` from committed state and consolidation proceeds. Recorded
|
|
2119
|
-
* siblings are never read, re-dispatched, or altered. It fabricates nothing.
|
|
2120
|
-
*
|
|
2121
|
-
* It does not itself run consolidation — the operator reaches `reviewable` with a
|
|
2122
|
-
* following `planr operate run` (offline when no runtime is available), so the
|
|
2123
|
-
* choice of a real or offline Chair stays the operator's.
|
|
2124
|
-
*/
|
|
2125
|
-
export async function reapStalledOperatingRoles(input) {
|
|
2126
|
-
if (!input.confirmed) {
|
|
2127
|
-
throw new OperateError('E_OPERATE_AUTHORITY_REQUIRED', 'Abandoning a stalled lens is a governed action; re-run with --yes to confirm.');
|
|
2128
|
-
}
|
|
2129
|
-
const nowMs = (input.now?.() ?? new Date()).getTime();
|
|
2130
|
-
const store = new OperatingEventStore(input.projectRoot, { localRoot: input.localRoot });
|
|
2131
|
-
const state = await store.state();
|
|
2132
|
-
const cycle = state.cycles.find((record) => record.id === input.cycleId);
|
|
2133
|
-
if (!cycle || !['advising', 'blocked'].includes(cycle.state)) {
|
|
2134
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', `Cycle ${input.cycleId} must be advising or blocked to abandon a stalled lens.`);
|
|
2135
|
-
}
|
|
2136
|
-
// Read the machine-local session RAW (never `readAdapterSession`, which throws on
|
|
2137
|
-
// a lapsed lease — the exact condition this escape keys on).
|
|
2138
|
-
const target = adapterSessionPath(input.projectRoot, input.cycleId, input.localRoot);
|
|
2139
|
-
const session = await readFile(target, 'utf8')
|
|
2140
|
-
.then((raw) => JSON.parse(raw))
|
|
2141
|
-
.catch(() => null);
|
|
2142
|
-
if (!session) {
|
|
2143
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', `No adapter session exists for cycle ${input.cycleId}; nothing was dispatched to abandon.`);
|
|
2144
|
-
}
|
|
2145
|
-
if (session.phase !== 'advisors') {
|
|
2146
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', 'Only an advisors-phase session can have stalled lenses abandoned.');
|
|
2147
|
-
}
|
|
2148
|
-
// The lapsed-lease gate: a still-live lease means the runtime may yet record or
|
|
2149
|
-
// heartbeat, so the operator must not race it. Once the lease has lapsed, the
|
|
2150
|
-
// runtime is not governing the session and the operator may terminate the
|
|
2151
|
-
// lenses it left unrecorded.
|
|
2152
|
-
if (!sessionExpired(session, nowMs)) {
|
|
2153
|
-
throw new OperateError('E_OPERATE_ADVISOR_ISOLATION', 'The adapter lease has not lapsed; the runtime may still be working. Wait for the lease to ' +
|
|
2154
|
-
'expire, or use `planr operate harness abandon` with the active lease.', { recoveryCommand: retryRunCommand(session) });
|
|
2155
|
-
}
|
|
2156
|
-
const recorded = new Set(session.recordedRoles);
|
|
2157
|
-
const alreadyNotEvaluated = new Set(Object.keys(session.notEvaluatedRoles ?? {}));
|
|
2158
|
-
const candidates = session.roles.filter((role) => role !== 'chair' && !recorded.has(role) && !alreadyNotEvaluated.has(role));
|
|
2159
|
-
const targets = input.role ? candidates.filter((role) => role === input.role) : candidates;
|
|
2160
|
-
if (input.role && !session.roles.includes(input.role)) {
|
|
2161
|
-
throw new OperateError('E_OPERATE_CONFIG_INVALID', `Role ${input.role} was not part of the stalled session.`);
|
|
2162
|
-
}
|
|
2163
|
-
if (input.role && recorded.has(input.role)) {
|
|
2164
|
-
throw new OperateError('E_OPERATE_STATE_INVALID', `Role ${input.role} already recorded a result and cannot be abandoned.`);
|
|
2165
|
-
}
|
|
2166
|
-
const reason = input.reason?.trim() ||
|
|
2167
|
-
`Operator terminated this lens not_evaluated after its adapter lease lapsed on ` +
|
|
2168
|
-
`${new Date(nowMs).toISOString()} with no recorded result.`;
|
|
2169
|
-
const reaped = [];
|
|
2170
|
-
const notEvaluated = { ...(session.notEvaluatedRoles ?? {}) };
|
|
2171
|
-
for (const roleId of targets) {
|
|
2172
|
-
await governTerminalNotEvaluated({
|
|
2173
|
-
projectRoot: input.projectRoot,
|
|
2174
|
-
localRoot: input.localRoot,
|
|
2175
|
-
cycleId: input.cycleId,
|
|
2176
|
-
roleId,
|
|
2177
|
-
reason,
|
|
2178
|
-
correlationId: session.idempotencyKey,
|
|
2179
|
-
});
|
|
2180
|
-
// The committed gap is the source of truth; look it back up so the caller can
|
|
2181
|
-
// reference the durable governed gap id.
|
|
2182
|
-
const gap = (await store.state()).dataGaps.find((entry) => Array.isArray(entry.affectedRoles) && entry.affectedRoles.includes(roleId));
|
|
2183
|
-
reaped.push({ roleId, reason, gapId: String(gap?.id ?? '') });
|
|
2184
|
-
notEvaluated[roleId] = reason;
|
|
2185
|
-
}
|
|
2186
|
-
// Best-effort: reflect the terminal status in the (already lapsed) machine-local
|
|
2187
|
-
// session so an inspecting `harness resume`/handoff reads honestly. The committed
|
|
2188
|
-
// gap above — not this file — is what unblocks consolidation, so a failure here
|
|
2189
|
-
// is non-fatal.
|
|
2190
|
-
if (reaped.length > 0) {
|
|
2191
|
-
await atomicPrivateWrite(target, { ...session, notEvaluatedRoles: notEvaluated }).catch(() => undefined);
|
|
2192
|
-
}
|
|
2193
|
-
return {
|
|
2194
|
-
cycleId: input.cycleId,
|
|
2195
|
-
reaped,
|
|
2196
|
-
alreadyRecorded: [...recorded].sort(),
|
|
2197
|
-
next: [`planr operate run --cycle-id ${input.cycleId} --offline --yes`],
|
|
2198
|
-
};
|
|
2199
|
-
}
|
|
2200
|
-
//# sourceMappingURL=maintenance.js.map
|