coreason-manifest 0.3.0__py3-none-any.whl → 0.5.0__py3-none-any.whl

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.
@@ -80,29 +80,30 @@ class ManifestEngineAsync:
80
80
  # Clean up resources if necessary.
81
81
  pass
82
82
 
83
- async def load_and_validate(self, manifest_path: Union[str, Path], source_dir: Union[str, Path]) -> AgentDefinition:
84
- """Loads, validates, and verifies an Agent Manifest asynchronously.
83
+ async def validate_manifest_dict(self, raw_data: dict[str, Any]) -> AgentDefinition:
84
+ """Validates an Agent Manifest dictionary in memory.
85
+
86
+ Performs:
87
+ 1. Normalization (stripping version prefixes)
88
+ 2. Schema Validation
89
+ 3. Model Conversion
90
+ 4. Policy Enforcement
91
+
92
+ Does NOT perform Integrity Check (hashing).
85
93
 
86
94
  Args:
87
- manifest_path: Path to the agent.yaml file.
88
- source_dir: Path to the source code directory.
95
+ raw_data: The raw dictionary of the manifest.
89
96
 
90
97
  Returns:
91
- AgentDefinition: The fully validated and verified agent definition.
98
+ AgentDefinition: The fully validated agent definition.
92
99
 
93
100
  Raises:
94
101
  ManifestSyntaxError: If structure or schema is invalid.
95
102
  PolicyViolationError: If business rules are violated.
96
- IntegrityCompromisedError: If source code hash does not match.
97
- FileNotFoundError: If files are missing.
98
103
  """
99
- manifest_path = Path(manifest_path)
100
- source_dir = Path(source_dir)
101
-
102
- logger.info(f"Validating Agent Manifest: {manifest_path}")
103
-
104
- # 1. Load Raw YAML (I/O)
105
- raw_data = await ManifestLoader.load_raw_from_file_async(manifest_path)
104
+ # 1. Normalization (ensure version string is clean before schema/model validation)
105
+ # We access the static method on ManifestLoader.
106
+ ManifestLoader._normalize_data(raw_data)
106
107
 
107
108
  # 2. Schema Validation
108
109
  logger.debug("Running Schema Validation...")
@@ -128,13 +129,42 @@ class ManifestEngineAsync:
128
129
  logger.info(f"Policy Check: Fail - {duration_ms:.2f}ms")
129
130
  raise
130
131
 
132
+ return cast(AgentDefinition, agent_def)
133
+
134
+ async def load_and_validate(self, manifest_path: Union[str, Path], source_dir: Union[str, Path]) -> AgentDefinition:
135
+ """Loads, validates, and verifies an Agent Manifest asynchronously.
136
+
137
+ Args:
138
+ manifest_path: Path to the agent.yaml file.
139
+ source_dir: Path to the source code directory.
140
+
141
+ Returns:
142
+ AgentDefinition: The fully validated and verified agent definition.
143
+
144
+ Raises:
145
+ ManifestSyntaxError: If structure or schema is invalid.
146
+ PolicyViolationError: If business rules are violated.
147
+ IntegrityCompromisedError: If source code hash does not match.
148
+ FileNotFoundError: If files are missing.
149
+ """
150
+ manifest_path = Path(manifest_path)
151
+ source_dir = Path(source_dir)
152
+
153
+ logger.info(f"Validating Agent Manifest: {manifest_path}")
154
+
155
+ # 1. Load Raw YAML (I/O)
156
+ raw_data = await ManifestLoader.load_raw_from_file_async(manifest_path)
157
+
158
+ # 2. Validate Manifest Dict (Schema, Model, Policy)
159
+ agent_def = await self.validate_manifest_dict(raw_data)
160
+
131
161
  # 5. Integrity Check (Heavy I/O and CPU)
132
162
  logger.debug("Verifying Integrity...")
133
163
  # IntegrityChecker.verify is synchronous and does heavy IO, so we wrap it.
134
164
  await anyio.to_thread.run_sync(IntegrityChecker.verify, agent_def, source_dir, manifest_path)
135
165
 
136
166
  logger.info("Agent validation successful.")
137
- return cast(AgentDefinition, agent_def)
167
+ return agent_def
138
168
 
139
169
 
140
170
  class ManifestEngine:
@@ -179,3 +209,14 @@ class ManifestEngine:
179
209
  AgentDefinition: The fully validated and verified agent definition.
180
210
  """
181
211
  return cast(AgentDefinition, anyio.run(self._async.load_and_validate, manifest_path, source_dir))
212
+
213
+ def validate_manifest_dict(self, raw_data: dict[str, Any]) -> AgentDefinition:
214
+ """Validates an Agent Manifest dictionary synchronously.
215
+
216
+ Args:
217
+ raw_data: The raw dictionary of the manifest.
218
+
219
+ Returns:
220
+ AgentDefinition: The fully validated agent definition.
221
+ """
222
+ return cast(AgentDefinition, anyio.run(self._async.validate_manifest_dict, raw_data))
@@ -7,15 +7,23 @@ dictionaries, normalizing the data, and converting it into Pydantic models.
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
+ import inspect
10
11
  from pathlib import Path
11
- from typing import Any, Union
12
+ from typing import Any, Callable, Dict, List, Union, get_type_hints
13
+
14
+ try:
15
+ from typing import get_args, get_origin
16
+ except ImportError: # pragma: no cover
17
+ # For Python < 3.8, though project requires 3.12+
18
+ from typing_extensions import get_args, get_origin # type: ignore
12
19
 
13
20
  import aiofiles
14
21
  import yaml
15
- from pydantic import ValidationError
22
+ from coreason_identity import UserContext
23
+ from pydantic import ValidationError, create_model
16
24
 
17
25
  from coreason_manifest.errors import ManifestSyntaxError
18
- from coreason_manifest.models import AgentDefinition
26
+ from coreason_manifest.models import AgentDefinition, AgentInterface
19
27
 
20
28
 
21
29
  class ManifestLoader:
@@ -156,3 +164,108 @@ class ManifestLoader:
156
164
  while version and version[0] in ("v", "V"):
157
165
  version = version[1:]
158
166
  data["metadata"]["version"] = version
167
+
168
+ @staticmethod
169
+ def inspect_function(func: Callable[..., Any]) -> AgentInterface:
170
+ """Generates an AgentInterface from a Python function.
171
+
172
+ Scans the function signature. If `user_context` (by name) or UserContext (by type)
173
+ is found, it is marked as injected and excluded from the public schema.
174
+
175
+ Args:
176
+ func: The function to inspect.
177
+
178
+ Returns:
179
+ AgentInterface: The generated interface definition.
180
+
181
+ Raises:
182
+ ManifestSyntaxError: If forbidden arguments are found.
183
+ """
184
+ sig = inspect.signature(func)
185
+ try:
186
+ type_hints = get_type_hints(func)
187
+ except Exception:
188
+ # Fallback if get_type_hints fails (e.g. forward refs issues)
189
+ type_hints = {}
190
+
191
+ field_definitions: Dict[str, Any] = {}
192
+ injected: List[str] = []
193
+
194
+ for param_name, param in sig.parameters.items():
195
+ if param_name in ("self", "cls"):
196
+ continue
197
+
198
+ # Determine type annotation
199
+ annotation = type_hints.get(param_name, param.annotation)
200
+ if annotation is inspect.Parameter.empty:
201
+ annotation = Any
202
+
203
+ # Check for forbidden arguments
204
+ if param_name in ("api_key", "token"):
205
+ raise ManifestSyntaxError(f"Function argument '{param_name}' is forbidden. Use UserContext for auth.")
206
+
207
+ # Check for injection
208
+ is_injected = False
209
+ if param_name == "user_context":
210
+ is_injected = True
211
+ else:
212
+ # Check direct type
213
+ if annotation is UserContext:
214
+ is_injected = True
215
+ else:
216
+ # Check for Optional[UserContext], Annotated[UserContext, ...], Union[UserContext, ...]
217
+ origin = get_origin(annotation)
218
+ args = get_args(annotation)
219
+ if origin is not None:
220
+ # Recursively check if UserContext is in args (handles Optional/Union)
221
+ # or if this is Annotated (UserContext might be the first arg)
222
+ # We do a shallow check on args.
223
+ for arg in args:
224
+ if arg is UserContext:
225
+ is_injected = True
226
+ break
227
+
228
+ if is_injected:
229
+ if "user_context" not in injected:
230
+ injected.append("user_context")
231
+ continue
232
+
233
+ # Prepare for Pydantic model creation
234
+ default = param.default
235
+ if default is inspect.Parameter.empty:
236
+ default = ...
237
+
238
+ field_definitions[param_name] = (annotation, default)
239
+
240
+ # Create dynamic model to generate JSON Schema for inputs
241
+ # We assume strict mode or similar is handled by the consumer, here we just describe it.
242
+ try:
243
+ InputsModel = create_model("Inputs", **field_definitions)
244
+ inputs_schema = InputsModel.model_json_schema()
245
+ except Exception as e:
246
+ raise ManifestSyntaxError(f"Failed to generate schema from function signature: {e}") from e
247
+
248
+ # Handle return type for outputs
249
+ return_annotation = type_hints.get("return", sig.return_annotation)
250
+ outputs_schema = {}
251
+ if (
252
+ return_annotation is not inspect.Parameter.empty
253
+ and return_annotation is not None
254
+ and return_annotation is not type(None)
255
+ ):
256
+ try:
257
+ # If return annotation is a Pydantic model, use its schema
258
+ if hasattr(return_annotation, "model_json_schema"):
259
+ outputs_schema = return_annotation.model_json_schema()
260
+ else:
261
+ # Wrap in a model
262
+ OutputsModel = create_model("Outputs", result=(return_annotation, ...))
263
+ outputs_schema = OutputsModel.model_json_schema()
264
+ except Exception:
265
+ pass
266
+
267
+ return AgentInterface(
268
+ inputs=inputs_schema,
269
+ outputs=outputs_schema,
270
+ injected_params=injected,
271
+ )
@@ -20,6 +20,7 @@ from pydantic import (
20
20
  Field,
21
21
  PlainSerializer,
22
22
  field_validator,
23
+ model_validator,
23
24
  )
24
25
  from typing_extensions import Annotated
25
26
 
@@ -86,6 +87,7 @@ class AgentMetadata(BaseModel):
86
87
  name: str = Field(..., min_length=1, description="Name of the Agent.")
87
88
  author: str = Field(..., min_length=1, description="Author of the Agent.")
88
89
  created_at: datetime = Field(..., description="Creation timestamp (ISO 8601).")
90
+ requires_auth: bool = Field(default=False, description="Whether the agent requires user authentication.")
89
91
 
90
92
 
91
93
  class AgentInterface(BaseModel):
@@ -100,6 +102,7 @@ class AgentInterface(BaseModel):
100
102
 
101
103
  inputs: ImmutableDict = Field(..., description="Typed arguments the agent accepts (JSON Schema).")
102
104
  outputs: ImmutableDict = Field(..., description="Typed structure of the result.")
105
+ injected_params: List[str] = Field(default_factory=list, description="List of parameters injected by the system.")
103
106
 
104
107
 
105
108
  class Step(BaseModel):
@@ -218,3 +221,11 @@ class AgentDefinition(BaseModel):
218
221
  pattern=r"^[a-fA-F0-9]{64}$",
219
222
  description="SHA256 hash of the source code.",
220
223
  )
224
+
225
+ @model_validator(mode="after")
226
+ def validate_auth_requirements(self) -> AgentDefinition:
227
+ """Validate that agents requiring auth have user_context injected."""
228
+ if self.metadata.requires_auth:
229
+ if "user_context" not in self.interface.injected_params:
230
+ raise ValueError("Agent requires authentication but 'user_context' is not an injected parameter.")
231
+ return self
@@ -41,6 +41,14 @@
41
41
  "description": "Typed structure of the result.",
42
42
  "title": "Outputs",
43
43
  "type": "object"
44
+ },
45
+ "injected_params": {
46
+ "description": "List of parameters injected by the system.",
47
+ "items": {
48
+ "type": "string"
49
+ },
50
+ "title": "Injected Params",
51
+ "type": "array"
44
52
  }
45
53
  },
46
54
  "required": [
@@ -83,6 +91,12 @@
83
91
  "format": "date-time",
84
92
  "title": "Created At",
85
93
  "type": "string"
94
+ },
95
+ "requires_auth": {
96
+ "default": false,
97
+ "description": "Whether the agent requires user authentication.",
98
+ "title": "Requires Auth",
99
+ "type": "boolean"
86
100
  }
87
101
  },
88
102
  "required": [
@@ -0,0 +1,123 @@
1
+ from contextlib import asynccontextmanager
2
+ from importlib import resources
3
+ from pathlib import Path
4
+ from typing import AsyncIterator, List, Optional, Union
5
+
6
+ from fastapi import FastAPI, HTTPException, Request, status
7
+ from fastapi.responses import JSONResponse
8
+ from pydantic import BaseModel, Field
9
+
10
+ from coreason_manifest.engine import ManifestConfig, ManifestEngineAsync
11
+ from coreason_manifest.errors import ManifestSyntaxError, PolicyViolationError
12
+
13
+
14
+ # Response Model
15
+ class ValidationResponse(BaseModel):
16
+ valid: bool
17
+ agent_id: Optional[str] = None
18
+ version: Optional[str] = None
19
+ policy_violations: List[str] = Field(default_factory=list)
20
+
21
+
22
+ @asynccontextmanager
23
+ async def lifespan(app: FastAPI) -> AsyncIterator[None]:
24
+ # Locate policies
25
+ policy_path: Optional[Path] = None
26
+ tbom_path: Optional[Path] = None
27
+
28
+ # 1. Check local directory (Docker runtime with COPY or relative dev path)
29
+ # In Docker we will COPY to /app/policies/ or ./policies/ relative to WORKDIR
30
+ # We'll check common locations.
31
+ possible_dirs = [
32
+ Path("policies"),
33
+ Path("/app/policies"),
34
+ Path("src/coreason_manifest/policies"), # Dev from root
35
+ ]
36
+
37
+ for d in possible_dirs:
38
+ if (d / "compliance.rego").exists():
39
+ policy_path = d / "compliance.rego"
40
+ if (d / "tbom.json").exists():
41
+ tbom_path = d / "tbom.json"
42
+ break
43
+
44
+ # 2. Fallback to package resources
45
+ resource_context = None
46
+ if not policy_path:
47
+ try:
48
+ # Check if it exists as a resource
49
+ ref = resources.files("coreason_manifest.policies").joinpath("compliance.rego")
50
+ if ref.is_file():
51
+ resource_context = resources.as_file(ref)
52
+ policy_path = resource_context.__enter__()
53
+ # Check for TBOM in same dir if possible, or ignore for fallback
54
+ except Exception:
55
+ pass
56
+
57
+ # If still not found, fail.
58
+ if not policy_path:
59
+ raise RuntimeError("Could not locate compliance.rego policy file.")
60
+
61
+ config = ManifestConfig(
62
+ policy_path=policy_path,
63
+ tbom_path=tbom_path,
64
+ opa_path="opa", # Assumes OPA is in PATH (installed via Dockerfile)
65
+ )
66
+
67
+ engine = ManifestEngineAsync(config)
68
+
69
+ try:
70
+ async with engine:
71
+ app.state.engine = engine
72
+ yield
73
+ finally:
74
+ if resource_context:
75
+ resource_context.__exit__(None, None, None)
76
+
77
+
78
+ app = FastAPI(lifespan=lifespan)
79
+
80
+
81
+ @app.post("/validate", response_model=ValidationResponse) # type: ignore[misc]
82
+ async def validate_manifest(request: Request) -> Union[ValidationResponse, JSONResponse]:
83
+ engine: ManifestEngineAsync = app.state.engine
84
+
85
+ try:
86
+ raw_body = await request.json()
87
+ except Exception:
88
+ raise HTTPException(status_code=400, detail="Invalid JSON body") from None
89
+
90
+ try:
91
+ agent_def = await engine.validate_manifest_dict(raw_body)
92
+ return ValidationResponse(
93
+ valid=True,
94
+ agent_id=str(agent_def.metadata.id),
95
+ version=agent_def.metadata.version,
96
+ policy_violations=[],
97
+ )
98
+ except ManifestSyntaxError as e:
99
+ # Return 422 with the error
100
+ resp = ValidationResponse(valid=False, policy_violations=[f"Syntax Error: {str(e)}"])
101
+ return JSONResponse(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content=resp.model_dump())
102
+ except PolicyViolationError as e:
103
+ resp = ValidationResponse(valid=False, policy_violations=e.violations)
104
+ return JSONResponse(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content=resp.model_dump())
105
+
106
+
107
+ @app.get("/health") # type: ignore[misc]
108
+ async def health_check() -> dict[str, str]:
109
+ engine: ManifestEngineAsync = app.state.engine
110
+ policy_version = "unknown"
111
+ try:
112
+ import hashlib
113
+
114
+ # policy_path is guaranteed to exist by lifespan check
115
+ policy_path = Path(engine.config.policy_path)
116
+ if policy_path.exists():
117
+ with open(policy_path, "rb") as f:
118
+ digest = hashlib.sha256(f.read()).hexdigest()[:8]
119
+ policy_version = digest
120
+ except Exception:
121
+ pass
122
+
123
+ return {"status": "active", "policy_version": policy_version}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: coreason_manifest
3
- Version: 0.3.0
3
+ Version: 0.5.0
4
4
  Summary: This package is the definitive source of truth. If it isn't in the manifest, it doesn't exist. If it violates the manifest, it doesn't run.
5
5
  License: # The Prosperity Public License 3.0.0
6
6
 
@@ -68,12 +68,15 @@ Classifier: License :: Other/Proprietary License
68
68
  Classifier: Programming Language :: Python :: 3.12
69
69
  Classifier: Operating System :: OS Independent
70
70
  Requires-Dist: aiofiles (>=23.2.1,<24.0.0)
71
- Requires-Dist: anyio (>=4.3.0,<5.0.0)
72
- Requires-Dist: httpx (>=0.27.0,<0.28.0)
71
+ Requires-Dist: anyio (>=4.12.1,<5.0.0)
72
+ Requires-Dist: coreason-identity (>=0.1.0,<0.2.0)
73
+ Requires-Dist: fastapi (>=0.111.0,<0.112.0)
74
+ Requires-Dist: httpx (>=0.28.1,<0.29.0)
73
75
  Requires-Dist: jsonschema (>=4.25.1,<5.0.0)
74
76
  Requires-Dist: loguru (>=0.7.2,<0.8.0)
75
77
  Requires-Dist: pydantic (>=2.12.5,<3.0.0)
76
78
  Requires-Dist: pyyaml (>=6.0.3,<7.0.0)
79
+ Requires-Dist: uvicorn (>=0.30.1,<0.31.0)
77
80
  Project-URL: Documentation, https://github.com/CoReason-AI/coreason_manifest
78
81
  Project-URL: Homepage, https://github.com/CoReason-AI/coreason_manifest
79
82
  Project-URL: Repository, https://github.com/CoReason-AI/coreason_manifest
@@ -97,8 +100,10 @@ The definitive source of truth for CoReason-AI Asset definitions. "The Blueprint
97
100
  * **Open Agent Specification (OAS) Validation:** Parses and validates agent definitions against a strict schema.
98
101
  * **Compliance Enforcement:** Uses Open Policy Agent (OPA) / Rego to enforce complex business rules and allowlists.
99
102
  * **Integrity Verification:** Calculates and verifies SHA256 hashes of the agent's source code to prevent tampering.
103
+ * **Automatic Schema Generation:** Inspects Python functions to generate Agent Interfaces, automatically handling `UserContext` injection.
100
104
  * **Dependency Pinning:** Enforces strict version pinning for all library dependencies.
101
105
  * **Trusted Bill of Materials (TBOM):** Validates libraries against an approved list.
106
+ * **Compliance Microservice:** Can be run as a standalone API server (Service C) for centralized validation.
102
107
 
103
108
  ## Installation
104
109
 
@@ -108,30 +113,30 @@ pip install coreason-manifest
108
113
 
109
114
  ## Usage
110
115
 
111
- Here is how to initialize the engine and validate an agent manifest:
116
+ `coreason-manifest` supports two modes: **Library (CLI)** and **Server (Microservice)**.
117
+
118
+ ### 1. Library Usage
119
+
120
+ Use the python library to validate local agent files and verify source integrity.
112
121
 
113
122
  ```python
114
- from coreason_manifest import ManifestEngine, ManifestConfig, PolicyViolationError, IntegrityCompromisedError
123
+ from coreason_manifest import ManifestEngine, ManifestConfig
115
124
 
116
- # 1. Initialize configuration with policy path
117
- config = ManifestConfig(policy_path="./policies/gx_compliant.rego")
125
+ # Initialize and Validate
126
+ config = ManifestConfig(policy_path="./policies/compliance.rego")
118
127
  engine = ManifestEngine(config)
128
+ agent_def = engine.load_and_validate("agent.yaml", "./src")
129
+ ```
119
130
 
120
- # 2. Load & Validate Agent Manifest
121
- try:
122
- # This runs Schema Validation, Policy Enforcement, and Integrity Checks
123
- agent_def = engine.load_and_validate(
124
- manifest_path="./agents/payer_war_game/agent.yaml",
125
- source_dir="./agents/payer_war_game/src"
126
- )
127
- print(f"Agent {agent_def.metadata.name} is compliant and ready to run.")
131
+ ### 2. Server Mode
128
132
 
129
- except PolicyViolationError as e:
130
- print(f"Compliance Failure: {e.violations}")
133
+ Run the package as a FastAPI server to provide a centralized compliance API.
131
134
 
132
- except IntegrityCompromisedError:
133
- print("CRITICAL: Code has been tampered with after signing.")
135
+ ```bash
136
+ uvicorn coreason_manifest.server:app --host 0.0.0.0 --port 8000
134
137
  ```
135
138
 
136
- For detailed requirements and architecture, please refer to the [Product Requirements](docs/product_requirements.md).
139
+ For full details, see the [Usage Documentation](docs/usage.md).
140
+
141
+ For detailed requirements and architecture, please refer to the [Product Requirements](docs/product_requirements.md) or [Requirements](docs/requirements.md).
137
142
 
@@ -1,20 +1,21 @@
1
1
  coreason_manifest/__init__.py,sha256=R07xUHw9RWdWQPh7OWbpMT8kkzkEWfEI5hizu_5UNck,1528
2
- coreason_manifest/engine.py,sha256=zR_O2N-olwL1HSjAq03Um3qr-jbzmaIhOA19tpY0tFs,6753
2
+ coreason_manifest/engine.py,sha256=ENAkRuGFd1uY_5u4EYEsTZUMrqw5HgijKtkF9lk-E-c,8199
3
3
  coreason_manifest/errors.py,sha256=CKFWSucncoPLYUJcsuXtLIfneyr2d89oHRTiWPT4psU,1437
4
4
  coreason_manifest/integrity.py,sha256=CMBaa2A8DpC9hDSO-aj-YOzss6if1CajaeLEmTC703c,5344
5
- coreason_manifest/loader.py,sha256=cc1iV-yKfH3gyPaB-P_7AaTaPYkgj1NoDsJz4PReTgo,5479
5
+ coreason_manifest/loader.py,sha256=WET8HAnSw4dgon_zdiZaaU1dIUrsIQPYZzxlp0crTYo,10027
6
6
  coreason_manifest/main.py,sha256=YQO98w2wxkfNs-DpSLmiDTs9DtUeGsC48GEfbElXVPk,357
7
- coreason_manifest/models.py,sha256=pJIuEtCiiXcxxi2zRwken4ph2GFa66YHnOqHyySR5sU,6828
7
+ coreason_manifest/models.py,sha256=EuaE1Wl5T8f_eI9vF1VFp5hd0y9C7E52zAjB52EulKw,7497
8
8
  coreason_manifest/policies/compliance.rego,sha256=-drMuno6YkGOXKjvdLWawCZWK8iUxY7OcXpoXa_9Oyo,3035
9
9
  coreason_manifest/policies/tbom.json,sha256=rSn4V44_IdFqCC86J3Jc31qQKTV4J5BdmyO0CI4iOu0,167
10
10
  coreason_manifest/policy.py,sha256=vvEivq5HSjv-bMSrZ5VMM3eTomYFp39SBtuFajG9RU4,5009
11
11
  coreason_manifest/schemas/__init__.py,sha256=9TMs6jWKCIewAKkj-u0tq9c6N_-0CU6b5s9q6MTS6v4,17
12
- coreason_manifest/schemas/agent.schema.json,sha256=wdNYmpyCUEKR1UgMmRV4ZSQOm7xvnmSg5lvhQ3JKvSg,6368
12
+ coreason_manifest/schemas/agent.schema.json,sha256=VigUX3ltX7YaW9P7n0DNYGNOf8C6VCuXNy71u3LB9i4,6812
13
+ coreason_manifest/server.py,sha256=kHrReqoEx4sL5k5GQN7yNwLgvfnOl1kZf-dQehseuO4,4251
13
14
  coreason_manifest/utils/__init__.py,sha256=Q9gXiBtX3mD9GTu4z0JDHSHkbXC-MRHagrOaOmRH_1Q,435
14
15
  coreason_manifest/utils/logger.py,sha256=A7E6Hd_Jk1XDUajNEJQl-WtUv9M2LT76b4_TsbxnILw,1227
15
16
  coreason_manifest/validator.py,sha256=v33EzKroRwLEjZeuRRpTB7cqB38op3DV2EZpZhJ80a0,2240
16
- coreason_manifest-0.3.0.dist-info/METADATA,sha256=7a-XR2oNa4OqWlD9RqkuOc7B709pHJfu7BsKoHJxRis,7176
17
- coreason_manifest-0.3.0.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
18
- coreason_manifest-0.3.0.dist-info/licenses/LICENSE,sha256=3tYb7ZQe7sVXcbNmX22fDESFjOSIlCZodUGpZMkuSlk,3063
19
- coreason_manifest-0.3.0.dist-info/licenses/NOTICE,sha256=tqzUyP9VTCGxoHLgBI0AC1i0G7m_PSyESFL8Jwuw0dA,610
20
- coreason_manifest-0.3.0.dist-info/RECORD,,
17
+ coreason_manifest-0.5.0.dist-info/METADATA,sha256=GZU4pj0fFgv6x80fJDa71xfQTYCHH1BPnZnSdjv3kBo,7421
18
+ coreason_manifest-0.5.0.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
19
+ coreason_manifest-0.5.0.dist-info/licenses/LICENSE,sha256=3tYb7ZQe7sVXcbNmX22fDESFjOSIlCZodUGpZMkuSlk,3063
20
+ coreason_manifest-0.5.0.dist-info/licenses/NOTICE,sha256=tqzUyP9VTCGxoHLgBI0AC1i0G7m_PSyESFL8Jwuw0dA,610
21
+ coreason_manifest-0.5.0.dist-info/RECORD,,