@rse/ase 0.9.35 → 0.9.37

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/dst/ase-hook.js CHANGED
@@ -250,6 +250,11 @@ export default class HookCommand {
250
250
  const val = cfg.get("agent.persona");
251
251
  if (typeof val === "string")
252
252
  persona = val;
253
+ /* determine project boxing transparency */
254
+ let boxing = process.env.ASE_PROJECT_BOXING ?? "white";
255
+ const valBoxing = cfg.get("project.boxing");
256
+ if (typeof valBoxing === "string")
257
+ boxing = valBoxing;
253
258
  /* determine headless mode */
254
259
  const headless = (process.env.ASE_HEADLESS ?? "false") === "true" ? "true" : "false";
255
260
  /* provide ASE information to Anthropic Claude Code CLI shell commands
@@ -260,6 +265,7 @@ export default class HookCommand {
260
265
  `export ASE_PLUGIN_ROOT=${quote([pluginRoot])}\n` +
261
266
  `export ASE_USER_ID=${quote([userId])}\n` +
262
267
  `export ASE_PROJECT_ID=${quote([projectId])}\n` +
268
+ `export ASE_PROJECT_BOXING=${quote([boxing])}\n` +
263
269
  `export ASE_TASK_ID=${quote([taskId])}\n` +
264
270
  `export ASE_SESSION_ID=${quote([sessionId])}\n` +
265
271
  `export ASE_HEADLESS=${quote([headless])}\n` +
@@ -274,6 +280,7 @@ export default class HookCommand {
274
280
  `<ase-persona-style>${persona}</ase-persona-style>\n` +
275
281
  `<ase-user-id>${userId}</ase-user-id>\n` +
276
282
  `<ase-project-id>${projectId}</ase-project-id>\n` +
283
+ `<ase-project-boxing>${boxing}</ase-project-boxing>\n` +
277
284
  `<ase-task-id>${taskId}</ase-task-id>\n` +
278
285
  `<ase-session-id>${sessionId}</ase-session-id>\n` +
279
286
  `<ase-headless>${headless}</ase-headless>\n` +
@@ -289,7 +296,7 @@ export default class HookCommand {
289
296
  const banner = `\n⧉ ASE: ⎈ version: ${versionCurrentPlugin}${versionHint !== "" ? " " + versionHint.replaceAll(/\*/g, "") : ""}` +
290
297
  `\n⧉ ASE: ※ user: ${userId}, ⚑ project: ${projectId}` +
291
298
  `\n⧉ ASE: ◉ task: ${taskId}, ⏻ session: ${sessionId}` +
292
- `\n⧉ ASE: ☯ persona: ${persona}`;
299
+ `\n⧉ ASE: ☯ persona: ${persona}, ▢ boxing: ${boxing}`;
293
300
  /* inject markdown into session context.
294
301
  Anthropic Claude Code CLI and OpenAI Codex CLI expect the context nested in
295
302
  "hookSpecificOutput"; GitHub Copilot CLI expects a flat top-level
package/dst/ase-skills.js CHANGED
@@ -37,17 +37,19 @@ export class Skills {
37
37
  const time = pkg.time ?? {};
38
38
  const verEntry = version !== "" ? pkg.versions?.[version] : undefined;
39
39
  let repository = "";
40
+ let deps = "N.A.";
40
41
  if (verEntry !== undefined) {
41
42
  const r = verEntry.repository;
42
43
  if (typeof r === "string")
43
44
  repository = r;
44
45
  else if (r !== undefined && typeof r.url === "string")
45
46
  repository = r.url;
47
+ deps = Object.keys(verEntry.dependencies ?? {}).length;
46
48
  }
47
- return { version, time, repository };
49
+ return { version, time, repository, deps };
48
50
  }
49
51
  catch {
50
- return { version: "", time: {}, repository: "" };
52
+ return { version: "", time: {}, repository: "", deps: "N.A." };
51
53
  }
52
54
  }
53
55
  /* fetch GitHub stars given a repository URL (or empty string) */
@@ -83,7 +85,7 @@ export class Skills {
83
85
  static async fetchMavenInfo(coord) {
84
86
  const [groupId, artifactId] = coord.split(":", 2);
85
87
  if (groupId === undefined || artifactId === undefined || groupId === "" || artifactId === "")
86
- return { version: "", created: "", updated: "", repository: "" };
88
+ return { version: "", created: "", updated: "", repository: "", deps: "N.A." };
87
89
  try {
88
90
  const latest = await Skills.httpLimit(() => ofetch("https://search.maven.org/solrsearch/select" +
89
91
  `?q=g:%22${encodeURIComponent(groupId)}%22+AND+a:%22${encodeURIComponent(artifactId)}%22` +
@@ -113,6 +115,7 @@ export class Skills {
113
115
  }
114
116
  const created = typeof firstTs === "number" ? new Date(firstTs).toISOString() : updated;
115
117
  let repository = "";
118
+ let deps = "N.A.";
116
119
  if (version !== "") {
117
120
  try {
118
121
  const pom = await Skills.httpLimit(() => ofetch(`https://repo1.maven.org/maven2/${groupId.replace(/\./g, "/")}` +
@@ -126,16 +129,31 @@ export class Skills {
126
129
  if (url !== null)
127
130
  repository = url[1];
128
131
  }
132
+ /* count the `<dependency>` entries of the direct
133
+ `<dependencies>` block, skipping `test`/`provided`
134
+ scopes; a `<dependencyManagement>` block is ignored
135
+ as it only declares versions, not real dependencies */
136
+ const managed = /<dependencyManagement>[\s\S]*?<\/dependencyManagement>/gi;
137
+ const stripped = pom.replace(managed, "");
138
+ const depRe = /<dependency>([\s\S]*?)<\/dependency>/gi;
139
+ let count = 0;
140
+ let dep;
141
+ while ((dep = depRe.exec(stripped)) !== null) {
142
+ const scope = /<scope>\s*([^<\s]+)\s*<\/scope>/i.exec(dep[1]);
143
+ if (scope === null || (scope[1] !== "test" && scope[1] !== "provided"))
144
+ count++;
145
+ }
146
+ deps = count;
129
147
  }
130
148
  }
131
149
  catch {
132
150
  repository = "";
133
151
  }
134
152
  }
135
- return { version, created, updated, repository };
153
+ return { version, created, updated, repository, deps };
136
154
  }
137
155
  catch {
138
- return { version: "", created: "", updated: "", repository: "" };
156
+ return { version: "", created: "", updated: "", repository: "", deps: "N.A." };
139
157
  }
140
158
  }
141
159
  /* fetch the "Used By" count from `mvnrepository.com` as a downloads proxy
@@ -180,7 +198,7 @@ export class Skills {
180
198
  - "JavaScript"/"TypeScript": NPM registry (pacote) + GitHub stars + npm-downloads
181
199
  - "Java"/"Kotlin": Maven Central + GitHub stars + mvnrepository.com "Used By"
182
200
  - "Unknown": not supported -- return empty result */
183
- static async info(stack, components) {
201
+ static async info(stack, components, staleMonths = 18, smallScope = false) {
184
202
  if (stack === "JavaScript" || stack === "TypeScript") {
185
203
  /* per package: kick off packument and downloads in parallel,
186
204
  then stars as soon as the packument resolves; across packages
@@ -194,7 +212,7 @@ export class Skills {
194
212
  ]);
195
213
  const created = p.time.created ?? "";
196
214
  const updated = p.version !== "" ? (p.time[p.version] ?? "") : "";
197
- const rank = Skills.computeRank(downloads, stars, created, updated);
215
+ const rank = Skills.computeRank(downloads, stars, created, updated, p.deps, staleMonths, smallScope);
198
216
  return {
199
217
  name,
200
218
  version: p.version,
@@ -203,6 +221,7 @@ export class Skills {
203
221
  repository: p.repository,
204
222
  stars,
205
223
  downloads,
224
+ deps: p.deps,
206
225
  rank
207
226
  };
208
227
  }));
@@ -222,7 +241,7 @@ export class Skills {
222
241
  const [i, downloads, stars] = await Promise.all([
223
242
  infoPromise, downloadsPromise, starsPromise
224
243
  ]);
225
- const rank = Skills.computeRank(downloads, stars, i.created, i.updated);
244
+ const rank = Skills.computeRank(downloads, stars, i.created, i.updated, i.deps, staleMonths, smallScope);
226
245
  return {
227
246
  name,
228
247
  version: i.version,
@@ -231,6 +250,7 @@ export class Skills {
231
250
  repository: i.repository,
232
251
  stars,
233
252
  downloads,
253
+ deps: i.deps,
234
254
  rank
235
255
  };
236
256
  }));
@@ -253,7 +273,7 @@ export class Skills {
253
273
  is structurally unavailable, e.g. Maven Central exposes no
254
274
  per-artifact download counts) is likewise treated as neutral `1`, so
255
275
  such stacks can still be ranked by the remaining metrics. */
256
- static computeRank(downloads, stars, created, updated) {
276
+ static computeRank(downloads, stars, created, updated, deps, staleMonths, smallScope) {
257
277
  const d = typeof downloads === "number" ? downloads + 1 : 1;
258
278
  const s = typeof stars === "number" ? stars + 1 : 1;
259
279
  const cMs = created !== "" ? Date.parse(created) : NaN;
@@ -277,7 +297,31 @@ export class Skills {
277
297
  entry rankable without rewarding the missing date. */
278
298
  const lifespan = (!Number.isNaN(cMs) && !Number.isNaN(uMs)) ? Math.max(0, uMs - cMs) : 1;
279
299
  const recentness = !Number.isNaN(uMs) ? Math.exp(-Math.max(0, (now - uMs) / msPerDay) / halfLife) : 0.5;
280
- return d * s * lifespan * recentness;
300
+ let rank = d * s * lifespan * recentness;
301
+ /* hard, caller-tunable staleness penalty on top of the soft
302
+ `recentness` decay: unlike the smooth exp-decay above, this is a
303
+ two-tier *cliff* keyed off the `staleMonths` threshold. Past the
304
+ first tier (`staleMonths`) the rank is cut to `0.3x`, past the
305
+ second tier (`2 x staleMonths`, i.e. long abandoned) to `0.1x`.
306
+ A component below the first tier -- or one whose `updated` date
307
+ is unknown -- is left unpenalized. */
308
+ if (!Number.isNaN(uMs)) {
309
+ const ageMonths = (now - uMs) / msPerDay / 30;
310
+ if (ageMonths > 2 * staleMonths)
311
+ rank *= 0.1;
312
+ else if (ageMonths > staleMonths)
313
+ rank *= 0.3;
314
+ }
315
+ /* small-scope dependency-weight penalty: for a narrow, self-
316
+ contained need, dragging in a heavy dependency tree is usually
317
+ the wrong call, so each real component is demoted in proportion
318
+ to its own number of *direct* dependencies (`1 / (1 + deps)`).
319
+ A zero-dep component is left unpenalized; an unknown `deps` count
320
+ (`"N.A."`) is treated neutrally. This only applies when the
321
+ caller flags the need as small-scope. */
322
+ if (smallScope && typeof deps === "number")
323
+ rank *= 1 / (1 + deps);
324
+ return rank;
281
325
  }
282
326
  /* compute the per-alternative product-sum (rating) row from a
283
327
  weighted decision matrix. Each input row has the shape
@@ -318,20 +362,28 @@ export class SkillsMCP {
318
362
  "version + earliest/latest release timestamps from the Maven Central Solr " +
319
363
  "search endpoint, the SCM/project URL from the latest POM at `repo1.maven.org`, " +
320
364
  "GitHub stars (if applicable), and the \"Used By\" count from `mvnrepository.com` " +
321
- "as the `downloads` proxy. Returns a JSON `text` array of " +
322
- "`{ name, version, created, updated, repository, stars, downloads, rank }` " +
323
- "objects, sorted in descending order by `rank`. Failures of individual side " +
324
- "calls are isolated and reported as `\"N.A.\"` or empty string so every entry " +
325
- "has the full shape.",
365
+ "as the `downloads` proxy. The number of *direct* dependencies is read as `deps` " +
366
+ "(from the packument version entry for NPM, or the latest POM's `<dependencies>` " +
367
+ "block for Maven). Returns a JSON `text` array of " +
368
+ "`{ name, version, created, updated, repository, stars, downloads, deps, rank }` " +
369
+ "objects, sorted in descending order by `rank`. The `rank` applies a two-tier hard " +
370
+ "staleness penalty keyed off `staleMonths` (0.3x past the threshold, 0.1x past twice " +
371
+ "it) and, when `smallScope` is set, a dependency-weight penalty of `1/(1+deps)` so " +
372
+ "dependency-heavy components sink. Failures of individual side calls are isolated " +
373
+ "and reported as `\"N.A.\"` or empty string so every entry has the full shape.",
326
374
  inputSchema: {
327
375
  stack: z.string()
328
376
  .describe("Technology stack: \"JavaScript\", \"TypeScript\", \"Java\", \"Kotlin\", or \"Unknown\""),
329
377
  components: z.array(z.string())
330
- .describe("List of package names (NPM) or Maven coordinates `groupId:artifactId` (Java/Kotlin)")
378
+ .describe("List of package names (NPM) or Maven coordinates `groupId:artifactId` (Java/Kotlin)"),
379
+ staleMonths: z.number().optional()
380
+ .describe("Staleness threshold in months (default 18); a release older than this is rank-penalized"),
381
+ smallScope: z.boolean().optional()
382
+ .describe("If true, penalize each component by its direct-dependency count (small-scope need)")
331
383
  }
332
384
  }, async (args) => {
333
385
  try {
334
- const result = await Skills.info(args.stack, args.components);
386
+ const result = await Skills.info(args.stack, args.components, args.staleMonths, args.smallScope);
335
387
  return {
336
388
  content: [{ type: "text", text: JSON.stringify(result) }]
337
389
  };
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "homepage": "http://github.com/rse/ase",
7
7
  "repository": { "url": "git+https://github.com/rse/ase.git", "type": "git" },
8
8
  "bugs": { "url": "http://github.com/rse/ase/issues" },
9
- "version": "0.9.35",
9
+ "version": "0.9.37",
10
10
  "license": "Apache-2.0",
11
11
  "author": {
12
12
  "name": "Dr. Ralf S. Engelschall",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ase",
3
- "version": "0.9.35",
3
+ "version": "0.9.37",
4
4
  "description": "Agentic Software Engineering (ASE)",
5
5
  "keywords": [ "agentic", "software", "engineering" ],
6
6
  "homepage": "https://ase.tools",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ase",
3
- "version": "0.9.35",
3
+ "version": "0.9.37",
4
4
  "description": "Agentic Software Engineering (ASE)",
5
5
  "keywords": [ "agentic", "software", "engineering" ],
6
6
  "homepage": "https://ase.tools",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ase",
3
- "version": "0.9.35",
3
+ "version": "0.9.37",
4
4
  "description": "Agentic Software Engineering (ASE)",
5
5
  "keywords": [ "agentic", "software", "engineering" ],
6
6
  "homepage": "https://ase.tools",
@@ -16,7 +16,7 @@ any skill flow:
16
16
  ⧉ **ASE**: ⎈ version: **<ase-version/>** <ase-version-hint/>
17
17
  ⧉ **ASE**: ※ user: **<ase-user-id/>**, ⚑ project: **<ase-project-id/>**
18
18
  ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ⏻ session: **<ase-session-id/>**
19
- ⧉ **ASE**: ☯ persona: **<ase-persona-style/>**
19
+ ⧉ **ASE**: ☯ persona: **<ase-persona-style/>**, ▢ boxing: **<ase-project-boxing/>**
20
20
  </template>
21
21
 
22
22
  Prohibitions
@@ -243,6 +243,46 @@ Skill Identification
243
243
  steps at the end of a skill beside the explicit outputs via any
244
244
  <template/>.
245
245
 
246
+ Artifact Boxing Transparency
247
+ ----------------------------
248
+
249
+ - *IMPORTANT*: The *boxing* of a project (indicated by
250
+ <ase-project-boxing/> configuration) classifies how *transparent*
251
+ its *source artifacts* (specification, architecture, source code,
252
+ documentation, infrastructure, task plan, and other artifacts) are,
253
+ and thus how *deeply* you *MUST* inspect or produce them and how
254
+ *much* of their internals you *MUST* surface.
255
+
256
+ - *IMPORTANT*: Boxing modulates only the *work depth* (inspection and
257
+ production thoroughness) and the *output visibility* (surfaced
258
+ content and findings) of *artifact-touching* skills, per the three
259
+ lists below. It *MUST* *NOT* alter the *communication style*
260
+ (governed exclusively by the persona), and it *MUST* *NOT* apply to
261
+ skills that neither read, critique, nor write any project source
262
+ artifact.
263
+
264
+ - If <ase-project-boxing/> is `white`:
265
+ - Transparency: *fully*
266
+ - Work depth: inspect *fully*, produce *thoroughly*
267
+ - Findings surfaced: *all*
268
+ - Internals exposed: *full* (complete diffs, exhaustive rationale)
269
+
270
+ - If <ase-project-boxing/> is `grey`:
271
+ - Transparency: *partially*
272
+ - Work depth: inspect *significant* parts, produce *reasonably*
273
+ - Findings surfaced: *essentials*, summarize rest
274
+ - Internals exposed: *key* only (essential hunks, condensed rationale), summarize rest
275
+
276
+ - If <ase-project-boxing/> is `black`:
277
+ - Transparency: *none*
278
+ - Work depth: *minimum* work to satisfy the request
279
+ - Findings surfaced: *none* (report only the *outcome*)
280
+ - Internals exposed: *none* (no diffs, no code, no per-artifact explanation)
281
+
282
+ - *IMPORTANT*: Precedence rule: skill's *explicit* `black` branches
283
+ deterministically skip or suppress and *win* over the implicit decisions
284
+ above. Where no such branches exist, the decisions above apply.
285
+
246
286
  Template Patterns
247
287
  -----------------
248
288
 
@@ -360,3 +400,4 @@ Template Patterns
360
400
  clamped to zero so an over-long text never yields a negative count):
361
401
 
362
402
  <template><text/><ws/></template>
403
+
@@ -6,7 +6,7 @@
6
6
  "homepage": "http://github.com/rse/ase",
7
7
  "repository": { "url": "git+https://github.com/rse/ase.git", "type": "git" },
8
8
  "bugs": { "url": "http://github.com/rse/ase/issues" },
9
- "version": "0.9.35",
9
+ "version": "0.9.37",
10
10
  "license": "Apache-2.0",
11
11
  "author": {
12
12
  "name": "Dr. Ralf S. Engelschall",
@@ -121,6 +121,22 @@ interface quality, quality attributes, and architecture governance.
121
121
 
122
122
  <flow>
123
123
  1. <step id="STEP 1: Investigate Code Base">
124
+
125
+ <if condition="<ase-project-boxing/> is equal `black`">
126
+
127
+ The project source artifacts are classified as a *black box*, so
128
+ the user does *not* want the architecture inspected or its findings
129
+ surfaced. *Skip* the entire investigation and reporting: do *not*
130
+ invoke any `Agent` tool and do *not* read any source, only output
131
+ the following <template/> and then *SKIP* the remaining steps STEP 2
132
+ through STEP 4:
133
+
134
+ <template>
135
+ <ase-tpl-bullet-normal/> **ARCHITECTURE ANALYSIS**: *suppressed* (`project.boxing` is `black`)
136
+ </template>
137
+
138
+ </if>
139
+
124
140
  Investigate the code from an *architectural* perspective. If the
125
141
  code base is large, you *MUST* use the `Agent` tool (not inline
126
142
  work) to create multiple sub-agents to split the investigation
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ase-arch-discover
3
- argument-hint: "[--help|-h] [--limit|-l=12] <functionality>"
3
+ argument-hint: "[--help|-h] [--limit|-l=12] [--staleness|-s=18] [--small-scope|-S] <functionality>"
4
4
  description: >
5
5
  Discover additional, third-party components (libraries/frameworks) for
6
6
  the technology stack to provide needed functionality.
@@ -25,7 +25,7 @@ Discover Components
25
25
 
26
26
  <expand name="getopt"
27
27
  arg1="ase-arch-discover"
28
- arg2="--limit|-l=12">
28
+ arg2="--limit|-l=12 --staleness|-s=18 --small-scope|-S">
29
29
  $ARGUMENTS
30
30
  </expand>
31
31
 
@@ -166,18 +166,25 @@ for the technology stack to *provide* the *needed functionality*
166
166
  entries by Maven coordinate.
167
167
 
168
168
  6. Call the `ase_component_info(stack: "<stack/>", components:
169
- [ "<package-1/>", ..., "<package-C/>" ])` tool of the `ase` MCP
170
- server *once* for the entire candidate set of discovered packages.
171
- The tool dispatches internally on <stack/> and fetches all
172
- metadata in maximum parallel and returns an array of objects `{
173
- name, version, created, updated, repository, stars, downloads,
174
- rank }`. For each
175
- component <component-K/> (K=1-C) read from its corresponding
176
- entry: <version-K/> from `version`, <updated-K/> from `updated`,
177
- <created-K/> from `created`, <repository-K/> from `repository`,
178
- <stars-K/> from `stars` (numeric or `N.A.`), <downloads-K/>
179
- from `downloads` (numeric or `N.A.`) and <rank-K/> from `rank`
180
- (numeric).
169
+ [ "<package-1/>", ..., "<package-C/>" ], staleMonths:
170
+ <getopt-option-staleness/>, smallScope: <getopt-option-small-scope/>)`
171
+ tool of the `ase` MCP server *once* for the entire candidate set of
172
+ discovered packages. When the <getopt-option-small-scope/> option is
173
+ enabled, the ranking treats the <functionality/> as *small-scope*,
174
+ i.e. narrow, self-contained, and low-effort enough that a
175
+ *dependency-free/hand-rolled* implementation is a realistic
176
+ alternative to pulling in a third-party component. The tool
177
+ dispatches internally on <stack/>
178
+ and fetches all metadata in maximum parallel and returns an array
179
+ of objects `{ name, version, created, updated, repository, stars,
180
+ downloads, deps, rank }`. For each component <component-K/>
181
+ (K=1-C) read from its corresponding entry: <version-K/> from
182
+ `version`, <updated-K/> from `updated`, <created-K/> from
183
+ `created`, <repository-K/> from `repository`, <stars-K/> from
184
+ `stars` (numeric or `N.A.`), <downloads-K/> from `downloads`
185
+ (numeric or `N.A.`), <deps-K/> from `deps` (numeric or `N.A.`)
186
+ and <rank-K/> from `rank` (numeric). The returned `rank` already
187
+ reflects the staleness and small-scope dependency penalties.
181
188
 
182
189
  7. Sort, in descending order, the discovered candidate components
183
190
  <component-K/> (K=1-C) by their `rank` field and trim the result
@@ -192,7 +199,15 @@ for the technology stack to *provide* the *needed functionality*
192
199
  you should not stumble over) is its single most distinguishing
193
200
  perspective, and remember this as an <info-K/> (K=1-N) formatted
194
201
  like `<type/>: <hint/>` where <type/> is one of `USP`, `Crux`,
195
- or `Gotcha` and <hint/> is a 1-6 word hint. Do not output
202
+ or `Gotcha` and <hint/> is a 1-6 word hint.
203
+
204
+ *Staleness override*: determine the coarse age <age-K/> (like
205
+ `2y`) of the last release from <updated-K/>. If <updated-K/> is
206
+ known and its age exceeds *twice* <getopt-option-staleness/>
207
+ months, *append* to <info-K/> the hint `Gotcha: stale/abandoned
208
+ -- last release <age-K/> ago`; else if its age exceeds
209
+ <getopt-option-staleness/> months, *append* to <info-K/> the
210
+ hint `Gotcha: aging -- last release <age-K/> ago`. Do not output
196
211
  anything.
197
212
  </step>
198
213
 
@@ -217,11 +232,11 @@ for the technology stack to *provide* the *needed functionality*
217
232
  <template>
218
233
  <ase-tpl-bullet-normal/> **COMPONENT RANKING**:
219
234
 
220
- | ⚑ *Component* | ▣ *Package* | ❖ *Version* | ↓ *Downloads* | ⎈ *Stars* | ⏲ *Updated* | ☆ *Created* |
221
- | :------------ | :------------- | -----------: | -----------------: | -------------: | :--------------- | :----------- |
222
- | **<name-1/>** | `<package-1/>` | <version-1/> | **<downloads-1/>** | **<stars-1/>** | **<updated-1/>** | <created-1/> |
235
+ | ⚑ *Component* | ▣ *Package* | ❖ *Version* | ↓ *Downloads* | ⎈ *Stars* | ⏲ *Updated* | ☆ *Created* | ⚭ *Dep.* |
236
+ | :------------ | :------------- | -----------: | -----------------: | -------------: | :--------------- | :----------- | ---------: |
237
+ | **<name-1/>** | `<package-1/>` | <version-1/> | **<downloads-1/>** | **<stars-1/>** | **<updated-1/>** | <created-1/> | <deps-1/> |
223
238
  [...]
224
- | **<name-N/>** | `<package-N/>` | <version-N/> | **<downloads-N/>** | **<stars-N/>** | **<updated-N/>** | <created-N/> |
239
+ | **<name-N/>** | `<package-N/>` | <version-N/> | **<downloads-N/>** | **<stars-N/>** | **<updated-N/>** | <created-N/> | <deps-N/> |
225
240
  </template>
226
241
  </step>
227
242
  </flow>
@@ -8,6 +8,8 @@
8
8
  `ase-arch-discover`
9
9
  [`--help`|`-h`]
10
10
  [`--limit`|`-l=12`]
11
+ [`--staleness`|`-s=18`]
12
+ [`--small-scope`|`-S`]
11
13
  *functionality*
12
14
 
13
15
  ## DESCRIPTION
@@ -20,9 +22,13 @@ The skill determines the project's technology stack (TypeScript,
20
22
  JavaScript, Kotlin, or Java), derives essential keywords from the
21
23
  requested functionality, queries the corresponding package registry
22
24
  (NPM or Maven Central), retrieves metadata (version, downloads,
23
- stars, dates) via the `ase_component_info` MCP tool, and reports
24
- the top-ranked components as a Markdown table together with a single
25
- distinguishing hint (USP, Crux, or Gotcha) per component.
25
+ stars, dates, dependency count) via the `ase_component_info` MCP tool,
26
+ and reports the top-ranked components as a Markdown table together with
27
+ a single distinguishing hint (USP, Crux, or Gotcha) per component.
28
+
29
+ The ranking penalizes *stale* components (last release older than the
30
+ `--staleness` threshold) and, when the `--small-scope` option is given,
31
+ demotes dependency-heavy components.
26
32
 
27
33
  ## OPTIONS
28
34
 
@@ -31,6 +37,19 @@ distinguishing hint (USP, Crux, or Gotcha) per component.
31
37
  in the final ranking (default: 12). Raise it for a broader, more
32
38
  exhaustive survey, lower it for a quicker, narrower lookup.
33
39
 
40
+ `--staleness`|`-s=18`:
41
+ The *staleness threshold* in months (default: 18). A component whose
42
+ last release is older than this is rank-penalized and flagged with an
43
+ `aging` gotcha; older than *twice* the threshold, it is penalized
44
+ harder and flagged as `stale/abandoned`.
45
+
46
+ `--small-scope`|`-S`:
47
+ Treat the requested *functionality* as *small-scope* (default: off).
48
+ When enabled, the ranking demotes dependency-heavy components by a
49
+ dependency-weight penalty, since a dependency-free/hand-rolled
50
+ implementation is a realistic alternative for narrow, self-contained
51
+ functionality.
52
+
34
53
  ## ARGUMENTS
35
54
 
36
55
  *functionality*:
@@ -57,6 +76,12 @@ Discover a broader set of up to 20 HTTP client components:
57
76
  ❯ /ase-arch-discover --limit 20 HTTP client with retries
58
77
  ```
59
78
 
79
+ Discover HTTP clients, flagging any without a release in the last 12 months:
80
+
81
+ ```text
82
+ ❯ /ase-arch-discover --staleness 12 HTTP client with retries
83
+ ```
84
+
60
85
  ## SEE ALSO
61
86
 
62
87
  [`ase-arch-analyze`](../ase-arch-analyze/help.md), [`ase-meta-search`](../ase-meta-search/help.md), [`ase-meta-evaluate`](../ase-meta-evaluate/help.md).
@@ -54,6 +54,20 @@ problems in *performance* and *efficiency*, or problems in *security*.
54
54
 
55
55
  2. <step id="STEP 2: Investigate Code Base">
56
56
 
57
+ <if condition="<ase-project-boxing/> is equal `black`">
58
+
59
+ The project source artifacts are classified as a *black box*, so
60
+ the user does *not* want them inspected or their problems surfaced.
61
+ *Skip* the entire investigation and analysis: do *not* invoke any
62
+ `Glob` or `Agent` tool and do *not* read any source, only output
63
+ the following <template/> and then *SKIP* the remaining step STEP 3:
64
+
65
+ <template>
66
+ <ase-tpl-bullet-normal/> **CODE ANALYSIS**: *suppressed* (`project.boxing` is `black`)
67
+ </template>
68
+
69
+ </if>
70
+
57
71
  First, use the following <template/> to give a hint on this step:
58
72
 
59
73
  <template>
@@ -109,14 +123,19 @@ problems in *performance* and *efficiency*, or problems in *security*.
109
123
 
110
124
  3. <step id="STEP 3: Show Results">
111
125
 
112
- Before reporting, *apply the severity floor* selected via
113
- <getopt-option-severity/> (default `LOW`): define the ordinal rank
114
- `LOW`=1, `MEDIUM`=2, `HIGH`=3. *Keep* a detected problem if and only
115
- if its `severity` field is `ACCEPTED` *or* `rank(severity)` is greater
116
- than or equal to `rank(<getopt-option-severity/>)`; *silently drop*
117
- all other problems (they are neither reported nor persisted). With
118
- the default floor `LOW`, all problems are kept. `ACCEPTED` problems
119
- are *never* dropped.
126
+ Before reporting, determine the *effective severity floor* <floor/>:
127
+ define the ordinal rank `LOW`=1, `MEDIUM`=2, `HIGH`=3, start from
128
+ <floor><getopt-option-severity/></floor> (default `LOW`), and - if
129
+ <ase-project-boxing/> is equal `grey` - raise <floor/> to `MEDIUM`
130
+ whenever its current rank is below `rank(MEDIUM)` (grey boxing
131
+ surfaces only *material* findings of severity `MEDIUM` and above).
132
+
133
+ Then *apply the effective severity floor* <floor/>: *Keep* a detected
134
+ problem if and only if its `severity` field is `ACCEPTED` *or*
135
+ `rank(severity)` is greater than or equal to `rank(<floor/>)`;
136
+ *silently drop* all other problems (they are neither reported nor
137
+ persisted). With the default floor `LOW`, all problems are kept.
138
+ `ACCEPTED` problems are *never* dropped.
120
139
 
121
140
  Then renumber the surviving problems contiguously as `P<n/>` with
122
141
  <n/> = 1, 2, ... in the original ordering. If *all* problems are
@@ -140,8 +140,11 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
140
140
  You *MUST* perform the following sub-steps *internally* and *without
141
141
  any output* until and including the recommendation decision. Only
142
142
  sub-steps 4-6 below are allowed to produce output, and only if
143
- <getopt-option-auto/> is equal `false`. If <getopt-option-auto/> is
144
- equal `true`, *skip* the reporting sub-steps 4-6 entirely (perform
143
+ <getopt-option-auto/> is equal `false` *and* <ase-project-boxing/>
144
+ is *not* equal `black`.
145
+
146
+ If <getopt-option-auto/> is equal `true` or <ase-project-boxing/> is
147
+ equal `black`, *skip* the reporting sub-steps 4-6 entirely (perform
145
148
  no output at all) to speed up processing.
146
149
 
147
150
  1. *Propose* corresponding *feature approach*, including optionally,
@@ -187,7 +190,7 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
187
190
  <ase-tpl-foot title="APPROACHES"/>
188
191
  </template>
189
192
 
190
- 7. <if condition="<getopt-option-auto/> is not equal `true`">
193
+ 7. <if condition="<getopt-option-auto/> is not equal `true` and <ase-project-boxing/> is not equal `black`">
191
194
 
192
195
  In the following, you *MUST* *NOT* use your built-in
193
196
  <user-dialog-tool/> tool! Instead, you *MUST* just show a
@@ -43,6 +43,23 @@ code and *explain* it in a *brief*, *standardized*, and *concise* way.
43
43
  Second, explain *WHY* the code does it (*rationale*).
44
44
 
45
45
  Keep your explanations *brief* and *concise*.
46
+
47
+ <if condition="<ase-project-boxing/> is equal `black`">
48
+
49
+ The project source artifacts are classified as a *black box*, so the
50
+ user wants only the *minimal* surface explanation. Output *only* the
51
+ *WHAT* block (omit the *WHY* block) with the following <template/>:
52
+
53
+ <template>
54
+ <ase-tpl-bullet-normal/> **WHAT** (You should know what):
55
+ - [...]
56
+ - [...]
57
+ - [...]
58
+ </template>
59
+
60
+ </if>
61
+ <else>
62
+
46
63
  Output the result with the following <template/>:
47
64
 
48
65
  <template>
@@ -56,9 +73,21 @@ code and *explain* it in a *brief*, *standardized*, and *concise* way.
56
73
  - [...]
57
74
  - [...]
58
75
  </template>
76
+
77
+ </else>
59
78
  </step>
60
79
 
61
80
  3. <step id="STEP 3: ANALOGY and DIAGRAM">
81
+
82
+ <if condition="<ase-project-boxing/> is equal `black`">
83
+
84
+ The project source artifacts are classified as a *black box*, so
85
+ deeper elaboration is *not* wanted. *Skip* this STEP 3 and the
86
+ following STEP 4 entirely: do *not* output any ANALOGY, DIAGRAM,
87
+ CRUXES, or GOTCHAS, and do *not* dispatch any diagram rendering.
88
+
89
+ </if>
90
+
62
91
  **Give insights with ANALOGY and DIAGRAM**.
63
92
 
64
93
  First, give an analogy by comparing the code to something from
@@ -34,6 +34,21 @@ Give *insights* into the project through the source code of <getopt-arguments/>.
34
34
 
35
35
  <flow>
36
36
  1. <step id="STEP 1: PROJECT ABSTRACT">
37
+
38
+ <if condition="<ase-project-boxing/> is equal `black`">
39
+
40
+ The project source artifacts are classified as a *black box*, so the
41
+ user does *not* want them inspected or their internals surfaced.
42
+ *Skip* the entire insight gathering: do *not* read any source, only
43
+ output the following <template/> and then *SKIP* the remaining steps
44
+ STEP 2 through STEP 4:
45
+
46
+ <template>
47
+ <ase-tpl-bullet-normal/> **PROJECT INSIGHT**: *suppressed* (`project.boxing` is `black`)
48
+ </template>
49
+
50
+ </if>
51
+
37
52
  Determine an <abstract/> summary of this project.
38
53
  For this, check a potentially existing `README.*` file
39
54
  or scan the source files and figure it out indirectly.
@@ -33,6 +33,21 @@ related to a set of code quality aspects.
33
33
 
34
34
  1. <step id="STEP 1: Investigation">
35
35
 
36
+ <if condition="<ase-project-boxing/> is equal `black`">
37
+
38
+ The project source artifacts are classified as a *black box*, so
39
+ the user does *not* want them inspected or their problems surfaced.
40
+ *Skip* the entire investigation and reporting: do *not* invoke any
41
+ `Glob` or `Agent` tool and do *not* read any source, only output
42
+ the following <template/> and then *SKIP* the remaining steps STEP 2
43
+ and STEP 3:
44
+
45
+ <template>
46
+ <ase-tpl-bullet-normal/> **LINT**: *suppressed* (`project.boxing` is `black`)
47
+ </template>
48
+
49
+ </if>
50
+
36
51
  First, use the following <template/> to give a hint on this step:
37
52
 
38
53
  <template>
@@ -76,13 +91,18 @@ related to a set of code quality aspects.
76
91
  sort the list by `file` and then numerically by `line`, and set
77
92
  <problems/> to that list.
78
93
 
79
- Then *apply the severity floor* selected via <getopt-option-severity/>
80
- (default `LOW`): define the ordinal rank `LOW`=1, `MEDIUM`=2,
81
- `HIGH`=3. *Keep* a problem in <problems/> if and only if its
82
- `severity` field is `ACCEPTED` *or* `rank(severity)` is greater than
83
- or equal to `rank(<getopt-option-severity/>)`; *silently drop* all
84
- other problems. With the default floor `LOW`, all problems are kept.
85
- `ACCEPTED` problems are *never* dropped.
94
+ Then determine the *effective severity floor* <floor/>: define the
95
+ ordinal rank `LOW`=1, `MEDIUM`=2, `HIGH`=3, start from
96
+ <floor><getopt-option-severity/></floor> (default `LOW`), and - if
97
+ <ase-project-boxing/> is equal `grey` - raise <floor/> to `MEDIUM`
98
+ whenever its current rank is below `rank(MEDIUM)` (grey boxing
99
+ surfaces only *material* findings of severity `MEDIUM` and above).
100
+
101
+ Then *apply the effective severity floor* <floor/>: *Keep* a problem
102
+ in <problems/> if and only if its `severity` field is `ACCEPTED` *or*
103
+ `rank(severity)` is greater than or equal to `rank(<floor/>)`;
104
+ *silently drop* all other problems. With the default floor `LOW`, all
105
+ problems are kept. `ACCEPTED` problems are *never* dropped.
86
106
 
87
107
  You *MUST* *NOT* output anything else in this step 1.
88
108
 
@@ -145,6 +165,7 @@ related to a set of code quality aspects.
145
165
 
146
166
  2. Set <context></context> (set to empty).
147
167
  Set <diff></diff> (set to empty).
168
+ Set <diff-condensed></diff-condensed> (set to empty).
148
169
 
149
170
  3. Iterate over the change set:
150
171
 
@@ -153,7 +174,9 @@ related to a set of code quality aspects.
153
174
  1. Set <file/> to the `file` field of <item/>.
154
175
  Set <change-hunks/> to the `change-hunks` field of <item/>.
155
176
 
156
- Set <diff-file/> to the following <template/>:
177
+ Unless <ase-project-boxing/> is equal `grey` (where the
178
+ full unified diff is suppressed and this per-file header is
179
+ unused), set <diff-file/> to the following <template/>:
157
180
 
158
181
  <template>
159
182
  --- <file/> (original)
@@ -170,11 +193,18 @@ related to a set of code quality aspects.
170
193
  Set <new-text/> to the `new_text` field of <item/>.
171
194
  Set <context-after/> to the `context_after` field of <item/>.
172
195
 
173
- 2. Determine the hunk *body* as an ordered list of lines,
174
- each carrying a one-character prefix (` ` for context,
175
- `-` for old-side, `+` for new-side). Build it by
176
- concatenating, in order and *skipping any part that is
177
- empty*:
196
+ 2. *Skip* this substep entirely when <ase-project-boxing/>
197
+ is equal `grey` - the full unified diff is suppressed
198
+ there, so none of the <hunk-body/>, <old-count/>,
199
+ <new-count/>, <old-start/>, or <new-start/> values
200
+ below are consumed (substep 4 builds only the condensed
201
+ one-liner instead).
202
+
203
+ Otherwise, determine the hunk *body* as an ordered list
204
+ of lines, each carrying a one-character prefix (` ` for
205
+ context, `-` for old-side, `+` for new-side). Build it
206
+ by concatenating, in order and *skipping any part that
207
+ is empty*:
178
208
 
179
209
  - one ` `-prefixed line for *each* line of
180
210
  <context-before/> (if non-empty),
@@ -217,7 +247,27 @@ related to a set of code quality aspects.
217
247
 
218
248
  <template>`<file/>`:<line/></template>
219
249
 
220
- 4. Append the following <template/> to <diff-file/>,
250
+ 4. <if condition="<ase-project-boxing/> is equal `grey`">
251
+
252
+ The full unified diff is *suppressed* under grey boxing
253
+ (see substep 5 below), so *skip* the full-diff append
254
+ and instead build only a *condensed* one-line
255
+ representation of this hunk: determine <old-snippet/>
256
+ as the *single-line* collapse of <old-text/> (join its
257
+ lines with ` ⏎ `, or `∅` when <old-text/> is empty for
258
+ a pure insertion) and <new-snippet/> as the same
259
+ collapse of <new-text/> (or `∅` when empty for a pure
260
+ deletion). Then append the following <template/> to
261
+ <diff-condensed/> as a new line:
262
+
263
+ <template>
264
+ <ase-tpl-bullet-signal/> `<file/>`:<line/>: `<old-snippet/>` → `<new-snippet/>`
265
+ </template>
266
+
267
+ </if>
268
+ <else>
269
+
270
+ Append the following <template/> to <diff-file/>,
221
271
  emitting <hunk-body/> verbatim (one already-prefixed
222
272
  line per line, with no extra blank or space-only lines):
223
273
 
@@ -226,9 +276,12 @@ related to a set of code quality aspects.
226
276
  <hunk-body/>
227
277
  </template>
228
278
 
279
+ </else>
280
+
229
281
  </for>
230
282
 
231
- 3. Append <diff-file/> to <diff/>.
283
+ 3. Unless <ase-project-boxing/> is equal `grey` (where
284
+ <diff-file/> is unused), append <diff-file/> to <diff/>.
232
285
 
233
286
  </for>
234
287
 
@@ -241,7 +294,25 @@ related to a set of code quality aspects.
241
294
 
242
295
  </template>
243
296
 
244
- 5. <if condition="<getopt-option-auto/> is not 'true'">
297
+ 5. <if condition="<getopt-option-auto/> is not 'true' and <ase-project-boxing/> is not equal `black`">
298
+
299
+ <if condition="<ase-project-boxing/> is equal `grey`">
300
+
301
+ The project source artifacts are classified as a *grey box*, so
302
+ the user does *not* want the full artifact internals surfaced:
303
+ *suppress* the full unified diff and instead show only the
304
+ *condensed* one-line-per-hunk representation. Report the
305
+ solution with the following <template/>:
306
+
307
+ <template>
308
+ <ase-tpl-bullet-normal/> **<aspect/> SOLUTION**:
309
+
310
+ <diff-condensed/>
311
+
312
+ </template>
313
+
314
+ </if>
315
+ <else>
245
316
 
246
317
  Report the solution with the following <template/>:
247
318
 
@@ -254,6 +325,8 @@ related to a set of code quality aspects.
254
325
 
255
326
  </template>
256
327
 
328
+ </else>
329
+
257
330
  </if>
258
331
  <else>
259
332
 
@@ -140,8 +140,11 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
140
140
  You *MUST* perform the following sub-steps *internally* and *without
141
141
  any output* until and including the recommendation decision. Only
142
142
  sub-steps 4-6 below are allowed to produce output, and only if
143
- <getopt-option-auto/> is equal `false`. If <getopt-option-auto/> is
144
- equal `true`, *skip* the reporting sub-steps 4-6 entirely (perform
143
+ <getopt-option-auto/> is equal `false` *and* <ase-project-boxing/>
144
+ is *not* equal `black`.
145
+
146
+ If <getopt-option-auto/> is equal `true` or <ase-project-boxing/> is
147
+ equal `black`, *skip* the reporting sub-steps 4-6 entirely (perform
145
148
  no output at all) to speed up processing.
146
149
 
147
150
  1. *Propose* corresponding *refactoring approach*, including
@@ -187,7 +190,7 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
187
190
  <ase-tpl-foot title="APPROACHES"/>
188
191
  </template>
189
192
 
190
- 7. <if condition="<getopt-option-auto/> is not `true`">
193
+ 7. <if condition="<getopt-option-auto/> is not equal `true` and <ase-project-boxing/> is not equal `black`">
191
194
 
192
195
  In the following, you *MUST* *NOT* use your built-in
193
196
  <user-dialog-tool/> tool! Instead, you *MUST* just show a
@@ -194,8 +194,11 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
194
194
  You *MUST* perform the following sub-steps *internally* and *without
195
195
  any output* until and including the recommendation decision. Only
196
196
  sub-steps 4-6 below are allowed to produce output, and only if
197
- <getopt-option-auto/> is equal `false`. If <getopt-option-auto/> is
198
- equal `true`, *skip* the reporting sub-steps 4-6 entirely (perform
197
+ <getopt-option-auto/> is equal `false` *and* <ase-project-boxing/>
198
+ is *not* equal `black`.
199
+
200
+ If <getopt-option-auto/> is equal `true` or <ase-project-boxing/> is
201
+ equal `black`, *skip* the reporting sub-steps 4-6 entirely (perform
199
202
  no output at all) to speed up processing.
200
203
 
201
204
  1. *Propose* corresponding *resolution approach*, including optionally,
@@ -241,7 +244,7 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
241
244
  <ase-tpl-foot title="APPROACHES"/>
242
245
  </template>
243
246
 
244
- 7. <if condition="<getopt-option-auto/> is not `true`">
247
+ 7. <if condition="<getopt-option-auto/> is not equal `true` and <ase-project-boxing/> is not equal `black`">
245
248
 
246
249
  In the following, you *MUST* *NOT* use your built-in
247
250
  <user-dialog-tool/> tool! Instead, you *MUST* just show a
@@ -33,6 +33,21 @@ Analyze documents for spelling, punctuation, or grammar errors
33
33
 
34
34
  1. <step id="STEP 1: Investigation">
35
35
 
36
+ <if condition="<ase-project-boxing/> is equal `black`">
37
+
38
+ The project source artifacts are classified as a *black box*, so
39
+ the user does *not* want them inspected or their problems surfaced.
40
+ *Skip* the entire investigation and reporting: do *not* invoke any
41
+ `Glob` or `Agent` tool and do *not* read any document, only output
42
+ the following <template/> and then *SKIP* the remaining steps STEP 2
43
+ and STEP 3:
44
+
45
+ <template>
46
+ <ase-tpl-bullet-normal/> **PROOFREAD**: *suppressed* (`project.boxing` is `black`)
47
+ </template>
48
+
49
+ </if>
50
+
36
51
  First, use the following <template/> to give a hint on this step:
37
52
 
38
53
  <template>
@@ -141,7 +156,26 @@ Analyze documents for spelling, punctuation, or grammar errors
141
156
  <description/>
142
157
  </template>
143
158
 
144
- 3. <if condition="<getopt-option-auto/> is not 'true'">
159
+ 3. <if condition="<getopt-option-auto/> is not 'true' and <ase-project-boxing/> is equal `grey`">
160
+
161
+ The project source artifacts are classified as a *grey box*, so
162
+ the user does *not* want the full artifact internals surfaced:
163
+ *suppress* the full unified diff and instead show only a
164
+ *condensed* one-line representation. Determine <old-snippet/>
165
+ as the *single-line* collapse of <old-text/> (join its lines
166
+ with ` ⏎ `, or `∅` when <old-text/> is empty for a pure
167
+ insertion) and <new-snippet/> as the same collapse of
168
+ <new-text/> (or `∅` when empty for a pure deletion). Then
169
+ report the correction with the following <template/>:
170
+
171
+ <template>
172
+
173
+ <ase-tpl-bullet-normal/> **<type/> CORRECTION**: `<old-snippet/>` → `<new-snippet/>`
174
+
175
+ </template>
176
+
177
+ </if>
178
+ <elseif condition="<getopt-option-auto/> is not 'true'">
145
179
 
146
180
  Determine the hunk *body* as an ordered list of lines, each
147
181
  carrying a one-character prefix (` ` for context, `-` for
@@ -195,7 +229,7 @@ Analyze documents for spelling, punctuation, or grammar errors
195
229
 
196
230
  </template>
197
231
 
198
- </if>
232
+ </elseif>
199
233
 
200
234
  4. <if condition="<getopt-option-auto/> is not 'true'">
201
235
 
@@ -38,9 +38,12 @@ Format
38
38
  The *ChangeLog* file is a Markdown formatted file named `CHANGELOG.md`,
39
39
  and contains sections with headers in the style `N.M.K (YYYY-MM-DD)`.
40
40
 
41
- Each *ChangeLog* entry is always formatted as `<prefix/>: <summary/>`
42
- where the <prefix/> is one of the following tags and their usual related
43
- changes:
41
+ Each *ChangeLog* entry is always formatted as...
42
+
43
+ `<change-type/> [<artifact-kind/>]: <summary/>`
44
+
45
+ ...where the <change-type/> is one of the following tags and their usual
46
+ related changes:
44
47
 
45
48
  - `FEATURE`: new functionality or configuration
46
49
  - `IMPROVEMENT`: improved functionality or configuration
@@ -49,9 +52,21 @@ changes:
49
52
  - `CLEANUP`: cleaned up functionality or configuration
50
53
  - `REFACTOR`: refactored functionality or configuration
51
54
 
55
+ The <artifact-kind/> is one or more of the following *artifact* tags,
56
+ classifying which kind of artifact the change primarily touches. If
57
+ multiple artifact kinds apply, comma-separate them
58
+ (e.g. `[arch, code]`):
59
+
60
+ - `spec`: requirement/specification artifacts
61
+ - `arch`: architecture/design artifacts
62
+ - `code`: source code artifacts
63
+ - `docs`: documentation artifacts
64
+ - `infr`: infrastructure/build/tooling artifacts
65
+ - `othr`: any other artifacts
66
+
52
67
  The <summary/> is not longer than about 60-80 characters. The
53
68
  *ChangeLog* entries for a single product release version are also always
54
- grouped and sorted according to the above <prefix/> list.
69
+ grouped and sorted according to the above <change-type/> list.
55
70
 
56
71
  Processing
57
72
  ----------
@@ -123,6 +138,16 @@ Processing
123
138
  For each Git commit, reduce the Git commit messages to a single
124
139
  short <summary/> sentence, not longer than 60-80 characters.
125
140
 
141
+ For each entry, also determine the <artifact-kind/> *artifact kind*
142
+ tag(s) from the paths of the changed files. To classify a changed
143
+ file to its artifact class, call the `ase_artifact_list(kind: [
144
+ ... ])` tool of the `ase` MCP server *once*, passing the `kind`
145
+ tokens (`spec`, `arch`, `code`, `docs`, `infr`, `othr`), and read
146
+ the returned `artifacts` array of `{ kind, files }` objects to match
147
+ each changed file to its kind. Map the matched lower-cased kind back
148
+ to its upper-cased <artifact-kind/> tag, and comma-separate multiple
149
+ tags when more than one artifact class applies.
150
+
126
151
  If a <summary/> is too short or especially is not comprehensible
127
152
  enough because of too little context information, add some essential
128
153
  context, especially references to the class/module/package, etc.
@@ -144,11 +169,11 @@ Processing
144
169
  Without immediately modifying the `CHANGELOG.md` file, *consolidate*
145
170
  the entries in the first (most recent) section only, by summarizing
146
171
  and merging closely related entries. Perform the entry consolidation
147
- per <prefix/> group only.
172
+ per <change-type/> group only.
148
173
 
149
174
  Without immediately modifying the `CHANGELOG.md` file, *sort* the
150
175
  entries in the first (most recent) section only. Instead of the
151
- chronological commit order, group the entries by the <prefix/>es.
176
+ chronological commit order, group the entries by the <change-type/>s.
152
177
 
153
178
  </step>
154
179
 
@@ -15,10 +15,13 @@ The `ase-meta-changelog` skill helps to *complete*, *consolidate*, and
15
15
  file, based on the underlying *Git* commits and the currently staged
16
16
  changes in the Git *index*.
17
17
 
18
- Each entry is formatted as `<prefix>: <summary>` where *prefix* is
19
- one of `FEATURE`, `IMPROVEMENT`, `BUGFIX`, `UPDATE`, `CLEANUP`, or
20
- `REFACTOR`. Entries are grouped and sorted by this prefix. The
21
- date in the section header is also updated to the current date.
18
+ Each entry is formatted as `<change-type> [<artifact-kind>]: <summary>`
19
+ where *change-type* is one of `FEATURE`, `IMPROVEMENT`, `BUGFIX`,
20
+ `UPDATE`, `CLEANUP`, or `REFACTOR`, and *artifact-kind* is one or more
21
+ comma-separated *artifact class* tags out of `spec`, `arch`, `code`,
22
+ `docs`, `infr`, or `othr`. Entries are grouped and sorted by this
23
+ prefix. The date in the section header is also updated to the current
24
+ date.
22
25
 
23
26
  ## EXAMPLES
24
27
 
@@ -123,10 +123,28 @@ Procedure
123
123
  *not* output any further explanation.
124
124
  </if>
125
125
 
126
+ 4. <if condition="
127
+ <ase-project-boxing/> is equal `black` and
128
+ (<getopt-option-coherence/> is equal `true` or
129
+ <getopt-option-risk/> is equal `true` or
130
+ <getopt-option-blast/> is equal `true`)
131
+ ">
132
+ The project source artifacts are classified as a *black box*, so
133
+ the user does *not* want the staged changes scrutinized or their
134
+ coherence, risk, and blast-radius findings surfaced. The
135
+ requested scrutiny of STEP 3 through STEP 5 is therefore
136
+ suppressed: only output the following <template/> and then *SKIP*
137
+ the remaining steps STEP 3 through STEP 5:
138
+
139
+ <template>
140
+ <ase-tpl-bullet-normal/> **DIFF SCRUTINY**: *suppressed* (`project.boxing` is `black`)
141
+ </template>
142
+ </if>
143
+
126
144
  </step>
127
145
 
128
146
  3. <step id="STEP 3: Assess Intent Coherence"
129
- condition="<getopt-option-coherence/> is equal `true` and <diff/> is NOT empty">
147
+ condition="<getopt-option-coherence/> is equal `true` and <diff/> is NOT empty and <ase-project-boxing/> is not equal `black`">
130
148
 
131
149
  1. From the *same* captured <diff/> and <stat/>, *reconstruct the
132
150
  single intended change* as a thesis - the one logical, coherent purpose
@@ -203,7 +221,7 @@ Procedure
203
221
  </step>
204
222
 
205
223
  4. <step id="STEP 4: Score Against Risk Rubric"
206
- condition="<getopt-option-risk/> is equal `true` and <diff/> is NOT empty">
224
+ condition="<getopt-option-risk/> is equal `true` and <diff/> is NOT empty and <ase-project-boxing/> is not equal `black`">
207
225
 
208
226
  1. Score the *same* captured <diff/> and <stat/> information
209
227
  against the four-axis rubric below. Each axis is scored on an
@@ -275,7 +293,7 @@ Procedure
275
293
  </step>
276
294
 
277
295
  5. <step id="STEP 5: Render Blast-Radius Map"
278
- condition="<getopt-option-blast/> is equal `true` and <diff/> is NOT empty">
296
+ condition="<getopt-option-blast/> is equal `true` and <diff/> is NOT empty and <ase-project-boxing/> is not equal `black`">
279
297
 
280
298
  1. From the *same* captured <diff/> and <stat/>, *extract the
281
299
  touched modules* - the distinct changed source files (or their
@@ -67,6 +67,19 @@ Procedure
67
67
 
68
68
  2. <step id="STEP 2: Review Investigation">
69
69
 
70
+ <if condition="<ase-project-boxing/> is equal `black`">
71
+
72
+ The project source artifacts are classified as a *black box*, so
73
+ the user does *not* want the staged changes scrutinized or their
74
+ findings surfaced. *Skip* the entire review investigation: do
75
+ *not* invoke the `Agent` tool and do *not* read any change, set
76
+ <findings/> to the *empty* list, set <verdict/> to `SKIPPED (boxing:
77
+ black)`, set <summary/> to a *one-line* neutral restatement of the
78
+ change intent derived solely from STEP 1, and proceed *directly* to
79
+ STEP 3.
80
+
81
+ </if>
82
+
70
83
  First, use the following <template/> to give a hint on this step:
71
84
 
72
85
  <template>
@@ -102,13 +115,20 @@ Procedure
102
115
  severity floor below, so the floor only affects which findings are
103
116
  *rendered*, never the verdict.
104
117
 
105
- Then *apply the severity floor* selected via <getopt-option-severity/>
106
- (default `LOW`): define the ordinal rank `LOW`=1, `MEDIUM`=2,
107
- `HIGH`=3. *Keep* a finding in <findings/> if and only if its
108
- `severity` field is `ACCEPTED` *or* `rank(severity)` is greater than
109
- or equal to `rank(<getopt-option-severity/>)`; *silently drop* all
110
- other findings. With the default floor `LOW`, all findings are kept.
111
- `ACCEPTED` findings are *never* dropped.
118
+ Then determine the *effective severity floor* <floor/>: define the
119
+ ordinal rank `LOW`=1, `MEDIUM`=2, `HIGH`=3, start from
120
+ <floor><getopt-option-severity/></floor> (default `LOW`), and - if
121
+ <ase-project-boxing/> is equal `grey` - raise <floor/> to `MEDIUM`
122
+ whenever its current rank is below `rank(MEDIUM)` (grey boxing
123
+ surfaces only *material* findings of severity `MEDIUM` and above).
124
+ The floor affects only which findings are *rendered*, never the
125
+ <verdict/> derived above.
126
+
127
+ Then *apply the effective severity floor* <floor/>: *Keep* a finding
128
+ in <findings/> if and only if its `severity` field is `ACCEPTED` *or*
129
+ `rank(severity)` is greater than or equal to `rank(<floor/>)`;
130
+ *silently drop* all other findings. With the default floor `LOW`, all
131
+ findings are kept. `ACCEPTED` findings are *never* dropped.
112
132
 
113
133
  You *MUST* *NOT* output anything else in this STEP 2.
114
134