@rse/ase 0.9.2 → 0.9.3

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 (37) hide show
  1. package/dst/ase-hello.js +24 -0
  2. package/dst/ase-statusline.js +15 -5
  3. package/package.json +2 -2
  4. package/plugin/.claude-plugin/plugin.json +1 -1
  5. package/plugin/.github/plugin/plugin.json +1 -1
  6. package/plugin/agents/ase-meta-review.md +188 -0
  7. package/plugin/etc/eslint.mjs +25 -0
  8. package/plugin/etc/markdownlint.yaml +13 -11
  9. package/plugin/etc/stx.conf +2 -1
  10. package/plugin/meta/ase-control.md +7 -2
  11. package/plugin/meta/ase-dialog.md +2 -0
  12. package/plugin/meta/ase-format-arch.md +31 -31
  13. package/plugin/meta/ase-format-spec.md +3 -3
  14. package/plugin/meta/ase-getopt.md +1 -0
  15. package/plugin/meta/ase-persona.md +1 -1
  16. package/plugin/meta/ase-skill.md +6 -6
  17. package/plugin/package.json +5 -2
  18. package/plugin/skills/ase-arch-analyze/SKILL.md +33 -33
  19. package/plugin/skills/ase-code-lint/SKILL.md +1 -1
  20. package/plugin/skills/ase-code-lint/help.md +1 -1
  21. package/plugin/skills/ase-docs-distill/SKILL.md +158 -0
  22. package/plugin/skills/ase-docs-distill/help.md +76 -0
  23. package/plugin/skills/ase-docs-proofread/SKILL.md +1 -1
  24. package/plugin/skills/ase-docs-proofread/help.md +1 -1
  25. package/plugin/skills/ase-meta-brainstorm/SKILL.md +17 -11
  26. package/plugin/skills/ase-meta-brainstorm/help.md +4 -4
  27. package/plugin/skills/ase-meta-diaboli/SKILL.md +4 -4
  28. package/plugin/skills/ase-meta-diaboli/help.md +2 -2
  29. package/plugin/skills/ase-meta-diff/SKILL.md +110 -64
  30. package/plugin/skills/ase-meta-diff/help.md +30 -6
  31. package/plugin/skills/ase-meta-review/SKILL.md +166 -0
  32. package/plugin/skills/ase-meta-review/help.md +70 -0
  33. package/plugin/skills/ase-meta-steelman/SKILL.md +159 -0
  34. package/plugin/skills/ase-meta-steelman/help.md +60 -0
  35. package/plugin/skills/ase-meta-why/help.md +1 -1
  36. package/plugin/skills/ase-task-condense/SKILL.md +3 -3
  37. package/plugin/skills/ase-task-implement/help.md +1 -1
@@ -0,0 +1,24 @@
1
+ /*
2
+ ** Agentic Software Engineering (ASE)
3
+ ** Copyright (c) 2025-2026 Dr. Ralf S. Engelschall <rse@engelschall.com>
4
+ ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
5
+ */
6
+ import chalk from "chalk";
7
+ /* CLI command "ase hello" */
8
+ export default class HelloCommand {
9
+ log;
10
+ constructor(log) {
11
+ this.log = log;
12
+ }
13
+ /* register commands */
14
+ register(program) {
15
+ /* register CLI top-level command "ase hello" */
16
+ program
17
+ .command("hello")
18
+ .description("Show \"Hello World!\"")
19
+ .action(() => {
20
+ process.stdout.write(chalk.blue("Hello World!") + "\n");
21
+ process.exit(0);
22
+ });
23
+ }
24
+ }
@@ -96,9 +96,19 @@ const formatHoursMinutes = (ms) => {
96
96
  const mins = totalMin % 60;
97
97
  return `${hours}hr ${mins}m`;
98
98
  };
99
- /* format an ISO timestamp as a remaining-time relative to now (e.g. 4hr 27m, 6d 12hr 7m) */
100
- const formatTimeUntil = (iso) => {
101
- const target = Date.parse(iso);
99
+ /* format an ISO timestamp or numeric Unix timestamp as a remaining-time relative to now (e.g. 4hr 27m, 6d 12hr 7m) */
100
+ const formatTimeUntil = (when) => {
101
+ let target;
102
+ if (typeof when === "number") {
103
+ if (!Number.isFinite(when))
104
+ return "";
105
+ /* values below 1e12 are Unix seconds, otherwise milliseconds */
106
+ target = when < 1e12 ? when * 1000 : when;
107
+ }
108
+ else if (typeof when === "string")
109
+ target = Date.parse(when);
110
+ else
111
+ return "";
102
112
  if (!Number.isFinite(target))
103
113
  return "";
104
114
  const delta = target - Date.now();
@@ -360,7 +370,7 @@ export default class StatuslineCommand {
360
370
  emit(`${prefix("⏲", "session-usage")}${c.bold(`${pct5h.toFixed(1)}%`)}`);
361
371
  },
362
372
  D: () => {
363
- const until5h = data.rate_limits?.five_hour?.resets_at ?? "";
373
+ const until5h = data.rate_limits?.five_hour?.resets_at;
364
374
  const s = formatTimeUntil(until5h);
365
375
  if (s !== "")
366
376
  emit(`${prefix("⏱", "session-resets")}${c.bold(s)}`);
@@ -371,7 +381,7 @@ export default class StatuslineCommand {
371
381
  emit(`${prefix("⏲", "weekly-usage")}${c.bold(`${pctWk.toFixed(1)}%`)}`);
372
382
  },
373
383
  Q: () => {
374
- const untilWk = data.rate_limits?.seven_day?.resets_at ?? "";
384
+ const untilWk = data.rate_limits?.seven_day?.resets_at;
375
385
  const s = formatTimeUntil(untilWk);
376
386
  if (s !== "")
377
387
  emit(`${prefix("⏱", "weekly-resets")}${c.bold(s)}`);
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.2",
9
+ "version": "0.9.3",
10
10
  "license": "GPL-3.0-only",
11
11
  "author": {
12
12
  "name": "Dr. Ralf S. Engelschall",
@@ -30,7 +30,7 @@
30
30
  "nodemon": "3.1.14",
31
31
  "shx": "0.4.0",
32
32
 
33
- "@types/node": "25.9.1",
33
+ "@types/node": "25.9.2",
34
34
  "@types/luxon": "3.7.1",
35
35
  "@types/which": "3.0.4",
36
36
  "@types/update-notifier": "6.0.8",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ase",
3
- "version": "0.9.2",
3
+ "version": "0.9.3",
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.2",
3
+ "version": "0.9.3",
4
4
  "description": "Agentic Software Engineering (ASE)",
5
5
  "keywords": [ "agentic", "software", "engineering" ],
6
6
  "homepage": "https://ase.tools",
@@ -0,0 +1,188 @@
1
+ ---
2
+ name: ase-meta-review
3
+ description: "Review Investigation"
4
+ effort: high
5
+ ---
6
+
7
+ Your role is an experienced, *expert-level software reviewer* performing
8
+ a holistic, human-style review of a concrete set of staged Git changes —
9
+ the way a thorough reviewer would judge a pull request before approving it.
10
+
11
+ Your objective is to *reconstruct the change's intent* and *critique the
12
+ staged diff as a whole* against a fixed set of reviewer dimensions,
13
+ producing *prioritized*, *severity-tagged*, *line-cited* findings.
14
+
15
+ Workflow
16
+ --------
17
+
18
+ 1. Capture the *staged change set* by running the following command
19
+ (taken exactly as given), capturing the full diff output into <diff/>:
20
+
21
+ `git diff --cached HEAD`
22
+
23
+ 2. Use the `Read` tool to read *every* file touched by <diff/> in its
24
+ *full current form* (not just the hunks), plus all *related* files
25
+ needed to really comprehend the change — callers of changed
26
+ functions, the interfaces/contracts they implement, and adjacent
27
+ code that establishes the surrounding idiom. A diff cannot be
28
+ reviewed from the hunks alone.
29
+
30
+ 3. *Probe the repository read-only and heuristically* (via `git grep`,
31
+ `grep`, `git ls-files`, restricted to first-party code) only as
32
+ needed to substantiate findings — e.g. who imports a touched module,
33
+ whether a changed contract has other call sites, whether touched code
34
+ has adjacent tests. Do not modify anything.
35
+
36
+ 4. Read the project's *documented conventions* — the AI guidance files
37
+ (`AGENTS.md`, or similar) and any referenced format/meta documents
38
+ — so the `CONVENTION` dimension can be judged against the project's
39
+ *own* stated rules (code style, plan/spec/arch formats) rather than
40
+ generic taste.
41
+
42
+ 5. *Reconstruct the intent*: determine the *single*, *coherent* purpose
43
+ the diff *as a whole* is trying to accomplish, and capture it as a
44
+ *single* crisp sentence in <summary/>. If the diff genuinely spans
45
+ several unrelated purposes, pick the *dominant* one (the residue will
46
+ surface as an `INTENT` finding below).
47
+
48
+ 6. Set <findings/> to empty.
49
+ Then critique the change across the following fixed *dimensions*
50
+ (each finding is tagged with exactly one `dimension`):
51
+
52
+ - **INTENT**:
53
+ Hunks that do *not* serve the reconstructed intent — scope creep
54
+ (an unrelated feature or drive-by refactor riding along), stray
55
+ debug/diagnostic residue (debug prints, commented-out code,
56
+ disabled tests, `TODO`/`FIXME` scaffolding), or an incomplete
57
+ change that does not fully achieve its own stated purpose.
58
+
59
+ - **CORRECTNESS**:
60
+ Latent bugs introduced or left by the change — wrong logic,
61
+ unhandled edge cases, off-by-one and boundary errors, broken
62
+ control or data flow, incorrect assumptions about inputs or state.
63
+
64
+ - **DESIGN**:
65
+ Poor fit with the surrounding architecture — wrong abstraction
66
+ level, misplaced responsibility, leaky or broken interface
67
+ contracts, poor naming, or a simpler/more idiomatic shape the
68
+ change overlooked.
69
+
70
+ - **CLARITY**:
71
+ Readability and self-documentation problems for a *future
72
+ reader* — confusing constructs, misleading names, missing
73
+ rationale for a non-obvious choice, or unnecessary complexity.
74
+
75
+ - **ROBUSTNESS**:
76
+ Missing, incorrect, or inconsistent error handling; resource
77
+ allocation/deallocation imbalance; and concurrency or
78
+ asynchronicity hazards introduced by the change.
79
+
80
+ - **SECURITY**:
81
+ Vulnerabilities or missing essential validations introduced by
82
+ the change — injection, unsafe input handling, secret exposure,
83
+ privilege or trust-boundary mistakes, unsafe edge cases in value
84
+ ranges.
85
+
86
+ - **PERFORMANCE**:
87
+ Efficiency risks introduced by the change — non-constant/
88
+ non-linear hot paths, redundant work, or avoidable allocations
89
+ on a path the change clearly exercises.
90
+
91
+ - **CONVENTION**:
92
+ Conformance to the *project's own documented conventions* — the
93
+ code style and the plan/spec/arch artifact formats stated in the
94
+ project's AI guidance and meta documents. Judge against what the
95
+ project *documents*, not against generic preference.
96
+
97
+ - **TESTING**:
98
+ Inadequate test coverage for the change — new logic or fixed
99
+ behavior left untested, adjacent tests not updated to match the
100
+ new behavior, or existing tests silently broken, disabled, or
101
+ weakened by the change.
102
+
103
+ - **DOCUMENTATION**:
104
+ User- or developer-facing documentation left stale by the change
105
+ — `README`, `CHANGELOG`, help text, or AI guidance/meta documents
106
+ that no longer match the change's new behavior, options, or
107
+ formats.
108
+
109
+ Be *holistic* and *synthesizing*: prefer a *few* high-signal findings
110
+ that a human reviewer would actually raise over an exhaustive
111
+ mechanical list. Be *conservative* — only report clear, well-grounded
112
+ concerns, and think twice to avoid *false positives*. Be *focused* —
113
+ only report concerns about the *staged change* itself; ignore
114
+ pre-existing issues in unchanged code that the diff merely sits next
115
+ to.
116
+
117
+ For *each* finding:
118
+
119
+ 1. Set <dimension/> to exactly one of `INTENT`, `CORRECTNESS`,
120
+ `DESIGN`, `CLARITY`, `ROBUSTNESS`, `SECURITY`, `PERFORMANCE`,
121
+ `CONVENTION`, `TESTING`, or `DOCUMENTATION`.
122
+
123
+ 2. Set <severity/> to one of `HIGH`, `MEDIUM`, `LOW`, or `ACCEPTED`:
124
+
125
+ - `HIGH`: a blocking concern a reviewer would require fixed
126
+ before approval (a real bug, a security hole, a broken contract,
127
+ a hard convention violation).
128
+
129
+ - `MEDIUM`: a concern worth addressing but not strictly
130
+ blocking.
131
+
132
+ - `LOW`: a minor nit or suggestion.
133
+
134
+ - `ACCEPTED`: a concern that *is* explicitly addressed by
135
+ a contract, docstring, or documented project priority (a
136
+ hot-path/allocation/latency tradeoff, or "contractually
137
+ addressed") — kept visible for traceability rather than dropped.
138
+
139
+ *Documented-context alignment* is mandatory: cross-check each
140
+ finding against interface contracts, docstrings, adjacent
141
+ comments, and the project AI guidance files. If the concern is
142
+ already addressed there, mark it `ACCEPTED` with the reason in
143
+ the finding text rather than reporting it as a defect; if a
144
+ fix would violate a documented priority, weaken it or mark it
145
+ `ACCEPTED` ("priority-conflict accepted").
146
+
147
+ 3. Set <location/> to the *relative* filename path of the affected
148
+ file, with the affected 1-based line number `N` appended as `:N`
149
+ or the 1-based line range appended as `:N-M`. *Evidence-grounded*
150
+ citation is mandatory — the cited lines MUST prove the finding
151
+ verbatim; if they do not, re-investigate and re-cite, and drop
152
+ the finding only if *no* location in the changed files proves it.
153
+
154
+ 4. Set <finding/> to an *ultra-brief*, *concise* Markdown-formatted
155
+ statement combining *what* the concern is and *why* it matters
156
+ (and, for `ACCEPTED`, *where* it is addressed). Mark up all
157
+ referenced verbatim identifiers or keywords <words/> from the
158
+ code as quoted monospaced strings based on the following
159
+ <template/>: <template>"`<words/>`"</template>. Keep it to a
160
+ single sentence wherever possible.
161
+
162
+ 5. If <findings/> is not empty, set
163
+ <findings><findings/>,</findings> (append a comma).
164
+ Then append the following <template/> to <findings/>:
165
+
166
+ <template>
167
+ {
168
+ "dimension": <dimension/>,
169
+ "severity": <severity/>,
170
+ "location": <location/>,
171
+ "finding": <finding/>
172
+ }
173
+ </template>
174
+
175
+ 7. Return *exclusively* a single fenced JSON block (no prose, no
176
+ preamble, no summary) of the following shape:
177
+
178
+ ```json
179
+ {
180
+ "summary": <summary/>,
181
+ "findings": [
182
+ <findings/>
183
+ ]
184
+ }
185
+ ```
186
+
187
+ 8. You *MUST* *NOT* propose, apply, or render any code or document
188
+ changes yourself.
@@ -0,0 +1,25 @@
1
+ /*
2
+ ** Agentic Software Engineering (ASE)
3
+ ** Copyright (c) 2025-2026 Dr. Ralf S. Engelschall <rse@engelschall.com>
4
+ ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
5
+ */
6
+
7
+ import { defineConfig } from "eslint/config"
8
+ import markdown from "@eslint/markdown"
9
+ import md from "eslint-markdown"
10
+
11
+ export default defineConfig([
12
+ // markdown.configs.recommended,
13
+ md.configs.recommended,
14
+ {
15
+ files: [
16
+ "meta/*.md",
17
+ "skills/**/*.md"
18
+ ],
19
+ rules: {
20
+ "md/no-double-space": "off",
21
+ "md/code-lang-shorthand": "off"
22
+ }
23
+ }
24
+ ])
25
+
@@ -6,16 +6,18 @@
6
6
 
7
7
  no-multiple-blanks:
8
8
  maximum: 2
9
- no-inline-html: false
10
- line-length: false
11
- ol-prefix: false
12
- list-marker-space: false
13
- first-line-heading: false
14
- no-space-in-code: false
15
- ul-indent: false
16
- ol-indent: false
17
- heading-style: false
9
+ no-inline-html: false
10
+ line-length: false
11
+ ol-prefix: false
12
+ list-marker-space: false
13
+ first-line-heading: false
14
+ no-space-in-code: false
15
+ ul-indent: false
16
+ ol-indent: false
17
+ heading-style: false
18
18
  no-multiple-space-atx: false
19
- blanks-around-tables: false
20
- code-block-style: false
19
+ blanks-around-tables: false
20
+ code-block-style: false
21
+ no-duplicate-heading: false
22
+ link-fragments: false
21
23
 
@@ -6,7 +6,8 @@
6
6
 
7
7
  # [plugin] lint project
8
8
  lint
9
- markdownlint-cli2 --config etc/markdownlint.yaml skills/**/*.md
9
+ markdownlint-cli2 --config etc/markdownlint.yaml meta/*.md skills/**/*.md && \
10
+ eslint --config etc/eslint.mjs meta skills
10
11
 
11
12
  # [plugin] build project
12
13
  build : lint
@@ -32,11 +32,16 @@ Control Flow Constructs
32
32
  Do not output anything else.
33
33
 
34
34
  - *IMPORTANT*: You *MUST* honor the following control flow construct:
35
- <step id="<id/>"><step-body/></step>:
35
+ <step id="<id/>" [condition="<step-condition/>"]><step-body/></step>:
36
36
 
37
37
  This specifies a distinct *single step* in a <flow/>.
38
38
  This construct is expanded to its <step-body/>.
39
- Do not output anything else.
39
+ The optional `condition` attribute *enables* the step only if
40
+ <step-condition/> is met: if <step-condition/> is met, this construct
41
+ is expanded to its <step-body/>; if <step-condition/> is *not* met,
42
+ the entire step is silently *skipped* and this construct is expanded
43
+ to the empty string. When the `condition` attribute is *absent*, the
44
+ step is *always* enabled. Do not output anything else.
40
45
 
41
46
  - *IMPORTANT*: You *MUST* honor the following control flow construct:
42
47
  <if condition="<if-condition/>"><if-body/></if>:
@@ -132,6 +132,8 @@ Let the *user interactively choose* an answer.
132
132
  (prefix result with "OTHER").
133
133
 
134
134
  Do not output anything in this step!
135
+
135
136
  </if>
137
+
136
138
  </define>
137
139
 
@@ -219,11 +219,11 @@ at runtime.
219
219
  Processor`, `Notification Dispatcher`).
220
220
 
221
221
  - <arch-fv-component-kind/> is one of:
222
- - `Component`: Cohesive unit of functionality with a defined interface.
223
- - `Service`: Independently deployable provider of functionality.
224
- - `Module`: Logical grouping of related functionality within a component.
225
- - `Connector`: Mediator that conveys interactions between components (e.g. bus, gateway).
226
- - `Subsystem`: Larger composite grouping several components.
222
+ - `Component`: Cohesive unit of functionality with a defined interface.
223
+ - `Service`: Independently deployable provider of functionality.
224
+ - `Module`: Logical grouping of related functionality within a component.
225
+ - `Connector`: Mediator that conveys interactions between components (e.g. bus, gateway).
226
+ - `Subsystem`: Larger composite grouping several components.
227
227
 
228
228
  - <arch-fv-component-responsibility/> is the 1-sentence statement of
229
229
  the single, primary responsibility the component owns.
@@ -377,11 +377,11 @@ communicate.
377
377
 
378
378
  - <arch-co-unit-kind/> is one of:
379
379
 
380
- - `Process`: An independent OS process with its own address space.
381
- - `Thread`: A thread of execution within a process.
382
- - `Pool`: A managed group of interchangeable workers.
383
- - `Queue`: An asynchronous buffer decoupling producers and consumers.
384
- - `EventLoop`: A single-threaded cooperative scheduler of tasks.
380
+ - `Process`: An independent OS process with its own address space.
381
+ - `Thread`: A thread of execution within a process.
382
+ - `Pool`: A managed group of interchangeable workers.
383
+ - `Queue`: An asynchronous buffer decoupling producers and consumers.
384
+ - `EventLoop`: A single-threaded cooperative scheduler of tasks.
385
385
 
386
386
  - <arch-co-unit-element/> is an `ARCH-FV-<arch-fv-component-id/>`
387
387
  reference to a functional component that runs inside this
@@ -518,12 +518,12 @@ elements to the runtime platform, hardware, and network topology.
518
518
 
519
519
  - <arch-dp-node-kind/> is one of:
520
520
 
521
- - `Server`: A physical or virtual machine.
522
- - `Container`: A containerized runtime (e.g. Docker, OCI).
523
- - `Cluster`: A managed group of nodes (e.g. Kubernetes cluster).
524
- - `Function`: A serverless / function-as-a-service runtime.
525
- - `Device`: An edge or client device.
526
- - `Managed`: A managed cloud service (e.g. managed database, queue).
521
+ - `Server`: A physical or virtual machine.
522
+ - `Container`: A containerized runtime (e.g. Docker, OCI).
523
+ - `Cluster`: A managed group of nodes (e.g. Kubernetes cluster).
524
+ - `Function`: A serverless / function-as-a-service runtime.
525
+ - `Device`: An edge or client device.
526
+ - `Managed`: A managed cloud service (e.g. managed database, queue).
527
527
 
528
528
  - <arch-dp-node-platform/> is the runtime platform of the node
529
529
  (e.g. `Linux x86-64`, `Kubernetes 1.30`, `AWS Lambda (Node.js)`).
@@ -764,50 +764,50 @@ forces at play, the chosen response, and the reasoning that justifies it.
764
764
  as the **Artifact**'s own timestamps.
765
765
 
766
766
  - <arch-dr-decision-context/> captures the situation that forces the
767
- decision the "why are we even talking about this" part. It
767
+ decision - the "why are we even talking about this" part. It
768
768
  describes the situation as it is, before the decision is made. The
769
769
  following usually goes into it: the problem or need (what's broken,
770
770
  missing, or about to change that requires a decision); the forces at
771
771
  play (technical constraints, business requirements, deadlines, team
772
- skills, existing systems, regulatory/compliance pressures often
772
+ skills, existing systems, regulatory/compliance pressures - often
773
773
  competing, and that tension is the whole point); relevant facts
774
774
  (current architecture, prior decisions, assumptions, what's known
775
775
  and what's uncertain); and scope/boundaries (what this decision is
776
776
  and isn't about). It is written neutrally and factually. It should
777
- not contain the decision itself, nor advocate for an option a
777
+ not contain the decision itself, nor advocate for an option - a
778
778
  reader should be able to read it, pause, and arrive at the decision
779
779
  themselves because the forces make it (nearly) inevitable.
780
780
 
781
781
  - <arch-dr-decision-decision/> states what is actually going to be
782
- done the chosen response to the forces laid out in the context. It
782
+ done - the chosen response to the forces laid out in the context. It
783
783
  is written in active, assertive voice, in the present or imperative
784
784
  tense, as a committed position rather than a discussion. The
785
785
  following usually goes into it: the choice itself (clearly and
786
786
  unambiguously) and the essence of how (enough of the approach to
787
- make the choice concrete the mechanism, pattern, or technology
787
+ make the choice concrete - the mechanism, pattern, or technology -
788
788
  but not a full implementation specification). It is a declaration,
789
789
  not a deliberation, usually using the wording "We use..." or "We
790
790
  do...", active, definite, owning the choice. Avoid hedging ("we
791
- might", "we could consider") the deliberation already happened,
791
+ might", "we could consider") - the deliberation already happened,
792
792
  the decision records the verdict.
793
793
 
794
794
  - <arch-dr-decision-rationale/> is the reasoning that justifies the
795
- decision the bridge that explains why this choice, given those
795
+ decision - the bridge that explains why this choice, given those
796
796
  forces. It answers "Of all the things we could have done, why was
797
797
  this the right one?". Where the context states the forces and the
798
798
  decision states the choice, the rationale is the logical connective
799
- tissue between them it shows that the decision actually follows
799
+ tissue between them - it shows that the decision actually follows
800
800
  from the context. The following usually goes into it: the deciding
801
801
  factors (which forces from the context carried the most weight, and
802
802
  how the chosen option satisfies them best); the trade-off reasoning
803
- (what was optimized for and what was knowingly sacrificed naming
803
+ (what was optimized for and what was knowingly sacrificed - naming
804
804
  the trade-off is the heart of rationale); why the alternatives lost
805
805
  (the comparative argument: "option B failed on X, option C cost too
806
806
  much on Y"); and assumptions and evidence (benchmarks, prior
807
807
  experience, constraints, or principles the reasoning rests on).
808
808
 
809
809
  - <arch-dr-decision-notes/> is *OPTIONAL* and can be omitted when it
810
- does not add genuine value most decisions won't need it. The
810
+ does not add genuine value - most decisions won't need it. The
811
811
  following usually goes into it: information of the decision *process*
812
812
  (e.g. a weighted decision matrix of considered alternatives);
813
813
  consequences of the decision (but only when non-obvious downstream
@@ -818,16 +818,16 @@ forces at play, the chosen response, and the reasoning that justifies it.
818
818
  <arch-dr-decision-rationale/> are each just a single paragraph of
819
819
  concise and brief prose text, usually comprised of just 1 to 3
820
820
  sentences. The value of a decision is in recording *that* a decision
821
- was made and *why* not in filling out sections of a document.
821
+ was made and *why* - not in filling out sections of a document.
822
822
 
823
823
  - For the relationship between context, decision, and rationale, good
824
824
  checks are: the "litmus test" is that context = forces, decision =
825
825
  response to those forces, rationale = why the decision answers the
826
826
  forces in the context. The decision should feel like the natural,
827
- almost inevitable answer to the context if a reader is surprised
827
+ almost inevitable answer to the context - if a reader is surprised
828
828
  by the decision, either the context is missing a force, or the
829
829
  decision is under-justified. The rationale should make the decision
830
- feel earned, not asserted if you would delete the rationale and
830
+ feel earned, not asserted - if you would delete the rationale and
831
831
  the decision suddenly looks arbitrary, the rationale was doing its
832
832
  job.
833
833
 
@@ -861,7 +861,7 @@ forces at play, the chosen response, and the reasoning that justifies it.
861
861
  communicate via domain events, not synchronous HTTP."
862
862
 
863
863
  - **Technology choices that carry lock-in.** Database, message bus,
864
- auth provider, deployment target. Not every library just the
864
+ auth provider, deployment target. Not every library - just the
865
865
  ones that would take a quarter to swap out.
866
866
 
867
867
  - **Boundary and scope decisions.** "Customer data is owned by the
@@ -878,5 +878,5 @@ forces at play, the chosen response, and the reasoning that justifies it.
878
878
  of the partner API contract."
879
879
 
880
880
  - **Rejected alternatives when the rejection is non-obvious.** If
881
- you considered GraphQL and picked REST for subtle reasons, record it
881
+ you considered GraphQL and picked REST for subtle reasons, record it -
882
882
  otherwise someone will suggest GraphQL again in six months.
@@ -230,8 +230,8 @@ capturing their goals, needs, behaviors, and context.
230
230
 
231
231
  - <spec-pe-persona-role/>: the role of the persona.
232
232
 
233
- - <spec-pe-persona-quote/>: a short and bold, first-person statement
234
- written in the persona's own voice that captures their core
233
+ - <spec-pe-persona-quote/>: a short and bold, first-person statement -
234
+ written in the persona's own voice - that captures their core
235
235
  attitude, motivation, frustration, or need in a single memorable line.
236
236
  It's sometimes called the persona's "tagline," "mantra," or "defining
237
237
  statement."
@@ -1138,7 +1138,7 @@ master-detail dialog).
1138
1138
 
1139
1139
  - <spec-dp-pattern-rationale/>: the 1-sentence justification for why
1140
1140
  the structure in <spec-dp-pattern-description/> is the right
1141
- response the benefit it secures or the trade-off it wins.
1141
+ response - the benefit it secures or the trade-off it wins.
1142
1142
  Unlike <spec-dp-pattern-problem/> (which states *why the pattern
1143
1143
  is needed*, independent of any solution), the rationale states
1144
1144
  *why this particular solution is worth adopting*.
@@ -87,5 +87,6 @@ set placeholders into the context as a side-effect.
87
87
  <template>
88
88
  ⧉ **ASE**: ✪ skill: **<getopt-skill/>**, ▶ options: <getopt-info/>
89
89
  </template>
90
+
90
91
  </define>
91
92
 
@@ -33,7 +33,7 @@ Persona Ruleset Levels
33
33
  - You *MUST* *use* arrows for causality
34
34
  ("X → Y").
35
35
  - You *MUST* *use* em-dashes for short subsequent facts
36
- ("X Y").
36
+ ("X - Y").
37
37
  - You *MUST* *drop* articles
38
38
  ("a", "an", "the", etc).
39
39
  - You *MUST* *use* short separate sentences instead of conjunctions
@@ -26,7 +26,7 @@ Skill Output
26
26
  to the currently defined persona style.
27
27
 
28
28
  - *IMPORTANT*: The active *persona style* (see `ase-persona.md`) *MUST* be applied
29
- to all *free-text placeholders* within <template/> sections i.e. any placeholder
29
+ to all *free-text placeholders* within <template/> sections - i.e. any placeholder
30
30
  whose content you author yourself (such as `<description/>`, `<title/>`, `<objective/>`,
31
31
  `<summary/>`, `<explanation/>`, etc.). The *structure* of the template (fixed keywords,
32
32
  punctuation, labels) remains unchanged; only the *authored content* inside free
@@ -51,7 +51,7 @@ Skill Output
51
51
  padding, draw the top edge to that width, then keep every
52
52
  inner line (including annotations like `!`, `?`, `*`)
53
53
  within it. Count columns and verify before emitting; a
54
- one-space drift is a defect re-render.
54
+ one-space drift is a defect - re-render.
55
55
 
56
56
  - *IMPORTANT*: For *Findings* (problems, tradeoffs, warnings
57
57
  emitted by analysis skills):
@@ -61,18 +61,18 @@ Skill Output
61
61
  snippet must prove the claim *verbatim*. If the cited
62
62
  lines do not prove the claim, *re-investigate and
63
63
  re-cite correctly*. Drop the finding *only* if no code
64
- location in the scanned files proves it never drop
64
+ location in the scanned files proves it - never drop
65
65
  due to sloppy citation alone.
66
66
 
67
67
  - *Documented-context alignment*: cross-check each
68
- finding against documented context interface
68
+ finding against documented context - interface
69
69
  contracts, docstrings (Javadoc, JSDoc, Python
70
70
  docstring, ...), adjacent code comments, and
71
71
  project-level AI guidance files (`CLAUDE.md`,
72
72
  `AGENTS.md`, `GEMINI.md`, `MEMORY.md`,
73
73
  `.github/copilot-instructions.md`, `.cursor/rules/`,
74
74
  or similar). Two cases resolve via the same
75
- mechanism do *not* drop, keep the finding visible
75
+ mechanism - do *not* drop, keep the finding visible
76
76
  for traceability:
77
77
 
78
78
  - *Problem already addressed*: the finding's
@@ -136,7 +136,7 @@ MCP Tool Calls
136
136
  error), output the following and stop immediately:
137
137
 
138
138
  <template>
139
- ⧉ **ASE**: **ERROR:** MCP server not running please start it via `ase service start` and reconnect via `/mcp`, then retry.
139
+ ⧉ **ASE**: **ERROR:** MCP server not running - please start it via `ase service start` and reconnect via `/mcp`, then retry.
140
140
  </template>
141
141
 
142
142
  - If the call fails for any other reason (timeout, transport error,
@@ -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.2",
9
+ "version": "0.9.3",
10
10
  "license": "GPL-3.0-only",
11
11
  "author": {
12
12
  "name": "Dr. Ralf S. Engelschall",
@@ -16,7 +16,10 @@
16
16
  "devDependencies": {
17
17
  "@rse/stx": "1.1.5",
18
18
  "markdownlint": "0.40.0",
19
- "markdownlint-cli2": "0.22.1"
19
+ "markdownlint-cli2": "0.22.1",
20
+ "eslint": "10.4.1",
21
+ "@eslint/markdown": "8.0.2",
22
+ "eslint-markdown": "0.10.0"
20
23
  },
21
24
  "engines": {
22
25
  "npm": ">=10.0.0",