@smartmemory/compose 0.3.6-beta → 0.3.8
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/.claude/skills/compose/SKILL.md +42 -88
- package/.compose-deps.json +1 -13
- package/README.md +72 -5
- package/bin/compose.js +754 -347
- package/bin/git-hooks/pre-push.template +29 -0
- package/bin/judgment-import.js +7 -0
- package/bin/judgment-migrate.js +387 -0
- package/contracts/comp-obs-contract.schema.json +9 -3
- package/contracts/feature-json.schema.json +5 -0
- package/contracts/fluid-record.schema.json +209 -0
- package/contracts/judgment-record.schema.json +425 -4
- package/contracts/lifecycle-backfill.schema.json +322 -0
- package/dist/assets/App-Z4MU-H_F.js +916 -0
- package/dist/assets/_baseUniq-ClWoCPFl.js +1 -0
- package/dist/assets/arc-DY26UIVo.js +1 -0
- package/dist/assets/architectureDiagram-Q4EWVU46-6Ggq4DqJ.js +36 -0
- package/dist/assets/blockDiagram-DXYQGD6D-CH3Ked0l.js +132 -0
- package/dist/assets/{browser-BSM23If2.js → browser-BWkrenen.js} +6 -6
- package/dist/assets/{c4Diagram-LMCZKHZV-DZf45Fbz.js → c4Diagram-AHTNJAMY-Bk8dYilu.js} +1 -1
- package/dist/assets/channel-SnZzzh7k.js +1 -0
- package/dist/assets/{chunk-JWPE2WC7-_7ujgd_Q.js → chunk-4BX2VUAB-BMR0XaAQ.js} +1 -1
- package/dist/assets/chunk-4TB4RGXK-JytR14a9.js +206 -0
- package/dist/assets/{chunk-XXDRQBXY-DfdVhbmA.js → chunk-55IACEB6-B4Q97BCP.js} +1 -1
- package/dist/assets/{chunk-VR4S4FIN-Dt9NZ67m.js → chunk-EDXVE4YY-R_qarkSf.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-BY4_PV5H.js → chunk-FMBD7UC4-C9s7KR9m.js} +1 -1
- package/dist/assets/chunk-OYMX7WX6-BySQzVxc.js +231 -0
- package/dist/assets/{chunk-2Q5K7J3B-Dn1spZYu.js → chunk-QZHKN3VN-DdpSYZsW.js} +1 -1
- package/dist/assets/{chunk-32BRIVSS-pURGrJDk.js → chunk-YZCP3GAM-iE_tzriw.js} +1 -1
- package/dist/assets/classDiagram-6PBFFD2Q-CBu92dSH.js +1 -0
- package/dist/assets/classDiagram-v2-HSJHXN6E-CBu92dSH.js +1 -0
- package/dist/assets/clone-DgklGjHm.js +1 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-BieYif4o.js → cose-bilkent-S5V4N54A-BdlU6ZX_.js} +1 -1
- package/dist/assets/dagre-KV5264BT-Cp3F5KTn.js +4 -0
- package/dist/assets/diagram-5BDNPKRD-DiR6_2q_.js +10 -0
- package/dist/assets/diagram-G4DWMVQ6-w0i-p5HX.js +24 -0
- package/dist/assets/diagram-MMDJMWI5-tIHhwUv3.js +43 -0
- package/dist/assets/diagram-TYMM5635-BAeY3B19.js +24 -0
- package/dist/assets/erDiagram-SMLLAGMA-Ckx_Knko.js +85 -0
- package/dist/assets/flowDiagram-DWJPFMVM-DeoNka6J.js +162 -0
- package/dist/assets/ganttDiagram-T4ZO3ILL-BmGnFbEg.js +292 -0
- package/dist/assets/gitGraphDiagram-UUTBAWPF-Dk48IHsx.js +106 -0
- package/dist/assets/graph-BNzKGvoy.js +1 -0
- package/dist/assets/graph-CI_1htl0.js +331 -0
- package/dist/assets/index-BEfrNBp8.js +123 -0
- package/dist/assets/index-yyrA5OZd.css +1 -0
- package/dist/assets/infoDiagram-42DDH7IO-BRf827i0.js +2 -0
- package/dist/assets/{ishikawaDiagram-FXEZZL3T-CzEB9fQS.js → ishikawaDiagram-UXIWVN3A-0kCZaeCM.js} +5 -5
- package/dist/assets/{journeyDiagram-5HDEW3XC-Bz8TCdz2.js → journeyDiagram-VCZTEJTY-rvU7ayRt.js} +1 -1
- package/dist/assets/{kanban-definition-HUTT4EX6-tozrMoV_.js → kanban-definition-6JOO6SKY-DpQwX1C5.js} +7 -7
- package/dist/assets/katex-DkKDou_j.js +257 -0
- package/dist/assets/layout-BI8cXFPI.js +1 -0
- package/dist/assets/{linear-Ck7gpa5N.js → linear-a0glcDiw.js} +1 -1
- package/dist/assets/min-vPHfnXcC.js +1 -0
- package/dist/assets/{mindmap-definition-LN4V7U3C-DTcHO0DJ.js → mindmap-definition-QFDTVHPH-D14eF-7C.js} +7 -7
- package/dist/assets/mobile-B7m9EO9D.js +17 -0
- package/dist/assets/pieDiagram-DEJITSTG-Cno-gETh.js +30 -0
- package/dist/assets/quadrantDiagram-34T5L4WZ-BUQM1Hfm.js +7 -0
- package/dist/assets/{requirementDiagram-TGXJPOKE-bnI2zJeT.js → requirementDiagram-MS252O5E-pOXlN2-q.js} +3 -3
- package/dist/assets/sankeyDiagram-XADWPNL6-Crynd3_b.js +10 -0
- package/dist/assets/sequenceDiagram-FGHM5R23-D9fZdCM8.js +157 -0
- package/dist/assets/stateDiagram-FHFEXIEX-CW9qVec8.js +1 -0
- package/dist/assets/stateDiagram-v2-QKLJ7IA2-DkVLzHbY.js +1 -0
- package/dist/assets/{timeline-definition-FHXFAJF6-D267GQFF.js → timeline-definition-GMOUNBTQ-BcHzhm_8.js} +3 -3
- package/dist/assets/vennDiagram-DHZGUBPP-BfytJcWk.js +34 -0
- package/dist/assets/wardley-RL74JXVD-DLj-IjyB.js +162 -0
- package/dist/assets/wardleyDiagram-NUSXRM2D-Ds0Ue68c.js +20 -0
- package/dist/assets/xychartDiagram-5P7HB3ND-vjWDXFL6.js +7 -0
- package/dist/index.html +3 -3
- package/lib/agent-string.js +7 -5
- package/lib/append-integrity.js +81 -0
- package/lib/backfill-evidence.js +109 -0
- package/lib/bug-escalation.js +39 -4
- package/lib/build-stream-schema.js +3 -1
- package/lib/build-stream-writer.js +25 -0
- package/lib/build.js +1624 -195
- package/lib/canon-guard.js +245 -0
- package/lib/canon-override.js +196 -0
- package/lib/canon-registry.js +291 -0
- package/lib/cli-commands.js +144 -0
- package/lib/codex-preflight.js +50 -15
- package/lib/colleague/context.js +215 -0
- package/lib/colleague/writeback.js +95 -0
- package/lib/completion-gate.js +1421 -0
- package/lib/completion-writer.js +47 -47
- package/lib/consumer-fanout.js +105 -11
- package/lib/coverage-gate.js +200 -0
- package/lib/dir-lock.js +170 -0
- package/lib/dispatch-ledger.js +301 -0
- package/lib/dispatch-metrics.js +236 -0
- package/lib/experiment-judge.js +6 -1
- package/lib/feature-json.js +1 -1
- package/lib/feature-reconciler.js +8 -0
- package/lib/feature-validator.js +64 -1
- package/lib/feature-writer.js +66 -2
- package/lib/fluid/factory.js +167 -0
- package/lib/fluid/ideabox-dates.js +73 -0
- package/lib/fluid/ideabox-migrate.js +154 -0
- package/lib/fluid/ideabox-ops.js +585 -0
- package/lib/fluid/ideabox-view.js +146 -0
- package/lib/fluid/import-ideabox.js +186 -0
- package/lib/fluid/local-provider.js +606 -0
- package/lib/fluid/provider.js +684 -0
- package/lib/fluid/record-shape.js +214 -0
- package/lib/fluid/record-store.js +328 -0
- package/lib/fluid/render-ideabox.js +261 -0
- package/lib/fluid/schema.js +40 -0
- package/lib/fluid/smartmemory-provider.js +1695 -0
- package/lib/gsd.js +63 -14
- package/lib/guard-cli.js +175 -0
- package/lib/guard-custody.js +141 -0
- package/lib/guard-descriptors.js +530 -0
- package/lib/guard-enrol.js +254 -0
- package/lib/health-score.js +1 -1
- package/lib/hooks-status.js +32 -3
- package/lib/ideabox-cli.js +315 -0
- package/lib/ideabox.js +121 -21
- package/lib/judgment/store/index.js +166 -0
- package/lib/judgment/store/records.js +184 -25
- package/lib/judgment/trace.js +380 -0
- package/lib/judgment-attest.js +259 -0
- package/lib/judgment-decision-write.js +277 -0
- package/lib/judgment-decisions.js +466 -0
- package/lib/judgment-gen.js +375 -22
- package/lib/judgment-verify.js +153 -0
- package/lib/judgment-writer.js +2842 -262
- package/lib/lane-gate.js +2 -0
- package/lib/lifecycle-modes.js +4 -4
- package/lib/lineage.js +400 -0
- package/lib/local-claude-connector.js +250 -54
- package/lib/maya-client.js +302 -0
- package/lib/maya-config.js +53 -0
- package/lib/maya-identity.js +283 -0
- package/lib/mcp-enforcement.js +21 -35
- package/lib/migrate-anon.js +5 -0
- package/lib/migrate-roadmap.js +15 -0
- package/lib/new.js +13 -1
- package/lib/pipeline-compat.js +104 -0
- package/lib/policy-catalog.js +295 -0
- package/lib/policy-check.js +0 -0
- package/lib/process-termination.js +98 -0
- package/lib/resolve-workspace.js +5 -1
- package/lib/result-normalizer.js +428 -153
- package/lib/review-normalize.js +4 -0
- package/lib/roadmap-errors.js +65 -0
- package/lib/roadmap-preservers.js +24 -4
- package/lib/roadmap-residue.js +299 -0
- package/lib/smartmemory-client.js +614 -78
- package/lib/smartmemory-config.js +54 -0
- package/lib/smartmemory-ingest.js +19 -2
- package/lib/step-prompt.js +7 -6
- package/lib/stratum-engine.js +53 -4
- package/lib/stratum-mcp-client.js +391 -31
- package/lib/test-bootstrap.js +31 -0
- package/lib/tool-inventory.js +122 -0
- package/lib/version-check.js +91 -19
- package/lib/vision-writer.js +88 -1
- package/package.json +7 -6
- package/pipelines/bug-fix.stratum.yaml +205 -211
- package/pipelines/build-quick.profiles.json +12 -0
- package/pipelines/build-quick.stratum.yaml +263 -350
- package/pipelines/content.stratum.yaml +81 -77
- package/pipelines/coverage-sweep.stratum.yaml +49 -30
- package/pipelines/plan.stratum.yaml +76 -86
- package/pipelines/refactor.stratum.yaml +125 -125
- package/pipelines/research.stratum.yaml +56 -58
- package/pipelines/review-fix.profiles.json +6 -0
- package/pipelines/review-fix.stratum.yaml +110 -83
- package/presets/team-feature.profiles.json +6 -0
- package/presets/team-feature.stratum.yaml +93 -66
- package/presets/team-research.profiles.json +6 -0
- package/presets/team-research.stratum.yaml +89 -80
- package/presets/team-review.profiles.json +8 -0
- package/presets/team-review.stratum.yaml +98 -80
- package/scripts/cost-census.mjs +70 -0
- package/scripts/guard-sign/compose-guard-sign.sh +62 -0
- package/server/agent-health.js +22 -0
- package/server/agent-hooks.js +14 -1
- package/server/agent-server.js +5 -248
- package/server/agent-spawn.js +3 -4
- package/server/agent-workspace.js +294 -0
- package/server/build-routes.js +6 -5
- package/server/build-stream-bridge.js +53 -0
- package/server/cc-session-watcher.js +4 -1
- package/server/coalescing-buffer.js +7 -1
- package/server/completion-projection.js +228 -0
- package/server/compose-mcp-tools.js +124 -24
- package/server/compose-mcp.js +91 -790
- package/server/decision-event-emit.js +41 -2
- package/server/decision-event-id.js +17 -0
- package/server/decision-events-snapshot.js +3 -0
- package/server/design-routes.js +14 -8
- package/server/feature-scan.js +76 -2
- package/server/file-watcher.js +170 -21
- package/server/ideabox-routes.js +166 -224
- package/server/index.js +70 -100
- package/server/lifecycle-guard.js +240 -10
- package/server/lifecycle-phase-history.js +276 -0
- package/server/maya-routes.js +507 -0
- package/server/mcp-tool-defs.js +940 -0
- package/server/mcp-tool-policy.js +35 -3
- package/server/model-tiers.js +22 -5
- package/server/pipeline-routes.js +21 -11
- package/server/project-root.js +58 -19
- package/server/remote-utils.js +3 -1
- package/server/schema-validator.js +7 -1
- package/server/session-manager.js +5 -6
- package/server/session-routes.js +3 -1
- package/server/stratum-client.js +57 -10
- package/server/stratum-sync.js +6 -3
- package/server/summarizer.js +3 -4
- package/server/supervisor.js +0 -1
- package/server/vision-routes.js +208 -98
- package/server/vision-server.js +86 -23
- package/server/vision-store.js +60 -6
- package/server/vision-utils.js +3 -4
- package/server/workspace-activity.js +18 -0
- package/server/workspace-middleware.js +2 -2
- package/server/workspace-runtime.js +243 -0
- package/server/worktree-gc.js +1 -0
- package/dist/assets/App-BG3ngu8H.js +0 -896
- package/dist/assets/abnfDiagram-VRR7QNED-CjB_sD3D.js +0 -1
- package/dist/assets/arc-_v4hR_uD.js +0 -1
- package/dist/assets/architectureDiagram-ZJ3FMSHR-DreJmzXQ.js +0 -36
- package/dist/assets/blockDiagram-677ZJIJ3-BG9-c0O1.js +0 -132
- package/dist/assets/channel-B3U5wFAT.js +0 -1
- package/dist/assets/chunk-EX3LRPZG-DdELs1qP.js +0 -231
- package/dist/assets/chunk-MOJQB5TN-D-ky35G-.js +0 -88
- package/dist/assets/chunk-RYQCIY6F-Dag_kVlO.js +0 -1
- package/dist/assets/chunk-V7JOEXUC-BtewURat.js +0 -206
- package/dist/assets/classDiagram-OUVF2IWQ-B6fCN-ht.js +0 -1
- package/dist/assets/classDiagram-v2-EOCWNBFH-B6fCN-ht.js +0 -1
- package/dist/assets/cynefin-VYW2F7L2-CT2BA6KE.js +0 -178
- package/dist/assets/cynefinDiagram-TSTJHNR4-Bh6exbyg.js +0 -62
- package/dist/assets/dagre-VKFMJZFB-aXMLSmQL.js +0 -4
- package/dist/assets/diagram-FQU43EPY-Dr7JAOuQ.js +0 -3
- package/dist/assets/diagram-G47NLZAW-DUvA3FQK.js +0 -24
- package/dist/assets/diagram-NH7WQ7WH-BQUARqcu.js +0 -24
- package/dist/assets/diagram-OA4YK3LP-dDUc1zHi.js +0 -30
- package/dist/assets/diagram-WEI45ONY-B2h5Qlb1.js +0 -41
- package/dist/assets/ebnfDiagram-CCIWWBDH-DThRGupB.js +0 -1
- package/dist/assets/erDiagram-Q63AITRT-BUCsprO2.js +0 -85
- package/dist/assets/flowDiagram-23GEKE2U-DXtNNi6r.js +0 -156
- package/dist/assets/ganttDiagram-NO4QXBWP-D4zbBHh_.js +0 -292
- package/dist/assets/gitGraphDiagram-IHSO6WYX-DpoQws0W.js +0 -106
- package/dist/assets/graph-BXPQrYYB.js +0 -331
- package/dist/assets/graph-C9eacEi8.js +0 -1
- package/dist/assets/index-3ZH5eMcZ.js +0 -119
- package/dist/assets/index-LIwREYgH.css +0 -1
- package/dist/assets/infoDiagram-FWYZ7A6U-Bbas2GAo.js +0 -2
- package/dist/assets/katex-C5jXJg4s.js +0 -257
- package/dist/assets/layout-DEXfKzaS.js +0 -1
- package/dist/assets/map-Czzmt4hB.js +0 -1
- package/dist/assets/mobile-CaoXUwAr.js +0 -17
- package/dist/assets/pegDiagram-2B236MQR-CHiINrNy.js +0 -1
- package/dist/assets/pieDiagram-ENE6RG2P-CfS4YFlR.js +0 -39
- package/dist/assets/quadrantDiagram-ABIIQ3AL-CadesS9w.js +0 -7
- package/dist/assets/railroadDiagram-RFXS5EU6-CgWEspBN.js +0 -1
- package/dist/assets/sankeyDiagram-HTMAVEWB-YWKFgOGw.js +0 -40
- package/dist/assets/sequenceDiagram-DBY2YBRQ-BvkNOyF9.js +0 -162
- package/dist/assets/sizeCapture-X5ZJPWSS-DlFPA2yO.js +0 -1
- package/dist/assets/stateDiagram-2N3HPSRC-h8NIx0kQ.js +0 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-DjPgZtJ9.js +0 -1
- package/dist/assets/swimlanes-5IMT3BWC-CT5n22kG.js +0 -2
- package/dist/assets/swimlanesDiagram-G3AALYLV-Dn318Bhq.js +0 -8
- package/dist/assets/vennDiagram-L72KCM5P-Dj-wWLYG.js +0 -34
- package/dist/assets/wardleyDiagram-EHGQE667-BxCeYxkG.js +0 -78
- package/dist/assets/xychartDiagram-FW5EYKEG-DMFqWn7z.js +0 -7
- package/lib/staleness.js +0 -87
- package/server/ideabox-cache.js +0 -77
|
@@ -48,3 +48,57 @@ export function resolveProjectTag(cwd) {
|
|
|
48
48
|
export function sourcePathFor(projectTag, repoRel) {
|
|
49
49
|
return `compose/${projectTag}/${repoRel}`;
|
|
50
50
|
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* GOV-COMPOSE-SEAM-1 step 0 (`plumbing`).
|
|
54
|
+
*
|
|
55
|
+
* Translate the `smartmemory` config block into the three env vars Stratum's
|
|
56
|
+
* policy client reads, so Compose's ingest events and Stratum's enforcement
|
|
57
|
+
* events land in ONE workspace instead of two (or, today, one and nowhere).
|
|
58
|
+
*
|
|
59
|
+
* Two traps this function exists to close:
|
|
60
|
+
*
|
|
61
|
+
* 1. `workspaceId` is two different things. Top-level `compose.json#workspaceId`
|
|
62
|
+
* is a Compose PROJECT SLUG (`^[a-z][a-z0-9-]{1,63}$`, see
|
|
63
|
+
* discover-workspaces.js) used for provenance tagging. The SmartMemory
|
|
64
|
+
* workspace id lives at `smartmemory.workspaceId` and looks like
|
|
65
|
+
* `team_26f0bbe60a4c`. Sending the slug as `X-Workspace-Id` scopes every
|
|
66
|
+
* event to a workspace that does not exist, and the API answers 200, so the
|
|
67
|
+
* failure is silent. This reads the block, never the top level.
|
|
68
|
+
* 2. Stratum's `SmartMemoryClient` reads `process.env` ONCE at construction
|
|
69
|
+
* (policy/smartmemory_client.ts). Setting these after the MCP subprocess
|
|
70
|
+
* starts is a no-op — they must be in the spawn env, which is why this
|
|
71
|
+
* returns a plain object for `connect()` to merge rather than mutating
|
|
72
|
+
* `process.env`.
|
|
73
|
+
*
|
|
74
|
+
* Fail-quiet by design, matching the existing fail-open ingest contract: an
|
|
75
|
+
* unconfigured, disabled, or half-configured workspace returns `{}` and Stratum
|
|
76
|
+
* simply runs without policy delivery (it warns once on its own). A partial env
|
|
77
|
+
* would be worse than none — it produces events addressed to nowhere.
|
|
78
|
+
*
|
|
79
|
+
* @param {string} cwd
|
|
80
|
+
* @returns {{SMARTMEMORY_API_URL?: string, SMARTMEMORY_API_KEY?: string, SMARTMEMORY_WORKSPACE_ID?: string}}
|
|
81
|
+
*/
|
|
82
|
+
export function resolveStratumPolicyEnv(cwd) {
|
|
83
|
+
let cfg;
|
|
84
|
+
try {
|
|
85
|
+
cfg = getSmartmemoryConfig(cwd);
|
|
86
|
+
} catch {
|
|
87
|
+
return {};
|
|
88
|
+
}
|
|
89
|
+
if (cfg.enabled !== true) return {};
|
|
90
|
+
|
|
91
|
+
const baseUrl = typeof cfg.baseUrl === 'string' ? cfg.baseUrl.trim() : '';
|
|
92
|
+
// NEVER cfg.workspaceId's top-level namesake — see trap 1 above.
|
|
93
|
+
const workspaceId = typeof cfg.workspaceId === 'string' ? cfg.workspaceId.trim() : '';
|
|
94
|
+
const apiKey = cfg.apiKeyEnv ? process.env[cfg.apiKeyEnv] : undefined;
|
|
95
|
+
|
|
96
|
+
// All three or nothing.
|
|
97
|
+
if (!baseUrl || !workspaceId || !apiKey) return {};
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
SMARTMEMORY_API_URL: baseUrl,
|
|
101
|
+
SMARTMEMORY_API_KEY: apiKey,
|
|
102
|
+
SMARTMEMORY_WORKSPACE_ID: workspaceId,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
@@ -26,9 +26,23 @@ export function renderFeatureEventContent(row, projectTag) {
|
|
|
26
26
|
return `[compose:${projectTag}] ${row.ts} ${row.tool} ${row.code ?? row.feature_code ?? '-'} by ${row.actor ?? 'mcp:agent'}`;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
/** PURE. One deterministic line per gate-log entry. Shared with sync.
|
|
29
|
+
/** PURE. One deterministic line per gate-log entry. Shared with sync.
|
|
30
|
+
*
|
|
31
|
+
* GOV-COMPOSE-SEAM-1 step 0 (F2): this is a **Vision UI product gate** — a
|
|
32
|
+
* human approving a feature in the Compose UI, keyed by the UI gate id and a
|
|
33
|
+
* feature code. It is NOT Stratum's `gate_resolution`, which is a flow-step
|
|
34
|
+
* gate keyed by `run_id`/`step_id` and emitted by the engine when a run carries
|
|
35
|
+
* a policy bundle. The design assumed these were two records of one event and
|
|
36
|
+
* called for deduping them by `run_id`; they are two events, and no Stratum
|
|
37
|
+
* run id exists at this call site (see gate-log-store.js). Deduping them would
|
|
38
|
+
* have destroyed a real record.
|
|
39
|
+
*
|
|
40
|
+
* So they are disambiguated instead of merged: this line is tagged
|
|
41
|
+
* `vision-gate` rather than the bare `gate`, so a workspace query can separate
|
|
42
|
+
* product approvals from enforcement gates without guessing from shape.
|
|
43
|
+
*/
|
|
30
44
|
export function renderGateLogContent(entry, projectTag) {
|
|
31
|
-
return `[compose:${projectTag}] ${entry.timestamp} gate:${entry.decision} ${entry.feature_code ?? '-'} ${entry.id}`;
|
|
45
|
+
return `[compose:${projectTag}] ${entry.timestamp} vision-gate:${entry.decision} ${entry.feature_code ?? '-'} ${entry.id}`;
|
|
32
46
|
}
|
|
33
47
|
|
|
34
48
|
/** PURE. context for an event item (cli:compose regime — content-hash dedupe). */
|
|
@@ -45,6 +59,9 @@ export function buildGateLogContext(projectTag, entry) {
|
|
|
45
59
|
return {
|
|
46
60
|
origin: 'cli:compose',
|
|
47
61
|
project: projectTag,
|
|
62
|
+
// Explicit record kind so a Compose product-gate approval is never mistaken
|
|
63
|
+
// for a Stratum enforcement `gate_resolution`. See renderGateLogContent.
|
|
64
|
+
record_kind: 'compose_vision_gate',
|
|
48
65
|
source_path: sourcePathFor(projectTag, '.compose/data/gate-log.jsonl'),
|
|
49
66
|
event: entry,
|
|
50
67
|
};
|
package/lib/step-prompt.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { readdirSync, readFileSync, existsSync } from 'node:fs';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
|
-
import {
|
|
7
|
+
import { findStaleArtifacts } from './lineage.js';
|
|
8
8
|
import { readHypotheses, formatRejectedHypotheses } from './bug-ledger.js';
|
|
9
9
|
|
|
10
10
|
// ---------------------------------------------------------------------------
|
|
@@ -242,13 +242,14 @@ export function buildGateContext(gateDispatch, context, gateExtras) {
|
|
|
242
242
|
sections.push(`## Files Changed by This Feature\n${context.filesChanged.map(f => '- ' + f).join('\n')}`);
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
-
// Staleness warnings — flag artifacts
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
245
|
+
// Staleness warnings — derivation-based (COMP-PROV-LINEAGE): flag artifacts
|
|
246
|
+
// whose upstream (wasDerivedFrom) changed more recently than they did. Phase-
|
|
247
|
+
// independent, so it does not need gateExtras.toPhase.
|
|
248
|
+
if (context.featureDir) {
|
|
249
|
+
const stale = findStaleArtifacts(context.featureDir).filter(a => a.stale);
|
|
249
250
|
if (stale.length > 0) {
|
|
250
251
|
const lines = stale.map(a =>
|
|
251
|
-
`- **${a.file}**
|
|
252
|
+
`- **${a.file}** may be outdated — an upstream it was derived from (${a.staleAgainst.join(', ')}) changed more recently`
|
|
252
253
|
);
|
|
253
254
|
sections.push(`## Stale Artifacts\nThe following artifacts may be outdated:\n${lines.join('\n')}`);
|
|
254
255
|
}
|
package/lib/stratum-engine.js
CHANGED
|
@@ -137,6 +137,46 @@ const BIN_CONFIG = {
|
|
|
137
137
|
},
|
|
138
138
|
};
|
|
139
139
|
|
|
140
|
+
// Sibling checkout's package.json — used only to tell the user when the
|
|
141
|
+
// installed dependency is shadowing a checkout at a different version.
|
|
142
|
+
export const LIVE_STRATUM_TS_PACKAGE_JSON = resolve(
|
|
143
|
+
__dirname, '..', '..', 'stratum', 'ts', 'package.json',
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
function readPackageVersion(packageJsonPath) {
|
|
147
|
+
try {
|
|
148
|
+
const version = JSON.parse(readFileSync(packageJsonPath, 'utf8'))?.version;
|
|
149
|
+
return typeof version === 'string' ? version : undefined;
|
|
150
|
+
} catch {
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// One warning per (kind, paths, versions) per process: the resolver runs on every connect.
|
|
156
|
+
const shadowWarned = new Set();
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* The installed dependency wins over the sibling checkout by design (CI has no
|
|
160
|
+
* sibling). In the monorepo that silently runs a STALE stratum after a local
|
|
161
|
+
* rebuild — found 2026-08-30 when the STRAT-LEARN-COST census ran against
|
|
162
|
+
* 0.3.3 (no `stratum_usage_report`) while `stratum/ts` was at 0.3.4. Say so
|
|
163
|
+
* once, with the escape hatch, whenever the two versions differ.
|
|
164
|
+
*/
|
|
165
|
+
function warnIfSiblingShadowed(kind, envVar, installedPackageJsonPath, siblingPackageJsonPath, warn) {
|
|
166
|
+
if (!siblingPackageJsonPath || !existsSync(siblingPackageJsonPath)) return;
|
|
167
|
+
const installedVersion = readPackageVersion(installedPackageJsonPath);
|
|
168
|
+
const siblingVersion = readPackageVersion(siblingPackageJsonPath);
|
|
169
|
+
if (!installedVersion || !siblingVersion || installedVersion === siblingVersion) return;
|
|
170
|
+
const key = `${kind}|${installedPackageJsonPath}|${siblingPackageJsonPath}|${installedVersion}|${siblingVersion}`;
|
|
171
|
+
if (shadowWarned.has(key)) return;
|
|
172
|
+
shadowWarned.add(key);
|
|
173
|
+
warn(
|
|
174
|
+
`[stratum-engine] using installed @smartmemory/stratum ${installedVersion}; `
|
|
175
|
+
+ `the sibling checkout at ${dirname(siblingPackageJsonPath)} is ${siblingVersion} and is NOT what compose runs. `
|
|
176
|
+
+ `Set ${envVar} to run a rebuilt checkout (${kind === 'mcp' ? 'dist/mcp/main.js' : 'dist/cli/stratum.js'}).`,
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
140
180
|
/** Resolve a bin from an installed @smartmemory/stratum package, if present. */
|
|
141
181
|
function resolveInstalledBin(packageBin, requireResolve) {
|
|
142
182
|
let packageJsonPath;
|
|
@@ -156,7 +196,7 @@ function resolveInstalledBin(packageBin, requireResolve) {
|
|
|
156
196
|
? packageJson.bin?.[packageBin]
|
|
157
197
|
: undefined;
|
|
158
198
|
if (typeof relativeBin !== 'string') return undefined;
|
|
159
|
-
return resolve(dirname(packageJsonPath), relativeBin);
|
|
199
|
+
return { bin: resolve(dirname(packageJsonPath), relativeBin), packageJsonPath };
|
|
160
200
|
} catch {
|
|
161
201
|
return undefined;
|
|
162
202
|
}
|
|
@@ -168,7 +208,7 @@ function resolveInstalledBin(packageBin, requireResolve) {
|
|
|
168
208
|
*
|
|
169
209
|
* @param {'mcp'|'cli'} kind
|
|
170
210
|
* @param {string} [cwd]
|
|
171
|
-
* @param {{env?: object, requireResolve?: Function, siblingBins?: object}} [deps]
|
|
211
|
+
* @param {{env?: object, requireResolve?: Function, siblingBins?: object, siblingPackageJson?: string, warn?: Function}} [deps]
|
|
172
212
|
*/
|
|
173
213
|
export function resolveStratumBin(kind, cwd = process.cwd(), deps = {}) {
|
|
174
214
|
const config = BIN_CONFIG[kind];
|
|
@@ -180,11 +220,20 @@ export function resolveStratumBin(kind, cwd = process.cwd(), deps = {}) {
|
|
|
180
220
|
|| (kind === 'cli' ? env.COMPOSE_STRATUM_TS_BIN : undefined);
|
|
181
221
|
if (envCandidate && existsSync(envCandidate)) return envCandidate;
|
|
182
222
|
|
|
183
|
-
const
|
|
223
|
+
const installed = resolveInstalledBin(
|
|
184
224
|
config.packageBin,
|
|
185
225
|
deps.requireResolve ?? require.resolve.bind(require),
|
|
186
226
|
);
|
|
187
|
-
if (
|
|
227
|
+
if (installed && existsSync(installed.bin)) {
|
|
228
|
+
warnIfSiblingShadowed(
|
|
229
|
+
kind,
|
|
230
|
+
config.env,
|
|
231
|
+
installed.packageJsonPath,
|
|
232
|
+
deps.siblingPackageJson ?? LIVE_STRATUM_TS_PACKAGE_JSON,
|
|
233
|
+
deps.warn ?? ((message) => console.warn(message)),
|
|
234
|
+
);
|
|
235
|
+
return installed.bin;
|
|
236
|
+
}
|
|
188
237
|
|
|
189
238
|
const siblingCandidate = deps.siblingBins?.[kind] ?? config.sibling;
|
|
190
239
|
if (siblingCandidate && existsSync(siblingCandidate)) return siblingCandidate;
|