@@ -42,6 +42,26 @@ def write_bundle(
4242 generated_at = datetime .now (UTC ).isoformat ().replace ("+00:00" , "Z" )
4343 source_hash = self ._sha256_file (source_file )
4444 result_payload = result .to_dict ()
45+ contract_metadata = self ._contract_metadata (result )
46+ contract_counts = self ._contract_counts (contract_metadata )
47+
48+ artifact_files = [
49+ "summary.json" ,
50+ "trace.json" ,
51+ "policies.json" ,
52+ "tool-results.json" ,
53+ "handoffs.json" ,
54+ "branches.json" ,
55+ "approvals-required.json" ,
56+ "contract.json" ,
57+ "obligations.json" ,
58+ "falsification-gates.json" ,
59+ "claim-boundaries.json" ,
60+ "outputs.txt" ,
61+ "replies.txt" ,
62+ "assurance-claims.md" ,
63+ "limitations.md" ,
64+ ]
4565
4666 files : list [Path ] = []
4767 files .append (
@@ -55,19 +75,7 @@ def write_bundle(
5575 "source_file" : str (source_file ),
5676 "source_sha256" : source_hash ,
5777 "status" : result .status ,
58- "artifact_files" : [
59- "summary.json" ,
60- "trace.json" ,
61- "policies.json" ,
62- "tool-results.json" ,
63- "handoffs.json" ,
64- "branches.json" ,
65- "approvals-required.json" ,
66- "outputs.txt" ,
67- "replies.txt" ,
68- "assurance-claims.md" ,
69- "limitations.md" ,
70- ],
78+ "artifact_files" : artifact_files ,
7179 },
7280 )
7381 )
@@ -88,6 +96,14 @@ def write_bundle(
8896 "handoffs" : len (result .handoffs ),
8997 "branches" : len (result .branches ),
9098 "approvals_required" : len (result .approvals_required ),
99+ "contract_attempts" : contract_counts ["attempts" ],
100+ "contract_obligations" : contract_counts ["obligations" ],
101+ "contract_evidence_requirements" : contract_counts [
102+ "evidence_requirements"
103+ ],
104+ "contract_falsification_gates" : contract_counts [
105+ "falsification_gates"
106+ ],
91107 },
92108 "variables" : result_payload ["variables" ],
93109 "memory" : result_payload ["memory" ],
@@ -99,14 +115,136 @@ def write_bundle(
99115 files .append (self ._write_json (output_dir / "tool-results.json" , result .tool_results ))
100116 files .append (self ._write_json (output_dir / "handoffs.json" , result .handoffs ))
101117 files .append (self ._write_json (output_dir / "branches.json" , result .branches ))
102- files .append (self ._write_json (output_dir / "approvals-required.json" , result .approvals_required ))
118+ files .append (
119+ self ._write_json (output_dir / "approvals-required.json" , result .approvals_required )
120+ )
121+ files .append (self ._write_json (output_dir / "contract.json" , contract_metadata ))
122+ files .append (
123+ self ._write_json (
124+ output_dir / "obligations.json" ,
125+ self ._obligations_payload (contract_metadata ),
126+ )
127+ )
128+ files .append (
129+ self ._write_json (
130+ output_dir / "falsification-gates.json" ,
131+ self ._falsification_payload (contract_metadata ),
132+ )
133+ )
134+ files .append (
135+ self ._write_json (
136+ output_dir / "claim-boundaries.json" ,
137+ self ._claim_boundaries_payload (contract_metadata ),
138+ )
139+ )
103140 files .append (self ._write_text (output_dir / "outputs.txt" , "\n " .join (result .outputs ) + "\n " ))
104141 files .append (self ._write_text (output_dir / "replies.txt" , "\n " .join (result .replies ) + "\n " ))
105142 files .append (self ._write_text (output_dir / "assurance-claims.md" , self ._claims_text (result )))
106143 files .append (self ._write_text (output_dir / "limitations.md" , self ._limitations_text ()))
107144
108145 return EvidenceBundle (output_dir = output_dir , files = tuple (files ))
109146
147+ def _contract_metadata (self , result : ExecutionResult ) -> dict [str , Any ]:
148+ metadata = getattr (result , "contract_metadata" , None )
149+ if isinstance (metadata , dict ):
150+ return metadata
151+ return {
152+ "contract_type" : "ix.cognition.contracts" ,
153+ "schema_version" : "1.0" ,
154+ "runtime_semantics" : "metadata_only_not_executed" ,
155+ "counts" : {
156+ "attempts" : 0 ,
157+ "obligations" : 0 ,
158+ "evidence_requirements" : 0 ,
159+ "falsification_gates" : 0 ,
160+ },
161+ "attempts" : [],
162+ }
163+
164+ def _contract_counts (self , metadata : dict [str , Any ]) -> dict [str , int ]:
165+ counts = metadata .get ("counts" , {})
166+ if not isinstance (counts , dict ):
167+ counts = {}
168+ return {
169+ "attempts" : int (counts .get ("attempts" , 0 )),
170+ "obligations" : int (counts .get ("obligations" , 0 )),
171+ "evidence_requirements" : int (counts .get ("evidence_requirements" , 0 )),
172+ "falsification_gates" : int (counts .get ("falsification_gates" , 0 )),
173+ }
174+
175+ def _obligations_payload (self , metadata : dict [str , Any ]) -> dict [str , Any ]:
176+ obligations : list [dict [str , Any ]] = []
177+ for attempt in self ._attempts (metadata ):
178+ attempt_name = str (attempt .get ("name" , "" ))
179+ for obligation in self ._obligations (attempt ):
180+ obligations .append (
181+ {
182+ "attempt" : attempt_name ,
183+ "id" : obligation .get ("id" ),
184+ "source" : obligation .get ("source" ),
185+ "evidence_required" : list (obligation .get ("evidence_required" , [])),
186+ "falsify_if" : list (obligation .get ("falsify_if" , [])),
187+ }
188+ )
189+ return {
190+ "schema_version" : "1.0" ,
191+ "runtime_semantics" : metadata .get ("runtime_semantics" ),
192+ "obligations" : obligations ,
193+ }
194+
195+ def _falsification_payload (self , metadata : dict [str , Any ]) -> dict [str , Any ]:
196+ gates : list [dict [str , Any ]] = []
197+ for attempt in self ._attempts (metadata ):
198+ attempt_name = str (attempt .get ("name" , "" ))
199+ for obligation in self ._obligations (attempt ):
200+ obligation_id = obligation .get ("id" )
201+ for condition in obligation .get ("falsify_if" , []):
202+ gates .append (
203+ {
204+ "attempt" : attempt_name ,
205+ "obligation" : obligation_id ,
206+ "condition" : condition ,
207+ }
208+ )
209+ return {
210+ "schema_version" : "1.0" ,
211+ "runtime_semantics" : metadata .get ("runtime_semantics" ),
212+ "falsification_gates" : gates ,
213+ }
214+
215+ def _claim_boundaries_payload (self , metadata : dict [str , Any ]) -> dict [str , Any ]:
216+ attempts : list [dict [str , Any ]] = []
217+ for attempt in self ._attempts (metadata ):
218+ attempts .append (
219+ {
220+ "attempt" : attempt .get ("name" ),
221+ "purpose" : list (attempt .get ("purpose" , [])),
222+ "non_goals" : list (attempt .get ("non_goals" , [])),
223+ "claim_boundaries" : list (attempt .get ("claim_boundaries" , [])),
224+ "human_approval_required" : list (
225+ attempt .get ("human_approval_required" , [])
226+ ),
227+ "handoff_contracts" : list (attempt .get ("handoff_contracts" , [])),
228+ }
229+ )
230+ return {
231+ "schema_version" : "1.0" ,
232+ "runtime_semantics" : metadata .get ("runtime_semantics" ),
233+ "attempts" : attempts ,
234+ }
235+
236+ def _attempts (self , metadata : dict [str , Any ]) -> list [dict [str , Any ]]:
237+ attempts = metadata .get ("attempts" , [])
238+ if not isinstance (attempts , list ):
239+ return []
240+ return [attempt for attempt in attempts if isinstance (attempt , dict )]
241+
242+ def _obligations (self , attempt : dict [str , Any ]) -> list [dict [str , Any ]]:
243+ obligations = attempt .get ("obligations" , [])
244+ if not isinstance (obligations , list ):
245+ return []
246+ return [obligation for obligation in obligations if isinstance (obligation , dict )]
247+
110248 def _write_json (self , path : Path , payload : Any ) -> Path :
111249 path .write_text (json .dumps (payload , indent = 2 , sort_keys = True ) + "\n " , encoding = "utf-8" )
112250 return path
@@ -123,6 +261,8 @@ def _sha256_file(self, path: Path) -> str:
123261 return digest .hexdigest ()
124262
125263 def _claims_text (self , result : ExecutionResult ) -> str :
264+ contract_metadata = self ._contract_metadata (result )
265+ contract_counts = self ._contract_counts (contract_metadata )
126266 return (
127267 "# IX Assurance Claims\n \n "
128268 "This evidence bundle supports only bounded, runtime-observed claims.\n \n "
@@ -133,10 +273,14 @@ def _claims_text(self, result: ExecutionResult) -> str:
133273 f"- Tool results captured: { len (result .tool_results )} .\n "
134274 f"- Agent handoffs captured: { len (result .handoffs )} .\n "
135275 f"- Conditional branches captured: { len (result .branches )} .\n "
136- f"- Human approval requirements captured: { len (result .approvals_required )} .\n \n "
276+ f"- Human approval requirements captured: { len (result .approvals_required )} .\n "
277+ f"- Cognition attempt contracts captured: { contract_counts ['attempts' ]} .\n "
278+ f"- Cognition obligations captured: { contract_counts ['obligations' ]} .\n \n "
137279 "## Not claimed\n \n "
138280 "- This bundle does not certify the script as safe, complete, lawful, or production-ready.\n "
139281 "- This bundle does not prove external system behavior beyond the deterministic IX runtime output.\n "
282+ "- This bundle does not execute or certify cognition-contract obligations.\n "
283+ "- This bundle does not certify AGI, AGI-candidate status, or deployment readiness.\n "
140284 "- This bundle does not replace human review.\n "
141285 )
142286
@@ -149,5 +293,9 @@ def _limitations_text(self) -> str:
149293 "automation, or legal compliance.\n \n "
150294 "Current IX built-in tools are deterministic and side-effect free. External network, "
151295 "email, filesystem mutation, procurement, deployment, and real-world actuation tools "
152- "are intentionally not part of this bundle model.\n "
296+ "are intentionally not part of this bundle model.\n \n "
297+ "Cognition-contract artifacts are declarative metadata. They record the contract, "
298+ "obligations, claim boundaries, and falsification gates that a downstream cognition "
299+ "system may later attempt. They do not execute cognition, prove learning, prove "
300+ "transfer, certify AGI, or authorize self-approval.\n "
153301 )
0 commit comments