universal-dev-standards 5.8.0 → 5.10.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.
@@ -0,0 +1,459 @@
1
+ # Feature Discovery Standards - AI Optimized
2
+ # Source: core/feature-discovery-standards.md
3
+
4
+ id: feature-discovery-standards
5
+ meta:
6
+ version: "1.0.0"
7
+ updated: "2026-05-13"
8
+ source: core/feature-discovery-standards.md
9
+ description: Language-agnostic methodology for exhaustive feature discovery in legacy systems; defines Deterministic-First principle, Software Form Taxonomy, five static foundations, dynamic/human observation protocols, and cross-layer validation matrix
10
+ pipeline_position: "Discovery → feature-manifest-standard → behavior-snapshot"
11
+ references:
12
+ - "XSPEC-202: Feature Discovery Standards"
13
+ - "XSPEC-199/200/201: Migration completeness protocol suite"
14
+
15
+ # === CORE PRINCIPLE ===
16
+ core_principle:
17
+ name: Deterministic-First
18
+ statement: |
19
+ AI cannot tell you what it doesn't know it doesn't know.
20
+ RAG solves "find details about a known feature."
21
+ It does NOT solve "discover that this feature exists."
22
+ Exhaustive feature discovery requires deterministic tools (grep/AST/log/schema) — not AI inference.
23
+ blocking_rule: |
24
+ If deterministic extraction results are absent when entering Discovery Phase,
25
+ AI MUST output: [BLOCKED] Missing deterministic extraction artifacts.
26
+ Run extraction tools first before AI analysis.
27
+ rag_prohibition:
28
+ phase: Discovery Phase
29
+ rule: AI is PROHIBITED from generating a feature list through inference or RAG retrieval alone
30
+ rationale: AI will not report what it doesn't know it missed — only deterministic tools produce exhaustive lists
31
+ ai_role_in_discovery:
32
+ - Classify extracted items into feature categories
33
+ - Assign confidence scores to candidates
34
+ - Fill business-purpose descriptions for confirmed entries
35
+ - NOT generate the initial feature list
36
+
37
+ # === SOFTWARE FORM TAXONOMY ===
38
+ software_form_taxonomy:
39
+ description: Identify the software form before choosing extraction strategy. If ambiguous, check detection_signals or ask the user.
40
+ forms:
41
+ web:
42
+ entry_points:
43
+ - Route definitions (routes files, controllers)
44
+ - HTTP method handlers (GET/POST/PUT/PATCH/DELETE)
45
+ - Middleware registrations
46
+ detection_signals:
47
+ - routes/ or app/Http/ directory
48
+ - composer.json (PHP) / package.json with express/fastify/hono (Node) / requirements.txt with django/flask/fastapi (Python)
49
+ - controllers/ or handlers/ directory
50
+ extraction_tools:
51
+ - "grep routes for route definitions (framework-specific)"
52
+ - "DB schema extraction (SHOW TABLES / INFORMATION_SCHEMA / schema.prisma)"
53
+ - "access log analysis: awk '{print $7}' access.log | sort -u"
54
+ - "grep form action and AJAX calls in view templates"
55
+ - "grep for email/notification sending patterns"
56
+
57
+ cli:
58
+ entry_points:
59
+ - main() function and equivalents
60
+ - Argument parser registrations (subcommands, flags, options)
61
+ - Shell completion definitions
62
+ detection_signals:
63
+ - "argparse / click / cobra / clap / typer import"
64
+ - cmd/ or commands/ directory
65
+ - No web server bind/listen calls
66
+ extraction_tools:
67
+ - "grep -rE 'ArgumentParser|getopt|click\\.command|cobra\\.Command|clap::App|typer\\.Typer' ."
68
+ - "Run with --help and list all subcommands recursively"
69
+ - "find . -name '*_complete*' -o -name '*.completion.sh' (shell completion files)"
70
+ - "grep subcommand registration patterns"
71
+
72
+ gui:
73
+ entry_points:
74
+ - Menu item handlers
75
+ - Button/widget event listeners
76
+ - UI definition files (.ui, .fxml, .qml, .xib, .storyboard)
77
+ detection_signals:
78
+ - ".ui / .qrc / .fxml / .glade / .qml / .xib / .storyboard files"
79
+ - "QMainWindow / JFrame / NSViewController / Activity / Fragment subclasses"
80
+ - "addEventListener / connect(SIGNAL) / @IBAction / Slot annotation"
81
+ extraction_tools:
82
+ - "find . -name '*.ui' -o -name '*.fxml' -o -name '*.glade' -o -name '*.qml'"
83
+ - "grep -rE 'addEventListener|Slot\\(|@IBAction|on_click|connect\\(SIGNAL'"
84
+ - "Extract menu items from UI definition XML files"
85
+ - "grep keyboard shortcut constant definitions"
86
+
87
+ daemon:
88
+ entry_points:
89
+ - main() with event loop
90
+ - Signal handlers (SIGTERM, SIGINT, SIGUSR1, SIGUSR2, SIGHUP)
91
+ - Socket bind/listen registrations
92
+ - Configuration option definitions
93
+ detection_signals:
94
+ - systemd .service unit file
95
+ - "signal() / sigaction() calls"
96
+ - "bind() / listen() socket calls"
97
+ - "No UI framework imports"
98
+ extraction_tools:
99
+ - "grep -rE 'signal\\(|SIGTERM|SIGUSR[12]|SIGHUP' ."
100
+ - "netstat -tlnp (if process is running)"
101
+ - "Parse config file schema — each option = one configurable behavior"
102
+ - "find /etc/systemd -name '*.service' 2>/dev/null"
103
+
104
+ library:
105
+ entry_points:
106
+ - Public API surface (exported symbols)
107
+ - Header files (C/C++)
108
+ - index.d.ts / __init__.py / index.js exports
109
+ detection_signals:
110
+ - No main() entry point
111
+ - package.json with 'main' or 'exports' fields
112
+ - Header files in include/ or src/ with public API markers
113
+ - "setup.py / pyproject.toml without console_scripts entry point"
114
+ extraction_tools:
115
+ - "cat index.d.ts or src/__init__.py or include/*.h"
116
+ - "grep -rE '^(public|export|__all__)' ."
117
+ - "nm <binary> | grep ' T ' for exported symbols"
118
+ - "Analyze existing test files — tests ARE the API specification"
119
+
120
+ mobile:
121
+ entry_points:
122
+ - Activity / Fragment (Android)
123
+ - UIViewController / SwiftUI View (iOS)
124
+ - Intent filters and deep link handlers
125
+ - Push notification handlers
126
+ detection_signals:
127
+ - AndroidManifest.xml
128
+ - Info.plist
129
+ - "extends Activity / AppCompatActivity"
130
+ - "implements UIApplicationDelegate"
131
+ extraction_tools:
132
+ - "grep android:name in AndroidManifest.xml for all Activities and Services"
133
+ - "grep CFBundleURLTypes in Info.plist for deep link schemes"
134
+ - "find . -name '*.storyboard' -o -name '*.xib'"
135
+ - "grep -rE 'onReceive|BroadcastReceiver|UNUserNotification|didReceiveRemoteNotification'"
136
+
137
+ embedded:
138
+ entry_points:
139
+ - Interrupt handlers (ISR)
140
+ - Main control loop (usually infinite)
141
+ - Communication protocol parsers (UART/SPI/I2C/CAN/USB)
142
+ - Watchdog / timer handlers
143
+ detection_signals:
144
+ - "#include <avr/interrupt.h> or equivalent"
145
+ - "ISR() macro usage"
146
+ - "HAL_ prefix functions (STM32 HAL)"
147
+ - "No OS process model"
148
+ extraction_tools:
149
+ - "grep -rE 'ISR\\(|__interrupt|INTERRUPT_HANDLER|_irq_handler'"
150
+ - "grep -rE 'HAL_UART|SPI_Transmit|I2C_Master|CAN_Transmit'"
151
+ - "grep -rE 'WATCHDOG|WDT_|tim_irq'"
152
+ - "Parse linker script (.ld) for memory map and section layout"
153
+
154
+ # === FIVE STATIC FOUNDATIONS ===
155
+ static_foundations:
156
+ description: |
157
+ Apply to ALL software forms when git history, access logs, and runtime execution are unavailable.
158
+ Execute in order 1→5; each foundation produces one candidate list.
159
+ ANY item appearing in ANY foundation = confirmed feature candidate.
160
+ Merge results into the cross-layer validation matrix before writing feature-manifest.yaml.
161
+
162
+ foundations:
163
+ - name: Entry Points
164
+ order: 1
165
+ description: All locations where program execution begins — the most reliable foundation; directly maps to features
166
+ what_to_find:
167
+ - main() functions and framework equivalents
168
+ - Route/handler registrations (web)
169
+ - Event listener registrations
170
+ - Public API surface (library)
171
+ output: "Entry point inventory (file:line, handler name, interaction type)"
172
+
173
+ - name: Call Graph
174
+ order: 2
175
+ description: From all entry points, trace all reachable functions — reveals hidden features in deeply nested logic and utility wrappers
176
+ tools:
177
+ - "C/C++: cflow src/main.c; doxygen + graphviz"
178
+ - "Python: pyan3 *.py --html > callgraph.html"
179
+ - "JavaScript/TypeScript: madge --image graph.svg src/"
180
+ - "Java: jdeps -v myapp.jar"
181
+ - "Go: go tool callgraph ./..."
182
+ dead_code_note: "Functions unreachable from any entry point = dead code OR dynamic dispatch — flag for human review, do not silently exclude"
183
+ output: "Call graph (entry points → reachable functions); dead code candidate list"
184
+
185
+ - name: String Mining
186
+ order: 3
187
+ description: UI strings, error messages, and log calls reveal features and boundary conditions that are hard to find in code structure alone
188
+ extraction_commands:
189
+ - "grep -rhoE '\"[^\"{10,}\"' . | sort -u > strings.txt # strings ≥10 chars"
190
+ - "grep -rE 'throw|raise|Error|Exception' . | grep -oE '\"[^\"]+\"' # error messages"
191
+ - "grep -rE 'log\\.|logger\\.|console\\.log|printf\\(|print\\(' . # log calls"
192
+ - "grep -rE 'Button|Label|Menu|Dialog|MessageBox|Toast' . # UI element strings"
193
+ error_message_value: "Each unique error message = a boundary condition = a test scenario. Feed string corpus to AI for feature classification."
194
+ output: "String corpus (UI labels, error messages, log entries) — feed to AI for classification after collection"
195
+
196
+ - name: Resource Files
197
+ order: 4
198
+ description: Internationalization files, icons, config schemas, and templates are fingerprints of features — often more complete than code analysis
199
+ what_to_find:
200
+ - "i18n/l10n files (*.po, *.json locale, messages.properties, *.resx, *.strings)"
201
+ - "Icon files (each icon typically represents one feature or action)"
202
+ - "Config schema (each option = one configurable behavior = one feature dimension)"
203
+ - "Report/document templates (*.jrxml, *.tpl, *.template, *.docx template)"
204
+ - "Installation/deployment scripts (Makefile, *.sh, Dockerfile, *.spec)"
205
+ i18n_value: "i18n file keys are often the most complete inventory of all UI elements — each key = one visible feature element"
206
+ output: "Resource inventory (i18n keys, icon names, config options, template names)"
207
+
208
+ - name: External Interfaces
209
+ order: 5
210
+ description: All ways the software interacts with the outside world — frequently missed because they appear as utility code rather than features
211
+ what_to_find:
212
+ - "File I/O: fopen, open(), File., fs., ifstream, ofstream, Path.read_text"
213
+ - "Network: http://, https://, socket, bind, connect, tcp, udp, WebSocket"
214
+ - "Process execution: exec(), system(), Process., subprocess, os.system"
215
+ - "Library loading: LoadLibrary, dlopen, importlib.import_module"
216
+ - "Environment variables: getenv, os.environ, ENV[], process.env"
217
+ - "OS registry/config: RegOpenKey (Windows), UserDefaults (macOS)"
218
+ extraction_commands:
219
+ - "grep -rE 'fopen|open\\(|File\\.|fs\\.' . | grep -v test"
220
+ - "grep -rE 'http://|https://|socket\\(' . | grep -v test"
221
+ - "grep -rE 'exec\\(|system\\(|subprocess|Process\\.' . | grep -v test"
222
+ - "grep -rE 'getenv|os\\.environ|process\\.env' ."
223
+ output: "External interface inventory (file paths accessed, URLs called, env vars read, processes spawned)"
224
+
225
+ # === DYNAMIC OBSERVATION PROTOCOL ===
226
+ dynamic_observation:
227
+ description: Use when the legacy system can be executed in any environment — even partially. Dynamic observation produces more complete data than static analysis.
228
+ value: "Running the system once with tracing enabled produces a definitive reachability map that static analysis cannot match."
229
+
230
+ prerequisites:
231
+ - Legacy system can be launched (even in a degraded/dev mode)
232
+ - A person familiar with the system is available to demonstrate realistic usage
233
+
234
+ platforms:
235
+ linux:
236
+ system_calls: "strace -f -o trace.log ./oldapp # records every syscall"
237
+ library_calls: "ltrace -f -o ltrace.log ./oldapp # records every library call"
238
+ open_files: "lsof -p <pid> # shows all open files and sockets"
239
+ network: "tcpdump -i any -w net.pcap # captures all network traffic"
240
+ file_access: "inotifywait -mr /path/to/watch # caution: very noisy on large directories"
241
+
242
+ macos:
243
+ file_system: "fswatch /path/to/app # file system events"
244
+ dtrace: "sudo dtrace -n 'syscall::open*:entry { printf(\"%s\\n\", copyinstr(arg0)); }'"
245
+ network: "tcpdump -i any -w net.pcap"
246
+
247
+ windows:
248
+ process: "Process Monitor (Sysinternals ProcMon.exe) # file/registry/network/process events"
249
+ network: "WireShark # full network capture"
250
+ registry: "Process Monitor with Registry filter enabled"
251
+
252
+ universal_coverage:
253
+ tools:
254
+ - "C/C++: gcov (compile with -fprofile-arcs -ftest-coverage) + lcov for HTML report"
255
+ - "Python: coverage.py run ./script.py && coverage.py report"
256
+ - "Java: JaCoCo (Gradle/Maven plugin)"
257
+ - "JavaScript/TypeScript: nyc or c8 wrapping test runner"
258
+ - "Go: go test -coverprofile=coverage.out && go tool cover -html=coverage.out"
259
+ value: "Code coverage with REAL usage scenarios = definitive map of reachable code"
260
+
261
+ recommended_workflow:
262
+ - "Step 1: Have a domain expert demonstrate a complete typical workday"
263
+ - "Step 2: Run strace/coverage in parallel during the demonstration"
264
+ - "Step 3: Replay the demonstration 3 times for edge cases"
265
+ - "Step 4: Analyze trace for system calls, files accessed, URLs called"
266
+
267
+ output: "Execution trace (system calls, file accesses, network connections, code coverage map)"
268
+
269
+ # === HUMAN OBSERVATION PROTOCOL ===
270
+ human_observation:
271
+ description: |
272
+ Last resort for features that deterministic tools and dynamic tracing cannot find.
273
+ Required when: system cannot run, domain experts are unavailable for tracing, or features are triggered by rare business events.
274
+
275
+ techniques:
276
+ - name: User Demo Recording
277
+ steps:
278
+ - "Find 1-2 heavy users of the legacy system"
279
+ - "Ask them to screen-record (with audio) a full typical workday"
280
+ - "Review recording for any interaction not captured in other foundations"
281
+ - "Pay special attention to keyboard shortcuts, context menus, and 'power user' workflows"
282
+ value: "Reveals habitual workflows and undocumented shortcuts invisible to code analysis"
283
+
284
+ - name: Support Ticket Mining
285
+ steps:
286
+ - "Search last 6-12 months of support tickets / Jira / GitHub issues"
287
+ - "Each recurring issue type = a boundary condition or edge case feature"
288
+ - "Tickets requesting 'restore old behavior' = high-risk migration targets"
289
+ - "Group by frequency — top 20 most-reported issues likely represent missing features"
290
+
291
+ - name: Internal Knowledge Mining
292
+ sources:
293
+ - "Internal Wiki / Confluence pages about the system"
294
+ - "Slack/Teams message history filtered by system name"
295
+ - "Email threads about system behavior or change requests"
296
+ - "Old release notes (even informal changelog.txt)"
297
+
298
+ confidence_assignment:
299
+ human_observed_unverified:
300
+ value: 0.7
301
+ meaning: "Feature confirmed by user observation but not yet located in source code"
302
+ action: "Add to feature-manifest with confidence: 0.7; find source code before AC generation"
303
+ human_observed_code_located:
304
+ value: 1.0
305
+ meaning: "Feature confirmed by user AND code verified"
306
+ action: "Upgrade to 1.0 after locating the corresponding code"
307
+
308
+ output: "Human observation log (feature name, observer, date, description, confidence)"
309
+
310
+ # === CROSS-LAYER VALIDATION MATRIX ===
311
+ cross_layer_matrix:
312
+ description: |
313
+ After running all applicable foundations, merge results into this matrix.
314
+ ANY item with at least one checkmark = confirmed feature candidate → include in feature-manifest.
315
+ Items with zero checkmarks across all applicable layers = dead code candidates → flag for human review, do not silently exclude.
316
+
317
+ columns:
318
+ - id: entry_point
319
+ label: "Entry Point"
320
+ source: "Foundation 1: Entry Points"
321
+ - id: db_or_schema
322
+ label: "DB/Schema"
323
+ source: "Foundation 1 (web): DB schema; or data file for other forms"
324
+ - id: log_or_dynamic
325
+ label: "Log/Dynamic"
326
+ source: "Access log (web) or dynamic observation trace"
327
+ - id: ui_or_resource
328
+ label: "UI/Resource"
329
+ source: "Foundation 3: String Mining + Foundation 4: Resource Files"
330
+ - id: notification_or_external
331
+ label: "Notification/External"
332
+ source: "Foundation 5: External Interfaces"
333
+ - id: git_or_history
334
+ label: "Git/History"
335
+ source: "git log --grep / commit history (if available)"
336
+ - id: human
337
+ label: "Human"
338
+ source: "Human observation protocol"
339
+
340
+ confidence_formula: |
341
+ confidence = (columns_with_checkmark) / (columns_applicable_to_this_form)
342
+ Minimum to include in feature-manifest: ≥ 1 checkmark in any column
343
+ Confidence < 0.5: flag for human review before AC generation
344
+ Confidence < 0.3: require human confirmation before including in manifest
345
+
346
+ example: |
347
+ | Feature Candidate | Entry Point | DB/Schema | Log/Dynamic | UI/Resource | Notification/Ext | Git/History | Human | Confidence |
348
+ |-------------------|-------------|---------------|-------------|-------------|-----------------|-------------|-------|------------|
349
+ | UserLogin | ✅ Auth.php | ✅ users tbl | ✅ POST /login | ✅ login.html | ✅ JWT email | ✅ 2019-03 | ✅ | 1.0 |
350
+ | MonthlyReconcile | ❌ | ✅ invoices | ✅ log entry | ❌ | ✅ email tpl | ✅ 2020-11 | ✅ | 0.71 |
351
+ | AdminUserDelete | ✅ Admin.php | ✅ users tbl | ❌ | ✅ admin.html | ❌ | ✅ 2021-06 | ❌ | 0.57 |
352
+
353
+ merge_rule: "Use feature-manifest FM-NNN schema to represent each confirmed row; confidence from this matrix becomes the manifest confidence field"
354
+
355
+ # === RULES FOR AI ===
356
+ rules:
357
+ - id: deterministic-first
358
+ trigger: starting feature discovery for any legacy system
359
+ instruction: |
360
+ REQUIRE deterministic extraction results before generating any feature list.
361
+ If no extraction artifacts exist, output:
362
+ [BLOCKED] Missing deterministic extraction artifacts.
363
+ Run the following tools for <detected_form>:
364
+ <list applicable tools from Software Form Taxonomy>
365
+ Do not proceed with feature list generation until artifacts are provided.
366
+ priority: required
367
+
368
+ - id: no-rag-for-discovery
369
+ trigger: feature discovery phase
370
+ instruction: |
371
+ Do NOT use RAG or long-context inference alone to generate the initial feature list.
372
+ RAG is permitted ONLY for filling in details (description, side_effects, confidence rationale)
373
+ of features already identified by deterministic extraction.
374
+ priority: required
375
+
376
+ - id: identify-form-first
377
+ trigger: starting feature discovery
378
+ instruction: |
379
+ Identify the software form (web/cli/gui/daemon/library/mobile/embedded) before selecting extraction strategy.
380
+ Use detection_signals from software_form_taxonomy to determine the form.
381
+ If ambiguous, ask the user: "This looks like [form] based on [signal]. Confirm or specify --form <type>."
382
+ priority: required
383
+
384
+ - id: apply-all-static-foundations
385
+ trigger: source-only analysis (no git, no log, no runtime)
386
+ instruction: |
387
+ Execute ALL five static foundations in order: entry_points → call_graph → string_mining → resource_files → external_interfaces.
388
+ Do not skip foundations even if earlier ones seem comprehensive — each foundation catches different categories of features.
389
+ Each foundation produces a candidate list. Merge ALL lists into the cross-layer matrix.
390
+ priority: required
391
+
392
+ - id: prefer-dynamic-observation
393
+ trigger: legacy system can be executed in any environment
394
+ instruction: |
395
+ When the system can run, prefer dynamic observation over static analysis.
396
+ Running with strace/coverage + domain expert demonstration produces a more complete feature map.
397
+ Static foundations are still required — dynamic observation complements, not replaces them.
398
+ priority: recommended
399
+
400
+ - id: human-observation-for-gaps
401
+ trigger: features cannot be confirmed through any tool-based foundation
402
+ instruction: |
403
+ When a feature candidate cannot be confirmed through any tool-based foundation,
404
+ escalate to human observation protocol.
405
+ Assign confidence: 0.7 for human-observed but code-unverified features.
406
+ Do not include confidence < 0.3 features in manifest without explicit human confirmation.
407
+ priority: required
408
+
409
+ - id: matrix-before-manifest
410
+ trigger: generating feature-manifest.yaml
411
+ instruction: |
412
+ Complete the cross-layer validation matrix before writing feature-manifest.yaml.
413
+ Only items with ≥1 checkmark in the matrix should become FM-NNN entries.
414
+ Zero-checkmark items are dead code candidates — list separately for human review.
415
+ priority: required
416
+
417
+ - id: dead-code-handling
418
+ trigger: call graph analysis reveals unreachable code
419
+ instruction: |
420
+ Functions unreachable from any entry point are dead code candidates.
421
+ Do NOT silently exclude them — list them in a separate section of the feature manifest as dead_code_candidates.
422
+ Dynamic dispatch (virtual functions, reflection) can make code appear unreachable in static analysis.
423
+ Require human confirmation before classifying anything as dead code.
424
+ priority: required
425
+
426
+ # Quick Reference
427
+ quick_reference:
428
+ software_forms:
429
+ columns: [Form, Key Entry Points, Primary Detection Signal, Fastest Extraction Tool]
430
+ rows:
431
+ - [web, Routes + Controllers, routes/ directory, "grep 'Route::' or framework equivalent"]
432
+ - [cli, main() + arg parser, argparse/click/cobra import, "run --help; grep arg parser"]
433
+ - [gui, Menu/Button handlers, .ui/.fxml/.xib files, "find . -name '*.ui'"]
434
+ - [daemon, main() + signal handlers, systemd .service file, "grep signal()/bind()"]
435
+ - [library, Public API exports, No main(); index.d.ts, "cat index.d.ts or __init__.py"]
436
+ - [mobile, Activity/ViewController, AndroidManifest.xml / Info.plist, "grep android:name"]
437
+ - [embedded, ISR + main loop, ISR() macro, "grep ISR\\("]
438
+
439
+ static_foundations_order:
440
+ columns: [Order, Foundation, What It Catches, Output]
441
+ rows:
442
+ - [1, Entry Points, "Direct feature invocation points", "Entry point inventory"]
443
+ - [2, Call Graph, "Hidden logic reachable from entry points", "Call graph + dead code candidates"]
444
+ - [3, String Mining, "UI features + boundary conditions", "String corpus for AI classification"]
445
+ - [4, Resource Files, "i18n keys (often most complete list), icons, config", "Resource inventory"]
446
+ - [5, External Interfaces, "File I/O, network, env vars, process calls", "External interface inventory"]
447
+
448
+ pipeline:
449
+ description: "Where this standard fits in the migration/refactoring pipeline"
450
+ flow: "feature-discovery-standards (FIND) → feature-manifest-standard (REPRESENT) → behavior-snapshot (VERIFY)"
451
+ gate_sequence: "Gate 0 (characterization) → Gate 1 (manifest exists) → Gate N (no not_implemented)"
452
+
453
+ related_standards:
454
+ - feature-manifest-standard.ai.yaml
455
+ - behavior-snapshot.ai.yaml
456
+ - reverse-engineering-standards.ai.yaml
457
+ - anti-hallucination.ai.yaml
458
+ - acceptance-criteria-traceability.ai.yaml
459
+ - refactoring-standards.ai.yaml
@@ -4,16 +4,17 @@
4
4
  standard:
5
5
  id: feature-manifest-standard
6
6
  name: Feature Manifest Standard
7
- description: Machine-readable feature inventory format for migration and refactoring projects; defines FM-NNN schema, confidence scoring, and FEATURE_STUB hook protocol
7
+ description: Machine-readable feature inventory format for migration and refactoring projects; defines FM-NNN schema, confidence scoring, FEATURE_STUB hook protocol, and language pack extension point
8
8
 
9
9
  meta:
10
- version: "1.0.0"
11
- updated: "2026-05-12"
10
+ version: "1.1.0"
11
+ updated: "2026-05-13"
12
12
  source: core/feature-manifest-standard.md
13
13
  references:
14
14
  - "XSPEC-200: Migration Feature Inventory and Completeness Gate"
15
15
  - "XSPEC-201: Refactor/Migration Completeness Protocol"
16
16
  - "XSPEC-199: AC not_implemented status"
17
+ - "XSPEC-203: Language Pack Architecture (language_packs extension point)"
17
18
 
18
19
  manifest_schema:
19
20
  description: Structure of feature-manifest.yaml for a migration or refactoring project
@@ -39,7 +40,7 @@ standard:
39
40
  - controller: "ClassName::methodName"
40
41
  - confidence: "0.0–1.0 (see confidence_scoring)"
41
42
  - side_effects: "list of DB_READ|DB_WRITE|EMAIL|QUEUE|HTTP_CALL|FILE"
42
- - migration_risks: "list of risk labels (see migration_risks)"
43
+ - migration_risks: "list of risk labels (generic from migration_risks.generic, or from a language pack — see migration_risks.language_packs)"
43
44
  - ac_id: "null initially; set by Planner"
44
45
  - status: "not_implemented (initial value for all migration features)"
45
46
 
@@ -62,22 +63,7 @@ standard:
62
63
  human_review_rule: "All features with confidence < 0.5 MUST be reviewed by a human before AC generation"
63
64
 
64
65
  migration_risks:
65
- description: Risk labels for migration to target language
66
- php_to_csharp:
67
- - label: SESSION_HANDLING
68
- description: PHP session → ASP.NET Core Session/Cookie middleware
69
- - label: ORM_DIFFERENCES
70
- description: Eloquent ORM → Entity Framework behavioral differences
71
- - label: TIMEZONE_HANDLING
72
- description: PHP timezone functions → .NET DateTimeOffset
73
- - label: FILE_UPLOAD_PATH
74
- description: PHP $_FILES superglobal → ASP.NET Core IFormFile
75
- - label: REGEX_DIFFERENCES
76
- description: PHP PCRE syntax vs .NET Regex syntax differences
77
- - label: ARRAY_FUNCTIONS
78
- description: PHP array_* functions → LINQ equivalents
79
- - label: EXCEPTION_HIERARCHY
80
- description: PHP exception hierarchy vs .NET exception hierarchy differences
66
+ description: Risk labels for migration projects. Generic labels apply to all language pairs; language-pair specific risks are provided by Language Packs (see language_packs).
81
67
  generic:
82
68
  - label: ASYNC_MODEL
83
69
  description: Sync code → async/await migration required
@@ -85,6 +71,23 @@ standard:
85
71
  description: Null handling differences between source and target language
86
72
  - label: STRING_ENCODING
87
73
  description: String encoding/collation differences
74
+ - label: CONCURRENCY_MODEL
75
+ description: Thread/concurrency model differences (e.g., GIL → goroutine, thread pool → async runtime)
76
+ - label: PACKAGE_ECOSYSTEM
77
+ description: Package management and dependency resolution differences between ecosystems
78
+ - label: TYPE_SYSTEM
79
+ description: Type system strictness differences (e.g., dynamic → static typing, structural → nominal)
80
+ language_packs:
81
+ description: |
82
+ Language-pair specific risks are provided by Language Packs in ai/language-packs/.
83
+ In feature-manifest.yaml features[].migration_risks, combine generic labels and language pack labels freely.
84
+ Language packs are optional — teams migrating between unsupported pairs use generic labels only.
85
+ reference: "See ai/language-packs/language-pack-<source>-to-<target>.ai.yaml"
86
+ available:
87
+ - id: php-to-csharp
88
+ file: "ai/language-packs/language-pack-php-to-csharp.ai.yaml"
89
+ description: PHP → C# (ASP.NET Core) migration risks
90
+ extension_point: true
88
91
 
89
92
  feature_stub_protocol:
90
93
  description: How to use FEATURE_STUB markers in target codebase (XSPEC-200)
@@ -3,12 +3,86 @@
3
3
 
4
4
  id: mock-boundary
5
5
  meta:
6
- version: "1.0.0"
7
- updated: "2026-05-04"
6
+ version: "1.1.0"
7
+ updated: "2026-05-13"
8
8
  source: core/mock-boundary.md
9
9
  description: >
10
10
  Rules defining what can and cannot be mocked to prevent hollow tests —
11
11
  tests that pass while the real system is broken.
12
+ v1.1.0: Added Level 1/Level 2 mock layer distinction and external
13
+ dependency testability matrix template (XSPEC-204).
14
+
15
+ # ─────────────────────────────────────────────────────────
16
+ # Mock Levels (v1.1.0)
17
+ # ─────────────────────────────────────────────────────────
18
+ mock_levels:
19
+ description: >
20
+ Two distinct levels of test doubles with separate governance rules.
21
+ Conflating them leads to the "STUB blocked ∩ real service unavailable = untestable"
22
+ deadlock in UAT environments.
23
+
24
+ level_1:
25
+ name: Code-level Mock
26
+ description: >
27
+ Test doubles within test code — jest.mock(), Moq.Mock<T>(), vi.fn(), etc.
28
+ governance: "Regulated by STUB marker rules (full-coverage-testing)"
29
+ examples:
30
+ - "vi.mock('../../src/services/sms-service.js')"
31
+ - "new Mock<ISmsService>()"
32
+ - "httpClient.Setup(x => x.PostAsync(...)).ReturnsAsync(...)"
33
+ rules:
34
+ - "Subject to // WARNING: STUB deployment-blocking rules"
35
+ - "Not allowed in flow/integration/E2E tests (see forbidden section)"
36
+ - "STUB marker must be placed at usage site"
37
+
38
+ level_2:
39
+ name: Infrastructure-level Stub Server
40
+ description: >
41
+ Independently running test-double services — WireMock, MockSoap, stub-server, json-server, etc.
42
+ These run as separate processes alongside the application under test.
43
+ governance: "Regulated by environment stratification rules (multi-environment-e2e-testing)"
44
+ examples:
45
+ - "WireMock running on port 9999, app configured via env var to hit it"
46
+ - "MockSoap sidecar for SOAP gateway simulation"
47
+ - "json-server for external REST API simulation"
48
+ rules:
49
+ - "NOT subject to STUB deployment-blocking rules (they are infrastructure, not code)"
50
+ - "MAY be used in UAT environment when real external service is unavailable"
51
+ - "MUST be documented in the external-dependency-testability-matrix as ⚠️"
52
+ - "MUST list dimensions NOT verifiable through the stub"
53
+ - "MUST NOT be deployed to or accessible from PRD environment"
54
+ - "MUST be deployed as sidecar (not bundled in production artifact)"
55
+
56
+ level_2_rationale: >
57
+ When full-coverage-testing blocks STUB markers AND the real external service
58
+ is unavailable in UAT (e.g., SMS gateway requires billing setup), Level 2
59
+ stub servers are the correct solution. They allow the flow to execute in UAT
60
+ while clearly documenting which verification dimensions are deferred to PRD.
61
+
62
+ # ─────────────────────────────────────────────────────────
63
+ # External Dependency Testability Matrix Template
64
+ # ─────────────────────────────────────────────────────────
65
+ external_dependency_testability_matrix:
66
+ rule: >
67
+ Projects with external service dependencies MUST maintain this matrix.
68
+ It answers: "In this environment, can we fully verify this service integration?"
69
+ location: "docs/testing/dependency-testability-matrix.md"
70
+ when_required: "Any project with SMS, payment, IdP, messaging, or external SOAP/REST dependencies"
71
+
72
+ template: |
73
+ ## External Dependency Testability Matrix
74
+
75
+ | External Service | local-dev | UAT | PRD | Unverifiable Dimensions in UAT |
76
+ |-----------------|:---------:|:---:|:---:|-------------------------------|
77
+ | SMS Gateway | ⚠️ L2-stub | ⚠️ L2-stub / ❌ | ✅ | Billing correctness, DR reporting, carrier delivery |
78
+ | Payment SOAP | ⚠️ L2-stub | ⚠️/❌ | ✅ | Real debit/credit, bank reconciliation, card validation |
79
+ | LDAP / AD | ⚠️ container | ⚠️ AD LDS | ✅ | Enterprise AD tree, group sync, GPO policies |
80
+ | Push Notification | ⚠️ mock | ⚠️ sandbox | ✅ | Production delivery rates, carrier-specific behavior |
81
+
82
+ Legend:
83
+ ✅ Full verification | ⚠️ Flow passes via stub (real-world dimensions deferred) | ❌ Cannot test
84
+
85
+ note: "L2-stub = Level 2 infrastructure stub server. Refer to mock-boundary Level 2 rules."
12
86
 
13
87
  # ─────────────────────────────────────────────────────────
14
88
  # Core Problem
@@ -223,6 +297,23 @@ rules:
223
297
  If any hollow test indicator triggers, rewrite the mocking strategy.
224
298
  priority: required
225
299
 
300
+ - id: level-2-stub-server-rules
301
+ trigger: UAT environment lacks a real external service (SMS, payment, IdP)
302
+ instruction: >
303
+ Use a Level 2 infrastructure stub server (WireMock, MockSoap, etc.) deployed
304
+ as a sidecar — not Level 1 code mocks, which are blocked in UAT by STUB rules.
305
+ Document the stub server in the external-dependency-testability-matrix as ⚠️
306
+ and list which verification dimensions are deferred to PRD.
307
+ priority: required
308
+
309
+ - id: no-stub-server-in-prd
310
+ trigger: deploying to production
311
+ instruction: >
312
+ Production artifact MUST NOT include stub server code.
313
+ Stub servers MUST NOT be running or accessible in PRD environment.
314
+ See deployment-standards for CI/CD exclusion rules.
315
+ priority: required
316
+
226
317
  # ─────────────────────────────────────────────────────────
227
318
  # Quick Reference
228
319
  # ─────────────────────────────────────────────────────────