@smartmemory/compose 0.1.38-beta → 0.1.40-beta

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 (62) hide show
  1. package/bin/compose.js +3 -1
  2. package/bin/git-hooks/pre-push.template +8 -0
  3. package/contracts/feature-json.schema.json +54 -4
  4. package/contracts/judge-result.json +27 -4
  5. package/dist/assets/{App-BOmZUQK9.js → App-DAlZEv-O.js} +163 -163
  6. package/dist/assets/{arc-BFMYxU8d.js → arc-CJH3_faQ.js} +1 -1
  7. package/dist/assets/{architectureDiagram-3BPJPVTR-Dr1TLm4n.js → architectureDiagram-3BPJPVTR-CcbjDL0X.js} +1 -1
  8. package/dist/assets/{blockDiagram-GPEHLZMM-DfiOIWI5.js → blockDiagram-GPEHLZMM-CUfnQl0d.js} +1 -1
  9. package/dist/assets/{c4Diagram-AAUBKEIU-CWZPV6Gi.js → c4Diagram-AAUBKEIU-BmyI1ykb.js} +1 -1
  10. package/dist/assets/channel-ZbvrEgVw.js +1 -0
  11. package/dist/assets/{chunk-2J33WTMH-DsfEX96t.js → chunk-2J33WTMH-BBqApkEh.js} +1 -1
  12. package/dist/assets/{chunk-4BX2VUAB-BYmdEdqH.js → chunk-4BX2VUAB-CH3WPC9v.js} +1 -1
  13. package/dist/assets/{chunk-55IACEB6-C074eKNZ.js → chunk-55IACEB6-DSF1sU8o.js} +1 -1
  14. package/dist/assets/{chunk-727SXJPM-rxaajQx0.js → chunk-727SXJPM-HjTVn9xp.js} +1 -1
  15. package/dist/assets/{chunk-AQP2D5EJ-Cg6-5M28.js → chunk-AQP2D5EJ-C2ZGpxjS.js} +1 -1
  16. package/dist/assets/{chunk-FMBD7UC4-FSbyjfSh.js → chunk-FMBD7UC4-CCfvaMbx.js} +1 -1
  17. package/dist/assets/{chunk-ND2GUHAM-DhD_mt3D.js → chunk-ND2GUHAM-Ke_5zZ4E.js} +1 -1
  18. package/dist/assets/{chunk-QZHKN3VN-LMU-D6pF.js → chunk-QZHKN3VN-D_3X_vH5.js} +1 -1
  19. package/dist/assets/classDiagram-4FO5ZUOK-CIpDpiGU.js +1 -0
  20. package/dist/assets/classDiagram-v2-Q7XG4LA2-CIpDpiGU.js +1 -0
  21. package/dist/assets/{cose-bilkent-S5V4N54A-CknvjYWn.js → cose-bilkent-S5V4N54A-BavWz_Ts.js} +1 -1
  22. package/dist/assets/{dagre-BM42HDAG-BWNVctIO.js → dagre-BM42HDAG-CJN2rIrd.js} +1 -1
  23. package/dist/assets/{diagram-2AECGRRQ-DhPeu8mD.js → diagram-2AECGRRQ-DFSD9lyx.js} +1 -1
  24. package/dist/assets/{diagram-5GNKFQAL-B8e2ppCQ.js → diagram-5GNKFQAL-B2Iz6xSI.js} +1 -1
  25. package/dist/assets/{diagram-KO2AKTUF-CJ2bkC5P.js → diagram-KO2AKTUF-BF77NHeO.js} +1 -1
  26. package/dist/assets/{diagram-LMA3HP47-CCyEuSkM.js → diagram-LMA3HP47-B9rERFCD.js} +1 -1
  27. package/dist/assets/{diagram-OG6HWLK6-CDe7c8Ym.js → diagram-OG6HWLK6-CIS_DZW7.js} +1 -1
  28. package/dist/assets/{erDiagram-TEJ5UH35-BDTpNyUZ.js → erDiagram-TEJ5UH35-BubvCPWm.js} +1 -1
  29. package/dist/assets/{flowDiagram-I6XJVG4X-CSEQ9sFL.js → flowDiagram-I6XJVG4X-CVjDg-md.js} +1 -1
  30. package/dist/assets/{ganttDiagram-6RSMTGT7-CJI3ZQCl.js → ganttDiagram-6RSMTGT7-rdIEkSjo.js} +1 -1
  31. package/dist/assets/{gitGraphDiagram-PVQCEYII-BmIOl3oN.js → gitGraphDiagram-PVQCEYII-Bv7mceGn.js} +1 -1
  32. package/dist/assets/{index-DHyg44Px.js → index-BPSrV_ie.js} +2 -2
  33. package/dist/assets/{infoDiagram-5YYISTIA-BiJXa7xo.js → infoDiagram-5YYISTIA-BhwEnN8y.js} +1 -1
  34. package/dist/assets/{ishikawaDiagram-YF4QCWOH-D2S-R9bH.js → ishikawaDiagram-YF4QCWOH-Bc3cYCKN.js} +1 -1
  35. package/dist/assets/{journeyDiagram-JHISSGLW-Dk6NJYdI.js → journeyDiagram-JHISSGLW-DA82WE4d.js} +1 -1
  36. package/dist/assets/{kanban-definition-UN3LZRKU-DrTme_f5.js → kanban-definition-UN3LZRKU-CS3ptTQL.js} +1 -1
  37. package/dist/assets/{linear-DAL46yON.js → linear-VVoHRBmK.js} +1 -1
  38. package/dist/assets/{mindmap-definition-RKZ34NQL-lzCtbkrz.js → mindmap-definition-RKZ34NQL-Dx93Nhkp.js} +1 -1
  39. package/dist/assets/{pieDiagram-4H26LBE5-BGGc2f7U.js → pieDiagram-4H26LBE5-CO107nas.js} +1 -1
  40. package/dist/assets/{quadrantDiagram-W4KKPZXB-DN8kBgF9.js → quadrantDiagram-W4KKPZXB-CrMXIHGP.js} +1 -1
  41. package/dist/assets/{requirementDiagram-4Y6WPE33-CqTXzyF-.js → requirementDiagram-4Y6WPE33-Jhy0JAv1.js} +1 -1
  42. package/dist/assets/{sankeyDiagram-5OEKKPKP-l5oIrkxp.js → sankeyDiagram-5OEKKPKP-Byqar1oo.js} +1 -1
  43. package/dist/assets/{sequenceDiagram-3UESZ5HK-B5mMGwpr.js → sequenceDiagram-3UESZ5HK-BXn-Yp_S.js} +1 -1
  44. package/dist/assets/{stateDiagram-AJRCARHV-B8yZRkdR.js → stateDiagram-AJRCARHV-BsH4tWQo.js} +1 -1
  45. package/dist/assets/stateDiagram-v2-BHNVJYJU-CW-BZJp6.js +1 -0
  46. package/dist/assets/{timeline-definition-PNZ67QCA-uc4a9RNG.js → timeline-definition-PNZ67QCA-RaJbKHNh.js} +1 -1
  47. package/dist/assets/{vennDiagram-CIIHVFJN-Dxp9IL4U.js → vennDiagram-CIIHVFJN-Cq50SepU.js} +1 -1
  48. package/dist/assets/{wardley-L42UT6IY-1u4vjxUt.js → wardley-L42UT6IY-CfLD0dlo.js} +1 -1
  49. package/dist/assets/{wardleyDiagram-YWT4CUSO-DWpWWd1b.js → wardleyDiagram-YWT4CUSO-O_yLrImv.js} +1 -1
  50. package/dist/assets/{xychartDiagram-2RQKCTM6-Cpcj31O3.js → xychartDiagram-2RQKCTM6-DnL9O2jh.js} +1 -1
  51. package/dist/index.html +1 -1
  52. package/lib/feature-validator.js +373 -3
  53. package/lib/feature-writer.js +158 -1
  54. package/lib/tracker/github-api.js +8 -1
  55. package/lib/xref-citation.js +235 -0
  56. package/package.json +1 -1
  57. package/server/compose-mcp-tools.js +2 -1
  58. package/server/compose-mcp.js +11 -5
  59. package/dist/assets/channel-GvJclmQg.js +0 -1
  60. package/dist/assets/classDiagram-4FO5ZUOK-DV6SPGMl.js +0 -1
  61. package/dist/assets/classDiagram-v2-Q7XG4LA2-DV6SPGMl.js +0 -1
  62. package/dist/assets/stateDiagram-v2-BHNVJYJU-BK-1uf4O.js +0 -1
package/bin/compose.js CHANGED
@@ -1589,6 +1589,7 @@ if (cmd === 'validate') {
1589
1589
  let code = null
1590
1590
  let blockOn = 'error'
1591
1591
  let asJson = false
1592
+ let externalXref = false
1592
1593
  for (let i = 0; i < args.length; i++) {
1593
1594
  const a = args[i]
1594
1595
  if (a === '--help' || a === '-h') {
@@ -1608,6 +1609,7 @@ Exit codes:
1608
1609
  process.exit(0)
1609
1610
  }
1610
1611
  if (a === '--json') { asJson = true; continue }
1612
+ if (a === '--external') { externalXref = true; continue }
1611
1613
  if (a.startsWith('--scope=')) scope = a.slice('--scope='.length)
1612
1614
  else if (a === '--scope') scope = args[++i]
1613
1615
  else if (a.startsWith('--code=')) code = a.slice('--code='.length)
@@ -1638,7 +1640,7 @@ Exit codes:
1638
1640
  try {
1639
1641
  result = scope === 'feature'
1640
1642
  ? await validateFeature(valCwd, code)
1641
- : await validateProject(valCwd)
1643
+ : await validateProject(valCwd, { external: externalXref })
1642
1644
  } catch (err) {
1643
1645
  if (err.code === 'INVALID_INPUT') {
1644
1646
  console.error(`Error [INVALID_INPUT]: ${err.message}`)
@@ -2,6 +2,14 @@
2
2
  # Compose pre-push hook — runs `compose validate` and blocks the push on
3
3
  # any error-severity drift finding. Installed by `compose hooks install --pre-push`;
4
4
  # placeholders below are substituted at install time.
5
+ #
6
+ # External-reference (xref) resolution is OFF here by default: github xref:
7
+ # citations / kind:"external" links emit XREF_RESOLUTION_SKIPPED (warning,
8
+ # non-blocking under --block-on=error) while local/url/malformed still
9
+ # surface. Opt in to network github resolution by exporting
10
+ # COMPOSE_XREF_ONLINE=1, or set `xref.prePushOnline: true` in
11
+ # .compose/compose.json — both are honored by `compose validate` directly
12
+ # (no flag change needed below). XREF_TARGET_MISSING stays error and blocks.
5
13
 
6
14
  set -u
7
15
  COMPOSE_NODE="__COMPOSE_NODE__"
@@ -68,12 +68,62 @@
68
68
  "type": "array",
69
69
  "items": {
70
70
  "type": "object",
71
- "required": ["kind", "to_code"],
72
71
  "properties": {
73
- "kind": { "type": "string", "enum": ["surfaced_by", "blocks", "depends_on", "follow_up", "supersedes", "related"] },
72
+ "kind": { "type": "string", "enum": ["surfaced_by", "blocks", "depends_on", "follow_up", "supersedes", "related", "external"] },
74
73
  "to_code": { "type": "string", "pattern": "^[A-Z][A-Z0-9-]*[A-Z0-9]$" },
75
- "note": { "type": "string" }
76
- }
74
+ "note": { "type": "string" },
75
+ "provider": { "type": "string", "enum": ["github", "local", "url", "jira", "linear", "notion", "obsidian"] },
76
+ "repo": { "type": "string" },
77
+ "issue": { "type": "integer", "minimum": 1 },
78
+ "url": { "type": "string", "pattern": "^[a-zA-Z][a-zA-Z0-9+\\-.]*://" },
79
+ "expect": { "type": "string" }
80
+ },
81
+ "allOf": [
82
+ {
83
+ "if": { "not": { "required": ["kind"], "properties": { "kind": { "const": "external" } } } },
84
+ "then": { "required": ["kind", "to_code"] }
85
+ },
86
+ {
87
+ "if": { "properties": { "kind": { "const": "external" } }, "required": ["kind"] },
88
+ "then": {
89
+ "required": ["provider"],
90
+ "allOf": [
91
+ {
92
+ "if": { "properties": { "provider": { "const": "github" } }, "required": ["provider"] },
93
+ "then": {
94
+ "required": ["repo", "issue"],
95
+ "properties": {
96
+ "repo": { "pattern": "^[^\\s/#]+/[^\\s/#]+$" },
97
+ "expect": { "enum": ["open", "closed"] }
98
+ }
99
+ }
100
+ },
101
+ {
102
+ "if": { "properties": { "provider": { "const": "local" } }, "required": ["provider"] },
103
+ "then": {
104
+ "required": ["repo", "to_code"],
105
+ "properties": {
106
+ "repo": {
107
+ "pattern": "^[A-Za-z0-9._-]+$",
108
+ "not": { "enum": [".", ".."] }
109
+ },
110
+ "expect": { "enum": ["PLANNED", "IN_PROGRESS", "PARTIAL", "COMPLETE", "SUPERSEDED", "PARKED", "BLOCKED", "KILLED"] }
111
+ }
112
+ }
113
+ },
114
+ {
115
+ "if": { "properties": { "provider": { "enum": ["url", "jira", "linear", "notion", "obsidian"] } }, "required": ["provider"] },
116
+ "then": {
117
+ "required": ["url"],
118
+ "properties": {
119
+ "url": { "type": "string", "pattern": "^[a-zA-Z][a-zA-Z0-9+\\-.]*://" }
120
+ }
121
+ }
122
+ }
123
+ ]
124
+ }
125
+ }
126
+ ]
77
127
  }
78
128
  },
79
129
  "completions": {
@@ -29,7 +29,7 @@
29
29
  },
30
30
  "stakes": {
31
31
  "enum": ["cheap", "default", "paranoid"],
32
- "description": "Depth class set by caller. v1: cheap (T1 only), default (T1+T2). paranoid raises StakesNotAvailableError until v2."
32
+ "description": "Depth class set by caller. cheap (T1 only), default (T1+T2). paranoid (T1+T2, then a T3 adversary over every interpretive 'met'). STRAT-JUDGE-T3-READJAIL: the paranoid T3 is now a true cross-model jailed Codex adversary (macOS sandbox-exec read-jail confining reads to the staged turn tree) when available, else an honest probe-time degrade to the v1 in-process Claude cold-read. Per-predicate provenance is in predicates[].t3."
33
33
  },
34
34
  "predicates": {
35
35
  "type": "array",
@@ -50,7 +50,7 @@
50
50
  "id": { "type": "string" },
51
51
  "type": {
52
52
  "enum": ["deterministic", "verified", "judged"],
53
- "description": "Predicate type sets the tier ceiling. deterministic = T1 only. verified = T2. judged = T3 in v2, downgraded to T2 in v1."
53
+ "description": "Predicate type sets the tier ceiling. deterministic = T1 only. verified = T2. judged = T2, plus T3 cold-read adversary when stakes=paranoid (else T2-terminal; judge_kernel_meta.degraded_judged flags judged predicates that got no adversary)."
54
54
  },
55
55
  "statement": { "type": "string" },
56
56
  "verdict": {
@@ -97,13 +97,36 @@
97
97
  "reason": { "type": "string" }
98
98
  }
99
99
  }
100
+ },
101
+ "t3": {
102
+ "type": ["object", "null"],
103
+ "description": "STRAT-JUDGE-T3-READJAIL. Populated ONLY when a T3 adversary was reached for this predicate (stakes='paranoid' AND T2='met'); null/absent means no adversary ran for this predicate (the absence is itself the honest signal). Descriptive of what actually ran, never intent. Authoritative T3 model identity is t3.model_id — top-level meta.model_id is the T1/T2 worker-lane identity only.",
104
+ "required": ["mode", "residual"],
105
+ "properties": {
106
+ "mode": {
107
+ "enum": ["codex_jailed", "codex_jailed_error", "claude_cold_fallback"],
108
+ "description": "codex_jailed: true cross-model Codex adversary, OS read-jailed (macOS sandbox-exec) to the staged turn tree. claude_cold_fallback: probe-time degrade to in-process Claude cold-read (no OS jail; reasoning-isolation+ordering only). codex_jailed_error: jailed adversary failed post-launch — predicate resolved ambiguous, error surfaced, NEVER silently relabeled fallback."
109
+ },
110
+ "guarantee": {
111
+ "type": ["string", "null"],
112
+ "description": "os_read_jail+cross_model | reasoning_isolation+ordering | null (error)."
113
+ },
114
+ "model_id": {
115
+ "type": ["string", "null"],
116
+ "description": "The actual model that ran T3 (authoritative for the adversary lane)."
117
+ },
118
+ "residual": {
119
+ "type": "string",
120
+ "description": "The accepted residual for this mode, verbatim from the design Problem statement. Never rounded up to 'confined'."
121
+ }
122
+ }
100
123
  }
101
124
  }
102
125
  }
103
126
  },
104
127
  "tier_disagreements": {
105
128
  "type": "array",
106
- "description": "Cross-tier disagreements within a single judge call. Empty in v1 (single-tier-per-predicate after T1). Reserved for v2+ T2/T3 quorum resolution.",
129
+ "description": "Cross-tier disagreements within a single judge call. Populated when stakes=paranoid and T3 contradicts a T2 'met' (resolved to 'ambiguous'; T4 quorum deferred). Empty for cheap/default.",
107
130
  "items": {
108
131
  "type": "object",
109
132
  "required": ["predicate", "tiers", "resolution"],
@@ -142,7 +165,7 @@
142
165
  },
143
166
  "degraded_judged": {
144
167
  "type": "boolean",
145
- "description": "True when a 'judged' predicate was downgraded to T2 because T3 is unavailable in v1."
168
+ "description": "True when a 'judged' predicate did not receive adversarial (T3) verification — i.e. stakes was cheap/default so T2 was terminal. False once T3 ran (stakes=paranoid)."
146
169
  }
147
170
  }
148
171
  }