agentic 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/.agentic.yml +2 -0
- data/.architecture/decisions/ArchitecturalFeatureBuilder.md +136 -0
- data/.architecture/decisions/ArchitectureConsiderations.md +200 -0
- data/.architecture/decisions/adr_001_observer_pattern_implementation.md +196 -0
- data/.architecture/decisions/adr_002_plan_orchestrator.md +320 -0
- data/.architecture/decisions/adr_003_plan_orchestrator_interface.md +179 -0
- data/.architecture/decisions/adrs/ADR-001-dependency-management.md +147 -0
- data/.architecture/decisions/adrs/ADR-002-system-boundaries.md +162 -0
- data/.architecture/decisions/adrs/ADR-003-content-safety.md +158 -0
- data/.architecture/decisions/adrs/ADR-004-agent-permissions.md +161 -0
- data/.architecture/decisions/adrs/ADR-005-adaptation-engine.md +127 -0
- data/.architecture/decisions/adrs/ADR-006-extension-system.md +273 -0
- data/.architecture/decisions/adrs/ADR-007-learning-system.md +156 -0
- data/.architecture/decisions/adrs/ADR-008-prompt-generation.md +325 -0
- data/.architecture/decisions/adrs/ADR-009-task-failure-handling.md +353 -0
- data/.architecture/decisions/adrs/ADR-010-task-input-handling.md +251 -0
- data/.architecture/decisions/adrs/ADR-011-task-observable-pattern.md +391 -0
- data/.architecture/decisions/adrs/ADR-012-task-output-handling.md +205 -0
- data/.architecture/decisions/adrs/ADR-013-architecture-alignment.md +211 -0
- data/.architecture/decisions/adrs/ADR-014-agent-capability-registry.md +80 -0
- data/.architecture/decisions/adrs/ADR-015-persistent-agent-store.md +100 -0
- data/.architecture/decisions/adrs/ADR-016-agent-assembly-engine.md +117 -0
- data/.architecture/decisions/adrs/ADR-017-streaming-observability.md +171 -0
- data/.architecture/decisions/capability_tools_distinction.md +150 -0
- data/.architecture/decisions/cli_command_structure.md +61 -0
- data/.architecture/implementation/agent_self_assembly_implementation.md +267 -0
- data/.architecture/implementation/agent_self_assembly_summary.md +138 -0
- data/.architecture/members.yml +187 -0
- data/.architecture/planning/self_implementation_exercise.md +295 -0
- data/.architecture/planning/session_compaction_rule.md +43 -0
- data/.architecture/planning/streaming_observability_feature.md +223 -0
- data/.architecture/principles.md +151 -0
- data/.architecture/recalibration/0-2-0.md +92 -0
- data/.architecture/recalibration/agent_self_assembly.md +238 -0
- data/.architecture/recalibration/cli_command_structure.md +91 -0
- data/.architecture/recalibration/implementation_roadmap_0-2-0.md +301 -0
- data/.architecture/recalibration/progress_tracking_0-2-0.md +114 -0
- data/.architecture/recalibration_process.md +127 -0
- data/.architecture/reviews/0-2-0.md +181 -0
- data/.architecture/reviews/cli_command_duplication.md +98 -0
- data/.architecture/templates/adr.md +105 -0
- data/.architecture/templates/implementation_roadmap.md +125 -0
- data/.architecture/templates/progress_tracking.md +89 -0
- data/.architecture/templates/recalibration_plan.md +70 -0
- data/.architecture/templates/version_comparison.md +124 -0
- data/.claude/settings.local.json +13 -0
- data/.claude-sessions/001-task-class-architecture-implementation.md +129 -0
- data/.claude-sessions/002-plan-orchestrator-interface-review.md +105 -0
- data/.claude-sessions/architecture-governance-implementation.md +37 -0
- data/.claude-sessions/architecture-review-session.md +27 -0
- data/ArchitecturalFeatureBuilder.md +136 -0
- data/ArchitectureConsiderations.md +229 -0
- data/CHANGELOG.md +57 -2
- data/CLAUDE.md +111 -0
- data/CONTRIBUTING.md +286 -0
- data/MAINTAINING.md +301 -0
- data/README.md +582 -28
- data/docs/agent_capabilities_api.md +259 -0
- data/docs/artifact_extension_points.md +757 -0
- data/docs/artifact_generation_architecture.md +323 -0
- data/docs/artifact_implementation_plan.md +596 -0
- data/docs/artifact_integration_points.md +345 -0
- data/docs/artifact_verification_strategies.md +581 -0
- data/docs/streaming_observability_architecture.md +510 -0
- data/exe/agentic +6 -1
- data/lefthook.yml +5 -0
- data/lib/agentic/adaptation_engine.rb +124 -0
- data/lib/agentic/agent.rb +181 -4
- data/lib/agentic/agent_assembly_engine.rb +442 -0
- data/lib/agentic/agent_capability_registry.rb +260 -0
- data/lib/agentic/agent_config.rb +63 -0
- data/lib/agentic/agent_specification.rb +46 -0
- data/lib/agentic/capabilities/examples.rb +530 -0
- data/lib/agentic/capabilities.rb +14 -0
- data/lib/agentic/capability_provider.rb +146 -0
- data/lib/agentic/capability_specification.rb +118 -0
- data/lib/agentic/cli/agent.rb +31 -0
- data/lib/agentic/cli/capabilities.rb +191 -0
- data/lib/agentic/cli/config.rb +134 -0
- data/lib/agentic/cli/execution_observer.rb +796 -0
- data/lib/agentic/cli.rb +1068 -0
- data/lib/agentic/default_agent_provider.rb +35 -0
- data/lib/agentic/errors/llm_error.rb +184 -0
- data/lib/agentic/execution_plan.rb +53 -0
- data/lib/agentic/execution_result.rb +91 -0
- data/lib/agentic/expected_answer_format.rb +46 -0
- data/lib/agentic/extension/domain_adapter.rb +109 -0
- data/lib/agentic/extension/plugin_manager.rb +163 -0
- data/lib/agentic/extension/protocol_handler.rb +116 -0
- data/lib/agentic/extension.rb +45 -0
- data/lib/agentic/factory_methods.rb +9 -1
- data/lib/agentic/generation_stats.rb +61 -0
- data/lib/agentic/learning/README.md +84 -0
- data/lib/agentic/learning/capability_optimizer.rb +613 -0
- data/lib/agentic/learning/execution_history_store.rb +251 -0
- data/lib/agentic/learning/pattern_recognizer.rb +500 -0
- data/lib/agentic/learning/strategy_optimizer.rb +706 -0
- data/lib/agentic/learning.rb +131 -0
- data/lib/agentic/llm_assisted_composition_strategy.rb +188 -0
- data/lib/agentic/llm_client.rb +215 -15
- data/lib/agentic/llm_config.rb +65 -1
- data/lib/agentic/llm_response.rb +163 -0
- data/lib/agentic/logger.rb +1 -1
- data/lib/agentic/observable.rb +51 -0
- data/lib/agentic/persistent_agent_store.rb +385 -0
- data/lib/agentic/plan_execution_result.rb +129 -0
- data/lib/agentic/plan_orchestrator.rb +464 -0
- data/lib/agentic/plan_orchestrator_config.rb +57 -0
- data/lib/agentic/retry_config.rb +63 -0
- data/lib/agentic/retry_handler.rb +125 -0
- data/lib/agentic/structured_outputs.rb +1 -1
- data/lib/agentic/task.rb +193 -0
- data/lib/agentic/task_definition.rb +39 -0
- data/lib/agentic/task_execution_result.rb +92 -0
- data/lib/agentic/task_failure.rb +66 -0
- data/lib/agentic/task_output_schemas.rb +112 -0
- data/lib/agentic/task_planner.rb +54 -19
- data/lib/agentic/task_result.rb +48 -0
- data/lib/agentic/ui.rb +244 -0
- data/lib/agentic/verification/critic_framework.rb +116 -0
- data/lib/agentic/verification/llm_verification_strategy.rb +60 -0
- data/lib/agentic/verification/schema_verification_strategy.rb +47 -0
- data/lib/agentic/verification/verification_hub.rb +62 -0
- data/lib/agentic/verification/verification_result.rb +50 -0
- data/lib/agentic/verification/verification_strategy.rb +26 -0
- data/lib/agentic/version.rb +1 -1
- data/lib/agentic.rb +74 -2
- data/plugins/README.md +41 -0
- metadata +245 -6
@@ -0,0 +1,581 @@
|
|
1
|
+
# Artifact Verification Strategies
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
The artifact generation system requires comprehensive verification strategies that go beyond the existing text/JSON verification. This document outlines verification approaches for different types of generated artifacts, integrating with the existing `VerificationHub` architecture.
|
6
|
+
|
7
|
+
## Existing Verification System
|
8
|
+
|
9
|
+
The current system uses:
|
10
|
+
- **VerificationHub**: Coordinates multiple verification strategies
|
11
|
+
- **VerificationStrategy**: Base class for verification implementations
|
12
|
+
- **VerificationResult**: Standardized result format with verification status, confidence, and messages
|
13
|
+
- **SchemaVerificationStrategy**: Validates JSON output against schemas
|
14
|
+
|
15
|
+
## Artifact-Specific Verification Strategies
|
16
|
+
|
17
|
+
### 1. Base Artifact Verification Strategy
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
module Agentic
|
21
|
+
module Verification
|
22
|
+
class ArtifactVerificationStrategy < VerificationStrategy
|
23
|
+
# Verifies artifact results using file-based validation
|
24
|
+
# @param task [ArtifactTask] The artifact task to verify
|
25
|
+
# @param result [ArtifactResult] The artifact result to verify
|
26
|
+
# @return [VerificationResult] The verification result
|
27
|
+
def verify(task, result)
|
28
|
+
unless result.successful?
|
29
|
+
return VerificationResult.new(
|
30
|
+
task_id: task.id,
|
31
|
+
verified: false,
|
32
|
+
confidence: 0.0,
|
33
|
+
messages: ["Artifact task failed, skipping verification"]
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Verify each artifact according to its type
|
38
|
+
artifact_results = result.artifacts.map do |artifact|
|
39
|
+
verify_single_artifact(artifact, task)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Combine verification results
|
43
|
+
combine_artifact_results(task.id, artifact_results)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def verify_single_artifact(artifact, task)
|
49
|
+
strategy = get_strategy_for_artifact_type(artifact.type)
|
50
|
+
strategy.verify_artifact(artifact, task)
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_strategy_for_artifact_type(type)
|
54
|
+
case type
|
55
|
+
when "ruby_source" then RubySourceVerificationStrategy.new
|
56
|
+
when "javascript_source" then JavaScriptSourceVerificationStrategy.new
|
57
|
+
when "python_source" then PythonSourceVerificationStrategy.new
|
58
|
+
when "json_config" then JsonConfigVerificationStrategy.new
|
59
|
+
when "yaml_config" then YamlConfigVerificationStrategy.new
|
60
|
+
when "markdown_doc" then MarkdownDocVerificationStrategy.new
|
61
|
+
when "html_file" then HtmlFileVerificationStrategy.new
|
62
|
+
when "css_file" then CssFileVerificationStrategy.new
|
63
|
+
else GenericFileVerificationStrategy.new
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def combine_artifact_results(task_id, artifact_results)
|
68
|
+
verified = artifact_results.all? { |r| r[:verified] }
|
69
|
+
confidence = artifact_results.map { |r| r[:confidence] }.sum / artifact_results.size
|
70
|
+
messages = artifact_results.flat_map { |r| r[:messages] }
|
71
|
+
|
72
|
+
VerificationResult.new(
|
73
|
+
task_id: task_id,
|
74
|
+
verified: verified,
|
75
|
+
confidence: confidence,
|
76
|
+
messages: messages
|
77
|
+
)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
### 2. Source Code Verification Strategies
|
85
|
+
|
86
|
+
#### Ruby Source Verification
|
87
|
+
```ruby
|
88
|
+
class RubySourceVerificationStrategy
|
89
|
+
def verify_artifact(artifact, task)
|
90
|
+
checks = [
|
91
|
+
verify_syntax(artifact),
|
92
|
+
verify_rubocop_compliance(artifact),
|
93
|
+
verify_functionality(artifact, task)
|
94
|
+
]
|
95
|
+
|
96
|
+
combine_checks("Ruby source", checks)
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def verify_syntax(artifact)
|
102
|
+
begin
|
103
|
+
RubyVM::InstructionSequence.compile(artifact.content)
|
104
|
+
{ verified: true, confidence: 1.0, message: "Ruby syntax is valid" }
|
105
|
+
rescue SyntaxError => e
|
106
|
+
{ verified: false, confidence: 0.0, message: "Syntax error: #{e.message}" }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def verify_rubocop_compliance(artifact)
|
111
|
+
# Run RuboCop programmatically
|
112
|
+
require 'rubocop'
|
113
|
+
|
114
|
+
config = RuboCop::ConfigLoader.load_file('.rubocop.yml')
|
115
|
+
team = RuboCop::Cop::Team.new(config)
|
116
|
+
|
117
|
+
offenses = team.inspect_file(RuboCop::ProcessedSource.new(
|
118
|
+
artifact.content,
|
119
|
+
RUBY_VERSION.to_f,
|
120
|
+
artifact.path
|
121
|
+
))
|
122
|
+
|
123
|
+
if offenses.empty?
|
124
|
+
{ verified: true, confidence: 0.9, message: "RuboCop compliance verified" }
|
125
|
+
else
|
126
|
+
warnings = offenses.map(&:message).join("; ")
|
127
|
+
severity = offenses.any?(&:error?) ? 0.3 : 0.7
|
128
|
+
{ verified: offenses.none?(&:error?), confidence: severity, message: "RuboCop issues: #{warnings}" }
|
129
|
+
end
|
130
|
+
rescue => e
|
131
|
+
{ verified: true, confidence: 0.5, message: "RuboCop check failed: #{e.message}" }
|
132
|
+
end
|
133
|
+
|
134
|
+
def verify_functionality(artifact, task)
|
135
|
+
# Basic functionality verification based on task requirements
|
136
|
+
if task.input["test_cases"]
|
137
|
+
verify_against_test_cases(artifact, task.input["test_cases"])
|
138
|
+
else
|
139
|
+
{ verified: true, confidence: 0.7, message: "No test cases provided for functionality verification" }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def verify_against_test_cases(artifact, test_cases)
|
144
|
+
# Create a safe evaluation environment
|
145
|
+
passed_tests = 0
|
146
|
+
|
147
|
+
test_cases.each do |test_case|
|
148
|
+
begin
|
149
|
+
# Safely evaluate the code with test inputs
|
150
|
+
result = evaluate_ruby_safely(artifact.content, test_case["input"])
|
151
|
+
if result == test_case["expected_output"]
|
152
|
+
passed_tests += 1
|
153
|
+
end
|
154
|
+
rescue => e
|
155
|
+
# Test failed due to runtime error
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
confidence = passed_tests.to_f / test_cases.size
|
160
|
+
verified = confidence >= 0.8
|
161
|
+
|
162
|
+
{
|
163
|
+
verified: verified,
|
164
|
+
confidence: confidence,
|
165
|
+
message: "#{passed_tests}/#{test_cases.size} test cases passed"
|
166
|
+
}
|
167
|
+
end
|
168
|
+
|
169
|
+
def evaluate_ruby_safely(code, input)
|
170
|
+
# Implement safe Ruby evaluation with restricted environment
|
171
|
+
# This would use techniques like:
|
172
|
+
# - Restricted binding
|
173
|
+
# - Timeout protection
|
174
|
+
# - IO restrictions
|
175
|
+
# - Method whitelisting
|
176
|
+
end
|
177
|
+
end
|
178
|
+
```
|
179
|
+
|
180
|
+
#### JavaScript Source Verification
|
181
|
+
```ruby
|
182
|
+
class JavaScriptSourceVerificationStrategy
|
183
|
+
def verify_artifact(artifact, task)
|
184
|
+
checks = [
|
185
|
+
verify_syntax(artifact),
|
186
|
+
verify_eslint_compliance(artifact),
|
187
|
+
verify_type_safety(artifact)
|
188
|
+
]
|
189
|
+
|
190
|
+
combine_checks("JavaScript source", checks)
|
191
|
+
end
|
192
|
+
|
193
|
+
private
|
194
|
+
|
195
|
+
def verify_syntax(artifact)
|
196
|
+
# Use Node.js to check syntax
|
197
|
+
temp_file = Tempfile.new(['verify', '.js'])
|
198
|
+
temp_file.write(artifact.content)
|
199
|
+
temp_file.close
|
200
|
+
|
201
|
+
result = `node --check #{temp_file.path} 2>&1`
|
202
|
+
temp_file.unlink
|
203
|
+
|
204
|
+
if $?.success?
|
205
|
+
{ verified: true, confidence: 1.0, message: "JavaScript syntax is valid" }
|
206
|
+
else
|
207
|
+
{ verified: false, confidence: 0.0, message: "Syntax error: #{result}" }
|
208
|
+
end
|
209
|
+
rescue => e
|
210
|
+
{ verified: false, confidence: 0.0, message: "Syntax check failed: #{e.message}" }
|
211
|
+
end
|
212
|
+
|
213
|
+
def verify_eslint_compliance(artifact)
|
214
|
+
# Run ESLint if available
|
215
|
+
if system('which eslint > /dev/null 2>&1')
|
216
|
+
run_eslint_check(artifact)
|
217
|
+
else
|
218
|
+
{ verified: true, confidence: 0.5, message: "ESLint not available, skipping check" }
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def verify_type_safety(artifact)
|
223
|
+
# Check for TypeScript or JSDoc type annotations
|
224
|
+
if artifact.content.include?('@type') || artifact.content.include?('/**')
|
225
|
+
{ verified: true, confidence: 0.8, message: "Type annotations found" }
|
226
|
+
else
|
227
|
+
{ verified: true, confidence: 0.6, message: "No type annotations detected" }
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
```
|
232
|
+
|
233
|
+
### 3. Configuration File Verification Strategies
|
234
|
+
|
235
|
+
#### JSON Configuration Verification
|
236
|
+
```ruby
|
237
|
+
class JsonConfigVerificationStrategy
|
238
|
+
def verify_artifact(artifact, task)
|
239
|
+
checks = [
|
240
|
+
verify_json_syntax(artifact),
|
241
|
+
verify_schema_compliance(artifact, task),
|
242
|
+
verify_required_fields(artifact, task)
|
243
|
+
]
|
244
|
+
|
245
|
+
combine_checks("JSON configuration", checks)
|
246
|
+
end
|
247
|
+
|
248
|
+
private
|
249
|
+
|
250
|
+
def verify_json_syntax(artifact)
|
251
|
+
begin
|
252
|
+
JSON.parse(artifact.content)
|
253
|
+
{ verified: true, confidence: 1.0, message: "JSON syntax is valid" }
|
254
|
+
rescue JSON::ParserError => e
|
255
|
+
{ verified: false, confidence: 0.0, message: "JSON syntax error: #{e.message}" }
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def verify_schema_compliance(artifact, task)
|
260
|
+
schema = task.input["config_schema"]
|
261
|
+
return { verified: true, confidence: 0.5, message: "No schema provided" } unless schema
|
262
|
+
|
263
|
+
begin
|
264
|
+
json_data = JSON.parse(artifact.content)
|
265
|
+
# Use JSON Schema validation library
|
266
|
+
errors = JSON::Validator.fully_validate(schema, json_data)
|
267
|
+
|
268
|
+
if errors.empty?
|
269
|
+
{ verified: true, confidence: 0.9, message: "Schema validation passed" }
|
270
|
+
else
|
271
|
+
{ verified: false, confidence: 0.2, message: "Schema errors: #{errors.join('; ')}" }
|
272
|
+
end
|
273
|
+
rescue => e
|
274
|
+
{ verified: false, confidence: 0.0, message: "Schema validation failed: #{e.message}" }
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
def verify_required_fields(artifact, task)
|
279
|
+
required_fields = task.input["required_fields"] || []
|
280
|
+
return { verified: true, confidence: 1.0, message: "No required fields specified" } if required_fields.empty?
|
281
|
+
|
282
|
+
begin
|
283
|
+
json_data = JSON.parse(artifact.content)
|
284
|
+
missing_fields = required_fields - json_data.keys
|
285
|
+
|
286
|
+
if missing_fields.empty?
|
287
|
+
{ verified: true, confidence: 1.0, message: "All required fields present" }
|
288
|
+
else
|
289
|
+
{ verified: false, confidence: 0.3, message: "Missing required fields: #{missing_fields.join(', ')}" }
|
290
|
+
end
|
291
|
+
rescue => e
|
292
|
+
{ verified: false, confidence: 0.0, message: "Field verification failed: #{e.message}" }
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
```
|
297
|
+
|
298
|
+
### 4. Documentation Verification Strategies
|
299
|
+
|
300
|
+
#### Markdown Documentation Verification
|
301
|
+
```ruby
|
302
|
+
class MarkdownDocVerificationStrategy
|
303
|
+
def verify_artifact(artifact, task)
|
304
|
+
checks = [
|
305
|
+
verify_markdown_syntax(artifact),
|
306
|
+
verify_link_validity(artifact),
|
307
|
+
verify_content_completeness(artifact, task),
|
308
|
+
verify_code_block_syntax(artifact)
|
309
|
+
]
|
310
|
+
|
311
|
+
combine_checks("Markdown documentation", checks)
|
312
|
+
end
|
313
|
+
|
314
|
+
private
|
315
|
+
|
316
|
+
def verify_markdown_syntax(artifact)
|
317
|
+
# Use kramdown or similar parser
|
318
|
+
begin
|
319
|
+
require 'kramdown'
|
320
|
+
doc = Kramdown::Document.new(artifact.content)
|
321
|
+
|
322
|
+
if doc.warnings.empty?
|
323
|
+
{ verified: true, confidence: 1.0, message: "Markdown syntax is valid" }
|
324
|
+
else
|
325
|
+
warnings = doc.warnings.join('; ')
|
326
|
+
{ verified: true, confidence: 0.7, message: "Markdown warnings: #{warnings}" }
|
327
|
+
end
|
328
|
+
rescue => e
|
329
|
+
{ verified: false, confidence: 0.0, message: "Markdown parsing failed: #{e.message}" }
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
def verify_link_validity(artifact)
|
334
|
+
links = extract_links(artifact.content)
|
335
|
+
broken_links = []
|
336
|
+
|
337
|
+
links.each do |link|
|
338
|
+
unless link_valid?(link)
|
339
|
+
broken_links << link
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
if broken_links.empty?
|
344
|
+
{ verified: true, confidence: 0.9, message: "All links are valid" }
|
345
|
+
else
|
346
|
+
{ verified: false, confidence: 0.4, message: "Broken links: #{broken_links.join(', ')}" }
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
def verify_content_completeness(artifact, task)
|
351
|
+
required_sections = task.input["required_sections"] || []
|
352
|
+
return { verified: true, confidence: 1.0, message: "No required sections specified" } if required_sections.empty?
|
353
|
+
|
354
|
+
content = artifact.content.downcase
|
355
|
+
missing_sections = required_sections.reject { |section| content.include?(section.downcase) }
|
356
|
+
|
357
|
+
if missing_sections.empty?
|
358
|
+
{ verified: true, confidence: 1.0, message: "All required sections present" }
|
359
|
+
else
|
360
|
+
{ verified: false, confidence: 0.5, message: "Missing sections: #{missing_sections.join(', ')}" }
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
def verify_code_block_syntax(artifact)
|
365
|
+
code_blocks = extract_code_blocks(artifact.content)
|
366
|
+
syntax_errors = []
|
367
|
+
|
368
|
+
code_blocks.each do |block|
|
369
|
+
if block[:language] && !verify_code_syntax(block[:code], block[:language])
|
370
|
+
syntax_errors << "#{block[:language]} block at line #{block[:line]}"
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
if syntax_errors.empty?
|
375
|
+
{ verified: true, confidence: 0.8, message: "All code blocks have valid syntax" }
|
376
|
+
else
|
377
|
+
{ verified: false, confidence: 0.3, message: "Code syntax errors: #{syntax_errors.join(', ')}" }
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end
|
381
|
+
```
|
382
|
+
|
383
|
+
### 5. Multi-File Project Verification Strategy
|
384
|
+
|
385
|
+
```ruby
|
386
|
+
class ProjectVerificationStrategy < ArtifactVerificationStrategy
|
387
|
+
def verify(task, result)
|
388
|
+
checks = [
|
389
|
+
verify_project_structure(result),
|
390
|
+
verify_file_dependencies(result),
|
391
|
+
verify_build_system(result, task),
|
392
|
+
verify_integration(result, task)
|
393
|
+
]
|
394
|
+
|
395
|
+
# Combine project-level checks with individual file checks
|
396
|
+
individual_checks = super(task, result)
|
397
|
+
all_checks = checks + [individual_checks.to_h]
|
398
|
+
|
399
|
+
combine_project_checks(task.id, all_checks)
|
400
|
+
end
|
401
|
+
|
402
|
+
private
|
403
|
+
|
404
|
+
def verify_project_structure(result)
|
405
|
+
expected_structure = get_expected_structure(result.workspace_metadata["template"])
|
406
|
+
actual_files = result.artifacts.map { |a| File.basename(a.path) }
|
407
|
+
|
408
|
+
missing_files = expected_structure - actual_files
|
409
|
+
|
410
|
+
if missing_files.empty?
|
411
|
+
{ verified: true, confidence: 0.9, message: "Project structure is complete" }
|
412
|
+
else
|
413
|
+
{ verified: false, confidence: 0.4, message: "Missing files: #{missing_files.join(', ')}" }
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
def verify_file_dependencies(result)
|
418
|
+
dependency_errors = []
|
419
|
+
|
420
|
+
result.artifacts.each do |artifact|
|
421
|
+
dependencies = extract_dependencies(artifact)
|
422
|
+
dependencies.each do |dep|
|
423
|
+
unless dependency_satisfied?(dep, result.artifacts)
|
424
|
+
dependency_errors << "#{artifact.path}: missing dependency #{dep}"
|
425
|
+
end
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
if dependency_errors.empty?
|
430
|
+
{ verified: true, confidence: 0.8, message: "All dependencies satisfied" }
|
431
|
+
else
|
432
|
+
{ verified: false, confidence: 0.3, message: "Dependency errors: #{dependency_errors.join('; ')}" }
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
def verify_build_system(result, task)
|
437
|
+
build_files = result.artifacts.select { |a| build_file?(a.path) }
|
438
|
+
|
439
|
+
if build_files.empty?
|
440
|
+
{ verified: true, confidence: 0.6, message: "No build system detected" }
|
441
|
+
else
|
442
|
+
verify_build_execution(build_files, result.workspace_metadata["workspace_path"])
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
def verify_integration(result, task)
|
447
|
+
if task.input["integration_tests"]
|
448
|
+
run_integration_tests(result, task.input["integration_tests"])
|
449
|
+
else
|
450
|
+
{ verified: true, confidence: 0.7, message: "No integration tests specified" }
|
451
|
+
end
|
452
|
+
end
|
453
|
+
end
|
454
|
+
```
|
455
|
+
|
456
|
+
### 6. Security-Focused Verification Strategy
|
457
|
+
|
458
|
+
```ruby
|
459
|
+
class SecurityVerificationStrategy < VerificationStrategy
|
460
|
+
def verify(task, result)
|
461
|
+
return super unless result.is_a?(ArtifactResult)
|
462
|
+
|
463
|
+
security_checks = result.artifacts.map do |artifact|
|
464
|
+
check_artifact_security(artifact)
|
465
|
+
end
|
466
|
+
|
467
|
+
combine_security_checks(task.id, security_checks)
|
468
|
+
end
|
469
|
+
|
470
|
+
private
|
471
|
+
|
472
|
+
def check_artifact_security(artifact)
|
473
|
+
checks = [
|
474
|
+
scan_for_secrets(artifact),
|
475
|
+
check_dangerous_patterns(artifact),
|
476
|
+
verify_permissions(artifact),
|
477
|
+
scan_for_vulnerabilities(artifact)
|
478
|
+
]
|
479
|
+
|
480
|
+
combine_checks("Security", checks)
|
481
|
+
end
|
482
|
+
|
483
|
+
def scan_for_secrets(artifact)
|
484
|
+
secret_patterns = [
|
485
|
+
/api[_-]?key[s]?\s*[:=]\s*["'][\w\-]{20,}["']/i,
|
486
|
+
/password\s*[:=]\s*["'][\w\-]{8,}["']/i,
|
487
|
+
/token\s*[:=]\s*["'][\w\-]{20,}["']/i,
|
488
|
+
/secret\s*[:=]\s*["'][\w\-]{20,}["']/i
|
489
|
+
]
|
490
|
+
|
491
|
+
found_secrets = secret_patterns.any? { |pattern| artifact.content.match?(pattern) }
|
492
|
+
|
493
|
+
if found_secrets
|
494
|
+
{ verified: false, confidence: 0.0, message: "Potential secrets detected in #{artifact.path}" }
|
495
|
+
else
|
496
|
+
{ verified: true, confidence: 0.9, message: "No secrets detected" }
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
500
|
+
def check_dangerous_patterns(artifact)
|
501
|
+
dangerous_patterns = [
|
502
|
+
/eval\s*\(/,
|
503
|
+
/exec\s*\(/,
|
504
|
+
/system\s*\(/,
|
505
|
+
/`[^`]+`/,
|
506
|
+
/File\.delete/,
|
507
|
+
/rm\s+-rf/
|
508
|
+
]
|
509
|
+
|
510
|
+
found_dangerous = dangerous_patterns.any? { |pattern| artifact.content.match?(pattern) }
|
511
|
+
|
512
|
+
if found_dangerous
|
513
|
+
{ verified: false, confidence: 0.2, message: "Dangerous patterns detected in #{artifact.path}" }
|
514
|
+
else
|
515
|
+
{ verified: true, confidence: 0.8, message: "No dangerous patterns detected" }
|
516
|
+
end
|
517
|
+
end
|
518
|
+
end
|
519
|
+
```
|
520
|
+
|
521
|
+
## Integration with Existing System
|
522
|
+
|
523
|
+
### 1. Enhanced VerificationHub Configuration
|
524
|
+
```ruby
|
525
|
+
# In PlanOrchestrator or CLI setup
|
526
|
+
def setup_artifact_verification
|
527
|
+
hub = VerificationHub.new(
|
528
|
+
strategies: [
|
529
|
+
# Existing strategies
|
530
|
+
SchemaVerificationStrategy.new,
|
531
|
+
LlmVerificationStrategy.new,
|
532
|
+
|
533
|
+
# New artifact strategies
|
534
|
+
ArtifactVerificationStrategy.new,
|
535
|
+
SecurityVerificationStrategy.new,
|
536
|
+
ProjectVerificationStrategy.new
|
537
|
+
],
|
538
|
+
config: {
|
539
|
+
artifact_verification_enabled: true,
|
540
|
+
security_scanning_enabled: true,
|
541
|
+
build_verification_enabled: true
|
542
|
+
}
|
543
|
+
)
|
544
|
+
end
|
545
|
+
```
|
546
|
+
|
547
|
+
### 2. Conditional Strategy Application
|
548
|
+
```ruby
|
549
|
+
class EnhancedVerificationHub < VerificationHub
|
550
|
+
def verify(task, result)
|
551
|
+
# Use artifact-specific strategies for ArtifactTasks
|
552
|
+
if task.is_a?(ArtifactTask) && result.is_a?(ArtifactResult)
|
553
|
+
artifact_strategies = @strategies.select { |s| s.responds_to_artifacts? }
|
554
|
+
apply_strategies(artifact_strategies, task, result)
|
555
|
+
else
|
556
|
+
# Use existing logic for regular tasks
|
557
|
+
super(task, result)
|
558
|
+
end
|
559
|
+
end
|
560
|
+
end
|
561
|
+
```
|
562
|
+
|
563
|
+
## Quality Metrics and Reporting
|
564
|
+
|
565
|
+
### Artifact Quality Dashboard
|
566
|
+
```ruby
|
567
|
+
class ArtifactQualityReporter
|
568
|
+
def generate_report(verification_results)
|
569
|
+
{
|
570
|
+
overall_quality: calculate_overall_quality(verification_results),
|
571
|
+
security_score: calculate_security_score(verification_results),
|
572
|
+
code_quality: calculate_code_quality(verification_results),
|
573
|
+
documentation_score: calculate_documentation_score(verification_results),
|
574
|
+
project_structure_score: calculate_structure_score(verification_results),
|
575
|
+
recommendations: generate_recommendations(verification_results)
|
576
|
+
}
|
577
|
+
end
|
578
|
+
end
|
579
|
+
```
|
580
|
+
|
581
|
+
This comprehensive verification system ensures that generated artifacts meet quality, security, and functional requirements while integrating seamlessly with the existing Agentic verification architecture.
|