@geraldmaron/construct 1.4.2 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +36 -0
- package/README.md +41 -7
- package/bin/construct +1027 -64
- package/examples/distribution/sources/deck-one-pager.md +1 -1
- package/lib/acp/server.mjs +21 -7
- package/lib/adapters-sync.mjs +2 -1
- package/lib/audit-trail.mjs +185 -2
- package/lib/beads/auto-close.mjs +2 -1
- package/lib/beads/drift.mjs +2 -1
- package/lib/bridges/copilot-proxy.mjs +20 -5
- package/lib/certification/skill-inventory.mjs +10 -1
- package/lib/cli/approvals.mjs +147 -0
- package/lib/cli-commands.mjs +105 -14
- package/lib/comment-lint.mjs +127 -8
- package/lib/config/schema.mjs +6 -29
- package/lib/config/source-target-registry.mjs +70 -0
- package/lib/config/source-targets.mjs +179 -205
- package/lib/contracts/coverage.mjs +77 -0
- package/lib/contracts/validate.mjs +102 -13
- package/lib/contracts/violation-log.mjs +50 -4
- package/lib/db/migrate.mjs +69 -0
- package/lib/db/migrations/001_orchestration_runs.sql +9 -0
- package/lib/db/migrations/002_queue_provider.sql +50 -0
- package/lib/db/migrations/003_worker_registry.sql +17 -0
- package/lib/db/migrations/004_trace_events.sql +16 -0
- package/lib/db/migrations/005_shared_memory.sql +15 -0
- package/lib/db/migrations/006_orchestration_runs_tenant.sql +5 -0
- package/lib/decisions/enforced-baseline.json +0 -2
- package/lib/decisions/registry.mjs +3 -2
- package/lib/deployment/parity-contract.mjs +1 -1
- package/lib/deployment-mode.mjs +78 -2
- package/lib/diagram-export.mjs +10 -1
- package/lib/distill.mjs +5 -2
- package/lib/docs-verify.mjs +2 -1
- package/lib/doctor/cli.mjs +1 -0
- package/lib/doctor/command-on-path.mjs +24 -0
- package/lib/doctor/diagnosis.mjs +89 -0
- package/lib/doctor/embedding-health.mjs +50 -0
- package/lib/doctor/engine-health.mjs +93 -0
- package/lib/doctor/graph-validate.mjs +47 -0
- package/lib/doctor/index.mjs +18 -4
- package/lib/doctor/sidecar-providers.mjs +56 -0
- package/lib/doctor/watchers/consistency.mjs +93 -1
- package/lib/doctor/watchers/cx-budget.mjs +1 -1
- package/lib/doctor/watchers/graph-staleness.mjs +1 -1
- package/lib/doctor/watchers/mcp-protocol.mjs +17 -0
- package/lib/doctor/watchers/oracle-liveness.mjs +92 -0
- package/lib/doctor/watchers/orchestration-runs.mjs +108 -0
- package/lib/doctor/watchers/provider-breaker.mjs +78 -0
- package/lib/document-export.mjs +52 -27
- package/lib/document-extract/docling-client.mjs +9 -5
- package/lib/document-extract/docling-sidecar.py +30 -0
- package/lib/document-extract.mjs +1 -1
- package/lib/document-ingest.mjs +9 -0
- package/lib/embed/approval-queue.mjs +184 -88
- package/lib/embed/authority-guard.mjs +65 -2
- package/lib/embed/capability-jobs.mjs +365 -0
- package/lib/embed/capability-lifecycle.mjs +219 -0
- package/lib/embed/capability-loader.mjs +303 -0
- package/lib/embed/capability-runtime.mjs +58 -0
- package/lib/embed/cli.mjs +185 -8
- package/lib/embed/config.mjs +4 -0
- package/lib/embed/daemon.mjs +125 -6
- package/lib/embed/demand-fetch.mjs +190 -54
- package/lib/embed/inbox.mjs +12 -10
- package/lib/embed/presets/ops-triage.mjs +236 -0
- package/lib/embed/presets/pm-feedback.mjs +341 -0
- package/lib/embed/presets/tpm.mjs +401 -0
- package/lib/embed/providers/jira.mjs +72 -1
- package/lib/embed/providers/registry.mjs +140 -33
- package/lib/embedded-contract/capability.mjs +4 -0
- package/lib/embedded-contract/execution.mjs +1 -1
- package/lib/embedded-contract/model-resolve.mjs +53 -3
- package/lib/embedded-contract/workflow-defs.mjs +48 -73
- package/lib/embedded-contract/workflow-invoke.mjs +144 -4
- package/lib/embedded-contract/workflows/architecture-review.manifest.json +15 -0
- package/lib/embedded-contract/workflows/data-structure.manifest.json +14 -0
- package/lib/embedded-contract/workflows/evidence-ingest.manifest.json +14 -0
- package/lib/embedded-contract/workflows/memo-draft.manifest.json +14 -0
- package/lib/embedded-contract/workflows/operations-triage.manifest.json +18 -0
- package/lib/embedded-contract/workflows/operations.manifest.json +18 -0
- package/lib/embedded-contract/workflows/pm-feedback.manifest.json +18 -0
- package/lib/embedded-contract/workflows/prd-draft.manifest.json +15 -0
- package/lib/embedded-contract/workflows/proposal-review.manifest.json +15 -0
- package/lib/embedded-contract/workflows/research-synthesis.manifest.json +14 -0
- package/lib/embedded-contract/workflows/risk-review.manifest.json +15 -0
- package/lib/embedded-contract/workflows/structure-notes.manifest.json +14 -0
- package/lib/embedded-contract/workflows/transcript-process.manifest.json +14 -0
- package/lib/embedded-contract/workflows/triage.manifest.json +14 -0
- package/lib/env-config.mjs +50 -9
- package/lib/extensions/index.mjs +27 -0
- package/lib/extensions/loader.mjs +120 -0
- package/lib/extensions/manifest-schema.mjs +141 -0
- package/lib/extensions/manifests/anthropic.manifest.json +12 -0
- package/lib/extensions/manifests/atlassian-confluence.manifest.json +12 -0
- package/lib/extensions/manifests/atlassian-jira.manifest.json +53 -0
- package/lib/extensions/manifests/directory.manifest.json +12 -0
- package/lib/extensions/manifests/docling.manifest.json +37 -0
- package/lib/extensions/manifests/echo.manifest.json +8 -0
- package/lib/extensions/manifests/feedback.manifest.json +12 -0
- package/lib/extensions/manifests/github-copilot.manifest.json +12 -0
- package/lib/extensions/manifests/github.manifest.json +52 -0
- package/lib/extensions/manifests/linear.manifest.json +50 -0
- package/lib/extensions/manifests/local.manifest.json +12 -0
- package/lib/extensions/manifests/ollama.manifest.json +12 -0
- package/lib/extensions/manifests/openai.manifest.json +12 -0
- package/lib/extensions/manifests/openrouter-anthropic.manifest.json +12 -0
- package/lib/extensions/manifests/openrouter-deepseek.manifest.json +12 -0
- package/lib/extensions/manifests/openrouter-google.manifest.json +12 -0
- package/lib/extensions/manifests/openrouter-llama.manifest.json +12 -0
- package/lib/extensions/manifests/openrouter-qwen.manifest.json +12 -0
- package/lib/extensions/manifests/openrouter.manifest.json +12 -0
- package/lib/extensions/manifests/postgres.manifest.json +12 -0
- package/lib/extensions/manifests/salesforce.manifest.json +12 -0
- package/lib/extensions/manifests/slack.manifest.json +58 -0
- package/lib/extensions/manifests/whisper.manifest.json +36 -0
- package/lib/extensions/validate.mjs +175 -0
- package/lib/features.mjs +13 -9
- package/lib/flows/checkpoint.mjs +184 -0
- package/lib/flows/constants.mjs +27 -0
- package/lib/flows/define.mjs +146 -0
- package/lib/flows/engine.mjs +249 -0
- package/lib/flows/errors.mjs +19 -0
- package/lib/flows/index.mjs +27 -0
- package/lib/flows/joins.mjs +18 -0
- package/lib/flows/schema.mjs +90 -0
- package/lib/flows/state.mjs +31 -0
- package/lib/frameworks/loader.mjs +99 -0
- package/lib/frameworks/schema.mjs +157 -0
- package/lib/graph/build-from-corpus.mjs +67 -0
- package/lib/graph/build-from-embed.mjs +82 -0
- package/lib/graph/build-from-registry.mjs +164 -3
- package/lib/graph/cli.mjs +456 -12
- package/lib/graph/gap-queries.mjs +156 -0
- package/lib/graph/gaps.mjs +41 -0
- package/lib/graph/impacted.mjs +129 -0
- package/lib/graph/runtime-evidence.mjs +177 -0
- package/lib/graph/security-coverage.mjs +113 -0
- package/lib/graph/staleness.mjs +241 -10
- package/lib/graph/store.mjs +24 -7
- package/lib/graph/validate.mjs +161 -0
- package/lib/headhunt.mjs +9 -8
- package/lib/health-check.mjs +15 -7
- package/lib/hook-health.mjs +1 -1
- package/lib/hooks/agent-tracker.mjs +10 -4
- package/lib/hooks/edit-guard.mjs +3 -3
- package/lib/hooks/graph-impact-advisory.mjs +2 -2
- package/lib/hooks/guard-bash.mjs +41 -15
- package/lib/hooks/mcp-health-check.mjs +11 -4
- package/lib/hooks/model-fallback.mjs +50 -6
- package/lib/hooks/orchestration-dispatch-guard.mjs +14 -3
- package/lib/hooks/pre-compact.mjs +181 -173
- package/lib/hooks/rule-verifier.mjs +2 -1
- package/lib/hooks/session-reflect.mjs +2 -1
- package/lib/hooks/session-start.mjs +3 -3
- package/lib/host-capabilities.mjs +13 -2
- package/lib/host-disposition.mjs +19 -7
- package/lib/identity.mjs +92 -0
- package/lib/ingest/degraded-extract.mjs +96 -0
- package/lib/ingest/docling-remote.mjs +2 -1
- package/lib/ingest/provider-extract.mjs +7 -19
- package/lib/ingest/sidecar-providers.mjs +196 -0
- package/lib/ingest-tooling.mjs +11 -5
- package/lib/init-unified.mjs +57 -45
- package/lib/init-update.mjs +2 -1
- package/lib/install/legacy-global-cleanup.mjs +25 -0
- package/lib/intake/daemon.mjs +99 -8
- package/lib/intake/git-queue.mjs +110 -38
- package/lib/intake/queue-registry.mjs +50 -0
- package/lib/intake/queue.mjs +133 -17
- package/lib/intake/session-prelude.mjs +57 -8
- package/lib/integrations/intake-integrations.mjs +61 -111
- package/lib/intent-classifier.mjs +43 -5
- package/lib/libreoffice-export.mjs +8 -8
- package/lib/logging/rotate.mjs +5 -4
- package/lib/mcp/broker.mjs +332 -17
- package/lib/mcp/denied-store.mjs +95 -0
- package/lib/mcp/destructive-gate.mjs +30 -0
- package/lib/mcp/dispatch-envelope.mjs +199 -0
- package/lib/mcp/memory-bridge.mjs +2 -1
- package/lib/mcp/server.mjs +154 -1411
- package/lib/mcp/tool-definitions-memory.mjs +376 -0
- package/lib/mcp/tool-definitions-project.mjs +271 -0
- package/lib/mcp/tool-definitions-skills.mjs +311 -0
- package/lib/mcp/tool-definitions-workflow.mjs +398 -0
- package/lib/mcp/tool-definitions.mjs +25 -0
- package/lib/mcp/tool-registry.mjs +107 -0
- package/lib/mcp/tool-safety.mjs +1 -0
- package/lib/mcp/tools/orchestration-delegation-next.tool.mjs +68 -0
- package/lib/mcp/tools/orchestration-run.mjs +165 -25
- package/lib/mcp/tools/orchestration-task-result.tool.mjs +77 -0
- package/lib/mcp/tools/provider-write.mjs +187 -0
- package/lib/mcp/tools/scope.mjs +0 -3
- package/lib/mcp/tools/skills.mjs +1 -1
- package/lib/mcp/tools/storage.mjs +0 -8
- package/lib/mcp/transport/auth.mjs +238 -0
- package/lib/mcp/transport/http.mjs +136 -0
- package/lib/mcp/transport/mode.mjs +31 -0
- package/lib/mcp/transport/stdio.mjs +22 -0
- package/lib/mcp-catalog.json +4 -4
- package/lib/mcp-manager.mjs +34 -23
- package/lib/mcp-platform-config.mjs +31 -7
- package/lib/mode-capabilities.mjs +109 -0
- package/lib/model-router.mjs +42 -9
- package/lib/models/catalog.mjs +40 -1
- package/lib/net-guard.mjs +247 -0
- package/lib/observation-store.mjs +6 -2
- package/lib/ollama/provision-context.mjs +2 -1
- package/lib/opencode-config.mjs +22 -3
- package/lib/opencode-runtime-plugin.mjs +120 -2
- package/lib/oracle/actions.mjs +204 -10
- package/lib/oracle/cli.mjs +24 -3
- package/lib/oracle/dispatch.mjs +2 -1
- package/lib/oracle/execute.mjs +2 -2
- package/lib/oracle/gaps.mjs +3 -3
- package/lib/oracle/heartbeat.mjs +53 -0
- package/lib/oracle/read-model.mjs +69 -13
- package/lib/oracle/reconcile.mjs +3 -46
- package/lib/oracle/routing.mjs +37 -31
- package/lib/oracle/synthesize.mjs +1 -1
- package/lib/orchestration/classification.mjs +434 -0
- package/lib/orchestration/delegation-flow.mjs +132 -0
- package/lib/orchestration/flow-selection.mjs +418 -0
- package/lib/orchestration/gates.mjs +244 -0
- package/lib/orchestration/host-sampling.mjs +121 -0
- package/lib/orchestration/policy-constants.mjs +48 -0
- package/lib/orchestration/provider-outcome.mjs +197 -0
- package/lib/orchestration/readiness.mjs +114 -13
- package/lib/orchestration/run-store-postgres.mjs +32 -26
- package/lib/orchestration/run-store-sqlite.mjs +8 -14
- package/lib/orchestration/run-store.mjs +25 -12
- package/lib/orchestration/runtime.mjs +446 -39
- package/lib/orchestration/store.mjs +87 -12
- package/lib/orchestration/trace-store.mjs +125 -0
- package/lib/orchestration/web-capability.mjs +3 -2
- package/lib/orchestration/worker-runtime.mjs +162 -0
- package/lib/orchestration/worker.mjs +528 -89
- package/lib/orchestration-policy.mjs +67 -1111
- package/lib/packs/cli.mjs +144 -0
- package/lib/packs/core-pack.mjs +112 -0
- package/lib/packs/enablement.mjs +187 -0
- package/lib/packs/index.mjs +23 -0
- package/lib/packs/loader.mjs +176 -0
- package/lib/packs/manifest-schema.mjs +58 -0
- package/lib/packs/prompts.mjs +120 -0
- package/lib/packs/validate.mjs +208 -0
- package/lib/plugin-registry.mjs +4 -5
- package/lib/policy/audit-gate.mjs +42 -0
- package/lib/policy/consumption-budget.mjs +149 -0
- package/lib/policy/engine.mjs +81 -6
- package/lib/policy/role-authority.mjs +89 -0
- package/lib/prompt-composer.js +19 -3
- package/lib/providers/contract/adapters/confluence/governed-write.mjs +215 -0
- package/lib/providers/contract/adapters/confluence/manifest.json +17 -0
- package/lib/providers/contract/adapters/confluence/transport.mjs +135 -0
- package/lib/providers/contract/adapters/github/governed-write.mjs +121 -0
- package/lib/providers/contract/adapters/github/index.mjs +38 -3
- package/lib/providers/contract/adapters/jira/adf.mjs +151 -0
- package/lib/providers/contract/adapters/jira/createmeta.mjs +143 -0
- package/lib/providers/contract/adapters/jira/governed-write.mjs +182 -0
- package/lib/providers/contract/adapters/jira/manifest.json +17 -0
- package/lib/providers/contract/adapters/jira/transport.mjs +119 -0
- package/lib/providers/contract.mjs +207 -0
- package/lib/providers/credential-bootstrap.mjs +7 -4
- package/lib/providers/credential-sources.mjs +14 -2
- package/lib/providers/directory/index.mjs +273 -0
- package/lib/providers/feedback/index.mjs +392 -0
- package/lib/providers/filter-audit.mjs +68 -0
- package/lib/providers/filter-schema.mjs +54 -0
- package/lib/providers/github/index.mjs +31 -0
- package/lib/providers/instance-config.mjs +215 -0
- package/lib/providers/op-locate.mjs +96 -0
- package/lib/providers/op-run.mjs +64 -9
- package/lib/providers/registry.mjs +26 -3
- package/lib/providers/secret-audit-wiring.mjs +6 -0
- package/lib/providers/secret-resolver.mjs +240 -23
- package/lib/publish-template.mjs +6 -3
- package/lib/publish-tooling.mjs +4 -0
- package/lib/publish.mjs +32 -4
- package/lib/queue/pg-queue.mjs +395 -0
- package/lib/reflect.mjs +2 -1
- package/lib/registry/assemble.mjs +28 -2
- package/lib/registry/consolidation.mjs +8 -1
- package/lib/registry/custom-scaffold.mjs +200 -0
- package/lib/registry/custom-schema.mjs +137 -0
- package/lib/registry/loader.mjs +8 -3
- package/lib/registry/manifests/format-engines.default.json +15 -0
- package/lib/registry/manifests/surface-map.default.json +46 -0
- package/lib/registry/retired-paths.mjs +1 -0
- package/lib/registry/surface-map.mjs +100 -50
- package/lib/render-visual-check.mjs +240 -0
- package/lib/resources/budget.mjs +40 -17
- package/lib/roles/flavor-bindings.mjs +36 -14
- package/lib/roles/gateway.mjs +15 -8
- package/lib/roots.mjs +107 -0
- package/lib/runtime/uv-bootstrap.mjs +32 -6
- package/lib/runtime/whisper-bootstrap.mjs +11 -3
- package/lib/runtime-env.mjs +5 -2
- package/lib/scheduler/index.mjs +8 -20
- package/lib/schema-infer.mjs +31 -2
- package/lib/scopes/lifecycle.mjs +29 -25
- package/lib/scopes/loader.mjs +49 -12
- package/lib/scopes/teams.mjs +1 -1
- package/lib/security/ingest-boundary.mjs +80 -0
- package/lib/security/recall-wrapper.mjs +99 -0
- package/lib/security/trust.mjs +132 -0
- package/lib/service-manager.mjs +38 -19
- package/lib/setup.mjs +41 -23
- package/lib/skills-apply.mjs +4 -2
- package/lib/specialists/postconditions.mjs +2 -2
- package/lib/state-root.mjs +147 -0
- package/lib/status.mjs +597 -6
- package/lib/storage/admin.mjs +77 -5
- package/lib/storage/backend-registry.mjs +73 -0
- package/lib/storage/backend.mjs +63 -9
- package/lib/storage/embeddings-openai.mjs +12 -2
- package/lib/storage/hybrid-query.mjs +11 -3
- package/lib/storage/retrieval-hardening.mjs +384 -0
- package/lib/storage/shared-memory.mjs +158 -0
- package/lib/storage/vector-client.mjs +69 -2
- package/lib/team/health.mjs +72 -0
- package/lib/telemetry/backends/local.mjs +9 -3
- package/lib/telemetry/client.mjs +3 -7
- package/lib/template-registry.mjs +10 -12
- package/lib/tenant/context.mjs +82 -0
- package/lib/tenant/isolation.mjs +129 -0
- package/lib/test-corpus-inventory.mjs +104 -2
- package/lib/uninstall/uninstall.mjs +78 -12
- package/lib/validator.mjs +4 -6
- package/lib/worker/entrypoint.mjs +2 -1
- package/lib/worker/run.mjs +2 -2
- package/lib/worker/trace.mjs +5 -11
- package/lib/workflow-state.mjs +52 -8
- package/lib/workflows/liveness.mjs +203 -0
- package/lib/workflows/loader.mjs +177 -0
- package/lib/workflows/manifest-schema.mjs +71 -0
- package/lib/workflows/surface-parity.mjs +118 -0
- package/lib/workflows/validate.mjs +127 -0
- package/lib/writes/control-plane.mjs +140 -0
- package/lib/writes/envelope.mjs +206 -0
- package/lib/writes/sent-log.mjs +86 -0
- package/lib/writes/write-intent.mjs +109 -0
- package/package.json +16 -8
- package/personas/construct.md +12 -3
- package/registry/capabilities.json +143 -36
- package/rules/common/comments.md +1 -0
- package/schemas/project-config.schema.json +0 -12
- package/schemas/unified-registry.schema.json +2 -4
- package/scripts/sync-specialists.mjs +284 -81
- package/skills/docs/adr-workflow.md +1 -1
- package/skills/docs/codebase-research-workflow.md +3 -3
- package/skills/docs/prd-workflow.md +5 -6
- package/skills/docs/runbook-workflow.md +2 -2
- package/skills/docs/user-research-workflow.md +3 -3
- package/skills/operating/fleet-health-routing.md +77 -0
- package/skills/roles/ai-engineer.md +1 -1
- package/skills/roles/architect.md +0 -1
- package/skills/roles/business-strategist.md +1 -1
- package/skills/roles/data-analyst.telemetry.md +1 -1
- package/skills/roles/data-engineer.md +1 -1
- package/skills/roles/data-engineer.pipeline.md +1 -1
- package/skills/roles/data-engineer.vector-retrieval.md +1 -2
- package/skills/roles/data-engineer.warehouse.md +1 -1
- package/skills/roles/designer.accessibility.md +1 -1
- package/skills/roles/designer.md +0 -1
- package/skills/roles/devil-advocate.md +1 -1
- package/skills/roles/docs-keeper.md +1 -1
- package/skills/roles/evaluator.md +1 -1
- package/skills/roles/explorer.md +1 -1
- package/skills/roles/platform-engineer.md +1 -1
- package/skills/roles/qa.ai-eval.md +1 -2
- package/skills/roles/qa.api-contract.md +0 -1
- package/skills/roles/qa.data-pipeline.md +0 -1
- package/skills/roles/qa.md +0 -1
- package/skills/roles/qa.web-ui.md +0 -1
- package/skills/roles/release-manager.md +1 -1
- package/skills/roles/researcher.md +0 -2
- package/skills/roles/reviewer.md +0 -3
- package/skills/roles/security.ai.md +1 -1
- package/skills/roles/security.legal-compliance.md +1 -1
- package/skills/roles/security.md +0 -1
- package/skills/roles/security.privacy.md +0 -1
- package/skills/roles/security.supply-chain.md +1 -1
- package/skills/roles/sre.md +1 -1
- package/skills/roles/test-automation.md +1 -1
- package/skills/roles/trace-reviewer.md +1 -1
- package/skills/roles/ux-researcher.md +1 -1
- package/specialists/artifact-manifest.json +36 -36
- package/specialists/org/contracts/accessibility-to-qa.json +11 -3
- package/specialists/org/contracts/any-to-business-strategist.json +19 -7
- package/specialists/org/contracts/any-to-debugger.json +7 -1
- package/specialists/org/contracts/any-to-designer.json +7 -1
- package/specialists/org/contracts/any-to-docs-keeper.json +18 -4
- package/specialists/org/contracts/any-to-explorer.json +13 -4
- package/specialists/org/contracts/any-to-sre-incident.json +6 -2
- package/specialists/org/contracts/any-to-trace-reviewer.json +16 -4
- package/specialists/org/contracts/architect-to-ai-engineer.json +6 -2
- package/specialists/org/contracts/architect-to-data-engineer.json +17 -5
- package/specialists/org/contracts/architect-to-devil-advocate.json +11 -3
- package/specialists/org/contracts/architect-to-engineer.json +20 -4
- package/specialists/org/contracts/architect-to-evaluator.json +15 -5
- package/specialists/org/contracts/architect-to-legal-compliance.json +15 -5
- package/specialists/org/contracts/architect-to-operations.json +17 -4
- package/specialists/org/contracts/architect-to-platform-engineer.json +20 -4
- package/specialists/org/contracts/construct-to-orchestrator.json +10 -2
- package/specialists/org/contracts/data-analyst-to-product-manager.json +11 -2
- package/specialists/org/contracts/engineer-to-qa.json +20 -4
- package/specialists/org/contracts/engineer-to-reviewer.json +29 -5
- package/specialists/org/contracts/explorer-to-engineer.json +11 -3
- package/specialists/org/contracts/legal-compliance-to-release-manager.json +12 -4
- package/specialists/org/contracts/operations-to-user.json +53 -0
- package/specialists/org/contracts/operations-triage-output.json +53 -0
- package/specialists/org/contracts/pm-requirements-candidates.json +53 -0
- package/specialists/org/contracts/product-manager-to-architect.json +30 -10
- package/specialists/org/contracts/product-manager-to-data-analyst.json +13 -3
- package/specialists/org/contracts/product-manager-to-ux-researcher.json +15 -5
- package/specialists/org/contracts/qa-to-release-manager.json +11 -3
- package/specialists/org/contracts/researcher-to-architect.json +10 -2
- package/specialists/org/contracts/researcher-to-product-manager.json +16 -5
- package/specialists/org/contracts/reviewer-to-security.json +17 -3
- package/specialists/org/contracts/test-automation-to-engineer.json +11 -3
- package/specialists/org/contracts/trace-reviewer-to-sre.json +12 -4
- package/specialists/org/contracts/user-to-construct.json +11 -4
- package/specialists/org/frameworks/cx-architect-constraint-option-failure.md +66 -0
- package/specialists/org/frameworks/cx-engineer-feasibility-blast-radius.md +66 -0
- package/specialists/org/frameworks/cx-ops-dependency-sequencing.md +74 -0
- package/specialists/org/frameworks/cx-pm-value-tradeoff.md +66 -0
- package/specialists/org/frameworks/cx-qa-risk-based-coverage.md +69 -0
- package/specialists/org/groups/engineering-group.json +2 -6
- package/specialists/org/groups/governance-group.json +2 -3
- package/specialists/org/groups/operations-group.json +5 -8
- package/specialists/org/groups/product-group.json +4 -8
- package/specialists/org/groups/quality-group.json +3 -7
- package/specialists/org/groups/strategy-group.json +6 -9
- package/specialists/org/models.json.example +8 -0
- package/specialists/org/scopes/creative.json +6 -1
- package/specialists/org/scopes/operations.json +7 -1
- package/specialists/org/scopes/research.json +6 -1
- package/specialists/org/scopes/rnd.json +7 -1
- package/specialists/org/specialists/cx-architect.json +27 -8
- package/specialists/org/specialists/cx-designer.json +22 -8
- package/specialists/org/specialists/cx-engineer.json +71 -7
- package/specialists/org/specialists/cx-operations.json +89 -15
- package/specialists/org/specialists/cx-orchestrator.json +16 -4
- package/specialists/org/specialists/cx-product-manager.json +28 -9
- package/specialists/org/specialists/cx-qa.json +16 -6
- package/specialists/org/specialists/cx-researcher.json +40 -7
- package/specialists/org/specialists/cx-reviewer.json +61 -11
- package/specialists/org/specialists/cx-security.json +30 -10
- package/specialists/org/teams/design-team.json +3 -4
- package/specialists/org/teams/engineering-team.json +3 -10
- package/specialists/org/teams/governance-team.json +3 -5
- package/specialists/org/teams/operations-team.json +6 -12
- package/specialists/org/teams/product-management-team.json +2 -3
- package/specialists/org/teams/quality-team.json +4 -12
- package/specialists/org/teams/research-team.json +3 -3
- package/specialists/org/teams/strategy-team.json +7 -14
- package/specialists/prompts/cx-architect.md +20 -1
- package/specialists/prompts/cx-data-analyst.md +1 -1
- package/specialists/prompts/cx-designer.md +12 -4
- package/specialists/prompts/cx-engineer.md +15 -1
- package/specialists/prompts/cx-operations.md +14 -2
- package/specialists/prompts/cx-orchestrator.md +9 -5
- package/specialists/prompts/cx-product-manager.md +5 -1
- package/specialists/prompts/cx-qa.md +6 -2
- package/specialists/prompts/cx-researcher.md +25 -30
- package/specialists/prompts/cx-reviewer.md +19 -1
- package/specialists/prompts/cx-security.md +5 -1
- package/templates/distribution/construct-brand.typ +123 -59
- package/templates/distribution/construct-decision.typ +6 -3
- package/templates/distribution/construct-pdf.typ +11 -4
- package/templates/distribution/construct-prd.typ +6 -3
- package/templates/distribution/construct-research.typ +7 -4
- package/lib/providers/contract/adapters/git/index.mjs +0 -115
- package/lib/providers/contract/adapters/slack/index.mjs +0 -175
- package/specialists/org/contracts/business-strategist-to-product-manager.json +0 -39
- package/specialists/org/contracts/construct-to-rd-lead.json +0 -53
- package/specialists/org/contracts/data-engineer-to-platform-engineer.json +0 -36
- package/specialists/org/contracts/designer-to-accessibility.json +0 -36
- package/specialists/org/contracts/platform-engineer-to-engineer.json +0 -31
- package/specialists/org/contracts/qa-to-test-automation.json +0 -42
- package/specialists/org/contracts/rd-lead-to-architect.json +0 -38
- package/specialists/org/contracts/sre-to-release-manager.json +0 -36
- package/specialists/org/specialists/cx-accessibility.json +0 -69
- package/specialists/org/specialists/cx-ai-engineer.json +0 -75
- package/specialists/org/specialists/cx-business-strategist.json +0 -72
- package/specialists/org/specialists/cx-data-engineer.json +0 -71
- package/specialists/org/specialists/cx-devil-advocate.json +0 -71
- package/specialists/org/specialists/cx-docs-keeper.json +0 -82
- package/specialists/org/specialists/cx-evaluator.json +0 -69
- package/specialists/org/specialists/cx-explorer.json +0 -69
- package/specialists/org/specialists/cx-legal-compliance.json +0 -74
- package/specialists/org/specialists/cx-oracle.json +0 -46
- package/specialists/org/specialists/cx-platform-engineer.json +0 -80
- package/specialists/org/specialists/cx-rd-lead.json +0 -73
- package/specialists/org/specialists/cx-release-manager.json +0 -77
- package/specialists/org/specialists/cx-sre.json +0 -94
- package/specialists/org/specialists/cx-test-automation.json +0 -69
- package/specialists/org/specialists/cx-trace-reviewer.json +0 -69
- package/specialists/org/specialists/cx-ux-researcher.json +0 -68
- package/specialists/org/teams/accessibility-team.json +0 -39
- package/specialists/org/teams/ux-research-team.json +0 -39
- package/specialists/prompts/cx-accessibility.md +0 -55
- package/specialists/prompts/cx-ai-engineer.md +0 -124
- package/specialists/prompts/cx-business-strategist.md +0 -58
- package/specialists/prompts/cx-data-engineer.md +0 -55
- package/specialists/prompts/cx-devil-advocate.md +0 -59
- package/specialists/prompts/cx-docs-keeper.md +0 -164
- package/specialists/prompts/cx-evaluator.md +0 -49
- package/specialists/prompts/cx-explorer.md +0 -71
- package/specialists/prompts/cx-legal-compliance.md +0 -58
- package/specialists/prompts/cx-oracle.md +0 -98
- package/specialists/prompts/cx-platform-engineer.md +0 -97
- package/specialists/prompts/cx-rd-lead.md +0 -59
- package/specialists/prompts/cx-release-manager.md +0 -54
- package/specialists/prompts/cx-sre.md +0 -111
- package/specialists/prompts/cx-test-automation.md +0 -55
- package/specialists/prompts/cx-trace-reviewer.md +0 -101
- package/specialists/prompts/cx-ux-researcher.md +0 -53
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/writes/sent-log.mjs — durable JSONL record of executed external writes.
|
|
3
|
+
*
|
|
4
|
+
* WriteSentLog persists idempotency keys and outcomes so a retried or duplicate
|
|
5
|
+
* write-intent is deduplicated rather than re-executed against the remote system.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
|
|
11
|
+
export class WriteSentLog {
|
|
12
|
+
#records = [];
|
|
13
|
+
#persistPath = null;
|
|
14
|
+
|
|
15
|
+
constructor({ persistPath } = {}) {
|
|
16
|
+
if (persistPath) {
|
|
17
|
+
this.#persistPath = persistPath;
|
|
18
|
+
this.#load();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
record(entry) {
|
|
23
|
+
const rec = {
|
|
24
|
+
idempotencyKey: entry.idempotencyKey,
|
|
25
|
+
writeType: entry.writeType,
|
|
26
|
+
provider: entry.provider,
|
|
27
|
+
sentAt: entry.sentAt || new Date().toISOString(),
|
|
28
|
+
completedAt: entry.completedAt || null,
|
|
29
|
+
status: entry.status || 'pending',
|
|
30
|
+
externalUrl: entry.externalUrl || null,
|
|
31
|
+
externalId: entry.externalId || null,
|
|
32
|
+
result: entry.result || null,
|
|
33
|
+
error: entry.error || null,
|
|
34
|
+
};
|
|
35
|
+
this.#records.push(rec);
|
|
36
|
+
this.#persist();
|
|
37
|
+
return rec;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
findByIdempotencyKey(key) {
|
|
41
|
+
let found = null;
|
|
42
|
+
for (const r of this.#records) {
|
|
43
|
+
if (r.idempotencyKey === key) found = r;
|
|
44
|
+
}
|
|
45
|
+
return found;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
list({ provider, status, since } = {}) {
|
|
49
|
+
let results = [...this.#records];
|
|
50
|
+
if (provider) results = results.filter(r => r.provider === provider);
|
|
51
|
+
if (status) results = results.filter(r => r.status === status);
|
|
52
|
+
if (since) results = results.filter(r => new Date(r.sentAt) >= new Date(since));
|
|
53
|
+
return results;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
pruneOlderThan(ms) {
|
|
57
|
+
const cutoff = Date.now() - ms;
|
|
58
|
+
const before = this.#records.length;
|
|
59
|
+
this.#records = this.#records.filter(r => new Date(r.sentAt).getTime() > cutoff);
|
|
60
|
+
this.#persist();
|
|
61
|
+
return before - this.#records.length;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
#persist() {
|
|
65
|
+
if (!this.#persistPath) return;
|
|
66
|
+
try {
|
|
67
|
+
fs.mkdirSync(path.dirname(this.#persistPath), { recursive: true });
|
|
68
|
+
const lines = this.#records.map(r => JSON.stringify(r)).join('\n');
|
|
69
|
+
fs.writeFileSync(this.#persistPath, lines + '\n', 'utf8');
|
|
70
|
+
} catch {}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
#load() {
|
|
74
|
+
try {
|
|
75
|
+
if (!fs.existsSync(this.#persistPath)) return;
|
|
76
|
+
const lines = fs.readFileSync(this.#persistPath, 'utf8').split('\n').filter(Boolean);
|
|
77
|
+
for (const line of lines) {
|
|
78
|
+
try { this.#records.push(JSON.parse(line)); } catch {}
|
|
79
|
+
}
|
|
80
|
+
} catch {}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static resolvePersistPath(rootDir) {
|
|
84
|
+
return path.join(rootDir, '.cx', 'writes', 'sent-log.jsonl');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/writes/write-intent.mjs — the writeIntent record: the only artifact
|
|
3
|
+
* shape a specialist, embed capability, or MCP caller may produce when it
|
|
4
|
+
* wants an external write to happen.
|
|
5
|
+
*
|
|
6
|
+
* A writeIntent never executes anything by itself. `buildWriteIntent`
|
|
7
|
+
* validates and normalizes the record; `lib/writes/control-plane.mjs` is the
|
|
8
|
+
* only module that turns an *approved* writeIntent into a call through
|
|
9
|
+
* lib/writes/envelope.mjs. Nothing in this file resolves a provider adapter
|
|
10
|
+
* or performs I/O — it is schema and validation only, so it stays importable
|
|
11
|
+
* from any orchestration or embed path without smuggling in write access.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** Providers with a governed-write adapter under lib/providers/contract/adapters/*. */
|
|
15
|
+
export const KNOWN_PROVIDERS = Object.freeze(['jira', 'github', 'confluence']);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Validate a writeIntent's required shape. Returns `{ ok: true }` or
|
|
19
|
+
* `{ ok: false, errors: string[] }` — never throws, so a malformed proposal
|
|
20
|
+
* from a specialist degrades to a rejected intent rather than crashing the
|
|
21
|
+
* caller.
|
|
22
|
+
*
|
|
23
|
+
* @param {object} intent
|
|
24
|
+
* @param {string} intent.providerId - one of KNOWN_PROVIDERS
|
|
25
|
+
* @param {string} intent.writeKind - adapter-specific write type (e.g. 'issue', 'comment')
|
|
26
|
+
* @param {object} intent.payload - write payload passed to the adapter
|
|
27
|
+
* @param {object} [intent.requestedBy] - actor identity of the recommending specialist
|
|
28
|
+
* @returns {{ ok: boolean, errors?: string[] }}
|
|
29
|
+
*/
|
|
30
|
+
export function validateWriteIntent(intent) {
|
|
31
|
+
const errors = [];
|
|
32
|
+
if (!intent || typeof intent !== 'object') {
|
|
33
|
+
return { ok: false, errors: ['writeIntent must be an object'] };
|
|
34
|
+
}
|
|
35
|
+
if (!intent.providerId || typeof intent.providerId !== 'string') {
|
|
36
|
+
errors.push('writeIntent.providerId is required');
|
|
37
|
+
} else if (!KNOWN_PROVIDERS.includes(intent.providerId)) {
|
|
38
|
+
errors.push(`writeIntent.providerId "${intent.providerId}" is not a known governed provider (${KNOWN_PROVIDERS.join(', ')})`);
|
|
39
|
+
}
|
|
40
|
+
if (!intent.writeKind || typeof intent.writeKind !== 'string') {
|
|
41
|
+
errors.push('writeIntent.writeKind is required');
|
|
42
|
+
}
|
|
43
|
+
if (!intent.payload || typeof intent.payload !== 'object') {
|
|
44
|
+
errors.push('writeIntent.payload is required and must be an object');
|
|
45
|
+
}
|
|
46
|
+
return errors.length ? { ok: false, errors } : { ok: true };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Build a normalized writeIntent record from a specialist's recommendation.
|
|
51
|
+
* Throws on an invalid intent so a caller cannot silently enqueue a
|
|
52
|
+
* malformed record — the run should see the failure at recommend time, not
|
|
53
|
+
* discover it later when the control plane tries to execute it.
|
|
54
|
+
*
|
|
55
|
+
* @param {object} spec
|
|
56
|
+
* @param {string} spec.providerId
|
|
57
|
+
* @param {string} spec.writeKind
|
|
58
|
+
* @param {object} spec.payload
|
|
59
|
+
* @param {object} [spec.requestedBy] - { specialistId, role, serviceId, sessionId }
|
|
60
|
+
* @param {string} [spec.surface] - origin surface, e.g. 'embed-capability' | 'mcp' | 'cli'
|
|
61
|
+
* @returns {{ providerId: string, writeKind: string, payload: object, requestedBy: object, surface: string, tool: string }}
|
|
62
|
+
*/
|
|
63
|
+
export function buildWriteIntent(spec) {
|
|
64
|
+
const intent = {
|
|
65
|
+
providerId: spec?.providerId,
|
|
66
|
+
writeKind: spec?.writeKind,
|
|
67
|
+
payload: spec?.payload,
|
|
68
|
+
};
|
|
69
|
+
const result = validateWriteIntent(intent);
|
|
70
|
+
if (!result.ok) {
|
|
71
|
+
throw new Error(`buildWriteIntent: invalid writeIntent — ${result.errors.join('; ')}`);
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
providerId: intent.providerId,
|
|
75
|
+
writeKind: intent.writeKind,
|
|
76
|
+
payload: intent.payload,
|
|
77
|
+
requestedBy: spec?.requestedBy ?? {},
|
|
78
|
+
surface: spec?.surface ?? 'unknown',
|
|
79
|
+
tool: writeIntentToolName(intent.providerId, intent.writeKind),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The tool-name encoding shared with lib/embed/capability-jobs.mjs's
|
|
85
|
+
* ApprovalQueue.enqueue({ tool }) calls and lib/embed/authority-guard.mjs's
|
|
86
|
+
* grant keys — "<providerId>.<writeKind>", e.g. "jira.issue". Kept in one
|
|
87
|
+
* place so the control-plane drain and the enqueue side can never drift.
|
|
88
|
+
*
|
|
89
|
+
* @param {string} providerId
|
|
90
|
+
* @param {string} writeKind
|
|
91
|
+
* @returns {string}
|
|
92
|
+
*/
|
|
93
|
+
export function writeIntentToolName(providerId, writeKind) {
|
|
94
|
+
return `${providerId}.${writeKind}`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Parse a "<providerId>.<writeKind>" tool name back into its parts. Returns
|
|
99
|
+
* null when the name has no dot, which the caller should treat as
|
|
100
|
+
* unresolvable rather than guessing.
|
|
101
|
+
*
|
|
102
|
+
* @param {string} tool
|
|
103
|
+
* @returns {{ providerId: string, writeKind: string }|null}
|
|
104
|
+
*/
|
|
105
|
+
export function parseWriteIntentToolName(tool) {
|
|
106
|
+
const idx = typeof tool === 'string' ? tool.indexOf('.') : -1;
|
|
107
|
+
if (idx <= 0 || idx === tool.length - 1) return null;
|
|
108
|
+
return { providerId: tool.slice(0, idx), writeKind: tool.slice(idx + 1) };
|
|
109
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geraldmaron/construct",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"packageManager": "npm@11.5.1",
|
|
6
6
|
"description": "Construct — agent orchestration layer for OpenCode, Claude Code, and other coding surfaces",
|
|
@@ -57,9 +57,10 @@
|
|
|
57
57
|
"mcp": "node lib/mcp/server.mjs",
|
|
58
58
|
"doctor": "node ./bin/construct doctor",
|
|
59
59
|
"test": "node scripts/run-tests.mjs",
|
|
60
|
-
"test:functional": "XDG_CONFIG_HOME= XDG_STATE_HOME= XDG_CACHE_HOME= node --test --test-timeout=120000 --test-concurrency=1 tests/functional/*.functional.test.mjs",
|
|
61
|
-
"test:visual": "node -
|
|
60
|
+
"test:functional": "XDG_CONFIG_HOME= XDG_STATE_HOME= XDG_CACHE_HOME= ANTHROPIC_API_KEY= OPENAI_API_KEY= OPENROUTER_API_KEY= CX_MODEL_REASONING= CX_MODEL_STANDARD= CX_MODEL_FAST= CONSTRUCT_MODEL_REASONING= CONSTRUCT_MODEL_STANDARD= CONSTRUCT_MODEL_FAST= CONSTRUCT_PROVIDER_TIMEOUT_MS= WEB_SEARCH_URL= CX_USER_ENV_PATH= CONSTRUCT_TELEMETRY_URL= node --test --test-timeout=120000 --test-concurrency=1 tests/functional/*.functional.test.mjs",
|
|
61
|
+
"test:visual": "node --test --test-timeout=120000 tests/visual/*.test.mjs",
|
|
62
62
|
"test:unit": "node scripts/run-tests.mjs --exclude=tests/functional",
|
|
63
|
+
"ci:local": "bash scripts/ci-repro/run.sh",
|
|
63
64
|
"lint:js": "eslint bin/construct \"lib/**/*.mjs\" \"scripts/**/*.mjs\" \"tests/**/*.mjs\"",
|
|
64
65
|
"coverage": "c8 --reporter=text-summary --reporter=lcov --src=lib --src=bin node scripts/run-tests.mjs --exclude=tests/functional",
|
|
65
66
|
"docs:init": "node -e \"console.error('docs:init is deprecated — use: construct init --docs-preset=lean|product|full'); process.exit(1)\"",
|
|
@@ -70,33 +71,38 @@
|
|
|
70
71
|
"docs:build": "node scripts/npm-run.mjs npm --prefix apps/docs run build",
|
|
71
72
|
"lint:comments": "node ./bin/construct lint:comments",
|
|
72
73
|
"lint:contracts": "node ./bin/construct lint:contracts",
|
|
74
|
+
"graph:gate": "node scripts/run-graph-gate.mjs",
|
|
73
75
|
"lint:agents": "node ./bin/construct lint:agents",
|
|
74
76
|
"gates:audit": "node ./bin/construct gates:audit",
|
|
75
77
|
"evals": "node ./bin/construct evals",
|
|
76
78
|
"certify:demos": "node ./bin/construct certify demos",
|
|
77
79
|
"build:sea": "esbuild bin/construct --bundle --platform=node --target=node20 --packages=external --outfile=dist/construct-bundle.cjs 2>&1 || (echo 'esbuild not found — install with: npm install -g esbuild' && exit 1)",
|
|
80
|
+
"build:binary": "node scripts/build-binary.mjs",
|
|
81
|
+
"build:binary:fallback": "node scripts/build-sea.mjs",
|
|
78
82
|
"examples:deck": "node scripts/generate-deck-examples.mjs",
|
|
79
83
|
"examples:distribution": "node scripts/generate-distribution-examples.mjs",
|
|
80
84
|
"clean:artifacts": "node scripts/clean-artifacts.mjs",
|
|
81
85
|
"lint:scopes": "node scripts/lint-scopes.mjs",
|
|
82
86
|
"catalog:regen": "node scripts/catalog-regen.mjs",
|
|
83
87
|
"catalog:validate": "node scripts/catalog-validate.mjs",
|
|
88
|
+
"workflow-defs:check": "node scripts/check-workflow-defs-drift.mjs --check",
|
|
84
89
|
"docs:sync": "node scripts/docs-sync.mjs",
|
|
85
90
|
"learning:status": "node scripts/learning-status.mjs",
|
|
86
91
|
"lint:templates": "node scripts/lint-commits-pr.mjs",
|
|
87
92
|
"eval:routing": "node scripts/eval/score-intent-classifier.mjs",
|
|
88
93
|
"adapters": "node lib/adapters-sync.mjs",
|
|
89
|
-
"release:check": "npm run doctor && node ./bin/construct registry:validate --unified && npm run catalog:validate -- --check && npm test && npm run docs:update -- --check && npm run docs:site -- --check && npm run docs:sync -- --check && node ./bin/construct registry:generate-docs --check && npm run docs:verify -- --strict && node scripts/alignment/census.mjs --ratchet && npm run lint:comments && node ./bin/construct certify gate && npm run lint:templates",
|
|
94
|
+
"release:check": "npm run doctor && node ./bin/construct registry:validate --unified && npm run catalog:validate -- --check && npm run workflow-defs:check && npm test && node scripts/release-evidence-gate.mjs --skip-tests && npm run docs:update -- --check && npm run docs:site -- --check && npm run docs:sync -- --check && node ./bin/construct registry:generate-docs --check && npm run docs:verify -- --strict && node scripts/alignment/census.mjs --ratchet && npm run lint:comments && node ./bin/construct certify gate && npm run graph:gate && npm run lint:templates",
|
|
90
95
|
"release:gate": "node --test tests/functional/release-gate.functional.test.mjs",
|
|
91
96
|
"audit:published": "node scripts/audit-published-artifact.mjs",
|
|
92
97
|
"version": "node scripts/sync-construct-version.mjs && git add -f .construct/version",
|
|
93
98
|
"release:preflight": "node scripts/pre-release-check.mjs",
|
|
94
99
|
"release:preflight:no-auth": "node scripts/pre-release-check.mjs --skip-auth",
|
|
95
100
|
"npm:publish": "npm run release:check && npm publish --access public",
|
|
96
|
-
"postinstall": "node ./bin/construct-postinstall.mjs"
|
|
101
|
+
"postinstall": "node ./bin/construct-postinstall.mjs",
|
|
102
|
+
"deps:check": "node scripts/validate-dep-intent.mjs"
|
|
97
103
|
},
|
|
98
104
|
"dependencies": {
|
|
99
|
-
"@lancedb/lancedb": "^0.
|
|
105
|
+
"@lancedb/lancedb": "^0.31.0",
|
|
100
106
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
101
107
|
"apache-arrow": "^18.1.0",
|
|
102
108
|
"js-yaml": "^4.2.0"
|
|
@@ -110,6 +116,7 @@
|
|
|
110
116
|
"ai": "^6.0.208",
|
|
111
117
|
"ink": "^7.1.0",
|
|
112
118
|
"mammoth": "^1.12.0",
|
|
119
|
+
"postgres": "^3.4.9",
|
|
113
120
|
"pptx-embed-fonts": "^0.0.6",
|
|
114
121
|
"pptxgenjs": "^4.0.1",
|
|
115
122
|
"react": "^19.2.7",
|
|
@@ -124,9 +131,10 @@
|
|
|
124
131
|
"@eslint/js": "^9.39.4",
|
|
125
132
|
"c8": "^11.0.0",
|
|
126
133
|
"esbuild": "^0.28.1",
|
|
127
|
-
"postject": "1.0.0-alpha.6",
|
|
128
134
|
"eslint": "^10.4.1",
|
|
129
135
|
"globals": "^17.6.0",
|
|
130
|
-
"ink-testing-library": "^4.0.0"
|
|
136
|
+
"ink-testing-library": "^4.0.0",
|
|
137
|
+
"playwright": "^1.61.1",
|
|
138
|
+
"postject": "1.0.0-alpha.6"
|
|
131
139
|
}
|
|
132
140
|
}
|
package/personas/construct.md
CHANGED
|
@@ -25,9 +25,9 @@ Use the single-writer rule whenever multiple sessions are active: if two session
|
|
|
25
25
|
|
|
26
26
|
## Classify before acting <!-- cx:prio=1 -->
|
|
27
27
|
|
|
28
|
-
Before any non-trivial request, CALL the code-backed orchestration policy via the `orchestration_policy` MCP tool with the request text and your `fileCount` / `moduleCount` / `introducesContract` estimate. Do not classify from memory. Honor the returned `track
|
|
28
|
+
Before any non-trivial request, CALL the code-backed orchestration policy via the `orchestration_policy` MCP tool with the request text and your `fileCount` / `moduleCount` / `introducesContract` estimate. Do not classify from memory. Honor the returned `track`. When `track` is not immediate, dispatch through `orchestration_delegation_next` (below) — do not author the deliverable yourself and do not self-sequence off `orchestration_policy`'s specialist list from memory across turns.
|
|
29
29
|
|
|
30
|
-
Tracks: immediate (act directly), focused (one bounded specialist), orchestrated (plan → challenge → build → validate, tracker-backed). cx-
|
|
30
|
+
Tracks: immediate (act directly), focused (one bounded specialist), orchestrated (plan → challenge → build → validate, tracker-backed). cx-reviewer's plan-challenge mode is mandatory whenever `riskFlags` include architecture, security, dataIntegrity, or ai.
|
|
31
31
|
|
|
32
32
|
Orchestrated dispatches emit a task-packet with `goal`, `intent`, `workCategory`, `riskFlags`, `acceptanceCriteria` before naming specialists (`specialists/contracts.json:construct-to-orchestrator`).
|
|
33
33
|
|
|
@@ -45,9 +45,18 @@ General conversation is still valid for scoping, clarification, and lightweight
|
|
|
45
45
|
|
|
46
46
|
1. **Gates**. `framingChallenge`, `externalResearch`, `docAuthoring`
|
|
47
47
|
2. **Contract chain**. typed handoffs from `specialists/contracts.json`. Call `agent_contract` with `handoffPacket` from `orchestration_policy`.
|
|
48
|
-
3. **Specialist sequence**.
|
|
48
|
+
3. **Specialist sequence**. the engine's job, not yours — see below.
|
|
49
49
|
4. **Team routing**. name `teamRouting.primaryTeam` in the dispatch plan; route through `teamRouting.requiredApprovals` before DONE; if `teamRouting.blockedStatus` is set, stop and escalate along its `escalationPath` rather than proceeding.
|
|
50
50
|
|
|
51
|
+
## Dispatch one step at a time <!-- cx:prio=1 -->
|
|
52
|
+
|
|
53
|
+
Sequencing a multi-specialist chain is the flow engine's job (ADR-0067), not something to hold in your own context across turns. Once `orchestration_policy` says the track is not immediate, drive dispatch through `orchestration_delegation_next`, not by reading a full plan and self-sequencing:
|
|
54
|
+
|
|
55
|
+
- Mint a `run_id` for this dispatch (a session or task id is fine) and call `orchestration_delegation_next` with the same `request`/`fileCount`/`moduleCount` you gave `orchestration_policy`, plus that `run_id`.
|
|
56
|
+
- Act on exactly the returned `currentDelegation` — its `role`, `reason`, and `handoffContract` — and nothing else. Do not pre-plan the rest of the chain from a remembered dispatch plan.
|
|
57
|
+
- Call again with the same `run_id` for the next specialist. Repeat until `done: true`.
|
|
58
|
+
- The chain survives a restart: calling again with the same `run_id` in a later turn or session continues from wherever it left off, never re-running a specialist already dispatched.
|
|
59
|
+
|
|
51
60
|
Before DONE: postconditions met · sources cited · framing logged · ADRs have Rejected alternatives.
|
|
52
61
|
|
|
53
62
|
## Branch + commit approval <!-- cx:prio=1 -->
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
3
|
"catalog": {
|
|
4
|
-
"generatedAt": "2026-07-
|
|
4
|
+
"generatedAt": "2026-07-06T22:40:56.862Z",
|
|
5
5
|
"npmScripts": [
|
|
6
6
|
"adapters",
|
|
7
7
|
"audit:published",
|
|
8
|
+
"build:binary",
|
|
9
|
+
"build:binary:fallback",
|
|
8
10
|
"build:sea",
|
|
9
11
|
"catalog:regen",
|
|
10
12
|
"catalog:validate",
|
|
11
13
|
"certify:demos",
|
|
12
14
|
"clean:artifacts",
|
|
13
15
|
"coverage",
|
|
16
|
+
"deps:check",
|
|
14
17
|
"docs:build",
|
|
15
18
|
"docs:dev",
|
|
16
19
|
"docs:init",
|
|
@@ -24,6 +27,7 @@
|
|
|
24
27
|
"examples:deck",
|
|
25
28
|
"examples:distribution",
|
|
26
29
|
"gates:audit",
|
|
30
|
+
"graph:gate",
|
|
27
31
|
"learning:status",
|
|
28
32
|
"lint:agents",
|
|
29
33
|
"lint:comments",
|
|
@@ -42,7 +46,8 @@
|
|
|
42
46
|
"test:functional",
|
|
43
47
|
"test:unit",
|
|
44
48
|
"test:visual",
|
|
45
|
-
"version"
|
|
49
|
+
"version",
|
|
50
|
+
"workflow-defs:check"
|
|
46
51
|
],
|
|
47
52
|
"cliCommands": [
|
|
48
53
|
{
|
|
@@ -57,6 +62,12 @@
|
|
|
57
62
|
"core": false,
|
|
58
63
|
"internal": true
|
|
59
64
|
},
|
|
65
|
+
{
|
|
66
|
+
"name": "approvals",
|
|
67
|
+
"category": "Core",
|
|
68
|
+
"core": true,
|
|
69
|
+
"internal": false
|
|
70
|
+
},
|
|
60
71
|
{
|
|
61
72
|
"name": "artifact",
|
|
62
73
|
"category": "Work",
|
|
@@ -159,6 +170,12 @@
|
|
|
159
170
|
"core": false,
|
|
160
171
|
"internal": false
|
|
161
172
|
},
|
|
173
|
+
{
|
|
174
|
+
"name": "db",
|
|
175
|
+
"category": "Models & Integrations",
|
|
176
|
+
"core": false,
|
|
177
|
+
"internal": false
|
|
178
|
+
},
|
|
162
179
|
{
|
|
163
180
|
"name": "decisions",
|
|
164
181
|
"category": "Advanced",
|
|
@@ -309,6 +326,12 @@
|
|
|
309
326
|
"core": false,
|
|
310
327
|
"internal": false
|
|
311
328
|
},
|
|
329
|
+
{
|
|
330
|
+
"name": "flow",
|
|
331
|
+
"category": "Models & Integrations",
|
|
332
|
+
"core": false,
|
|
333
|
+
"internal": false
|
|
334
|
+
},
|
|
312
335
|
{
|
|
313
336
|
"name": "gates:audit",
|
|
314
337
|
"category": "Advanced",
|
|
@@ -519,6 +542,12 @@
|
|
|
519
542
|
"core": false,
|
|
520
543
|
"internal": true
|
|
521
544
|
},
|
|
545
|
+
{
|
|
546
|
+
"name": "pack",
|
|
547
|
+
"category": "Work",
|
|
548
|
+
"core": false,
|
|
549
|
+
"internal": false
|
|
550
|
+
},
|
|
522
551
|
{
|
|
523
552
|
"name": "plugin",
|
|
524
553
|
"category": "Models & Integrations",
|
|
@@ -801,6 +830,12 @@
|
|
|
801
830
|
"core": false,
|
|
802
831
|
"internal": false
|
|
803
832
|
},
|
|
833
|
+
{
|
|
834
|
+
"name": "workers",
|
|
835
|
+
"category": "Core",
|
|
836
|
+
"core": true,
|
|
837
|
+
"internal": false
|
|
838
|
+
},
|
|
804
839
|
{
|
|
805
840
|
"name": "workflow",
|
|
806
841
|
"category": "Work",
|
|
@@ -815,15 +850,25 @@
|
|
|
815
850
|
}
|
|
816
851
|
],
|
|
817
852
|
"workflows": [
|
|
853
|
+
{
|
|
854
|
+
"type": "architecture-review",
|
|
855
|
+
"description": "Review an architecture or design for trade-offs, failure modes, and security exposure.",
|
|
856
|
+
"tier": "reasoning"
|
|
857
|
+
},
|
|
858
|
+
{
|
|
859
|
+
"type": "data-structure",
|
|
860
|
+
"description": "Parse, validate, and profile a raw dataset into a structured, described shape.",
|
|
861
|
+
"tier": "standard"
|
|
862
|
+
},
|
|
818
863
|
{
|
|
819
864
|
"type": "evidence-ingest",
|
|
820
865
|
"description": "Ingest and structure raw evidence (notes, documents, signals) into a normalized summary.",
|
|
821
866
|
"tier": "fast"
|
|
822
867
|
},
|
|
823
868
|
{
|
|
824
|
-
"type": "
|
|
825
|
-
"description": "
|
|
826
|
-
"tier": "
|
|
869
|
+
"type": "memo-draft",
|
|
870
|
+
"description": "Draft a decision or status memo from a problem statement and context.",
|
|
871
|
+
"tier": "fast"
|
|
827
872
|
},
|
|
828
873
|
{
|
|
829
874
|
"type": "prd-draft",
|
|
@@ -831,8 +876,13 @@
|
|
|
831
876
|
"tier": "standard"
|
|
832
877
|
},
|
|
833
878
|
{
|
|
834
|
-
"type": "
|
|
835
|
-
"description": "Review
|
|
879
|
+
"type": "proposal-review",
|
|
880
|
+
"description": "Review a proposal for correctness, risk, and hidden assumptions before acceptance.",
|
|
881
|
+
"tier": "standard"
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
"type": "research-synthesis",
|
|
885
|
+
"description": "Synthesize multiple sources into a cited, evidence-graded research summary.",
|
|
836
886
|
"tier": "reasoning"
|
|
837
887
|
},
|
|
838
888
|
{
|
|
@@ -841,9 +891,9 @@
|
|
|
841
891
|
"tier": "reasoning"
|
|
842
892
|
},
|
|
843
893
|
{
|
|
844
|
-
"type": "
|
|
845
|
-
"description": "
|
|
846
|
-
"tier": "
|
|
894
|
+
"type": "structure-notes",
|
|
895
|
+
"description": "Structure an unclassified brain-dump or rough notes into a normalized summary with extracted intents.",
|
|
896
|
+
"tier": "fast"
|
|
847
897
|
},
|
|
848
898
|
{
|
|
849
899
|
"type": "transcript-process",
|
|
@@ -851,32 +901,23 @@
|
|
|
851
901
|
"tier": "fast"
|
|
852
902
|
},
|
|
853
903
|
{
|
|
854
|
-
"type": "
|
|
855
|
-
"description": "
|
|
856
|
-
"tier": "standard"
|
|
857
|
-
},
|
|
858
|
-
{
|
|
859
|
-
"type": "memo-draft",
|
|
860
|
-
"description": "Draft a decision or status memo from a problem statement and context.",
|
|
861
|
-
"tier": "fast"
|
|
862
|
-
},
|
|
863
|
-
{
|
|
864
|
-
"type": "structure-notes",
|
|
865
|
-
"description": "Structure an unclassified brain-dump or rough notes into a normalized summary with extracted intents.",
|
|
904
|
+
"type": "triage",
|
|
905
|
+
"description": "Classify and route unstructured input to the appropriate workflow.",
|
|
866
906
|
"tier": "fast"
|
|
867
907
|
}
|
|
868
908
|
],
|
|
869
909
|
"workflowTypes": [
|
|
910
|
+
"architecture-review",
|
|
911
|
+
"data-structure",
|
|
870
912
|
"evidence-ingest",
|
|
871
|
-
"
|
|
913
|
+
"memo-draft",
|
|
872
914
|
"prd-draft",
|
|
873
|
-
"
|
|
874
|
-
"risk-review",
|
|
915
|
+
"proposal-review",
|
|
875
916
|
"research-synthesis",
|
|
917
|
+
"risk-review",
|
|
918
|
+
"structure-notes",
|
|
876
919
|
"transcript-process",
|
|
877
|
-
"
|
|
878
|
-
"memo-draft",
|
|
879
|
-
"structure-notes"
|
|
920
|
+
"triage"
|
|
880
921
|
]
|
|
881
922
|
},
|
|
882
923
|
"capabilities": [
|
|
@@ -1073,7 +1114,10 @@
|
|
|
1073
1114
|
"workflow",
|
|
1074
1115
|
"workflow invoke"
|
|
1075
1116
|
],
|
|
1076
|
-
"npmScripts": [
|
|
1117
|
+
"npmScripts": [
|
|
1118
|
+
"release:check",
|
|
1119
|
+
"workflow-defs:check"
|
|
1120
|
+
],
|
|
1077
1121
|
"workflows": [
|
|
1078
1122
|
"evidence-ingest"
|
|
1079
1123
|
]
|
|
@@ -1193,7 +1237,10 @@
|
|
|
1193
1237
|
"workflow",
|
|
1194
1238
|
"workflow invoke"
|
|
1195
1239
|
],
|
|
1196
|
-
"npmScripts": [
|
|
1240
|
+
"npmScripts": [
|
|
1241
|
+
"release:check",
|
|
1242
|
+
"workflow-defs:check"
|
|
1243
|
+
],
|
|
1197
1244
|
"workflows": [
|
|
1198
1245
|
"prd-draft"
|
|
1199
1246
|
]
|
|
@@ -1234,7 +1281,10 @@
|
|
|
1234
1281
|
"workflow",
|
|
1235
1282
|
"workflow invoke"
|
|
1236
1283
|
],
|
|
1237
|
-
"npmScripts": [
|
|
1284
|
+
"npmScripts": [
|
|
1285
|
+
"release:check",
|
|
1286
|
+
"workflow-defs:check"
|
|
1287
|
+
],
|
|
1238
1288
|
"workflows": [
|
|
1239
1289
|
"architecture-review"
|
|
1240
1290
|
]
|
|
@@ -1274,7 +1324,10 @@
|
|
|
1274
1324
|
"workflow",
|
|
1275
1325
|
"workflow invoke"
|
|
1276
1326
|
],
|
|
1277
|
-
"npmScripts": [
|
|
1327
|
+
"npmScripts": [
|
|
1328
|
+
"release:check",
|
|
1329
|
+
"workflow-defs:check"
|
|
1330
|
+
],
|
|
1278
1331
|
"workflows": [
|
|
1279
1332
|
"proposal-review"
|
|
1280
1333
|
]
|
|
@@ -1315,7 +1368,10 @@
|
|
|
1315
1368
|
"workflow",
|
|
1316
1369
|
"workflow invoke"
|
|
1317
1370
|
],
|
|
1318
|
-
"npmScripts": [
|
|
1371
|
+
"npmScripts": [
|
|
1372
|
+
"release:check",
|
|
1373
|
+
"workflow-defs:check"
|
|
1374
|
+
],
|
|
1319
1375
|
"workflows": [
|
|
1320
1376
|
"risk-review"
|
|
1321
1377
|
]
|
|
@@ -1396,7 +1452,10 @@
|
|
|
1396
1452
|
"workflow",
|
|
1397
1453
|
"workflow invoke"
|
|
1398
1454
|
],
|
|
1399
|
-
"npmScripts": [
|
|
1455
|
+
"npmScripts": [
|
|
1456
|
+
"release:check",
|
|
1457
|
+
"workflow-defs:check"
|
|
1458
|
+
],
|
|
1400
1459
|
"workflows": [
|
|
1401
1460
|
"transcript-process"
|
|
1402
1461
|
]
|
|
@@ -1436,7 +1495,10 @@
|
|
|
1436
1495
|
"workflow",
|
|
1437
1496
|
"workflow invoke"
|
|
1438
1497
|
],
|
|
1439
|
-
"npmScripts": [
|
|
1498
|
+
"npmScripts": [
|
|
1499
|
+
"release:check",
|
|
1500
|
+
"workflow-defs:check"
|
|
1501
|
+
],
|
|
1440
1502
|
"workflows": [
|
|
1441
1503
|
"data-structure"
|
|
1442
1504
|
]
|
|
@@ -1476,13 +1538,58 @@
|
|
|
1476
1538
|
"workflow",
|
|
1477
1539
|
"workflow invoke"
|
|
1478
1540
|
],
|
|
1479
|
-
"npmScripts": [
|
|
1541
|
+
"npmScripts": [
|
|
1542
|
+
"release:check",
|
|
1543
|
+
"workflow-defs:check"
|
|
1544
|
+
],
|
|
1480
1545
|
"workflows": [
|
|
1481
1546
|
"memo-draft"
|
|
1482
1547
|
]
|
|
1483
1548
|
},
|
|
1484
1549
|
"_semanticDigest": "{\"description\":\"Draft a decision or status memo from a problem statement and context.\",\"criticality\":\"P2\",\"verification\":{\"functional\":\"tests/functional/embedded-contract-workflow-invoke.functional.test.mjs\"}}"
|
|
1485
1550
|
},
|
|
1551
|
+
{
|
|
1552
|
+
"id": "workflow.triage",
|
|
1553
|
+
"kind": "workflow",
|
|
1554
|
+
"name": "Triage Workflow",
|
|
1555
|
+
"description": "Classify and route unstructured input to the appropriate workflow.",
|
|
1556
|
+
"criticality": "P2",
|
|
1557
|
+
"ownerSpecialists": [
|
|
1558
|
+
"orchestrator",
|
|
1559
|
+
"researcher"
|
|
1560
|
+
],
|
|
1561
|
+
"embeddedWorkflow": "triage",
|
|
1562
|
+
"surfaces": {
|
|
1563
|
+
"mcp": {
|
|
1564
|
+
"supported": true,
|
|
1565
|
+
"primary": true,
|
|
1566
|
+
"tool": "workflow_invoke"
|
|
1567
|
+
},
|
|
1568
|
+
"cli": {
|
|
1569
|
+
"supported": true,
|
|
1570
|
+
"command": "construct workflow invoke",
|
|
1571
|
+
"jsonTwin": true
|
|
1572
|
+
}
|
|
1573
|
+
},
|
|
1574
|
+
"verification": {
|
|
1575
|
+
"functional": "tests/functional/embedded-contract-triage.functional.test.mjs"
|
|
1576
|
+
},
|
|
1577
|
+
"humanGate": "proposal-only",
|
|
1578
|
+
"edges": {
|
|
1579
|
+
"cliCommands": [
|
|
1580
|
+
"workflow",
|
|
1581
|
+
"workflow invoke"
|
|
1582
|
+
],
|
|
1583
|
+
"npmScripts": [
|
|
1584
|
+
"release:check",
|
|
1585
|
+
"workflow-defs:check"
|
|
1586
|
+
],
|
|
1587
|
+
"workflows": [
|
|
1588
|
+
"triage"
|
|
1589
|
+
]
|
|
1590
|
+
},
|
|
1591
|
+
"_semanticDigest": "{\"description\":\"Classify and route unstructured input to the appropriate workflow.\",\"criticality\":\"P2\",\"verification\":{\"functional\":\"tests/functional/embedded-contract-triage.functional.test.mjs\"}}"
|
|
1592
|
+
},
|
|
1486
1593
|
{
|
|
1487
1594
|
"id": "document-type.research-brief",
|
|
1488
1595
|
"kind": "document-type",
|
package/rules/common/comments.md
CHANGED
|
@@ -42,6 +42,7 @@ The blank line between the comment and the code is required. It signals "this co
|
|
|
42
42
|
- **Narrative voice** (`// We weight BM25`, `// Now test the keys`, `// This correctly scores`) delete them
|
|
43
43
|
- **Point-in-time notes** (`// X removed`, `// previously`, `// no longer`) belongs in git log
|
|
44
44
|
- **Noise sentinels** (`// ok`, `// best effort`, `// skip`) delete them; use `/* non-critical */` inline only when the catch clause would otherwise look like a bug
|
|
45
|
+
- **Other-project comparisons** (`// per the LangGraph thread-vs-store split`) delete them; describe the behavior on its own terms. A prior-art comparison belongs in a decision document (`docs/decisions/**`, `docs/notes/**`) where it can carry a citation
|
|
45
46
|
|
|
46
47
|
## SLA annotations (hooks only)
|
|
47
48
|
|