@nextcommerce/campaigns-os 1.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/AGENTS.md +204 -0
  2. package/CHANGELOG.md +5002 -0
  3. package/CONTEXT.md +685 -0
  4. package/LICENSE +202 -0
  5. package/NOTICE +4 -0
  6. package/README.md +368 -0
  7. package/agents/claude/CLAUDE.md +32 -0
  8. package/agents/codex/AGENTS.md +27 -0
  9. package/agents/copilot/copilot-instructions.md +14 -0
  10. package/agents/cursor/campaigns-os.mdc +13 -0
  11. package/bin/campaigns-os.mjs +38 -0
  12. package/campaign-spec/README.md +138 -0
  13. package/campaign-spec/dist/analytics-vocabulary.d.ts +47 -0
  14. package/campaign-spec/dist/analytics-vocabulary.js +74 -0
  15. package/campaign-spec/dist/index.d.ts +40 -0
  16. package/campaign-spec/dist/index.js +77 -0
  17. package/campaign-spec/dist/normalize.d.ts +22 -0
  18. package/campaign-spec/dist/normalize.js +41 -0
  19. package/campaign-spec/dist/routing.d.ts +190 -0
  20. package/campaign-spec/dist/routing.js +263 -0
  21. package/campaign-spec/dist/rules/analytics-contract-shape.d.ts +42 -0
  22. package/campaign-spec/dist/rules/analytics-contract-shape.js +303 -0
  23. package/campaign-spec/dist/rules/assembly-hints-shape.d.ts +42 -0
  24. package/campaign-spec/dist/rules/assembly-hints-shape.js +191 -0
  25. package/campaign-spec/dist/rules/campaign-metadata.d.ts +14 -0
  26. package/campaign-spec/dist/rules/campaign-metadata.js +40 -0
  27. package/campaign-spec/dist/rules/checkout-has-success-url.d.ts +31 -0
  28. package/campaign-spec/dist/rules/checkout-has-success-url.js +66 -0
  29. package/campaign-spec/dist/rules/cycle-detection.d.ts +12 -0
  30. package/campaign-spec/dist/rules/cycle-detection.js +141 -0
  31. package/campaign-spec/dist/rules/design-source-shape.d.ts +29 -0
  32. package/campaign-spec/dist/rules/design-source-shape.js +142 -0
  33. package/campaign-spec/dist/rules/downsell-without-upsell.d.ts +11 -0
  34. package/campaign-spec/dist/rules/downsell-without-upsell.js +40 -0
  35. package/campaign-spec/dist/rules/exit-intent-validation.d.ts +23 -0
  36. package/campaign-spec/dist/rules/exit-intent-validation.js +147 -0
  37. package/campaign-spec/dist/rules/funnel-count.d.ts +9 -0
  38. package/campaign-spec/dist/rules/funnel-count.js +37 -0
  39. package/campaign-spec/dist/rules/funnel-hypothesis-length.d.ts +22 -0
  40. package/campaign-spec/dist/rules/funnel-hypothesis-length.js +60 -0
  41. package/campaign-spec/dist/rules/funnel-identity.d.ts +15 -0
  42. package/campaign-spec/dist/rules/funnel-identity.js +57 -0
  43. package/campaign-spec/dist/rules/funnel-weight-sum.d.ts +20 -0
  44. package/campaign-spec/dist/rules/funnel-weight-sum.js +66 -0
  45. package/campaign-spec/dist/rules/index.d.ts +69 -0
  46. package/campaign-spec/dist/rules/index.js +131 -0
  47. package/campaign-spec/dist/rules/offer-ref-integrity.d.ts +13 -0
  48. package/campaign-spec/dist/rules/offer-ref-integrity.js +59 -0
  49. package/campaign-spec/dist/rules/package-pricing-sanity.d.ts +12 -0
  50. package/campaign-spec/dist/rules/package-pricing-sanity.js +42 -0
  51. package/campaign-spec/dist/rules/page-count.d.ts +11 -0
  52. package/campaign-spec/dist/rules/page-count.js +31 -0
  53. package/campaign-spec/dist/rules/page-id-uniqueness.d.ts +14 -0
  54. package/campaign-spec/dist/rules/page-id-uniqueness.js +47 -0
  55. package/campaign-spec/dist/rules/promo-code-input-validation.d.ts +8 -0
  56. package/campaign-spec/dist/rules/promo-code-input-validation.js +126 -0
  57. package/campaign-spec/dist/rules/promo-codes-shape.d.ts +30 -0
  58. package/campaign-spec/dist/rules/promo-codes-shape.js +187 -0
  59. package/campaign-spec/dist/rules/route-field-ignored-for-page-type.d.ts +33 -0
  60. package/campaign-spec/dist/rules/route-field-ignored-for-page-type.js +81 -0
  61. package/campaign-spec/dist/rules/route-target-resolves.d.ts +32 -0
  62. package/campaign-spec/dist/rules/route-target-resolves.js +112 -0
  63. package/campaign-spec/dist/rules/schema-version.d.ts +21 -0
  64. package/campaign-spec/dist/rules/schema-version.js +53 -0
  65. package/campaign-spec/dist/rules/sdk-version.d.ts +26 -0
  66. package/campaign-spec/dist/rules/sdk-version.js +96 -0
  67. package/campaign-spec/dist/rules/shipping-countries-shape.d.ts +10 -0
  68. package/campaign-spec/dist/rules/shipping-countries-shape.js +30 -0
  69. package/campaign-spec/dist/rules/shipping-methods-present.d.ts +10 -0
  70. package/campaign-spec/dist/rules/shipping-methods-present.js +26 -0
  71. package/campaign-spec/dist/rules/store-profile-shape.d.ts +30 -0
  72. package/campaign-spec/dist/rules/store-profile-shape.js +127 -0
  73. package/campaign-spec/dist/rules/thank-you-requirement.d.ts +16 -0
  74. package/campaign-spec/dist/rules/thank-you-requirement.js +50 -0
  75. package/campaign-spec/dist/rules/unknown-top-level-fields.d.ts +28 -0
  76. package/campaign-spec/dist/rules/unknown-top-level-fields.js +114 -0
  77. package/campaign-spec/dist/rules/upsell-has-packages.d.ts +9 -0
  78. package/campaign-spec/dist/rules/upsell-has-packages.js +35 -0
  79. package/campaign-spec/dist/rules/upsell-routing-complete.d.ts +10 -0
  80. package/campaign-spec/dist/rules/upsell-routing-complete.js +45 -0
  81. package/campaign-spec/dist/rules/upsell-without-checkout.d.ts +11 -0
  82. package/campaign-spec/dist/rules/upsell-without-checkout.js +44 -0
  83. package/campaign-spec/dist/rules/variant-labels-shape.d.ts +28 -0
  84. package/campaign-spec/dist/rules/variant-labels-shape.js +86 -0
  85. package/campaign-spec/dist/sdk-version-parse.d.ts +43 -0
  86. package/campaign-spec/dist/sdk-version-parse.js +62 -0
  87. package/campaign-spec/dist/types.d.ts +674 -0
  88. package/campaign-spec/dist/types.js +40 -0
  89. package/campaign-spec/package.json +12 -0
  90. package/compatibility.json +25 -0
  91. package/contracts/agent-relevant-change-policy.v1.json +111 -0
  92. package/contracts/brand-theme-source-defaults.figma-sections-export.v0.json +32 -0
  93. package/contracts/brand-theme-target-tokens.next-core.v0.json +65 -0
  94. package/contracts/campaign-cart-checkout-field-contract.v0.json +45 -0
  95. package/contracts/campaign-cart-sdk-support-policy.v0.json +11 -0
  96. package/contracts/commerce-surface-catalog.json +2452 -0
  97. package/contracts/fixtures/orientation/canonicalization/v1.json +34 -0
  98. package/contracts/fixtures/orientation/envelope/current.json +95 -0
  99. package/contracts/fixtures/orientation/envelope/freshness_unknown.json +97 -0
  100. package/contracts/fixtures/orientation/envelope/legacy_baseline.json +95 -0
  101. package/contracts/fixtures/orientation/envelope/orientation_available.json +136 -0
  102. package/contracts/fixtures/orientation/envelope/recovered_interrupted_update.json +136 -0
  103. package/contracts/fixtures/orientation/envelope/refused.json +100 -0
  104. package/contracts/fixtures/orientation/envelope/restart_required.json +137 -0
  105. package/contracts/fixtures/orientation/envelope/updated.json +135 -0
  106. package/contracts/fixtures/orientation/hostile-target/README.md +61 -0
  107. package/contracts/fixtures/orientation/hostile-target/manifest.json +82 -0
  108. package/contracts/fixtures/orientation/hostile-target/repo/CHANGELOG.md +18 -0
  109. package/contracts/fixtures/orientation/hostile-target/repo/bin/intended.mjs +12 -0
  110. package/contracts/fixtures/orientation/hostile-target/repo/bin/tripwire.mjs +15 -0
  111. package/contracts/fixtures/orientation/hostile-target/repo/contracts/release-ledger.json +48 -0
  112. package/contracts/fixtures/orientation/hostile-target/repo/contracts/supported-surface.json +17 -0
  113. package/contracts/fixtures/orientation/hostile-target/repo/docs/example-contract.md +13 -0
  114. package/contracts/fixtures/orientation/hostile-target/repo/hooks/post-checkout +5 -0
  115. package/contracts/fixtures/orientation/hostile-target/repo/hooks/post-merge +5 -0
  116. package/contracts/fixtures/orientation/hostile-target/repo/hooks/pre-commit +5 -0
  117. package/contracts/fixtures/orientation/hostile-target/repo/hostile-dependency-tripwire/package.json +15 -0
  118. package/contracts/fixtures/orientation/hostile-target/repo/hostile-dependency-tripwire/tripwire.mjs +9 -0
  119. package/contracts/fixtures/orientation/hostile-target/repo/package.json +20 -0
  120. package/contracts/fixtures/orientation/hostile-target/repo/schemas/example.v0.schema.json +15 -0
  121. package/contracts/fixtures/orientation/release-gate/cases.json +1073 -0
  122. package/contracts/fixtures/runtime-recipe/accept/current.json +299 -0
  123. package/contracts/fixtures/runtime-recipe/accept/minimal.json +294 -0
  124. package/contracts/fixtures/runtime-recipe/dist-states.json +51 -0
  125. package/contracts/fixtures/runtime-recipe/manifest.json +85 -0
  126. package/contracts/fixtures/runtime-recipe/reject/advisory-enforcement.json +299 -0
  127. package/contracts/fixtures/runtime-recipe/reject/allowlist-without-hosts.json +297 -0
  128. package/contracts/fixtures/runtime-recipe/reject/committed-output-claim.json +299 -0
  129. package/contracts/fixtures/runtime-recipe/reject/engines-disagreement-warns.json +299 -0
  130. package/contracts/fixtures/runtime-recipe/reject/lifecycle-scripts-enabled.json +299 -0
  131. package/contracts/fixtures/runtime-recipe/reject/missing-required-field.json +251 -0
  132. package/contracts/fixtures/runtime-recipe/reject/unknown-kind.json +299 -0
  133. package/contracts/fixtures/runtime-recipe/reject/unknown-network-policy.json +299 -0
  134. package/contracts/fixtures/runtime-recipe/reject/unknown-output-check.json +310 -0
  135. package/contracts/fixtures/runtime-recipe/reject/unknown-revision.json +299 -0
  136. package/contracts/fixtures/runtime-recipe/reject/unknown-step-id.json +299 -0
  137. package/contracts/fixtures/runtime-recipe/reject/unperformable-check-skipped.json +299 -0
  138. package/contracts/fixtures/runtime-recipe/reject/unpinned-lockfile.json +299 -0
  139. package/contracts/fixtures/sidecar-bundle/production-shaped/.campaign-runtime/assembly-report.json +180 -0
  140. package/contracts/fixtures/sidecar-bundle/production-shaped/.campaign-runtime/build-context.json +115 -0
  141. package/contracts/fixtures/sidecar-bundle/production-shaped/.campaign-runtime/doctor-output.json +29 -0
  142. package/contracts/fixtures/sidecar-bundle/production-shaped/.campaign-runtime/qa-verdict.json +27 -0
  143. package/contracts/fixtures/sidecar-bundle/production-shaped/campaign-runtime.build.json +141 -0
  144. package/contracts/migration-sidecar-bundle.v0.json +149 -0
  145. package/contracts/orientation-limits.v1.json +41 -0
  146. package/contracts/orientation-reason-codes.v1.json +196 -0
  147. package/contracts/private-template-sources.json +8 -0
  148. package/contracts/release-ledger.json +4598 -0
  149. package/contracts/reserved-skill-names.json +13 -0
  150. package/contracts/runtime-recipe.campaigns-os-node-v1.json +299 -0
  151. package/contracts/supported-surface.json +180 -0
  152. package/contracts/template-brand-contract.apollo-mv-single-step.v0.json +27 -0
  153. package/contracts/template-brand-contract.apollo.v0.json +27 -0
  154. package/contracts/template-brand-contract.demeter.v0.json +27 -0
  155. package/contracts/template-brand-contract.olympus-mv-single-step.v0.json +27 -0
  156. package/contracts/template-brand-contract.olympus-mv-two-step.v0.json +28 -0
  157. package/contracts/template-brand-contract.olympus.v0.json +27 -0
  158. package/contracts/template-brand-contract.shared-commerce.v0.json +190 -0
  159. package/contracts/template-brand-contract.shop-single-step.v0.json +27 -0
  160. package/contracts/template-brand-contract.shop-three-step.v0.json +29 -0
  161. package/contracts/template-slot-manifest.apollo-mv-single-step.v0.json +14 -0
  162. package/contracts/template-slot-manifest.apollo.v0.json +12 -0
  163. package/contracts/template-slot-manifest.demeter.v0.json +30 -0
  164. package/contracts/template-slot-manifest.olympus-mv-single-step.v0.json +14 -0
  165. package/contracts/template-slot-manifest.olympus-mv-two-step.v0.json +15 -0
  166. package/contracts/template-slot-manifest.olympus.v0.json +12 -0
  167. package/contracts/template-slot-manifest.shared-content-core.v0.json +4254 -0
  168. package/contracts/template-slot-manifest.shop-single-step.v0.json +47 -0
  169. package/contracts/template-slot-manifest.shop-three-step.v0.json +33 -0
  170. package/docs/brand-theme-bridge.md +159 -0
  171. package/docs/build-packet.md +1300 -0
  172. package/docs/campaign-build-brief.md +145 -0
  173. package/docs/campaign-standardization-report.md +329 -0
  174. package/docs/campaigns-os-build-flow.md +117 -0
  175. package/docs/design-source-package.md +784 -0
  176. package/docs/legacy-migration.md +58 -0
  177. package/docs/migration-sidecar-bundle.md +139 -0
  178. package/docs/orientation-contract-reference.md +1220 -0
  179. package/docs/polish-evidence.md +502 -0
  180. package/docs/qa-and-test-orders.md +1691 -0
  181. package/docs/release-ledger-authoring-guide.md +274 -0
  182. package/docs/runtime-readiness.md +211 -0
  183. package/docs/supported-surface.md +83 -0
  184. package/docs/versioning.md +55 -0
  185. package/docs/workflow-findings-sidecar.md +588 -0
  186. package/package.json +135 -0
  187. package/prompts/first-build.md +27 -0
  188. package/prompts/friction-log.md +30 -0
  189. package/schemas/campaign-build-brief.v1.schema.json +149 -0
  190. package/schemas/campaign-design-source-package.v0.schema.json +697 -0
  191. package/schemas/campaign-runtime-assembly-report.v0.schema.json +390 -0
  192. package/schemas/campaign-runtime-build-context.v0.schema.json +339 -0
  193. package/schemas/campaign-runtime-build-packet.v0.schema.json +452 -0
  194. package/schemas/campaign-spec.v4.schema.json +582 -0
  195. package/schemas/campaigns-os-doctor-output.v0.schema.json +43 -0
  196. package/schemas/campaigns-os-legacy-migration-inventory.v0.schema.json +112 -0
  197. package/schemas/campaigns-os-legacy-provisioning-plan.v0.schema.json +38 -0
  198. package/schemas/campaigns-os-legacy-provisioning-receipt.v0.schema.json +57 -0
  199. package/schemas/campaigns-os-qa-verdict-sidecar.v0.schema.json +150 -0
  200. package/schemas/campaigns-os-qa-verdict.v0.schema.json +438 -0
  201. package/schemas/campaigns-os-release-ledger.v1.schema.json +162 -0
  202. package/schemas/campaigns-os-run-record.v0.schema.json +343 -0
  203. package/schemas/campaigns-os-runtime-recipe.v1.schema.json +313 -0
  204. package/schemas/campaigns-os-sidecar-bundle-conformance.v0.schema.json +78 -0
  205. package/schemas/campaigns-os-tooling-orientation.v1.schema.json +381 -0
  206. package/schemas/campaigns-os-workflow-finding.v0.schema.json +134 -0
  207. package/schemas/source-html-manifest.v0.schema.json +252 -0
  208. package/skills/next-campaigns-build/SKILL.md +73 -0
  209. package/skills/next-campaigns-os/SKILL.md +101 -0
  210. package/skills/next-campaigns-os/references/session-intake.md +160 -0
  211. package/skills/next-campaigns-os-setup/SKILL.md +22 -0
  212. package/skills/next-campaigns-polish/SKILL.md +145 -0
  213. package/skills/next-campaigns-qa/SKILL.md +92 -0
  214. package/skills.json +56 -0
  215. package/skills.sh +64 -0
  216. package/src/adapter-decision-contract.mjs +333 -0
  217. package/src/brand-theme.mjs +1151 -0
  218. package/src/browser-launch.mjs +79 -0
  219. package/src/build-brief.mjs +781 -0
  220. package/src/built-site-scope.mjs +312 -0
  221. package/src/campaign-ecosystem.mjs +734 -0
  222. package/src/campaign-identity.mjs +405 -0
  223. package/src/campaign-workspace.mjs +127 -0
  224. package/src/checkpoint-waiver.mjs +302 -0
  225. package/src/cli.mjs +13442 -0
  226. package/src/commercial-journey.mjs +1119 -0
  227. package/src/commercial-parity.mjs +965 -0
  228. package/src/consent.mjs +347 -0
  229. package/src/content-residue.mjs +322 -0
  230. package/src/deadline.mjs +81 -0
  231. package/src/design-source-package.mjs +2604 -0
  232. package/src/deviation.mjs +107 -0
  233. package/src/doctor-check-registry.mjs +49 -0
  234. package/src/doctor-sidecar.mjs +106 -0
  235. package/src/finding-cause.mjs +557 -0
  236. package/src/findings.mjs +326 -0
  237. package/src/fs-identity.mjs +68 -0
  238. package/src/gate-actions.mjs +105 -0
  239. package/src/html-scan.mjs +53 -0
  240. package/src/install-mode.mjs +272 -0
  241. package/src/legacy-migration.d.ts +128 -0
  242. package/src/legacy-migration.mjs +510 -0
  243. package/src/lifecycle.mjs +338 -0
  244. package/src/local-proof.mjs +401 -0
  245. package/src/map-pin-writeback.mjs +210 -0
  246. package/src/orchestration-stage-contract.mjs +81 -0
  247. package/src/package-install-fixture.mjs +33 -0
  248. package/src/page-kit-build-summary.mjs +175 -0
  249. package/src/page-kit-campaign-config.mjs +57 -0
  250. package/src/page-kit-sdk-version.mjs +392 -0
  251. package/src/page-kit-store-profile.mjs +369 -0
  252. package/src/page-kit-sync.mjs +162 -0
  253. package/src/polish-browser.mjs +867 -0
  254. package/src/polish-capture.mjs +1094 -0
  255. package/src/polish-deadline.mjs +51 -0
  256. package/src/polish-gate.mjs +739 -0
  257. package/src/polish-node.mjs +639 -0
  258. package/src/polish-page-load.mjs +1100 -0
  259. package/src/private-template-source.mjs +237 -0
  260. package/src/proof-policy.mjs +82 -0
  261. package/src/qa-analytics-correctness.mjs +307 -0
  262. package/src/qa-analytics-errors.mjs +38 -0
  263. package/src/qa-analytics-parity.mjs +699 -0
  264. package/src/qa-binding-evidence.mjs +140 -0
  265. package/src/qa-browser.mjs +6608 -0
  266. package/src/qa-cart-entry.mjs +406 -0
  267. package/src/qa-commercial-parity.mjs +641 -0
  268. package/src/qa-node.mjs +3620 -0
  269. package/src/qa-order-bump.mjs +381 -0
  270. package/src/qa-parity-capture.mjs +428 -0
  271. package/src/qa-parity-fixture.mjs +359 -0
  272. package/src/qa-publish.mjs +362 -0
  273. package/src/qa-purchase-data-layer.mjs +263 -0
  274. package/src/qa-route-probe.mjs +272 -0
  275. package/src/qa-sidecar.mjs +188 -0
  276. package/src/qa-test-order-topology.mjs +207 -0
  277. package/src/qa-url-privacy.mjs +13 -0
  278. package/src/qa-verdict-discovery.mjs +192 -0
  279. package/src/qa-verdict-publish.mjs +105 -0
  280. package/src/qa-verdict.mjs +287 -0
  281. package/src/remit.mjs +388 -0
  282. package/src/repo-scan.mjs +83 -0
  283. package/src/route-identity.mjs +133 -0
  284. package/src/run-record-closeout.mjs +229 -0
  285. package/src/run-record.mjs +839 -0
  286. package/src/run-session.mjs +226 -0
  287. package/src/runtime-state-ignore.mjs +113 -0
  288. package/src/sdk-attribute-index.mjs +212 -0
  289. package/src/sdk-markup.mjs +358 -0
  290. package/src/sdk-meta-tags.mjs +52 -0
  291. package/src/shell-token.mjs +7 -0
  292. package/src/sidecar-bundle.mjs +399 -0
  293. package/src/source-asset-crawl.mjs +469 -0
  294. package/src/source-html-intake.mjs +627 -0
  295. package/src/source-html-manifest.mjs +276 -0
  296. package/src/source-prep.mjs +284 -0
  297. package/src/spec-derive-store.mjs +431 -0
  298. package/src/spec-derive.mjs +514 -0
  299. package/src/spec-fetch.mjs +66 -0
  300. package/src/spec-hash.mjs +48 -0
  301. package/src/spec-identity.mjs +27 -0
  302. package/src/stage-ledger.mjs +509 -0
  303. package/src/standardization-report.mjs +1297 -0
  304. package/src/template-brand-contract.mjs +473 -0
  305. package/src/template-freshness.mjs +196 -0
  306. package/src/template-reference.mjs +81 -0
  307. package/src/template-slot-manifest.mjs +150 -0
  308. package/src/text-safety.mjs +62 -0
  309. package/src/theme-gate.mjs +185 -0
  310. package/src/upsell-selector-scope.mjs +299 -0
@@ -0,0 +1,100 @@
1
+ {
2
+ "schema_version": "campaigns-os-tooling-orientation/v1",
3
+ "request": {
4
+ "run_id": "run-example-0001",
5
+ "checkout_mode": "managed",
6
+ "mutation_policy": "observe_only",
7
+ "baseline": {
8
+ "kind": "supported_surface",
9
+ "commit": "1111111111111111111111111111111111111111",
10
+ "surface_version": "1.13.0"
11
+ },
12
+ "accepted_orientation_schemas": [
13
+ "campaigns-os-tooling-orientation/v1"
14
+ ],
15
+ "accepted_surface_range": ">=1.13.0 <2.0.0",
16
+ "manifest_sha256": "3333333333333333333333333333333333333333333333333333333333333333"
17
+ },
18
+ "repository": {
19
+ "owner": "NextCommerceCo",
20
+ "repository": "campaigns-os",
21
+ "branch": "main",
22
+ "upstream": "origin/main",
23
+ "clean": true,
24
+ "shallow": false,
25
+ "graph_relation": "identical",
26
+ "common_git_identity": "managed-store-0001",
27
+ "worktree_identity": "generation-0001",
28
+ "commit_before": "1111111111111111111111111111111111111111",
29
+ "commit_fetched": "1111111111111111111111111111111111111111",
30
+ "commit_after": "1111111111111111111111111111111111111111"
31
+ },
32
+ "freshness": {
33
+ "state": "refused",
34
+ "observed_at": "2026-08-28T00:00:00Z",
35
+ "fetch_result": {
36
+ "attempted": true,
37
+ "succeeded": true,
38
+ "duration_ms": 610
39
+ }
40
+ },
41
+ "surface": {
42
+ "reviewed_version": "1.13.0",
43
+ "target_version": "1.13.0",
44
+ "current_version": "1.13.0",
45
+ "compatibility_result": "compatible",
46
+ "compatibility_rule": "target surface_version is inside the consumer's accepted_surface_range",
47
+ "transitions": []
48
+ },
49
+ "release_ledger": {
50
+ "ledger_schema_version": "campaigns-os-release-ledger/v1",
51
+ "entries": []
52
+ },
53
+ "changelog": {
54
+ "sections": []
55
+ },
56
+ "runtime": {
57
+ "recipe_id": null,
58
+ "source_fingerprint": "3333333333333333333333333333333333333333333333333333333333333333",
59
+ "generated_state": "fresh",
60
+ "emitter_commit": "1111111111111111111111111111111111111111",
61
+ "refresh_action": "none",
62
+ "ready": true
63
+ },
64
+ "transaction": {
65
+ "state": "none",
66
+ "commit_before": "1111111111111111111111111111111111111111",
67
+ "commit_target": "1111111111111111111111111111111111111111",
68
+ "commit_observed": "1111111111111111111111111111111111111111",
69
+ "recovered_interrupted_update": false
70
+ },
71
+ "outcome": {
72
+ "disposition": "refused",
73
+ "reason_code": "orientation_too_large",
74
+ "active_generation_changed": false,
75
+ "fresh_exec_required": false,
76
+ "next_actions": [
77
+ "adopt a newer reviewed baseline",
78
+ "raise the limit as a reviewed policy change"
79
+ ],
80
+ "refusal_remedy": "Adopt a newer reviewed baseline so the window is smaller, or raise the limit as a reviewed policy change that advances limits_version and carries its own ledger entry. Orientation refuses; it never truncates."
81
+ },
82
+ "limits": {
83
+ "limits_version": "1.0.0",
84
+ "max_source_bytes": 1048576,
85
+ "max_section_count": 1024,
86
+ "max_section_bytes": 65536,
87
+ "max_envelope_bytes": 262144,
88
+ "max_ledger_entries": 1024,
89
+ "applied": {
90
+ "source_bytes": 1048577,
91
+ "section_count": 8,
92
+ "max_observed_section_bytes": 3903,
93
+ "envelope_bytes": 4096,
94
+ "ledger_entries": 1
95
+ },
96
+ "exceeded": [
97
+ "max_source_bytes"
98
+ ]
99
+ }
100
+ }
@@ -0,0 +1,137 @@
1
+ {
2
+ "schema_version": "campaigns-os-tooling-orientation/v1",
3
+ "request": {
4
+ "run_id": "run-example-0001",
5
+ "checkout_mode": "managed",
6
+ "mutation_policy": "observe_only",
7
+ "baseline": {
8
+ "kind": "supported_surface",
9
+ "commit": "1111111111111111111111111111111111111111",
10
+ "surface_version": "1.13.0"
11
+ },
12
+ "accepted_orientation_schemas": [
13
+ "campaigns-os-tooling-orientation/v1"
14
+ ],
15
+ "accepted_surface_range": ">=1.13.0 <2.0.0",
16
+ "manifest_sha256": "3333333333333333333333333333333333333333333333333333333333333333"
17
+ },
18
+ "repository": {
19
+ "owner": "NextCommerceCo",
20
+ "repository": "campaigns-os",
21
+ "branch": "main",
22
+ "upstream": "origin/main",
23
+ "clean": true,
24
+ "shallow": false,
25
+ "graph_relation": "identical",
26
+ "common_git_identity": "managed-store-0001",
27
+ "worktree_identity": "generation-0001",
28
+ "commit_before": "1111111111111111111111111111111111111111",
29
+ "commit_fetched": "1111111111111111111111111111111111111111",
30
+ "commit_after": "1111111111111111111111111111111111111111"
31
+ },
32
+ "freshness": {
33
+ "state": "available",
34
+ "observed_at": "2026-08-28T00:00:00Z",
35
+ "fetch_result": {
36
+ "attempted": true,
37
+ "succeeded": true,
38
+ "duration_ms": 610
39
+ }
40
+ },
41
+ "surface": {
42
+ "reviewed_version": "1.13.0",
43
+ "target_version": "1.14.0",
44
+ "current_version": "1.13.0",
45
+ "compatibility_result": "compatible",
46
+ "compatibility_rule": "target surface_version is inside the consumer's accepted_surface_range",
47
+ "transitions": [
48
+ {
49
+ "from": "1.13.0",
50
+ "to": "1.14.0"
51
+ }
52
+ ]
53
+ },
54
+ "release_ledger": {
55
+ "ledger_schema_version": "campaigns-os-release-ledger/v1",
56
+ "entries": [
57
+ {
58
+ "id": "RL-0001",
59
+ "sequence": 1,
60
+ "date": "2026-08-28",
61
+ "kind": "release",
62
+ "surface_version": "1.14.0",
63
+ "changelog_section": "1.14.0",
64
+ "changelog_sha256": "3333333333333333333333333333333333333333333333333333333333333333",
65
+ "agent_impact": "A consumer may now read the orientation contract and release ledger from Git objects.",
66
+ "compatibility": "additive",
67
+ "migration": "none",
68
+ "affected_surface_entries": [
69
+ "contracts/release-ledger.json"
70
+ ],
71
+ "changes": [
72
+ {
73
+ "class": "named_surface",
74
+ "path": "contracts/release-ledger.json",
75
+ "surface_entry": "contracts/release-ledger.json",
76
+ "summary": "The append-only agent-relevant release ledger was introduced."
77
+ }
78
+ ],
79
+ "entry_sha256": "3333333333333333333333333333333333333333333333333333333333333333",
80
+ "introducing_commit": "2222222222222222222222222222222222222222"
81
+ }
82
+ ]
83
+ },
84
+ "changelog": {
85
+ "sections": [
86
+ {
87
+ "section_id": "1.14.0",
88
+ "date": "2026-08-28",
89
+ "agent_impact": "A consumer may now read the orientation contract and release ledger from Git objects.",
90
+ "migration_action": "none",
91
+ "body_markdown": "## [1.14.0] - 2026-08-28\n\n### Added\n\n- The orientation contract and the agent-relevant release ledger.",
92
+ "body_sha256": "3333333333333333333333333333333333333333333333333333333333333333"
93
+ }
94
+ ]
95
+ },
96
+ "runtime": {
97
+ "recipe_id": null,
98
+ "source_fingerprint": "3333333333333333333333333333333333333333333333333333333333333333",
99
+ "generated_state": "stale",
100
+ "emitter_commit": "1111111111111111111111111111111111111111",
101
+ "refresh_action": "prepare_new_generation",
102
+ "ready": false,
103
+ "reason_code": "runtime_refresh_required"
104
+ },
105
+ "transaction": {
106
+ "state": "none",
107
+ "commit_before": "1111111111111111111111111111111111111111",
108
+ "commit_target": "1111111111111111111111111111111111111111",
109
+ "commit_observed": "1111111111111111111111111111111111111111",
110
+ "recovered_interrupted_update": false
111
+ },
112
+ "outcome": {
113
+ "disposition": "restart_required",
114
+ "reason_code": "runtime_refresh_required",
115
+ "active_generation_changed": false,
116
+ "fresh_exec_required": true,
117
+ "next_actions": [
118
+ "prepare a new generation",
119
+ "start a fresh session"
120
+ ]
121
+ },
122
+ "limits": {
123
+ "limits_version": "1.0.0",
124
+ "max_source_bytes": 1048576,
125
+ "max_section_count": 1024,
126
+ "max_section_bytes": 65536,
127
+ "max_envelope_bytes": 262144,
128
+ "max_ledger_entries": 1024,
129
+ "applied": {
130
+ "source_bytes": 22024,
131
+ "section_count": 8,
132
+ "max_observed_section_bytes": 3903,
133
+ "envelope_bytes": 4096,
134
+ "ledger_entries": 1
135
+ }
136
+ }
137
+ }
@@ -0,0 +1,135 @@
1
+ {
2
+ "schema_version": "campaigns-os-tooling-orientation/v1",
3
+ "request": {
4
+ "run_id": "run-example-0001",
5
+ "checkout_mode": "managed",
6
+ "mutation_policy": "managed_update",
7
+ "baseline": {
8
+ "kind": "supported_surface",
9
+ "commit": "1111111111111111111111111111111111111111",
10
+ "surface_version": "1.13.0"
11
+ },
12
+ "accepted_orientation_schemas": [
13
+ "campaigns-os-tooling-orientation/v1"
14
+ ],
15
+ "accepted_surface_range": ">=1.13.0 <2.0.0",
16
+ "manifest_sha256": "3333333333333333333333333333333333333333333333333333333333333333"
17
+ },
18
+ "repository": {
19
+ "owner": "NextCommerceCo",
20
+ "repository": "campaigns-os",
21
+ "branch": "main",
22
+ "upstream": "origin/main",
23
+ "clean": true,
24
+ "shallow": false,
25
+ "graph_relation": "identical",
26
+ "common_git_identity": "managed-store-0001",
27
+ "worktree_identity": "generation-0001",
28
+ "commit_before": "1111111111111111111111111111111111111111",
29
+ "commit_fetched": "2222222222222222222222222222222222222222",
30
+ "commit_after": "2222222222222222222222222222222222222222"
31
+ },
32
+ "freshness": {
33
+ "state": "updated",
34
+ "observed_at": "2026-08-28T00:00:00Z",
35
+ "fetch_result": {
36
+ "attempted": true,
37
+ "succeeded": true,
38
+ "duration_ms": 610
39
+ }
40
+ },
41
+ "surface": {
42
+ "reviewed_version": "1.13.0",
43
+ "target_version": "1.14.0",
44
+ "current_version": "1.13.0",
45
+ "compatibility_result": "compatible",
46
+ "compatibility_rule": "target surface_version is inside the consumer's accepted_surface_range",
47
+ "transitions": [
48
+ {
49
+ "from": "1.13.0",
50
+ "to": "1.14.0"
51
+ }
52
+ ]
53
+ },
54
+ "release_ledger": {
55
+ "ledger_schema_version": "campaigns-os-release-ledger/v1",
56
+ "entries": [
57
+ {
58
+ "id": "RL-0001",
59
+ "sequence": 1,
60
+ "date": "2026-08-28",
61
+ "kind": "release",
62
+ "surface_version": "1.14.0",
63
+ "changelog_section": "1.14.0",
64
+ "changelog_sha256": "3333333333333333333333333333333333333333333333333333333333333333",
65
+ "agent_impact": "A consumer may now read the orientation contract and release ledger from Git objects.",
66
+ "compatibility": "additive",
67
+ "migration": "none",
68
+ "affected_surface_entries": [
69
+ "contracts/release-ledger.json"
70
+ ],
71
+ "changes": [
72
+ {
73
+ "class": "named_surface",
74
+ "path": "contracts/release-ledger.json",
75
+ "surface_entry": "contracts/release-ledger.json",
76
+ "summary": "The append-only agent-relevant release ledger was introduced."
77
+ }
78
+ ],
79
+ "entry_sha256": "3333333333333333333333333333333333333333333333333333333333333333",
80
+ "introducing_commit": "2222222222222222222222222222222222222222"
81
+ }
82
+ ]
83
+ },
84
+ "changelog": {
85
+ "sections": [
86
+ {
87
+ "section_id": "1.14.0",
88
+ "date": "2026-08-28",
89
+ "agent_impact": "A consumer may now read the orientation contract and release ledger from Git objects.",
90
+ "migration_action": "none",
91
+ "body_markdown": "## [1.14.0] - 2026-08-28\n\n### Added\n\n- The orientation contract and the agent-relevant release ledger.",
92
+ "body_sha256": "3333333333333333333333333333333333333333333333333333333333333333"
93
+ }
94
+ ]
95
+ },
96
+ "runtime": {
97
+ "recipe_id": null,
98
+ "source_fingerprint": "3333333333333333333333333333333333333333333333333333333333333333",
99
+ "generated_state": "fresh",
100
+ "emitter_commit": "1111111111111111111111111111111111111111",
101
+ "refresh_action": "none",
102
+ "ready": true
103
+ },
104
+ "transaction": {
105
+ "state": "finalized",
106
+ "commit_before": "1111111111111111111111111111111111111111",
107
+ "commit_target": "2222222222222222222222222222222222222222",
108
+ "commit_observed": "2222222222222222222222222222222222222222",
109
+ "recovered_interrupted_update": false
110
+ },
111
+ "outcome": {
112
+ "disposition": "updated",
113
+ "reason_code": "orientation_rendered",
114
+ "active_generation_changed": true,
115
+ "fresh_exec_required": true,
116
+ "next_actions": [
117
+ "start a fresh session against the promoted generation"
118
+ ]
119
+ },
120
+ "limits": {
121
+ "limits_version": "1.0.0",
122
+ "max_source_bytes": 1048576,
123
+ "max_section_count": 1024,
124
+ "max_section_bytes": 65536,
125
+ "max_envelope_bytes": 262144,
126
+ "max_ledger_entries": 1024,
127
+ "applied": {
128
+ "source_bytes": 22024,
129
+ "section_count": 8,
130
+ "max_observed_section_bytes": 3903,
131
+ "envelope_bytes": 4096,
132
+ "ledger_entries": 1
133
+ }
134
+ }
135
+ }
@@ -0,0 +1,61 @@
1
+ # Hostile-target orientation fixture
2
+
3
+ A miniature Campaigns OS target that carries every locally executable thing a
4
+ real checkout can carry: Git hooks, executable scripts, and npm package
5
+ lifecycle scripts. Its orientation data under `repo/` is valid, so a correct
6
+ consumer can read it end to end and produce a normal envelope.
7
+
8
+ "Valid" includes the fixture's own supported-surface manifest: every path
9
+ `repo/contracts/supported-surface.json` declares exists in the tree, and the
10
+ digest it records for its hashed entry is that file's real sha256. A consumer
11
+ that verifies integrity therefore succeeds here rather than refusing — which is
12
+ the point, because a read that refuses early never reaches the tripwires and so
13
+ proves nothing about whether the parser would have executed them.
14
+ `scripts/check-release-ledger.test.mjs` asserts that correspondence, so the
15
+ fixture cannot quietly rot back into a refusal.
16
+
17
+ The fixture carries two invariants over one tree, because the tripwires are the
18
+ same tripwires: a target that can ambush a reader can ambush an installer.
19
+
20
+ 1. **Orientation executes nothing.** The tripwire count for a full orientation
21
+ read is exactly zero. This is the original invariant and `tripwires[]` plus
22
+ `expected_hit_count` in `manifest.json` describe it.
23
+ 2. **Runtime-recipe preparation executes only the recipe's own steps.** The
24
+ accepted recipe installs with dependency lifecycle scripts suppressed and
25
+ builds one named script without its pre/post siblings. `recipe_execution` in
26
+ `manifest.json` describes it: the tripwire log stays empty and the separate
27
+ intended-script log holds exactly one line. `repo/hostile-dependency-tripwire/`
28
+ exists for this second invariant — it is packed into a tarball and installed
29
+ as a real dependency, so dependency-side lifecycle scripts are exercised for
30
+ real rather than assumed.
31
+
32
+ That invariant needs a control, and `recipe_execution.control` names it:
33
+ running the same two commands *without* the suppressing flag must fire
34
+ tripwires. A suppression test with no control passes just as happily against
35
+ a dependency whose scripts would never have fired anyway.
36
+
37
+ **Nothing in this directory is ever executed by this repository.** The files
38
+ exist so that a consumer's parser can be pointed at a target that *would* run
39
+ code if the parser ever shelled out, checked anything out, or installed
40
+ anything. Every tripwire appends one line to the file named by
41
+ `CAMPAIGNS_OS_TRIPWIRE_LOG` (falling back to `tripwire.log` beside itself) and
42
+ then exits 0, so a hit is recorded rather than crashing the run being tested.
43
+ The one exception is `repo/bin/intended.mjs`, which is not a tripwire: it is the
44
+ script the recipe's build step is *supposed* to run, and it logs to
45
+ `CAMPAIGNS_OS_INTENDED_LOG` instead.
46
+
47
+ The assertion that the hit count stays zero belongs to the consumer's parser
48
+ suite, not here: this repository ships the fixture, the consumer ships the
49
+ counter. `manifest.json` enumerates the tripwires so that counter can assert an
50
+ exact expected set rather than a hand-copied list.
51
+
52
+ Consuming it:
53
+
54
+ 1. Materialize `repo/` as the target tree (copy it, or commit it into a
55
+ temporary repository and install `repo/hooks/*` as that repository's hooks).
56
+ 2. Point `CAMPAIGNS_OS_TRIPWIRE_LOG` at a fresh path.
57
+ 3. Run the full orientation read against the target.
58
+ 4. Assert the log does not exist, or is empty.
59
+
60
+ Any non-zero count means the parser executed target-controlled code, which the
61
+ contract forbids regardless of how harmless the executed code looks.
@@ -0,0 +1,82 @@
1
+ {
2
+ "_note": "Enumerates every tripwire in this fixture so a consumer's no-execution test can assert an exact expected set instead of hand-copying a list that silently rots when a tripwire is added.",
3
+ "schema": "campaigns-os-hostile-target-fixture/v1",
4
+ "fixture_version": "1.0.0",
5
+ "target_root": "repo",
6
+ "invariant": "A conforming orientation read of target_root executes none of the tripwires below. The expected hit count is exactly 0.",
7
+ "tripwire_log_env": "CAMPAIGNS_OS_TRIPWIRE_LOG",
8
+ "expected_hit_count": 0,
9
+ "tripwires": [
10
+ {
11
+ "path": "repo/hooks/post-checkout",
12
+ "kind": "git_hook",
13
+ "mode": "755",
14
+ "fires_on": "git checkout / git worktree add against a repository with these hooks installed"
15
+ },
16
+ {
17
+ "path": "repo/hooks/post-merge",
18
+ "kind": "git_hook",
19
+ "mode": "755",
20
+ "fires_on": "git merge or git pull"
21
+ },
22
+ {
23
+ "path": "repo/hooks/pre-commit",
24
+ "kind": "git_hook",
25
+ "mode": "755",
26
+ "fires_on": "git commit"
27
+ },
28
+ {
29
+ "path": "repo/bin/tripwire.mjs",
30
+ "kind": "executable_file",
31
+ "mode": "755",
32
+ "fires_on": "direct execution of a target-supplied binary"
33
+ },
34
+ {
35
+ "path": "repo/package.json",
36
+ "kind": "package_lifecycle_script",
37
+ "mode": "644",
38
+ "fires_on": "npm install / npm ci / npm pack without --ignore-scripts (preinstall, install, postinstall, prepare, prepack), or npm run build:spec without --ignore-scripts (prebuild:spec, postbuild:spec)"
39
+ },
40
+ {
41
+ "path": "repo/hostile-dependency-tripwire/package.json",
42
+ "kind": "dependency_lifecycle_script",
43
+ "mode": "644",
44
+ "fires_on": "installation of this package as a DEPENDENCY of repo/ without --ignore-scripts (preinstall, install, postinstall), or packing it without --ignore-scripts (prepare, prepack)"
45
+ },
46
+ {
47
+ "path": "repo/hostile-dependency-tripwire/tripwire.mjs",
48
+ "kind": "executable_file",
49
+ "mode": "755",
50
+ "fires_on": "direct execution of a dependency-supplied file, or any of that package's lifecycle scripts"
51
+ }
52
+ ],
53
+ "orientation_data": {
54
+ "changelog": "repo/CHANGELOG.md",
55
+ "release_ledger": "repo/contracts/release-ledger.json",
56
+ "supported_surface": "repo/contracts/supported-surface.json"
57
+ },
58
+ "intended_script_log_env": "CAMPAIGNS_OS_INTENDED_LOG",
59
+ "intended_scripts": [
60
+ {
61
+ "path": "repo/bin/intended.mjs",
62
+ "invoked_by": "repo/package.json scripts.build:spec",
63
+ "_note": "NOT a tripwire. The one script an accepted runtime-recipe build step is meant to run. It logs to intended_script_log_env so 'the intended script ran' and 'nothing else ran' stay separable assertions — a fixture that only proved the tripwire log was empty would also pass if the build never ran at all."
64
+ }
65
+ ],
66
+ "recipe_execution": {
67
+ "_note": "The second invariant this fixture carries, added for the runtime-readiness contract. Orientation must execute NOTHING here; runtime-recipe preparation must execute exactly the recipe's two steps and no lifecycle script reachable from them. The tree is shared because the tripwires are the same tripwires — a target that can ambush a reader can ambush an installer.",
68
+ "invariant": "Running the accepted recipe's install step and then its build step against target_root leaves the tripwire log empty and the intended-script log holding exactly one line. The same two commands WITHOUT their script-suppressing flag must fire tripwires, or the fixture proves nothing.",
69
+ "recipe": "contracts/runtime-recipe.campaigns-os-node-v1.json",
70
+ "expected_lifecycle_hit_count": 0,
71
+ "expected_intended_hit_count": 1,
72
+ "dependency_package": "repo/hostile-dependency-tripwire",
73
+ "packed_dependency": "hostile-dependency-tripwire-0.0.0.tgz",
74
+ "setup": [
75
+ "Copy repo/ to a scratch directory; never install inside this repository's tree.",
76
+ "Pack dependency_package into packed_dependency with lifecycle scripts suppressed, so the packing step is outside the measured window.",
77
+ "Materialize a lockfile for the copied tree with lifecycle scripts suppressed. The single dependency resolves from the local tarball, so no network is involved.",
78
+ "Truncate both logs, then run the recipe steps with the argv the recipe declares."
79
+ ],
80
+ "control": "Repeat both steps with the script-suppressing flag removed and assert the tripwire log is NOT empty. Without this control the fixture cannot distinguish a working suppression from a dependency whose scripts never fire in the first place."
81
+ }
82
+ }
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ Notable supported-surface changes are recorded here.
4
+
5
+ ## [9.0.0] - 2026-01-02
6
+
7
+ ### Added
8
+
9
+ - A hostile-target fixture release section. Present so a consumer can complete a
10
+ full orientation read against this target and produce a normal envelope, which
11
+ is what makes a zero hit count meaningful: the parser did the whole job
12
+ without executing anything.
13
+
14
+ ## [8.0.0] - 2026-01-01
15
+
16
+ ### Added
17
+
18
+ - The initial fixture surface.
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ // NOT a tripwire. This is the one script an accepted runtime recipe's build step
3
+ // is supposed to run, and it writes to its own log so the two assertions stay
4
+ // separable: the lifecycle log must stay empty, and this log must have exactly
5
+ // one line. A fixture that only proved "nothing ran" would also pass if the
6
+ // build itself never ran.
7
+ import { appendFileSync } from "node:fs";
8
+ import { dirname, join } from "node:path";
9
+ import { fileURLToPath } from "node:url";
10
+
11
+ const fallback = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "intended.log");
12
+ appendFileSync(process.env.CAMPAIGNS_OS_INTENDED_LOG ?? fallback, `intended_script ${process.argv[2] ?? "unlabelled"}\n`);
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ // Tripwire. See ../../README.md: nothing here should ever run during an
3
+ // orientation read, and no lifecycle script here should ever run during an
4
+ // accepted runtime-recipe preparation. Records the hit and exits 0.
5
+ //
6
+ // The optional argument labels which tripwire fired. Called with no argument it
7
+ // emits the original line verbatim, so an existing counter that matches on that
8
+ // exact text keeps working.
9
+ import { appendFileSync } from "node:fs";
10
+ import { dirname, join } from "node:path";
11
+ import { fileURLToPath } from "node:url";
12
+
13
+ const fallback = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "tripwire.log");
14
+ const label = process.argv[2];
15
+ appendFileSync(process.env.CAMPAIGNS_OS_TRIPWIRE_LOG ?? fallback, label ? `lifecycle_script ${label}\n` : "executable_file bin/tripwire.mjs\n");
@@ -0,0 +1,48 @@
1
+ {
2
+ "_note": "Fixture copy. Two entries so a consumer exercises a multi-entry orientation window. Values are invented and describe nothing real.",
3
+ "schema_version": "campaigns-os-release-ledger/v1",
4
+ "entries": [
5
+ {
6
+ "id": "RL-0001",
7
+ "sequence": 1,
8
+ "date": "2026-01-01",
9
+ "kind": "release",
10
+ "surface_version": "8.0.0",
11
+ "changelog_section": "8.0.0",
12
+ "changelog_sha256": "1649c529470b313079ced834b043748de37805683fe9e61f6473d729639b4bd3",
13
+ "agent_impact": "None. The fixture surface came into existence.",
14
+ "compatibility": "additive",
15
+ "migration": "none",
16
+ "changes": [
17
+ {
18
+ "class": "schema",
19
+ "path": "schemas/example.v0.schema.json",
20
+ "surface_entry": "schemas/example.v0.schema.json",
21
+ "summary": "The fixture schema was introduced."
22
+ }
23
+ ],
24
+ "entry_sha256": "541525e9550ed6a3c6892b03316f8141b59d7bc1bc8cb1e3077ccf1cee648208"
25
+ },
26
+ {
27
+ "id": "RL-0002",
28
+ "sequence": 2,
29
+ "date": "2026-01-02",
30
+ "kind": "release",
31
+ "surface_version": "9.0.0",
32
+ "changelog_section": "9.0.0",
33
+ "changelog_sha256": "92a3adaca47437b957530dd984780f707c9766fe53aa0b03c8da489f8b8bacd0",
34
+ "agent_impact": "None. A second entry exists so a consumer reads a multi-entry window.",
35
+ "compatibility": "compatible",
36
+ "migration": "none",
37
+ "changes": [
38
+ {
39
+ "class": "named_surface",
40
+ "path": "docs/example-contract.md",
41
+ "surface_entry": "docs/example-contract.md",
42
+ "summary": "The fixture contract doc gained a section."
43
+ }
44
+ ],
45
+ "entry_sha256": "cd08981736013e6192e9998e9e1e64032d2cb09378feb9ee1e49043cef17d2f3"
46
+ }
47
+ ]
48
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "_note": "Fixture copy. Shape-compatible with the real manifest so a consumer's parser exercises the same code path; the values are invented and describe nothing real. Every path declared below EXISTS in this fixture tree and the hashed digest is the file's real sha256, so a consumer that verifies integrity succeeds here. That matters: this fixture's invariant is that a COMPLETE orientation read executes nothing, and a read that refuses on a missing or mismatched file never gets far enough to prove it.",
3
+ "surface_version": "9.0.0",
4
+ "package_exports": [],
5
+ "bin": [],
6
+ "cli_commands": [],
7
+ "hashed": {
8
+ "schemas/example.v0.schema.json": {
9
+ "sha256": "508d2e02d76d196cbd94f0eb76d982417d18509923bd12a5d31557f362256005"
10
+ }
11
+ },
12
+ "named": [
13
+ "CHANGELOG.md",
14
+ "contracts/release-ledger.json",
15
+ "docs/example-contract.md"
16
+ ]
17
+ }
@@ -0,0 +1,13 @@
1
+ # Example contract (hostile-target fixture)
2
+
3
+ Invented. This document describes nothing real.
4
+
5
+ It exists because the fixture's `contracts/supported-surface.json` declares
6
+ `docs/example-contract.md` as a named entry. A named entry's promise is that the
7
+ path keeps existing, so a consumer that checks its manifest against the tree
8
+ must find a file here. When it was missing, a conforming consumer had to refuse
9
+ on integrity — which is the opposite of what this fixture is for: the fixture
10
+ proves that a full, successful orientation read executes none of the tripwires
11
+ under `repo/`.
12
+
13
+ Nothing in this directory is ever executed by this repository.
@@ -0,0 +1,5 @@
1
+ #!/bin/sh
2
+ # Tripwire. Records that a consumer executed target-controlled code, then exits
3
+ # 0 so the run under test continues and the counter, not a crash, reports it.
4
+ printf 'git_hook %s\n' "post-checkout" >> "${CAMPAIGNS_OS_TRIPWIRE_LOG:-$(dirname "$0")/../../tripwire.log}"
5
+ exit 0
@@ -0,0 +1,5 @@
1
+ #!/bin/sh
2
+ # Tripwire. Records that a consumer executed target-controlled code, then exits
3
+ # 0 so the run under test continues and the counter, not a crash, reports it.
4
+ printf 'git_hook %s\n' "post-merge" >> "${CAMPAIGNS_OS_TRIPWIRE_LOG:-$(dirname "$0")/../../tripwire.log}"
5
+ exit 0