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.
- package/CHANGELOG.md +17 -0
- package/README.en.md +2 -1
- package/README.md +2 -1
- package/bin/wendkeep.mjs +1 -0
- package/docs/en/commands/ecosystem-bridges.md +172 -0
- package/docs/en/commands/verify.md +6 -0
- package/docs/pt-BR/commands/ecosystem-bridges.md +169 -0
- package/docs/pt-BR/commands/verify.md +6 -0
- package/package.json +2 -2
- package/packages/cli/src/index.mjs +10 -1
- package/packages/harness/src/sensors-core.mjs +49 -3
- package/packages/integrations/src/bridge-config.mjs +139 -0
- package/packages/integrations/src/bridge-contract.mjs +316 -0
- package/packages/integrations/src/bridge-diagnostics.mjs +45 -0
- package/packages/integrations/src/canonical-bridge-authority.mjs +32 -0
- package/packages/integrations/src/capabilities.mjs +34 -0
- package/packages/integrations/src/ecosystem-bridge.mjs +82 -0
- package/packages/integrations/src/index.mjs +6 -0
- package/packages/integrations/src/spec-kit-adapter.mjs +259 -0
- package/packages/integrations/src/superpowers-adapter.mjs +269 -0
- package/schema/ecosystem-bridge-artifact-manifest-v1.schema.json +30 -0
- package/schema/ecosystem-bridge-v1.schema.json +65 -0
- package/schema/wendkeep.evidence-envelope-v2.schema.json +39 -0
- package/schema/wendkeep.sensors.schema.json +14 -0
- package/src/doctor.mjs +6 -1
- package/src/ecosystem-bridge-artifact-collector.mjs +111 -0
- package/src/ecosystem-bridge-baseline.mjs +58 -0
- package/src/ecosystem-bridge-proof.mjs +97 -0
- package/src/ecosystem-bridges.mjs +227 -0
- package/src/evidence-envelope.mjs +2 -0
- package/src/task-contracts.mjs +19 -0
- package/src/task.mjs +82 -0
- package/src/verify.mjs +9 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,23 @@ All notable changes to **wendkeep** are documented here. Format based on
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project follows
|
|
5
5
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.89.0] — 2026-08-30
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Bridges opcionais oficiais para Spec Kit e Superpowers.** Projeções read-only preservam IDs,
|
|
12
|
+
hashes e ownership canônico do WendKeep; adapters são habilitados separadamente, validam
|
|
13
|
+
versões compatíveis e degradam com diagnósticos tipados sem afetar o Core nativo.
|
|
14
|
+
- **Prova externa vinculada ao Git e ao CI.** Dispatch deriva somente de contratos canônicos e
|
|
15
|
+
artifacts externos permanecem `reported` até que manifest, blob, task, sensor e Evidence
|
|
16
|
+
Envelope coincidam com o checkout versionado.
|
|
17
|
+
|
|
18
|
+
### Security
|
|
19
|
+
|
|
20
|
+
- **Autoridade única e drift fail-closed.** Ownership concorrente, projeção stale, hashes/paths
|
|
21
|
+
divergentes, claims fabricados e promoção autoafirmada para `verified` bloqueiam import,
|
|
22
|
+
dispatch e verify antes de qualquer execução externa.
|
|
23
|
+
|
|
7
24
|
## [0.88.0] — 2026-08-29
|
|
8
25
|
|
|
9
26
|
### Added
|
package/README.en.md
CHANGED
|
@@ -253,6 +253,7 @@ The README is the map; the guides provide syntax, options, exit codes, examples,
|
|
|
253
253
|
| **Native MCP** | semantic tools, effects/capabilities, stdio, schemas, pagination, budgets, audit, and client configuration | [Native MCP](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/mcp.md) |
|
|
254
254
|
| **Evidence recall and embeddings** | cursor/byte budgets, bounded lexical/FTS sidecars, and an optional local plugin contract that is off by default | [Optional embedding plugin](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/evidence-embeddings.md) |
|
|
255
255
|
| **Host capabilities** | versioned lifecycle/effect matrix, degraded mode, human waivers, and evidence/Observer coverage | [Host capabilities](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/capabilities.md) |
|
|
256
|
+
| **Ecosystem bridges** | optional Spec Kit/Superpowers adapters, canonical baseline, single ownership, drift, and Git/CI/Envelope proof with an index/worktree-identical manifest | [Ecosystem bridges](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/ecosystem-bridges.md) |
|
|
256
257
|
| **Operating profiles** | `profile`, `flow`, always-on Keep Core, and Wend Runtime governance | [Operating profiles](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/operating-profiles.md) |
|
|
257
258
|
| **Changes and verification** | `change`, specs, sensors, TDD, evidence, Task Contracts, and archive | [Changes and verification](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/changes-and-verification.md) |
|
|
258
259
|
| **Shared memory** | CORE, SHARED, status, validation, repair, and curation | [Memory](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/memory.md) |
|
|
@@ -570,7 +571,7 @@ explore → propose → apply (TDD) → verify → archive
|
|
|
570
571
|
|
|
571
572
|
- **Propose** — `wendkeep change new <slug>` scaffolds `08-Mudanças/<slug>/` (`proposta.md`, `design.md`, `tarefas.md`; `--simple` skips the design). `--guide` creates the compact GUIDE contract and omits automatic design/spec/ADR when `contract_impact:none`. It becomes the global *current* change. When the change declares `spec_impact: required`, you author the delta yourself at `specs/<capability>/spec.md` — there is no placeholder to delete. Multiple changes may remain open: `change list`/`status` and the hooks show every pending one, while commands without `--change` act on the current one alone. `change use <slug>` changes focus and `change continue <archived> <new>` creates an auditable continuation.
|
|
572
573
|
- **Apply** — implement each `tarefas.md` task. Mark machine proof with one or more `[sensor:<id>]` tags on the same task: every distinct ID enters the gate once, in declaration order. Also mark satisfied requirements with one or more `[req:<ID>]` tags. For causal TDD, add `[tdd]` and record `wendkeep tdd red|green`; the [TDD attestation guide](docs/en/commands/tdd.md) covers profiles, waivers, and exit codes.
|
|
573
|
-
- **Verify** — `wendkeep verify` runs declared sensors and writes an **Evidence Envelope v2** to `evidencia.json`, SHA-256-bound to project/repository/worktree/session, HEAD, index tree, normalized worktree digest, tasks, effective spec, TDD attestations, and sensor configuration. Each sensor records a sanitized command, execution window, duration, exit code, output digest, and a sanitized tail bounded to 2,000 characters. If HEAD changes during the run, no new envelope is published. `change status` reports `bound`, `stale`, `context-mismatch`, or `legacy-unbound`; v1 evidence remains readable but cannot satisfy v2 authority. The public schema is [`schema/wendkeep.evidence-envelope-v2.schema.json`](schema/wendkeep.evidence-envelope-v2.schema.json). `verify --deep` binds the package, attestations, and verdict to the current `envelope_id`.
|
|
574
|
+
- **Verify** — `wendkeep verify` runs declared sensors and writes an **Evidence Envelope v2** to `evidencia.json`, SHA-256-bound to project/repository/worktree/session, HEAD, index tree, normalized worktree digest, tasks, effective spec, TDD attestations, and sensor configuration. Each sensor records a sanitized command, execution window, duration, exit code, output digest, and a sanitized tail bounded to 2,000 characters; `artifact_results` binds explicit digests for versioned files without using stdout as proof. If HEAD changes during the run, no new envelope is published. `change status` reports `bound`, `stale`, `context-mismatch`, or `legacy-unbound`; v1 evidence remains readable but cannot satisfy v2 authority. The public schema is [`schema/wendkeep.evidence-envelope-v2.schema.json`](schema/wendkeep.evidence-envelope-v2.schema.json). `verify --deep` binds the package, attestations, and verdict to the current `envelope_id`.
|
|
574
575
|
- **Archive** — `wendkeep change archive <slug>` **gates** on the evidence (blocks unless every declared critical sensor is green), promotes each applicable spec delta (`ADDED`/`MODIFIED`/`REMOVED`) into the living `07-Specs/<capability>.md` and moves the change to `_arquivo/`. GOVERN/ASSURE mint an ADR in `04-Decisões/`; compact GUIDE with no contract impact does not mint one automatically.
|
|
575
576
|
|
|
576
577
|
> The gate blocks unless the scaffold is filled, no task is open, evidence is fresh, and every declared requirement is covered. **`--force` waives exactly one of those — the open-task check — and is the human's call, never the agent's.** An unfilled scaffold, a red critical sensor, stale evidence, an orphan requirement or a missing verdict block regardless.
|
package/README.md
CHANGED
|
@@ -253,6 +253,7 @@ The README is the map; the guides provide syntax, options, exit codes, examples,
|
|
|
253
253
|
| **Native MCP** | semantic tools, effects/capabilities, stdio, schemas, pagination, budgets, audit, and client configuration | [Native MCP](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/mcp.md) |
|
|
254
254
|
| **Evidence recall and embeddings** | cursor/byte budgets, bounded lexical/FTS sidecars, and an optional local plugin contract that is off by default | [Optional embedding plugin](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/evidence-embeddings.md) |
|
|
255
255
|
| **Host capabilities** | versioned lifecycle/effect matrix, degraded mode, human waivers, and evidence/Observer coverage | [Host capabilities](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/capabilities.md) |
|
|
256
|
+
| **Ecosystem bridges** | optional Spec Kit/Superpowers adapters, canonical baseline, single ownership, drift, and Git/CI/Envelope proof with an index/worktree-identical manifest | [Ecosystem bridges](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/ecosystem-bridges.md) |
|
|
256
257
|
| **Operating profiles** | `profile`, `flow`, always-on Keep Core, and Wend Runtime governance | [Operating profiles](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/operating-profiles.md) |
|
|
257
258
|
| **Changes and verification** | `change`, specs, sensors, TDD, evidence, Task Contracts, and archive | [Changes and verification](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/changes-and-verification.md) |
|
|
258
259
|
| **Shared memory** | CORE, SHARED, status, validation, repair, and curation | [Memory](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/memory.md) |
|
|
@@ -570,7 +571,7 @@ explore → propose → apply (TDD) → verify → archive
|
|
|
570
571
|
|
|
571
572
|
- **Propose** — `wendkeep change new <slug>` scaffolds `08-Mudanças/<slug>/` (`proposta.md`, `design.md`, `tarefas.md`; `--simple` skips the design). `--guide` creates the compact GUIDE contract and omits automatic design/spec/ADR when `contract_impact:none`. It becomes the global *current* change. When the change declares `spec_impact: required`, you author the delta yourself at `specs/<capability>/spec.md` — there is no placeholder to delete. Multiple changes may remain open: `change list`/`status` and the hooks show every pending one, while commands without `--change` act on the current one alone. `change use <slug>` changes focus and `change continue <archived> <new>` creates an auditable continuation.
|
|
572
573
|
- **Apply** — implement each `tarefas.md` task. Mark machine proof with one or more `[sensor:<id>]` tags on the same task: every distinct ID enters the gate once, in declaration order. Also mark satisfied requirements with one or more `[req:<ID>]` tags. For causal TDD, add `[tdd]` and record `wendkeep tdd red|green`; the [TDD attestation guide](docs/en/commands/tdd.md) covers profiles, waivers, and exit codes.
|
|
573
|
-
- **Verify** — `wendkeep verify` runs declared sensors and writes an **Evidence Envelope v2** to `evidencia.json`, SHA-256-bound to project/repository/worktree/session, HEAD, index tree, normalized worktree digest, tasks, effective spec, TDD attestations, and sensor configuration. Each sensor records a sanitized command, execution window, duration, exit code, output digest, and a sanitized tail bounded to 2,000 characters. If HEAD changes during the run, no new envelope is published. `change status` reports `bound`, `stale`, `context-mismatch`, or `legacy-unbound`; v1 evidence remains readable but cannot satisfy v2 authority. The public schema is [`schema/wendkeep.evidence-envelope-v2.schema.json`](schema/wendkeep.evidence-envelope-v2.schema.json). `verify --deep` binds the package, attestations, and verdict to the current `envelope_id`.
|
|
574
|
+
- **Verify** — `wendkeep verify` runs declared sensors and writes an **Evidence Envelope v2** to `evidencia.json`, SHA-256-bound to project/repository/worktree/session, HEAD, index tree, normalized worktree digest, tasks, effective spec, TDD attestations, and sensor configuration. Each sensor records a sanitized command, execution window, duration, exit code, output digest, and a sanitized tail bounded to 2,000 characters; `artifact_results` binds explicit digests for versioned files without using stdout as proof. If HEAD changes during the run, no new envelope is published. `change status` reports `bound`, `stale`, `context-mismatch`, or `legacy-unbound`; v1 evidence remains readable but cannot satisfy v2 authority. The public schema is [`schema/wendkeep.evidence-envelope-v2.schema.json`](schema/wendkeep.evidence-envelope-v2.schema.json). `verify --deep` binds the package, attestations, and verdict to the current `envelope_id`.
|
|
574
575
|
- **Archive** — `wendkeep change archive <slug>` **gates** on the evidence (blocks unless every declared critical sensor is green), promotes each applicable spec delta (`ADDED`/`MODIFIED`/`REMOVED`) into the living `07-Specs/<capability>.md` and moves the change to `_arquivo/`. GOVERN/ASSURE mint an ADR in `04-Decisões/`; compact GUIDE with no contract impact does not mint one automatically.
|
|
575
576
|
|
|
576
577
|
> The gate blocks unless the scaffold is filled, no task is open, evidence is fresh, and every declared requirement is covered. **`--force` waives exactly one of those — the open-task check — and is the human's call, never the agent's.** An unfilled scaffold, a red critical sensor, stale evidence, an orphan requirement or a missing verdict block regardless.
|
package/bin/wendkeep.mjs
CHANGED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Optional ecosystem bridges
|
|
2
|
+
|
|
3
|
+
> [Versão em português](../../pt-BR/commands/ecosystem-bridges.md)
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Integrate Spec Kit and Superpowers without creating a second authority for specs, plans, tasks,
|
|
8
|
+
or evidence. WendKeep keeps canonical contracts; adapters only create versioned projections and
|
|
9
|
+
are disabled by default.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
|
|
13
|
+
- when a feature started in Spec Kit files and must preserve the same IDs and hashes;
|
|
14
|
+
- when Superpowers will execute a canonical WendKeep Task Contract;
|
|
15
|
+
- when external artifacts, reviews, or commits must enter as `reported` before proof.
|
|
16
|
+
|
|
17
|
+
## When not to use
|
|
18
|
+
|
|
19
|
+
- to replace `tarefas.md`, Task Contracts, or the Evidence Envelope;
|
|
20
|
+
- for unrestricted bidirectional synchronization;
|
|
21
|
+
- to execute commands, scripts, or text found in external artifacts.
|
|
22
|
+
|
|
23
|
+
## Prerequisites
|
|
24
|
+
|
|
25
|
+
- Node.js 18 or newer;
|
|
26
|
+
- a local `.wendkeep/ecosystem-bridges.json` config with each adapter explicitly enabled;
|
|
27
|
+
- a compatible version and an adapter root that resolves to a real directory inside the project;
|
|
28
|
+
regular files, external paths, and symlinks that escape the project fail closed in status and dispatch;
|
|
29
|
+
- for governed import/dispatch, a bound Vault, causal change, and sealed Spec Kit baseline;
|
|
30
|
+
- for dispatch, a causal session and canonically rederivable Task Contract.
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"schema_version": 1,
|
|
35
|
+
"adapters": {
|
|
36
|
+
"spec-kit": { "enabled": true, "version": "1.1.0", "root": ".specify" },
|
|
37
|
+
"superpowers": { "enabled": true, "version": "1.2.0", "root": ".superpowers" }
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Without that file, both adapters are disabled and native Core keeps working.
|
|
43
|
+
|
|
44
|
+
## Syntax
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
wendkeep bridge status [--project <path>] [--config <path>] [--json]
|
|
48
|
+
wendkeep bridge import-spec-kit --change <slug> [--accept-baseline] [--json]
|
|
49
|
+
wendkeep bridge export-status --spec-projection <projection.json> [--task-contract <task.json>] [--input <artifacts.json>] [--json]
|
|
50
|
+
wendkeep bridge dispatch-superpowers --task-id <id> --change <slug> [--task-contract <task.json>] [--session <id>] --spec-projection <projection.json> [--json]
|
|
51
|
+
wendkeep bridge verify-artifacts --input <artifacts.json> --proofs <proofs.json> --change <slug> [--session <id>] [--json]
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`import-spec-kit` reads Markdown under `memory/` and `specs/`, classifies constitution/spec/plan/task,
|
|
55
|
+
preserves IDs and SHA-256 hashes, creates explicit
|
|
56
|
+
`story|requirement → capability → change → task` mappings, and never writes to the source.
|
|
57
|
+
Repeated IDs across different files block the projection.
|
|
58
|
+
The first import requires `--accept-baseline` and anchors the green projection in the Vault change;
|
|
59
|
+
later imports rederive the source and compare path, kind, hash, and mapping against that immutable baseline.
|
|
60
|
+
`dispatch-superpowers` contains only minimal
|
|
61
|
+
structural context derived from the Task Contract; transcripts, private content, and external
|
|
62
|
+
ownership are excluded.
|
|
63
|
+
Dispatch rederives the contract and active context from the Vault/checkout; submitted JSON is only
|
|
64
|
+
a comparison copy and never validates its own `binding`.
|
|
65
|
+
With Spec Kit active, the baseline and `--spec-projection` are mandatory and the source is
|
|
66
|
+
reimported before dispatch.
|
|
67
|
+
The `spec-projection` contract belongs exclusively to the `spec-kit` adapter: an incompatible
|
|
68
|
+
version, out-of-schema kind, or projection resealed by another adapter is rejected before producing `spec_refs`.
|
|
69
|
+
An `ok: false` decision requires at least one blocking diagnostic, while `ok: true` cannot coexist
|
|
70
|
+
with a blocking diagnostic; any inconsistency blocks dispatch without exposing references.
|
|
71
|
+
`export-status` recomputes and validates `projection_id`, returns a `reported` projection only, and
|
|
72
|
+
does not write to Spec Kit files.
|
|
73
|
+
|
|
74
|
+
## Options and exit codes
|
|
75
|
+
|
|
76
|
+
| Option | Effect |
|
|
77
|
+
|---|---|
|
|
78
|
+
| `--project <path>` | Selects the consumer root. |
|
|
79
|
+
| `--config <path>` | Overrides `.wendkeep/ecosystem-bridges.json`. |
|
|
80
|
+
| `--change <slug>` | Selects the change holding canonical baseline and Evidence Envelope. |
|
|
81
|
+
| `--accept-baseline` | Anchors only the first green Spec Kit baseline; never overwrites drift. |
|
|
82
|
+
| `--task-id <id>` | Selects the causal task and rederives its canonical contract. |
|
|
83
|
+
| `--task-contract <path>` | Optional copy that must match the rederived contract. |
|
|
84
|
+
| `--spec-projection <path>` | Links Spec Kit refs to dispatch without copying content. |
|
|
85
|
+
| `--input` / `--proofs` | Classifies external artifacts and their Git/CI/Envelope proofs. |
|
|
86
|
+
| `--json` | Emits the typed contract as one JSON line. |
|
|
87
|
+
|
|
88
|
+
- `0`: valid operation; optional disabled adapters are healthy too;
|
|
89
|
+
- `1`: enabled adapter blocked, drift, incompatibility, or missing proof;
|
|
90
|
+
- `2`: invalid argument, configuration, or input file.
|
|
91
|
+
|
|
92
|
+
## Examples
|
|
93
|
+
|
|
94
|
+
Small flow without adapters:
|
|
95
|
+
|
|
96
|
+
```powershell
|
|
97
|
+
node ./bin/wendkeep.mjs bridge status --json
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Medium read-only Spec Kit flow:
|
|
101
|
+
|
|
102
|
+
```powershell
|
|
103
|
+
node ./bin/wendkeep.mjs bridge import-spec-kit --change ecosystem-bridges --accept-baseline --json > spec-projection.json
|
|
104
|
+
node ./bin/wendkeep.mjs bridge dispatch-superpowers --task-id 3.1 --change ecosystem-bridges --session "$env:CODEX_THREAD_ID" --spec-projection spec-projection.json --json
|
|
105
|
+
node ./bin/wendkeep.mjs bridge export-status --spec-projection spec-projection.json --task-contract task-contract.json --json
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Large flow with external report and proof ingestion:
|
|
109
|
+
|
|
110
|
+
```powershell
|
|
111
|
+
node ./bin/wendkeep.mjs verify --change ecosystem-bridges
|
|
112
|
+
node ./bin/wendkeep.mjs bridge verify-artifacts --input artifacts.json --proofs ci-proofs.json --change ecosystem-bridges --json
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Before `verify`, commit the artifact and `.wendkeep/bridge-artifacts.json` to the Git index. The v1
|
|
116
|
+
manifest binds each item to `source`, `external_id`, `kind`, `path`, `sensor_id`, and `task_id`. The
|
|
117
|
+
matching sensor in `wendkeep.sensors.json` declares v1 `artifact_results` with `external_id`, `path`,
|
|
118
|
+
and `algorithm: sha256`; the runner computes the byte digest, including binary files, only after a
|
|
119
|
+
green run. This explicit result contains no artifact content, transcript, or artifact output tail.
|
|
120
|
+
The collector checks the index first and then requires the identical copy to exist in the worktree;
|
|
121
|
+
deleting or changing only the working copy fails closed, while absence from both index and worktree
|
|
122
|
+
still means that the optional bridge declared no artifacts.
|
|
123
|
+
|
|
124
|
+
Each `ci-proofs.json` reference contains only
|
|
125
|
+
`{"type":"evidence-envelope","external_id":"review-1"}`. Path, task, sensor, digests, and Git
|
|
126
|
+
blobs are rederived from the canonical manifest and Envelope; self-declared state, SHA, or authority
|
|
127
|
+
are ignored for promotion. `artifacts.json` remains only the external report to compare.
|
|
128
|
+
|
|
129
|
+
An artifact starts as `reported`. External JSON that merely declares `state: verified` remains
|
|
130
|
+
`reported`. Promotion to `verified` jointly requires a project-contained file equal to its Git
|
|
131
|
+
index blob, a green CI sensor with an explicit `artifact_results.digest`, a canonical Evidence
|
|
132
|
+
Envelope v2 bound to the checkout, and a matching Envelope `external_artifacts` entry.
|
|
133
|
+
`output_sha256` does not prove artifacts. The result
|
|
134
|
+
exposes a sealed proof bound to `evidence_envelope_id` without copying transcript or Vault content.
|
|
135
|
+
|
|
136
|
+
## Expected result
|
|
137
|
+
|
|
138
|
+
- Spec Kit remains a read-only external source;
|
|
139
|
+
- canonical plan, task, and evidence remain owned by WendKeep;
|
|
140
|
+
- Superpowers receives minimal dispatch without permission to rewrite scope;
|
|
141
|
+
- worktree creation/reuse and finishing remain delegated to the `wendkeep worktree` argv derived in dispatch;
|
|
142
|
+
- post-merge cleanup uses `wendkeep worktree finish <slug> --pr <number-or-url>`;
|
|
143
|
+
- drift and competing ownership block before execution;
|
|
144
|
+
- removing or disabling an adapter does not degrade Core.
|
|
145
|
+
|
|
146
|
+
## Common errors and diagnosis
|
|
147
|
+
|
|
148
|
+
| Code | Diagnosis |
|
|
149
|
+
|---|---|
|
|
150
|
+
| `BRIDGE_ADAPTER_DISABLED` | Normal optional state; enable explicitly when needed. |
|
|
151
|
+
| `BRIDGE_ADAPTER_MISSING` | Adapter is enabled, but its root is absent. |
|
|
152
|
+
| `BRIDGE_VERSION_INCOMPATIBLE` | Version falls outside the published compatibility range. |
|
|
153
|
+
| `BRIDGE_OWNERSHIP_CONFLICT` | External tool tried to own plan/task/evidence. |
|
|
154
|
+
| `BRIDGE_SOURCE_DRIFT` | Hash changed, a plan became stale, or a reference appeared/disappeared. |
|
|
155
|
+
| `BRIDGE_SOURCE_ID_DUPLICATE` | The same story/requirement ID appears in different files. |
|
|
156
|
+
| `BRIDGE_BASELINE_MISSING` | Spec Kit is active without canonical baseline or required projection. |
|
|
157
|
+
| `BRIDGE_BASELINE_STALE` | Source/projection diverged from the sealed Vault baseline. |
|
|
158
|
+
| `BRIDGE_PROJECTION_INVALID` | Content and `projection_id` differ or schema fields are incomplete. |
|
|
159
|
+
| `BRIDGE_SCHEMA_INVALID` | Runtime envelope does not satisfy the published contract. |
|
|
160
|
+
| `BRIDGE_ARTIFACT_MANIFEST_UNTRACKED` | Bridge manifest exists on only one side or differs between index and worktree. |
|
|
161
|
+
| `BRIDGE_ARTIFACT_FORGED` | Artifact path/bytes do not match the versioned file. |
|
|
162
|
+
| `BRIDGE_ARTIFACT_RESULT_MISSING` | A green sensor did not produce the explicit digest bound by the manifest. |
|
|
163
|
+
| `BRIDGE_PROOF_MISSING` | External report has no bound independent proof yet. |
|
|
164
|
+
| `BRIDGE_PROOF_UNVERIFIED` | Self-declared proof was retained as `reported`. |
|
|
165
|
+
|
|
166
|
+
`wendkeep doctor` renders a `[bridges]` section without importing, dispatching, or writing.
|
|
167
|
+
|
|
168
|
+
## Next steps
|
|
169
|
+
|
|
170
|
+
Review the projection before dispatch, keep generated files outside canonical control, and verify
|
|
171
|
+
artifacts through CI or an Evidence Envelope. See [Changes and verification](changes-and-verification.md)
|
|
172
|
+
and [Managed worktrees](worktrees.md) as well.
|
|
@@ -87,6 +87,12 @@ temporary in the same directory and an atomic rename. In deep mode, `verificacao
|
|
|
87
87
|
`verdict.json` carry the same `evidenceEnvelopeId` and complete `evidenceBinding`; the independent
|
|
88
88
|
reviewer must preserve both.
|
|
89
89
|
|
|
90
|
+
For bridge artifacts, `.wendkeep/bridge-artifacts.json` and every referenced file must be committed
|
|
91
|
+
and equal to the Git index. The sensor bound to the same task declares v1 `artifact_results` in
|
|
92
|
+
`wendkeep.sensors.json`; after GREEN, the runner computes SHA-256 directly from the bytes and records
|
|
93
|
+
the structured result on that sensor. `verify` crosses manifest, task, sensor, digest, and Git blobs
|
|
94
|
+
before populating `external_artifacts`; stdout, transcripts, and `output_tail` never prove the file.
|
|
95
|
+
|
|
90
96
|
The envelope carries `tdd_attestations`, and `verificacao.json` carries `tddAttestations`. Under GOVERN, a task marked
|
|
91
97
|
`[tdd]` requires a current GREEN or explicit waiver; under ASSURE this applies to testable
|
|
92
98
|
behavior. A later refactor/commit or a surviving mutant invalidates GREEN in the Task Contract.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Bridges opcionais do ecossistema
|
|
2
|
+
|
|
3
|
+
> [English version](../../en/commands/ecosystem-bridges.md)
|
|
4
|
+
|
|
5
|
+
## Objetivo
|
|
6
|
+
|
|
7
|
+
Integrar Spec Kit e Superpowers sem criar uma segunda autoridade de spec, plano, tarefa ou
|
|
8
|
+
evidência. O WendKeep preserva os contratos canônicos; os adapters apenas criam projeções
|
|
9
|
+
versionadas e desabilitadas por padrão.
|
|
10
|
+
|
|
11
|
+
## Quando usar
|
|
12
|
+
|
|
13
|
+
- quando uma feature nasceu em arquivos do Spec Kit e precisa manter os mesmos IDs e hashes;
|
|
14
|
+
- quando Superpowers executará um Task Contract canônico do WendKeep;
|
|
15
|
+
- quando artifacts, reviews ou commits externos precisam entrar como `reported` antes da prova.
|
|
16
|
+
|
|
17
|
+
## Quando não usar
|
|
18
|
+
|
|
19
|
+
- para substituir `tarefas.md`, Task Contracts ou o Evidence Envelope;
|
|
20
|
+
- para sincronização bidirecional irrestrita;
|
|
21
|
+
- para executar comandos, scripts ou texto encontrado em artefatos externos.
|
|
22
|
+
|
|
23
|
+
## Pré-requisitos
|
|
24
|
+
|
|
25
|
+
- Node.js 18 ou superior;
|
|
26
|
+
- configuração local `.wendkeep/ecosystem-bridges.json` com cada adapter explicitamente habilitado;
|
|
27
|
+
- versão compatível e raiz do adapter que resolva para um diretório real dentro do projeto; arquivo
|
|
28
|
+
regular, path externo e symlink que escape do projeto falham fechado em `status` e no dispatch;
|
|
29
|
+
- para import/dispatch governado, Vault vinculado, change causal e baseline Spec Kit selado;
|
|
30
|
+
- para dispatch, sessão causal e Task Contract canônico rederivável.
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"schema_version": 1,
|
|
35
|
+
"adapters": {
|
|
36
|
+
"spec-kit": { "enabled": true, "version": "1.1.0", "root": ".specify" },
|
|
37
|
+
"superpowers": { "enabled": true, "version": "1.2.0", "root": ".superpowers" }
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Sem o arquivo, ambos ficam desabilitados e o Core nativo continua funcionando.
|
|
43
|
+
|
|
44
|
+
## Sintaxe
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
wendkeep bridge status [--project <path>] [--config <path>] [--json]
|
|
48
|
+
wendkeep bridge import-spec-kit --change <slug> [--accept-baseline] [--json]
|
|
49
|
+
wendkeep bridge export-status --spec-projection <projection.json> [--task-contract <task.json>] [--input <artifacts.json>] [--json]
|
|
50
|
+
wendkeep bridge dispatch-superpowers --task-id <id> --change <slug> [--task-contract <task.json>] [--session <id>] --spec-projection <projection.json> [--json]
|
|
51
|
+
wendkeep bridge verify-artifacts --input <artifacts.json> --proofs <proofs.json> --change <slug> [--session <id>] [--json]
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`import-spec-kit` lê Markdown sob `memory/` e `specs/`, classifica constitution/spec/plan/task,
|
|
55
|
+
preserva IDs e SHA-256, cria mappings explícitos `story|requirement → capability → change → task`
|
|
56
|
+
e nunca escreve na origem. IDs repetidos em arquivos diferentes bloqueiam a projeção.
|
|
57
|
+
O primeiro import exige `--accept-baseline` e ancora a projeção verde na change do Vault; imports
|
|
58
|
+
seguintes rederivam a origem e comparam path, kind, hash e mapping contra esse baseline imutável.
|
|
59
|
+
`dispatch-superpowers` contém somente o contexto estrutural
|
|
60
|
+
mínimo derivado do Task Contract; transcript, conteúdo privado e ownership externo não entram.
|
|
61
|
+
O dispatch rederiva o contrato e o active context do Vault/checkout; um JSON submetido é apenas
|
|
62
|
+
uma cópia para comparação e nunca valida o próprio `binding`. Com Spec Kit ativo, baseline e
|
|
63
|
+
`--spec-projection` são obrigatórios e a origem é reimportada antes do dispatch.
|
|
64
|
+
O contrato `spec-projection` pertence exclusivamente ao adapter `spec-kit`: versão incompatível,
|
|
65
|
+
kind fora do schema ou projeção re-selada por outro adapter é rejeitada antes de produzir `spec_refs`.
|
|
66
|
+
Uma decisão `ok: false` exige ao menos um diagnóstico bloqueante, e `ok: true` não pode coexistir
|
|
67
|
+
com diagnóstico bloqueante; qualquer incoerência bloqueia o dispatch sem expor referências.
|
|
68
|
+
`export-status` recalcula e valida `projection_id`, devolve apenas uma projeção `reported` e não
|
|
69
|
+
grava nos arquivos do Spec Kit.
|
|
70
|
+
|
|
71
|
+
## Opções e códigos de saída
|
|
72
|
+
|
|
73
|
+
| Opção | Efeito |
|
|
74
|
+
|---|---|
|
|
75
|
+
| `--project <path>` | Seleciona a raiz do consumidor. |
|
|
76
|
+
| `--config <path>` | Substitui `.wendkeep/ecosystem-bridges.json`. |
|
|
77
|
+
| `--change <slug>` | Seleciona a change que guarda baseline e Evidence Envelope canônicos. |
|
|
78
|
+
| `--accept-baseline` | Ancora somente o primeiro baseline Spec Kit verde; não sobrescreve drift. |
|
|
79
|
+
| `--task-id <id>` | Seleciona a tarefa no contexto causal e rederiva o contrato canônico. |
|
|
80
|
+
| `--task-contract <path>` | Cópia opcional que deve coincidir com o contrato rederivado. |
|
|
81
|
+
| `--spec-projection <path>` | Liga referências Spec Kit ao dispatch sem copiar o conteúdo. |
|
|
82
|
+
| `--input` / `--proofs` | Classifica artifacts externos e suas provas Git/CI/Envelope. |
|
|
83
|
+
| `--json` | Emite o contrato tipado em uma linha JSON. |
|
|
84
|
+
|
|
85
|
+
- `0`: operação válida; adapters opcionais desabilitados também são saudáveis;
|
|
86
|
+
- `1`: adapter habilitado bloqueado, drift, incompatibilidade ou prova ausente;
|
|
87
|
+
- `2`: argumento, configuração ou arquivo de entrada inválido.
|
|
88
|
+
|
|
89
|
+
## Exemplos
|
|
90
|
+
|
|
91
|
+
Fluxo pequeno, sem adapters:
|
|
92
|
+
|
|
93
|
+
```powershell
|
|
94
|
+
node ./bin/wendkeep.mjs bridge status --json
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Fluxo médio, Spec Kit somente leitura:
|
|
98
|
+
|
|
99
|
+
```powershell
|
|
100
|
+
node ./bin/wendkeep.mjs bridge import-spec-kit --change ecosystem-bridges --accept-baseline --json > spec-projection.json
|
|
101
|
+
node ./bin/wendkeep.mjs bridge dispatch-superpowers --task-id 3.1 --change ecosystem-bridges --session "$env:CODEX_THREAD_ID" --spec-projection spec-projection.json --json
|
|
102
|
+
node ./bin/wendkeep.mjs bridge export-status --spec-projection spec-projection.json --task-contract task-contract.json --json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Fluxo grande, ingestão de relato e prova externa:
|
|
106
|
+
|
|
107
|
+
```powershell
|
|
108
|
+
node ./bin/wendkeep.mjs verify --change ecosystem-bridges
|
|
109
|
+
node ./bin/wendkeep.mjs bridge verify-artifacts --input artifacts.json --proofs ci-proofs.json --change ecosystem-bridges --json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Antes de `verify`, versione no índice Git o artefato e `.wendkeep/bridge-artifacts.json`. O manifest
|
|
113
|
+
v1 liga cada item a `source`, `external_id`, `kind`, `path`, `sensor_id` e `task_id`. O sensor
|
|
114
|
+
correspondente em `wendkeep.sensors.json` declara `artifact_results` v1 com `external_id`, `path` e
|
|
115
|
+
`algorithm: sha256`; o runner calcula o digest dos bytes, inclusive binários, somente depois de uma
|
|
116
|
+
execução verde. O resultado explícito não contém conteúdo, transcript nem output tail do artefato.
|
|
117
|
+
O collector consulta primeiro o índice e então exige a mesma cópia presente na worktree; apagar ou
|
|
118
|
+
alterar somente a cópia de trabalho falha fechado, enquanto a ausência simultânea no índice e na
|
|
119
|
+
worktree continua significando que o bridge opcional não declarou artifacts.
|
|
120
|
+
|
|
121
|
+
Cada referência em `ci-proofs.json` usa apenas
|
|
122
|
+
`{"type":"evidence-envelope","external_id":"review-1"}`. Path, task, sensor, digests e blobs Git
|
|
123
|
+
são rederivados do manifest e do Envelope canônicos; `state`, SHA ou autoridade autodeclarados são
|
|
124
|
+
ignorados para promoção. `artifacts.json` continua sendo somente o relato externo a comparar.
|
|
125
|
+
|
|
126
|
+
O artifact começa como `reported`. JSON externo que apenas declare `state: verified` continua
|
|
127
|
+
`reported`. A promoção para `verified` exige, em conjunto: arquivo dentro do projeto e igual ao
|
|
128
|
+
blob do índice Git, sensor CI verde com `artifact_results.digest` explícito, Evidence Envelope v2
|
|
129
|
+
canônico e bound ao checkout, e entrada correspondente em `external_artifacts` do Envelope.
|
|
130
|
+
`output_sha256` não prova artefatos.
|
|
131
|
+
O resultado expõe uma proof selada ligada ao `evidence_envelope_id`, sem copiar transcript ou Vault.
|
|
132
|
+
|
|
133
|
+
## Resultado esperado
|
|
134
|
+
|
|
135
|
+
- Spec Kit permanece uma fonte externa somente leitura;
|
|
136
|
+
- plano, tarefa e evidência canônicos continuam pertencendo ao WendKeep;
|
|
137
|
+
- Superpowers recebe um dispatch mínimo sem poder reescrever o escopo;
|
|
138
|
+
- criação/reuso e finalização de worktree permanecem nos comandos `wendkeep worktree` derivados no dispatch;
|
|
139
|
+
- cleanup pós-merge usa `wendkeep worktree finish <slug> --pr <número-ou-url>`;
|
|
140
|
+
- drift e ownership concorrente bloqueiam antes da execução;
|
|
141
|
+
- remover ou desabilitar um adapter não degrada o Core.
|
|
142
|
+
|
|
143
|
+
## Erros comuns e diagnóstico
|
|
144
|
+
|
|
145
|
+
| Código | Diagnóstico |
|
|
146
|
+
|---|---|
|
|
147
|
+
| `BRIDGE_ADAPTER_DISABLED` | Estado opcional normal; habilite explicitamente se necessário. |
|
|
148
|
+
| `BRIDGE_ADAPTER_MISSING` | Adapter habilitado, mas sua raiz não existe. |
|
|
149
|
+
| `BRIDGE_VERSION_INCOMPATIBLE` | Versão fora do compatibility range publicado. |
|
|
150
|
+
| `BRIDGE_OWNERSHIP_CONFLICT` | Ferramenta externa tentou possuir plano/tarefa/evidência. |
|
|
151
|
+
| `BRIDGE_SOURCE_DRIFT` | Hash mudou, plano ficou obsoleto ou uma referência apareceu/desapareceu. |
|
|
152
|
+
| `BRIDGE_SOURCE_ID_DUPLICATE` | O mesmo story/requirement ID apareceu em arquivos diferentes. |
|
|
153
|
+
| `BRIDGE_BASELINE_MISSING` | Spec Kit ativo sem baseline canônico ou projeção obrigatória. |
|
|
154
|
+
| `BRIDGE_BASELINE_STALE` | Origem/projeção divergiu do baseline selado no Vault. |
|
|
155
|
+
| `BRIDGE_PROJECTION_INVALID` | Conteúdo e `projection_id` não coincidem ou o schema está incompleto. |
|
|
156
|
+
| `BRIDGE_SCHEMA_INVALID` | Envelope runtime não cumpre o contrato publicado. |
|
|
157
|
+
| `BRIDGE_ARTIFACT_MANIFEST_UNTRACKED` | Manifest bridge ausente em apenas um lado ou diferente entre índice e worktree. |
|
|
158
|
+
| `BRIDGE_ARTIFACT_FORGED` | Path/bytes do artefato não correspondem ao arquivo versionado. |
|
|
159
|
+
| `BRIDGE_ARTIFACT_RESULT_MISSING` | Sensor verde não produziu o digest explícito ligado ao manifest. |
|
|
160
|
+
| `BRIDGE_PROOF_MISSING` | Relato externo ainda não possui prova independente vinculada. |
|
|
161
|
+
| `BRIDGE_PROOF_UNVERIFIED` | Prova autodeclarada foi mantida como `reported`. |
|
|
162
|
+
|
|
163
|
+
`wendkeep doctor` mostra a seção `[bridges]` sem fazer import, dispatch ou escrita.
|
|
164
|
+
|
|
165
|
+
## Próximos passos
|
|
166
|
+
|
|
167
|
+
Revise a projeção antes do dispatch, mantenha os arquivos gerados fora do controle canônico e
|
|
168
|
+
valide artifacts pelo CI ou Evidence Envelope. Consulte também [Changes e verificação](changes-and-verification.md)
|
|
169
|
+
e [Worktrees gerenciadas](worktrees.md).
|
|
@@ -88,6 +88,12 @@ mesmo diretório e rename atômico. No deep, `verificacao.json` e `verdict.json`
|
|
|
88
88
|
`evidenceEnvelopeId` e `evidenceBinding` completo; o verificador independente deve preservar ambos
|
|
89
89
|
no verdict.
|
|
90
90
|
|
|
91
|
+
Para artefatos de bridge, `.wendkeep/bridge-artifacts.json` e os arquivos referenciados precisam
|
|
92
|
+
estar versionados e iguais ao índice Git. O sensor ligado à mesma task declara `artifact_results`
|
|
93
|
+
v1 em `wendkeep.sensors.json`; após GREEN, o runner calcula o SHA-256 diretamente dos bytes e grava
|
|
94
|
+
o resultado estruturado no sensor. `verify` cruza manifest, task, sensor, digest e blobs Git antes
|
|
95
|
+
de preencher `external_artifacts`; stdout, transcript e `output_tail` nunca são prova do arquivo.
|
|
96
|
+
|
|
91
97
|
O envelope carrega `tdd_attestations`, e `verificacao.json`, `tddAttestations`. Em GOVERN, uma tarefa marcada
|
|
92
98
|
`[tdd]` precisa de GREEN atual ou waiver explícito; em ASSURE, isso vale para comportamento
|
|
93
99
|
testável. Refactor/commit posterior ou mutante sobrevivente invalida o GREEN no Task Contract.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wendkeep",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.89.0",
|
|
4
4
|
"description": "Vault-first persistent memory for AI coding agents, with an optional profile-aware governance runtime: OFF, FLOW, GUIDE, GOVERN, or ASSURE. Local-first and agent-agnostic (Claude Code, Codex, Cursor…).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"workspaces": [
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"scripts": {
|
|
47
47
|
"precheck": "node --check src/capabilities.mjs && node --check src/host-capabilities.mjs && node --check src/task-contracts.mjs && node --check src/task-leases.mjs && node --check src/task.mjs && node --check src/change.mjs && node --check src/archive-operation-lock.mjs && node --check src/worktree.mjs && node --check src/worktree-cleanup.mjs && node --check src/provenance-gate.mjs && node --check src/provenance-sources.mjs && node --check src/receipt-ledger.mjs && node --check src/evidence-envelope.mjs && node --check src/context.mjs && node --check src/active-context-health.mjs && node --check src/active-context-runtime.mjs && node --check hooks/active-context-store.mjs && node --check hooks/change-core.mjs && node --check hooks/brain-inject.mjs && node --check hooks/change-context.mjs && node --check hooks/session-stop.mjs && node --check packages/vault/src/worktree-metadata.mjs && node --check packages/vault/src/evidence-envelope.mjs && node --check packages/vault/src/memory-handoff.mjs && node --check packages/integrations/src/capabilities.mjs && node --check packages/pi/src/index.mjs && node --check src/sync-protocol.mjs && node --check src/sync-outbox.mjs && node --check src/sync-adapters.mjs && node --check src/sync-protocol-cli.mjs && node --check packages/mcp/src/sync.mjs && node --check src/portable.mjs && node --check src/tdd.mjs && node --check src/tdd-attestation.mjs && node --check src/tdd-attestation-store.mjs",
|
|
48
48
|
"check": "node --check scripts/validate-commit-range.mjs && node --check packages/commit/src/index.mjs && node --check packages/commit/src/cli.mjs && node --check packages/commit/src/git-runtime.mjs && node --check src/git-commit-hooks.mjs && node --check scripts/release.mjs && node --check scripts/release-plan.mjs && node --check scripts/release-provenance.mjs && node --check scripts/run-scope.mjs && node --check src/release-provenance.mjs && node --check bin/wendkeep.mjs && node --check packages/cli/src/index.mjs && node --check src/mcp.mjs && node --check src/init.mjs && node --check src/doctor.mjs && node --check src/active-context-health.mjs && node --check src/project-vault.mjs && node --check src/observer-auth.mjs && node --check src/observer-privacy.mjs && node --check src/observer-snapshot.mjs && node --check src/observer-store.mjs && node --check src/observer-memory.mjs && node --check src/observer-memory-publish.mjs && node --check src/observer-sql-store.mjs && node --check src/observer-sql-migrate.mjs && node --check src/observer-sql-publish.mjs && node --check src/observer-transcript-store.mjs && node --check src/observer-server.mjs && node --check src/observer.mjs && node --check src/observer-publish.mjs && node --check src/operating-profile.mjs && node --check src/profile.mjs && node --check src/flow.mjs && node --check src/work-kind.mjs && node --check src/delivery.mjs && node --check web/observer/app.mjs && node --check hooks/observer-publish.mjs && node --check hooks/evidence-context.mjs && node --check hooks/active-context-handoff-evidence.mjs && node --check hooks/evidence-recall.mjs && node --check hooks/memory-scope.mjs && node --check hooks/operating-profile-runtime.mjs && node --check hooks/operating-profile-task-store.mjs && node --check hooks/flow-core.mjs && node --check hooks/flow-protected-policy.mjs && node --check hooks/git-snapshot.mjs && node --check hooks/vault-path-safety.mjs && node --check hooks/vault-runtime-store.mjs && node --check packages/harness/src/index.mjs && node --check packages/harness/src/flow-store.mjs && node --check packages/harness/src/operating-profile.mjs && node --check packages/harness/src/sensors-core.mjs && node --check packages/integrations/src/host-hooks.mjs && node --check packages/integrations/src/hook-envelope.mjs && node --check packages/integrations/src/prompt-content.mjs && node --check packages/integrations/src/transcript-usage.mjs && node --check packages/integrations/src/transcripts.mjs && node --check packages/integrations/src/session-identity.mjs && node --check packages/integrations/src/index.mjs && node --check packages/mcp/src/audit.mjs && node --check packages/mcp/src/cli.mjs && node --check packages/mcp/src/config.mjs && node --check packages/mcp/src/effects.mjs && node --check packages/mcp/src/executor.mjs && node --check packages/mcp/src/server.mjs && node --check packages/mcp/src/stdio.mjs && node --check packages/mcp/src/index.mjs && node --check packages/vault/src/index.mjs && node --check packages/vault/src/project-vault.mjs && node --check packages/vault/src/vault-path-safety.mjs && node --check packages/vault/src/locale.mjs && node --check packages/vault/src/memory-schema.mjs && node --check packages/vault/src/memory-mode.mjs && node --check packages/vault/src/memory-scope.mjs && node --check packages/vault/src/memory-candidate-policy.mjs && node --check packages/vault/src/evidence-recall.mjs && node --check packages/vault/src/memory-handoff.mjs && node --check packages/vault/src/memory-store.mjs && node --check packages/vault/src/validate-core.mjs && node --check packages/vault/src/validate-memory.mjs",
|
|
49
|
-
"postcheck": "node --check packages/observer/src/index.mjs && node --check packages/observer/src/policy.mjs && node --check packages/observer/src/redaction.mjs && node --check packages/observer/src/authz.mjs && node --check packages/observer/src/token-registry.mjs && node --check packages/observer/src/encryption.mjs && node --check packages/observer/src/retention.mjs && node --check packages/observer/src/purge.mjs && node --check packages/observer/src/audit.mjs",
|
|
49
|
+
"postcheck": "node --check packages/observer/src/index.mjs && node --check packages/observer/src/policy.mjs && node --check packages/observer/src/redaction.mjs && node --check packages/observer/src/authz.mjs && node --check packages/observer/src/token-registry.mjs && node --check packages/observer/src/encryption.mjs && node --check packages/observer/src/retention.mjs && node --check packages/observer/src/purge.mjs && node --check packages/observer/src/audit.mjs && node --check src/ecosystem-bridges.mjs && node --check src/ecosystem-bridge-artifact-collector.mjs && node --check src/ecosystem-bridge-baseline.mjs && node --check src/ecosystem-bridge-proof.mjs && node --check packages/integrations/src/bridge-config.mjs && node --check packages/integrations/src/bridge-contract.mjs && node --check packages/integrations/src/bridge-diagnostics.mjs && node --check packages/integrations/src/canonical-bridge-authority.mjs && node --check packages/integrations/src/ecosystem-bridge.mjs && node --check packages/integrations/src/spec-kit-adapter.mjs && node --check packages/integrations/src/superpowers-adapter.mjs",
|
|
50
50
|
"test": "node --test --test-concurrency=2",
|
|
51
51
|
"test:core": "node scripts/run-scope.mjs core",
|
|
52
52
|
"release": "node scripts/release.mjs",
|
|
@@ -61,6 +61,7 @@ Usage:
|
|
|
61
61
|
serve: --vault P · --timeout-ms N.
|
|
62
62
|
config: --client generic|claude|codex|cursor · --vault P.
|
|
63
63
|
wendkeep capabilities [...] Show declared lifecycle/effect coverage by host. --host <id> · --host-version <v> · --json.
|
|
64
|
+
wendkeep bridge <sub> Optional ecosystem adapters: status | import-spec-kit | export-status | dispatch-superpowers | verify-artifacts.
|
|
64
65
|
wendkeep observer <sub> Local multi-project Observer: serve | register | publish | reconcile | status.
|
|
65
66
|
wendkeep worktree create <slug> [--base ref] [--branch name] [--open vscode|none] [--json]
|
|
66
67
|
wendkeep worktree list [--json]
|
|
@@ -237,6 +238,9 @@ async function main(argv) {
|
|
|
237
238
|
} else if (cmd === 'commit') {
|
|
238
239
|
const { COMMIT_HELP } = await import('../../commit/src/cli.mjs');
|
|
239
240
|
process.stdout.write(COMMIT_HELP);
|
|
241
|
+
} else if (cmd === 'bridge') {
|
|
242
|
+
const { BRIDGE_HELP } = await import('../../../src/ecosystem-bridges.mjs');
|
|
243
|
+
process.stdout.write(BRIDGE_HELP);
|
|
240
244
|
} else {
|
|
241
245
|
process.stdout.write(HELP);
|
|
242
246
|
}
|
|
@@ -250,7 +254,7 @@ async function main(argv) {
|
|
|
250
254
|
// `sync` starts with `init` and resolves the freshly bound Vault itself. Pre-resolving
|
|
251
255
|
// here would prevent that repair step from reporting a corrupt binding as its own
|
|
252
256
|
// first-stage failure (and could never make it as far as the guarded init).
|
|
253
|
-
&& !['init', 'sync', 'worktree', 'hook', 'observer', 'mcp', 'capabilities', 'commit', '--version', '-v', '--help', '-h', 'help'].includes(cmd)) {
|
|
257
|
+
&& !['init', 'sync', 'worktree', 'hook', 'observer', 'mcp', 'capabilities', 'commit', 'bridge', '--version', '-v', '--help', '-h', 'help'].includes(cmd)) {
|
|
254
258
|
await preferProjectVault(rest);
|
|
255
259
|
}
|
|
256
260
|
switch (cmd) {
|
|
@@ -294,6 +298,11 @@ async function main(argv) {
|
|
|
294
298
|
process.exit(runCapabilities(rest));
|
|
295
299
|
break;
|
|
296
300
|
}
|
|
301
|
+
case 'bridge': {
|
|
302
|
+
const { runEcosystemBridge } = await import('../../../src/ecosystem-bridges.mjs');
|
|
303
|
+
process.exit(runEcosystemBridge(rest));
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
297
306
|
case 'worktree': {
|
|
298
307
|
const { runWorktree } = await import('../../../src/worktree.mjs');
|
|
299
308
|
process.exit(await runWorktree(rest));
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
// at the PROJECT ROOT (wendkeep.sensors.json); evidence lives per-change in the vault.
|
|
4
4
|
import { spawnSync } from 'node:child_process';
|
|
5
5
|
import { createHash } from 'node:crypto';
|
|
6
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
7
|
-
import { dirname, join, resolve } from 'node:path';
|
|
6
|
+
import { existsSync, lstatSync, readFileSync, realpathSync } from 'node:fs';
|
|
7
|
+
import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
8
8
|
|
|
9
9
|
export const SENSOR_VAULT_ENV = 'WENDKEEP_SENSOR_VAULT';
|
|
10
10
|
const SENSOR_OUTPUT_MAX_BUFFER = 8 * 1024 * 1024;
|
|
11
11
|
const SENSOR_DIAGNOSTIC_MAX_LENGTH = 2000;
|
|
12
|
+
const SENSOR_ARTIFACT_MAX_BYTES = 1024 * 1024;
|
|
12
13
|
|
|
13
14
|
function sanitizeSensorDiagnostic(value) {
|
|
14
15
|
return String(value || '')
|
|
@@ -27,6 +28,41 @@ function sha256(value) {
|
|
|
27
28
|
return `sha256:${createHash('sha256').update(String(value || '')).digest('hex')}`;
|
|
28
29
|
}
|
|
29
30
|
|
|
31
|
+
function containedPath(root, target) {
|
|
32
|
+
const rel = relative(root, target);
|
|
33
|
+
return rel === '' || (rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function collectSensorArtifactResults(sensor, cwd) {
|
|
37
|
+
const declarations = sensor?.artifact_results;
|
|
38
|
+
if (declarations === undefined) return [];
|
|
39
|
+
if (!Array.isArray(declarations)) throw new Error('artifact_results must be an array');
|
|
40
|
+
const root = realpathSync(resolve(cwd || '.'));
|
|
41
|
+
const seen = new Set();
|
|
42
|
+
return declarations.map((declaration) => {
|
|
43
|
+
const externalId = String(declaration?.external_id || '').trim();
|
|
44
|
+
const configuredPath = String(declaration?.path || '').trim();
|
|
45
|
+
if (Object.keys(declaration || {}).some((key) => ![
|
|
46
|
+
'schema_version', 'external_id', 'path', 'algorithm',
|
|
47
|
+
].includes(key)) || declaration?.schema_version !== 1 || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(externalId)
|
|
48
|
+
|| !configuredPath || declaration?.algorithm !== 'sha256' || seen.has(externalId)) {
|
|
49
|
+
throw new Error('artifact result declaration is invalid');
|
|
50
|
+
}
|
|
51
|
+
seen.add(externalId);
|
|
52
|
+
const candidate = resolve(root, configuredPath);
|
|
53
|
+
if (!containedPath(root, candidate) || !existsSync(candidate) || !lstatSync(candidate).isFile()) {
|
|
54
|
+
throw new Error(`artifact result path is unavailable: ${externalId}`);
|
|
55
|
+
}
|
|
56
|
+
const file = realpathSync(candidate);
|
|
57
|
+
if (!containedPath(root, file) || lstatSync(file).size > SENSOR_ARTIFACT_MAX_BYTES) {
|
|
58
|
+
throw new Error(`artifact result path is unsafe: ${externalId}`);
|
|
59
|
+
}
|
|
60
|
+
const path = relative(root, file).replaceAll('\\', '/');
|
|
61
|
+
const digest = createHash('sha256').update(readFileSync(file)).digest('hex');
|
|
62
|
+
return { schema_version: 1, external_id: externalId, path, algorithm: 'sha256', digest };
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
30
66
|
function sensorNow(now) {
|
|
31
67
|
const value = typeof now === 'function' ? now() : (now || new Date().toISOString());
|
|
32
68
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -167,7 +203,17 @@ export function runSensors(sensors, ids, { spawn = spawnSync, cwd, env, now } =
|
|
|
167
203
|
output_sha256: sha256(rawOutput),
|
|
168
204
|
output_tail: boundedOutputTail,
|
|
169
205
|
};
|
|
170
|
-
if (entry.status === '
|
|
206
|
+
if (entry.status === 'green' && s.artifact_results !== undefined) {
|
|
207
|
+
try {
|
|
208
|
+
entry.artifact_results = collectSensorArtifactResults(s, cwd);
|
|
209
|
+
} catch (error) {
|
|
210
|
+
entry.status = 'red';
|
|
211
|
+
entry.exit_code = 1;
|
|
212
|
+
entry.artifact_results = [];
|
|
213
|
+
entry.note = sanitizeSensorDiagnostic(error?.message || 'artifact result collection failed');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (entry.status === 'red' && !entry.note) entry.note = sensorFailureNote(r);
|
|
171
217
|
if (s.type === 'mutation' && s.report) {
|
|
172
218
|
// Delegated mutation (Wave B): read the tool's mutation-testing-elements report and
|
|
173
219
|
// attach surviving mutants so verify can turn them into fix tasks.
|