@rsconcept/rstool 1.9.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +3 -3
  2. package/dist/mappers/model-adapter.d.ts +1 -2
  3. package/dist/mappers/schema-adapter.d.ts +1 -2
  4. package/dist/mappers/types.d.ts +4 -5
  5. package/dist/models/rstool-agent.js +1 -2
  6. package/dist/session/session-store.d.ts +3 -3
  7. package/dist/session/session-store.js +1 -2
  8. package/dist/wrapper/client.d.ts +3 -4
  9. package/docs/BRIEF.md +93 -0
  10. package/docs/CONCEPTUAL-SCHEMA.md +16 -1
  11. package/docs/CONSTRUCTIONS.md +14 -2
  12. package/docs/DIAGNOSTICS.md +3 -2
  13. package/docs/DOMAIN.md +12 -0
  14. package/docs/METHOD.md +208 -0
  15. package/docs/PORTAL-API.md +38 -285
  16. package/docs/PORTAL-MODELS.md +24 -0
  17. package/docs/PORTAL-OSS.md +56 -0
  18. package/docs/PORTAL-PUBLISH.md +39 -0
  19. package/docs/PORTAL-READ.md +301 -0
  20. package/docs/README.md +7 -4
  21. package/docs/REQUIREMENTS.md +61 -0
  22. package/docs/SYNTAX.md +4 -3
  23. package/docs/TYPIFICATION.md +1 -1
  24. package/docs/brief.schema.json +173 -0
  25. package/examples/README.md +16 -2
  26. package/examples/access-control/NOTES.md +23 -0
  27. package/examples/access-control/anti/collapsed.json +439 -0
  28. package/examples/access-control/anti/weakened.json +439 -0
  29. package/examples/access-control/brief-v1.json +231 -0
  30. package/examples/access-control/brief.json +310 -0
  31. package/examples/access-control/build-rsform.ts +151 -0
  32. package/examples/access-control/requirements-v1.md +9 -0
  33. package/examples/access-control/requirements-v2.md +4 -0
  34. package/examples/access-control/rsform-session-v1.json +439 -0
  35. package/examples/access-control/rsform-session.json +523 -0
  36. package/examples/audit-diagnostics.ts +9 -1
  37. package/examples/briefs.test.ts +126 -0
  38. package/examples/clinic-booking/NOTES.md +24 -0
  39. package/examples/clinic-booking/anti/collapsed.json +615 -0
  40. package/examples/clinic-booking/anti/species-as-genus.json +568 -0
  41. package/examples/clinic-booking/brief-v1.json +332 -0
  42. package/examples/clinic-booking/brief.json +405 -0
  43. package/examples/clinic-booking/build-rsform.ts +174 -0
  44. package/examples/clinic-booking/requirements-v1.md +9 -0
  45. package/examples/clinic-booking/requirements-v2.md +4 -0
  46. package/examples/clinic-booking/rsform-session-v1.json +615 -0
  47. package/examples/clinic-booking/rsform-session.json +700 -0
  48. package/examples/diagnostics-utils.ts +26 -0
  49. package/examples/kinship/brief.json +337 -0
  50. package/examples/kinship/build-rsform.ts +7 -4
  51. package/examples/kinship/rsform-session.json +20 -63
  52. package/examples/kinship/rsmodel-session.json +14 -14
  53. package/examples/kinship-subordination/NOTES.md +49 -0
  54. package/examples/kinship-subordination/brief.json +161 -0
  55. package/examples/kinship-subordination/build-rsform.ts +100 -0
  56. package/examples/kinship-subordination/rsform-session.json +795 -0
  57. package/examples/library-loans/NOTES.md +46 -0
  58. package/examples/library-loans/anti/collapsed.json +481 -0
  59. package/examples/library-loans/anti/species-as-genus.json +334 -0
  60. package/examples/library-loans/anti/uncovered.json +406 -0
  61. package/examples/library-loans/anti/weakened.json +464 -0
  62. package/examples/library-loans/brief-v1.json +340 -0
  63. package/examples/library-loans/brief.json +502 -0
  64. package/examples/library-loans/build-rsform.ts +239 -0
  65. package/examples/library-loans/requirements-v1.md +11 -0
  66. package/examples/library-loans/requirements-v2.md +5 -0
  67. package/examples/library-loans/rsform-session-v1.json +481 -0
  68. package/examples/library-loans/rsform-session.json +652 -0
  69. package/examples/library-loans/source-markup.md +18 -0
  70. package/examples/movd/brief.json +220 -0
  71. package/examples/movd/build-rsform.ts +5 -2
  72. package/examples/movd/rsform-session.json +14 -46
  73. package/examples/subordination/NOTES.md +59 -0
  74. package/examples/subordination/anti/collapsed.json +556 -0
  75. package/examples/subordination/anti/single-relation.json +125 -0
  76. package/examples/subordination/anti/transitive.json +573 -0
  77. package/examples/subordination/anti/weakened.json +539 -0
  78. package/examples/subordination/brief.json +386 -0
  79. package/examples/subordination/build-rsform.ts +63 -0
  80. package/examples/subordination/constants.ts +115 -0
  81. package/examples/subordination/rsform-session.json +556 -0
  82. package/examples/subordination/source-markup.md +19 -0
  83. package/examples/subordination/source.md +40 -0
  84. package/package.json +18 -10
  85. package/skills/INSTALL.md +28 -29
  86. package/skills/README.md +25 -10
  87. package/skills/rs-core/SKILL.md +56 -0
  88. package/skills/rs-explain/SKILL.md +28 -0
  89. package/skills/rs-explicate/SKILL.md +71 -0
  90. package/skills/rs-interpret/SKILL.md +67 -0
  91. package/skills/rs-portal/SKILL.md +51 -0
  92. package/skills/rs-review/SKILL.md +79 -0
  93. package/skills/rs-scope/SKILL.md +67 -0
  94. package/skills/rs-synthesis/SKILL.md +52 -0
  95. package/skills/rstool/SKILL.md +70 -0
  96. package/skills/rstool-helper/GUIDE.md +18 -299
  97. package/skills/rstool-helper/SKILL.md +8 -58
  98. package/skills/{rstool-helper → rstool-runtime}/EXAMPLES.md +16 -12
  99. package/skills/{rstool-helper → rstool-runtime}/REFERENCE.md +7 -5
  100. package/skills/rstool-runtime/SKILL.md +96 -0
  101. package/skills/scripts/brief-check.test.ts +165 -0
  102. package/skills/scripts/brief-check.ts +826 -0
  103. package/skills/scripts/check-brief.ts +94 -0
  104. package/skills/scripts/rstool-skills.mjs +119 -0
  105. package/skills/scripts/skill-stubs.test.ts +48 -0
@@ -0,0 +1,239 @@
1
+ /**
2
+ * «Выдача книг»: schema from software requirements v1, then change request v2 on top; anti-examples.
3
+ * Run from the package root: `pnpm run example:build-library-loans-schema`.
4
+ */
5
+ import { mkdirSync, writeFileSync } from 'node:fs';
6
+ import { resolve } from 'node:path';
7
+
8
+ import { type AgentConstituentaPatch, RSToolAgent } from '../../src';
9
+
10
+ import { describeBrief, formatDiagnostics } from '../diagnostics-utils';
11
+
12
+ const V1_ITEMS: AgentConstituentaPatch[] = [
13
+ { alias: 'X1', term: 'читатели', convention: 'Записанные читатели библиотеки.' },
14
+ { alias: 'X2', term: 'экземпляры', convention: 'Физические экземпляры книг фонда (ТЗ 1).' },
15
+ {
16
+ alias: 'X3',
17
+ term: 'издания',
18
+ convention: 'Издания: книга в конкретном издании; у издания может быть много экземпляров.'
19
+ },
20
+ {
21
+ alias: 'S1',
22
+ term: 'издание экземпляра',
23
+ definitionFormal: 'ℬ(X2×X3)',
24
+ convention: 'Пара (экземпляр, издание): экземпляр — копия издания (ТЗ 1).'
25
+ },
26
+ {
27
+ alias: 'S2',
28
+ term: 'выдачи',
29
+ definitionFormal: 'ℬ(X1×X2×Z)',
30
+ convention:
31
+ 'Тройка (читатель, экземпляр, день выдачи) для экземпляров, которые сейчас на руках (ТЗ 2). Дни — номера дней.'
32
+ },
33
+ {
34
+ alias: 'S3',
35
+ term: 'текущий день',
36
+ definitionFormal: 'Z',
37
+ convention: 'Номер текущего дня в той же нумерации, что и дни выдачи.'
38
+ },
39
+ {
40
+ alias: 'D1',
41
+ term: 'выданные экземпляры',
42
+ definitionFormal: 'Pr2(S2)',
43
+ definitionText: 'Экземпляры, которые сейчас на руках у читателей.'
44
+ },
45
+ {
46
+ alias: 'D2',
47
+ term: 'доступные экземпляры',
48
+ definitionFormal: 'X2\\D1',
49
+ definitionText: 'Экземпляры, которые сейчас не выданы.'
50
+ },
51
+ {
52
+ alias: 'F1',
53
+ term: 'экземпляры издания',
54
+ definitionFormal: '[ε∈X3] Pr1(Fi2[{ε}](S1))',
55
+ definitionText: 'Все экземпляры данного издания.'
56
+ },
57
+ {
58
+ alias: 'F2',
59
+ term: 'доступные экземпляры издания',
60
+ definitionFormal: '[ε∈X3] F1[ε]\\D1',
61
+ definitionText: 'Невыданные экземпляры данного издания.'
62
+ },
63
+ {
64
+ alias: 'D3',
65
+ term: 'доступные издания',
66
+ definitionFormal: 'D{ε∈X3 | F2[ε]≠∅}',
67
+ definitionText: 'Издания, у которых есть хотя бы один доступный экземпляр.'
68
+ },
69
+ {
70
+ alias: 'F3',
71
+ term: 'экземпляры читателя',
72
+ definitionFormal: '[ξ∈X1] Pr2(Fi1[{ξ}](S2))',
73
+ definitionText: 'Экземпляры на руках у данного читателя.'
74
+ },
75
+ {
76
+ alias: 'D4',
77
+ term: 'просроченные выдачи',
78
+ definitionFormal: 'D{σ∈S2 | pr3(σ)+14 < S3}',
79
+ definitionText: 'Выдачи, с которых прошло больше 14 дней.'
80
+ },
81
+ {
82
+ alias: 'D5',
83
+ term: 'читатели с выдачами',
84
+ definitionFormal: 'Pr1(S2)',
85
+ definitionText: 'Читатели, у которых есть экземпляр на руках.'
86
+ },
87
+ {
88
+ alias: 'D6',
89
+ term: 'должники',
90
+ definitionFormal: 'Pr1(D4)',
91
+ definitionText: 'Читатели с хотя бы одной просроченной выдачей.'
92
+ },
93
+ {
94
+ alias: 'A1',
95
+ term: 'экземпляр выдан одному читателю',
96
+ definitionFormal: 'card(Pr2(S2))=card(S2)',
97
+ definitionText: 'Один экземпляр не выдан двум читателям и не записан дважды (ТЗ 3).'
98
+ },
99
+ {
100
+ alias: 'A2',
101
+ term: 'не больше 5 экземпляров на руках',
102
+ definitionFormal: '∀ξ∈X1 card(F3[ξ])≤5',
103
+ definitionText: 'ТЗ 4.'
104
+ },
105
+ {
106
+ alias: 'A3',
107
+ term: 'у экземпляра одно издание',
108
+ definitionFormal: 'card(S1)=card(Pr1(S1)) & Pr1(S1)=X2',
109
+ definitionText: 'Каждый экземпляр — копия ровно одного издания (ТЗ 1).'
110
+ },
111
+ {
112
+ alias: 'A4',
113
+ term: 'выдача не из будущего',
114
+ definitionFormal: '∀σ∈S2 pr3(σ)≤S3',
115
+ definitionText: 'День выдачи не позже текущего дня.'
116
+ }
117
+ ];
118
+
119
+ /** Change request v2: renewals and reservations; D4 is redefined by decision DC8. */
120
+ const V2_ITEMS: AgentConstituentaPatch[] = [
121
+ {
122
+ alias: 'S4',
123
+ term: 'продления',
124
+ definitionFormal: 'ℬ(X2×Z)',
125
+ convention: 'Пара (экземпляр, номер продления 1, 2, …) для каждого сделанного продления текущей выдачи.'
126
+ },
127
+ {
128
+ alias: 'F4',
129
+ term: 'число продлений',
130
+ definitionFormal: '[ε∈X2] card(Fi1[{ε}](S4))',
131
+ definitionText: 'Сколько раз продлена выдача данного экземпляра.'
132
+ },
133
+ {
134
+ alias: 'D4',
135
+ definitionFormal: 'D{σ∈S2 | pr3(σ) + 14 * (1 + F4[pr2(σ)]) < S3}',
136
+ definitionText: 'Выдачи, у которых истёк срок: 14 дней плюс по 14 дней за каждое продление.'
137
+ },
138
+ {
139
+ alias: 'S5',
140
+ term: 'брони',
141
+ definitionFormal: 'ℬ(X1×X3)',
142
+ convention: 'Пара (читатель, издание): читатель забронировал издание (v2 п. 2).'
143
+ },
144
+ {
145
+ alias: 'D7',
146
+ term: 'забронированные издания',
147
+ definitionFormal: 'Pr2(S5)',
148
+ definitionText: 'Издания, на которые есть бронь.'
149
+ },
150
+ {
151
+ alias: 'A5',
152
+ term: 'не больше двух продлений',
153
+ definitionFormal: '∀ε∈X2 F4[ε]≤2',
154
+ definitionText: 'v2 п. 1.'
155
+ },
156
+ {
157
+ alias: 'A6',
158
+ term: 'продлевается только выданное',
159
+ definitionFormal: 'Pr1(S4)⊆D1',
160
+ definitionText: 'Продления есть только у экземпляров на руках.'
161
+ },
162
+ {
163
+ alias: 'A7',
164
+ term: 'бронь только недоступного издания',
165
+ definitionFormal: '∀ρ∈S5 F2[pr2(ρ)]=∅',
166
+ definitionText: 'Бронируют издание, у которого нет доступных экземпляров (v2 п. 2).'
167
+ }
168
+ ];
169
+
170
+ function replaceItem(items: AgentConstituentaPatch[], alias: string, patch: Partial<AgentConstituentaPatch>) {
171
+ return items.map(item => (item.alias === alias ? { ...item, ...patch } : item));
172
+ }
173
+
174
+ /** «Green but wrong» variants of v1 (see NOTES.md). */
175
+ const ANTI_EXAMPLES: Record<string, AgentConstituentaPatch[]> = {
176
+ 'uncovered': V1_ITEMS.filter(item => !['D2', 'F2', 'D3'].includes(item.alias)),
177
+ 'weakened': [
178
+ ...V1_ITEMS.filter(item => !['A1', 'D4', 'D6'].includes(item.alias)),
179
+ {
180
+ alias: 'S4',
181
+ term: 'просроченные выдачи',
182
+ definitionFormal: 'ℬ(X1×X2×Z)',
183
+ convention: 'Просроченные выдачи, их отмечает библиотекарь.'
184
+ },
185
+ { alias: 'D6', term: 'должники', definitionFormal: 'Pr1(S4)', definitionText: 'Читатели с просроченной выдачей.' }
186
+ ],
187
+ 'species-as-genus': [
188
+ ...V1_ITEMS.filter(item => !['S2', 'D1', 'F3', 'D4', 'D5', 'D6', 'A1', 'A2', 'A4'].includes(item.alias)),
189
+ {
190
+ alias: 'S2',
191
+ term: 'читатель экземпляра',
192
+ definitionFormal: 'ℬ(X2×X1)',
193
+ convention: 'Пара (экземпляр, читатель): у кого экземпляр сейчас.'
194
+ },
195
+ { alias: 'D1', term: 'выданные экземпляры', definitionFormal: 'Pr1(S2)' },
196
+ { alias: 'D5', term: 'читатели с выдачами', definitionFormal: 'Pr2(S2)' }
197
+ ],
198
+ 'collapsed': replaceItem(V1_ITEMS, 'D6', { definitionFormal: 'D5' })
199
+ };
200
+
201
+ function buildSession(title: string, items: AgentConstituentaPatch[]): string {
202
+ const tool = new RSToolAgent();
203
+ tool.createSession({ alias: 'LIB', title, comment: describeBrief(resolve(import.meta.dirname, 'brief-v1.json')) });
204
+ const result = tool.applySchemaPatch({ items, commitMessage: title });
205
+ const diagnostics = tool.listDiagnostics();
206
+ if (!result.success || diagnostics.length > 0) {
207
+ throw new Error(`${title}: ${formatDiagnostics(diagnostics)}`);
208
+ }
209
+ return tool.exportSession() + '\n';
210
+ }
211
+
212
+ function buildV2(): string {
213
+ const tool = new RSToolAgent();
214
+ tool.createSession({
215
+ alias: 'LIB',
216
+ title: 'Выдача книг',
217
+ comment: describeBrief(resolve(import.meta.dirname, 'brief.json'))
218
+ });
219
+ tool.applySchemaPatch({ items: V1_ITEMS, commitMessage: 'v1' });
220
+ const result = tool.applySchemaPatch({ items: V2_ITEMS, commitMessage: 'v2: продления и брони' });
221
+ const diagnostics = tool.listDiagnostics();
222
+ if (!result.success || diagnostics.length > 0) {
223
+ throw new Error(`v2: ${formatDiagnostics(diagnostics)}`);
224
+ }
225
+ return tool.exportSession() + '\n';
226
+ }
227
+
228
+ function run() {
229
+ const root = import.meta.dirname;
230
+ writeFileSync(resolve(root, 'rsform-session-v1.json'), buildSession('Выдача книг', V1_ITEMS));
231
+ writeFileSync(resolve(root, 'rsform-session.json'), buildV2());
232
+ mkdirSync(resolve(root, 'anti'), { recursive: true });
233
+ for (const [name, items] of Object.entries(ANTI_EXAMPLES)) {
234
+ writeFileSync(resolve(root, 'anti', `${name}.json`), buildSession(`Антипример: ${name}`, items));
235
+ }
236
+ console.log(`library-loans: v1, v2 + ${Object.keys(ANTI_EXAMPLES).length} anti-examples`);
237
+ }
238
+
239
+ run();
@@ -0,0 +1,11 @@
1
+ # ТЗ «Выдача книг», v1 (фрагмент)
2
+
3
+ 1. Фонд библиотеки состоит из экземпляров; каждый экземпляр — копия одного издания.
4
+ 2. Читатель берёт экземпляр на 14 дней. Выдача фиксирует читателя, экземпляр и день выдачи.
5
+ 3. Экземпляр не может быть выдан двум читателям одновременно.
6
+ 4. Читатель может держать на руках не больше 5 экземпляров.
7
+ 5. Выдача просрочена, если 14 дней с выдачи прошли, а экземпляр не возвращён. Должник — читатель с просроченной выдачей.
8
+ 6. Система показывает доступные экземпляры (не выданные) и издания, у которых есть доступный экземпляр.
9
+ 7. Возвращённый экземпляр снова доступен; история выдач хранится для отчётов.
10
+ 8. За просрочку начисляется штраф 10 рублей в день.
11
+ 9. Интерфейс каталога должен поддерживать поиск по автору и названию.
@@ -0,0 +1,5 @@
1
+ # Запрос на изменение v2
2
+
3
+ 1. Выдачу можно продлить, каждый раз ещё на 14 дней, но не больше двух раз.
4
+ 2. Читатель может забронировать издание, если сейчас у издания нет доступных экземпляров.
5
+ 3. Всё, что было в v1, должно работать как раньше.