wendkeep 0.88.0 → 0.89.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.
Files changed (33) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.en.md +2 -1
  3. package/README.md +2 -1
  4. package/bin/wendkeep.mjs +1 -0
  5. package/docs/en/commands/ecosystem-bridges.md +172 -0
  6. package/docs/en/commands/verify.md +6 -0
  7. package/docs/pt-BR/commands/ecosystem-bridges.md +169 -0
  8. package/docs/pt-BR/commands/verify.md +6 -0
  9. package/package.json +2 -2
  10. package/packages/cli/src/index.mjs +10 -1
  11. package/packages/harness/src/sensors-core.mjs +49 -3
  12. package/packages/integrations/src/bridge-config.mjs +139 -0
  13. package/packages/integrations/src/bridge-contract.mjs +316 -0
  14. package/packages/integrations/src/bridge-diagnostics.mjs +45 -0
  15. package/packages/integrations/src/canonical-bridge-authority.mjs +32 -0
  16. package/packages/integrations/src/capabilities.mjs +34 -0
  17. package/packages/integrations/src/ecosystem-bridge.mjs +82 -0
  18. package/packages/integrations/src/index.mjs +6 -0
  19. package/packages/integrations/src/spec-kit-adapter.mjs +259 -0
  20. package/packages/integrations/src/superpowers-adapter.mjs +269 -0
  21. package/schema/ecosystem-bridge-artifact-manifest-v1.schema.json +30 -0
  22. package/schema/ecosystem-bridge-v1.schema.json +65 -0
  23. package/schema/wendkeep.evidence-envelope-v2.schema.json +39 -0
  24. package/schema/wendkeep.sensors.schema.json +14 -0
  25. package/src/doctor.mjs +6 -1
  26. package/src/ecosystem-bridge-artifact-collector.mjs +111 -0
  27. package/src/ecosystem-bridge-baseline.mjs +58 -0
  28. package/src/ecosystem-bridge-proof.mjs +97 -0
  29. package/src/ecosystem-bridges.mjs +227 -0
  30. package/src/evidence-envelope.mjs +2 -0
  31. package/src/task-contracts.mjs +19 -0
  32. package/src/task.mjs +82 -0
  33. package/src/verify.mjs +9 -0
package/src/task.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import * as bridgeFs from 'node:fs';
1
2
  import { isAbsolute, resolve } from 'node:path';
2
3
  import { activeChange } from '../hooks/change-core.mjs';
3
4
  import { resolveActiveContext } from '../hooks/active-context-store.mjs';
@@ -6,6 +7,19 @@ import { buildTaskContractSnapshot, evaluateTaskContracts } from './task-contrac
6
7
  import { claimTaskLease, releaseTaskLease } from './task-leases.mjs';
7
8
  import { findProjectRoot } from '../packages/harness/src/sensors-core.mjs';
8
9
  import { resolveHookOperatingProfile } from '../hooks/operating-profile-runtime.mjs';
10
+ import { buildSuperpowersDispatch } from '../packages/integrations/src/superpowers-adapter.mjs';
11
+ import { importSpecKitProjection } from '../packages/integrations/src/spec-kit-adapter.mjs';
12
+ import { validateBridgeProjection } from '../packages/integrations/src/bridge-contract.mjs';
13
+ import { issueCanonicalDispatchAuthority } from '../packages/integrations/src/canonical-bridge-authority.mjs';
14
+
15
+ export function buildExternalTaskDispatch({ adapter = '', taskContract, ...options } = {}) {
16
+ if (String(adapter) !== 'superpowers') {
17
+ throw Object.assign(new Error(`unsupported task adapter: ${adapter || '(missing)'}`), {
18
+ code: 'TASK_ADAPTER_UNSUPPORTED',
19
+ });
20
+ }
21
+ return buildSuperpowersDispatch({ taskContract, ...options });
22
+ }
9
23
 
10
24
  const HELP = `wendkeep task <list|show|evaluate|claim|release> [task-id]
11
25
 
@@ -56,6 +70,74 @@ function commandState(argv) {
56
70
  };
57
71
  }
58
72
 
73
+ function resolveCanonicalTaskAuthority(argv = [], taskIdOverride = '') {
74
+ const state = commandState(argv);
75
+ const snapshot = buildTaskContractSnapshot(state);
76
+ const taskId = String(taskIdOverride || opt(argv, '--task-id') || '').trim();
77
+ const contract = snapshot.contracts.find((item) => item.task_id === taskId);
78
+ if (!contract) {
79
+ throw Object.assign(new Error(`task not found: ${taskId || '(missing id)'}`), { code: 'TASK_NOT_FOUND' });
80
+ }
81
+ return {
82
+ authority: 'wendkeep-canonical',
83
+ task_contract: structuredClone(contract),
84
+ active_context: structuredClone(snapshot.binding),
85
+ };
86
+ }
87
+
88
+ export function buildCanonicalExternalTaskDispatch({
89
+ adapter = '', authorityArgv = [], taskId = '', submittedTaskContract = null,
90
+ projectRoot = '', config, specKitProjection = null, baselineProjection = null, ...options
91
+ } = {}) {
92
+ if (adapter !== 'superpowers') return buildExternalTaskDispatch({ adapter, taskContract: null, ...options });
93
+ if (specKitProjection) {
94
+ const supplied = validateBridgeProjection(specKitProjection);
95
+ if (!supplied.valid) {
96
+ return {
97
+ schema_version: 1, adapter: 'superpowers', active: true, ok: false,
98
+ diagnostics: [{
99
+ schema_version: 1, code: 'BRIDGE_PROJECTION_INVALID', adapter: 'spec-kit', blocking: true,
100
+ message: 'submitted Spec Kit projection is not sealed by its complete decision state',
101
+ }],
102
+ };
103
+ }
104
+ }
105
+ if (config?.adapters?.['spec-kit']?.enabled) {
106
+ if (!specKitProjection || !baselineProjection) {
107
+ return {
108
+ schema_version: 1, adapter: 'superpowers', active: true, ok: false,
109
+ diagnostics: [{
110
+ schema_version: 1, code: 'BRIDGE_BASELINE_MISSING', adapter: 'spec-kit', blocking: true,
111
+ message: 'active Spec Kit dispatch requires its canonical baseline and submitted projection',
112
+ }],
113
+ };
114
+ }
115
+ const baseline = validateBridgeProjection(baselineProjection);
116
+ if (!baseline.valid || baselineProjection.projection_id !== specKitProjection.projection_id) {
117
+ return {
118
+ schema_version: 1, adapter: 'superpowers', active: true, ok: false,
119
+ diagnostics: [{
120
+ schema_version: 1, code: 'BRIDGE_BASELINE_STALE', adapter: 'spec-kit', blocking: true,
121
+ message: 'submitted projection does not match the canonical Spec Kit baseline',
122
+ }],
123
+ };
124
+ }
125
+ }
126
+ const canonical = resolveCanonicalTaskAuthority(authorityArgv, taskId);
127
+ const canonicalReceipt = issueCanonicalDispatchAuthority(canonical);
128
+ const liveProjection = specKitProjection
129
+ ? importSpecKitProjection({ projectRoot, config, previousProjection: baselineProjection || specKitProjection, fs: bridgeFs })
130
+ : null;
131
+ return buildExternalTaskDispatch({
132
+ adapter,
133
+ taskContract: submittedTaskContract || canonical.task_contract,
134
+ canonicalAuthority: canonicalReceipt,
135
+ specKitProjection: liveProjection,
136
+ config,
137
+ ...options,
138
+ });
139
+ }
140
+
59
141
  function write(value, json, line = '') {
60
142
  if (json) process.stdout.write(`${JSON.stringify(value)}\n`);
61
143
  else process.stdout.write(`${line || String(value)}\n`);
package/src/verify.mjs CHANGED
@@ -25,6 +25,7 @@ import { resolveCommandActiveContext } from './active-context-runtime.mjs';
25
25
  import { resolveHookOperatingProfile } from '../hooks/operating-profile-runtime.mjs';
26
26
  import { evaluateTddAttestation } from './tdd-attestation.mjs';
27
27
  import { readTddAttestationStore } from './tdd-attestation-store.mjs';
28
+ import { collectBridgeArtifactEvidence } from './ecosystem-bridge-artifact-collector.mjs';
28
29
  import { writeVaultFileAtomic } from '../packages/vault/src/vault-path-safety.mjs';
29
30
  import { evaluateHostCoverage } from '../packages/integrations/src/capabilities.mjs';
30
31
  import { evidenceCheckoutBinding } from '../packages/vault/src/evidence-envelope.mjs';
@@ -151,6 +152,13 @@ export function runVerify(argv) {
151
152
  process.stderr.write(`wendkeep verify: ${error.code || 'WENDKEEP_EVIDENCE_BINDING_FAILED'}: ${error.message}\n`);
152
153
  process.exit(2);
153
154
  }
155
+ let externalArtifacts;
156
+ try {
157
+ externalArtifacts = collectBridgeArtifactEvidence({ projectRoot, tasks, sensors: evidence });
158
+ } catch (error) {
159
+ process.stderr.write(`wendkeep verify: ${error.code || 'BRIDGE_ARTIFACT_COLLECTION_FAILED'}: ${error.message}\n`);
160
+ process.exit(2);
161
+ }
154
162
  const envelope = buildEvidenceEnvelope({
155
163
  identity,
156
164
  changeSlug: slug,
@@ -159,6 +167,7 @@ export function runVerify(argv) {
159
167
  effectiveSpecSha256: `sha256:${effective.hash}`,
160
168
  sensorConfigSha256: sensorConfigSha256(sensors, ids),
161
169
  sensors: evidence,
170
+ externalArtifacts,
162
171
  tddAttestations,
163
172
  startedAt,
164
173
  finishedAt: new Date().toISOString(),