@hasna/contracts 0.1.1 → 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.
package/README.md CHANGED
@@ -124,6 +124,12 @@ defaults are applied; output aliases such as `EvidenceRef` describe parsed data.
124
124
  - `hasna.validation_plan.v1`: deterministic checks a package or agent should run.
125
125
  - `hasna.proof_bundle.v1`: reviewable validation result that ties a subject to
126
126
  checks, evidence, verifier, and verdict.
127
+ - `hasna.scaffold_manifest.v1`: public, portable description of a scaffold's
128
+ type, status, capabilities, output shape, env vars, scripts, and validation
129
+ checks.
130
+ - `hasna.scaffold_install_record.v1`: portable receipt for a scaffold install
131
+ against a target repo or project, including installer, status, generated
132
+ resource refs, evidence, and proof refs.
127
133
 
128
134
  Every top-level contract includes a literal `schema` field. Consumers should
129
135
  reject objects whose embedded schema does not match the validator being used.
@@ -176,6 +182,11 @@ helpers. Owning packages still own storage and behavior.
176
182
  - `open-evals` owns evaluation execution and scored validation results.
177
183
  - `open-economy` owns budget, cost, and usage policy decisions.
178
184
  - `open-monitor` owns fleet health classification and alerting.
185
+ - `iapp-scaffolds` owns scaffold templates, registry behavior, install/setup
186
+ behavior, MCP tools, CLI UX, and private/internal scaffold metadata. It should
187
+ validate public scaffold manifests and install records with
188
+ `@hasna/contracts`, but `@hasna/contracts` must not import or execute
189
+ `iapp-scaffolds`.
179
190
 
180
191
  ## Downstream Integration Recipes
181
192
 
@@ -216,6 +227,10 @@ native domain objects immediately.
216
227
  - `open-actions`: keep domain action manifests, but expose shared `ActorRef`,
217
228
  `EvidenceRef`, `CapabilityCard`, `DecisionEnvelope`, and `WorkRun` adapter
218
229
  views.
230
+ - `iapp-scaffolds`: emit `ScaffoldManifest` documents for bundled templates,
231
+ write schema-tagged `ScaffoldInstallRecord` receipts for installs, and keep
232
+ template copying, setup wizards, source paths, and private metadata inside the
233
+ scaffold package.
219
234
  - `open-automations`: keep deterministic app/product automation recipes and
220
235
  connector/action recipes. Any agentic task, PR, review, or evaluation flow
221
236
  must hand off to OpenLoops rather than creating a second workflow queue.
package/dist/cli/index.js CHANGED
@@ -6074,7 +6074,7 @@ var coerce = {
6074
6074
  };
6075
6075
  var NEVER = INVALID;
6076
6076
  // src/schemas.ts
6077
- var CONTRACTS_PACKAGE_VERSION = "0.1.1";
6077
+ var CONTRACTS_PACKAGE_VERSION = "0.2.0";
6078
6078
  var SCHEMA_IDS = {
6079
6079
  actorRef: "hasna.actor_ref.v1",
6080
6080
  resourceRef: "hasna.resource_ref.v1",
@@ -6086,7 +6086,9 @@ var SCHEMA_IDS = {
6086
6086
  contextPack: "hasna.context_pack.v1",
6087
6087
  agentTrajectory: "hasna.agent_trajectory.v1",
6088
6088
  validationPlan: "hasna.validation_plan.v1",
6089
- proofBundle: "hasna.proof_bundle.v1"
6089
+ proofBundle: "hasna.proof_bundle.v1",
6090
+ scaffoldManifest: "hasna.scaffold_manifest.v1",
6091
+ scaffoldInstallRecord: "hasna.scaffold_install_record.v1"
6090
6092
  };
6091
6093
  var SchemaIdSchema = exports_external.string().regex(/^hasna\.[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*\.v[0-9]+$/);
6092
6094
  var TimestampSchema = exports_external.string().datetime();
@@ -6390,6 +6392,144 @@ var ValidationPlanSchema = contractBaseSchema(SCHEMA_IDS.validationPlan).extend(
6390
6392
  verifier: ActorPointerSchema.optional(),
6391
6393
  requiredEvidenceKinds: exports_external.array(EvidenceKindSchema).default([])
6392
6394
  }).strict();
6395
+ var ScaffoldTypeSchema = exports_external.enum([
6396
+ "open_source",
6397
+ "internal_app",
6398
+ "platform",
6399
+ "app",
6400
+ "agent",
6401
+ "content",
6402
+ "overlay",
6403
+ "other"
6404
+ ]);
6405
+ var ScaffoldStatusSchema = exports_external.enum(["draft", "active", "deprecated", "archived"]);
6406
+ var ScaffoldCapabilitySchema = exports_external.enum([
6407
+ "cli",
6408
+ "mcp",
6409
+ "library",
6410
+ "sdk",
6411
+ "rest_api",
6412
+ "dashboard",
6413
+ "database",
6414
+ "auth",
6415
+ "billing",
6416
+ "worker",
6417
+ "daemon",
6418
+ "native",
6419
+ "browser_extension",
6420
+ "ai_provider",
6421
+ "media_pipeline",
6422
+ "data_pipeline",
6423
+ "tests",
6424
+ "ci",
6425
+ "deployment",
6426
+ "docs",
6427
+ "other"
6428
+ ]);
6429
+ var ScaffoldEnvVarSchema = exports_external.object({
6430
+ key: exports_external.string().regex(/^[A-Z][A-Z0-9_]*$/),
6431
+ description: exports_external.string().min(1),
6432
+ required: exports_external.boolean().default(false),
6433
+ secret: exports_external.boolean().default(false),
6434
+ group: exports_external.string().min(1).optional(),
6435
+ default: exports_external.string().optional()
6436
+ }).strict().superRefine((value, ctx) => {
6437
+ if (value.secret && value.default !== undefined) {
6438
+ ctx.addIssue({
6439
+ code: exports_external.ZodIssueCode.custom,
6440
+ message: "Secret scaffold env vars cannot include defaults",
6441
+ path: ["default"]
6442
+ });
6443
+ }
6444
+ });
6445
+ var ScaffoldScriptSchema = exports_external.object({
6446
+ name: exports_external.string().min(1),
6447
+ command: exports_external.string().min(1),
6448
+ description: exports_external.string().min(1).optional(),
6449
+ required: exports_external.boolean().default(false)
6450
+ }).strict();
6451
+ var ScaffoldOutputShapeSchema = exports_external.object({
6452
+ packageManager: exports_external.enum(["bun", "npm", "pnpm", "yarn", "cargo", "pip", "other"]).optional(),
6453
+ languages: exports_external.array(exports_external.string().min(1)).default([]),
6454
+ requiredFiles: exports_external.array(exports_external.string().min(1)).default([]),
6455
+ requiredDirectories: exports_external.array(exports_external.string().min(1)).default([]),
6456
+ optionalDirectories: exports_external.array(exports_external.string().min(1)).default([])
6457
+ }).strict();
6458
+ var ScaffoldManifestSchema = contractBaseSchema(SCHEMA_IDS.scaffoldManifest).extend({
6459
+ name: exports_external.string().min(1),
6460
+ version: exports_external.string().min(1),
6461
+ summary: exports_external.string().min(1),
6462
+ type: ScaffoldTypeSchema,
6463
+ status: ScaffoldStatusSchema.default("draft"),
6464
+ capabilities: exports_external.array(ScaffoldCapabilitySchema).default([]),
6465
+ techStack: exports_external.array(exports_external.string().min(1)).default([]),
6466
+ tags: TagsSchema,
6467
+ source: ResourcePointerSchema.optional(),
6468
+ output: ScaffoldOutputShapeSchema,
6469
+ env: exports_external.array(ScaffoldEnvVarSchema).default([]),
6470
+ scripts: exports_external.array(ScaffoldScriptSchema).default([]),
6471
+ validationChecks: exports_external.array(ValidationCheckSchema).default([]),
6472
+ evidenceRefs: exports_external.array(EvidencePointerSchema).default([])
6473
+ }).strict().superRefine((value, ctx) => {
6474
+ if (value.source?.uri?.startsWith("file://")) {
6475
+ ctx.addIssue({
6476
+ code: exports_external.ZodIssueCode.custom,
6477
+ message: "Public scaffold manifest source refs cannot use local file:// URIs",
6478
+ path: ["source", "uri"]
6479
+ });
6480
+ }
6481
+ if (value.status === "active" && value.validationChecks.length === 0) {
6482
+ ctx.addIssue({
6483
+ code: exports_external.ZodIssueCode.custom,
6484
+ message: "Active scaffold manifests require validation checks",
6485
+ path: ["validationChecks"]
6486
+ });
6487
+ }
6488
+ if (value.status === "active" && value.output.requiredFiles.length === 0 && value.output.requiredDirectories.length === 0) {
6489
+ ctx.addIssue({
6490
+ code: exports_external.ZodIssueCode.custom,
6491
+ message: "Active scaffold manifests require at least one required file or directory",
6492
+ path: ["output"]
6493
+ });
6494
+ }
6495
+ });
6496
+ var ScaffoldInstallStatusSchema = exports_external.enum(["installed", "failed", "cancelled", "partial", "unknown"]);
6497
+ var ScaffoldInstallRecordSchema = contractBaseSchema(SCHEMA_IDS.scaffoldInstallRecord).extend({
6498
+ scaffoldId: exports_external.string().min(1),
6499
+ scaffoldVersion: exports_external.string().min(1).optional(),
6500
+ manifestRef: ResourcePointerSchema.optional(),
6501
+ target: ResourcePointerSchema,
6502
+ status: ScaffoldInstallStatusSchema,
6503
+ installedAt: TimestampSchema.optional(),
6504
+ installer: ActorPointerSchema.optional(),
6505
+ packageManager: exports_external.enum(["bun", "npm", "pnpm", "yarn", "cargo", "pip", "other"]).optional(),
6506
+ options: MetadataSchema.optional(),
6507
+ generatedFiles: exports_external.array(ResourcePointerSchema).default([]),
6508
+ evidenceRefs: exports_external.array(EvidencePointerSchema).default([]),
6509
+ proofBundleRefs: exports_external.array(ResourcePointerSchema).default([])
6510
+ }).strict().superRefine((value, ctx) => {
6511
+ if (value.status === "installed" && !value.installedAt) {
6512
+ ctx.addIssue({
6513
+ code: exports_external.ZodIssueCode.custom,
6514
+ message: "Installed scaffold records require installedAt",
6515
+ path: ["installedAt"]
6516
+ });
6517
+ }
6518
+ if (value.status === "installed" && value.generatedFiles.length === 0 && value.evidenceRefs.length === 0 && value.proofBundleRefs.length === 0) {
6519
+ ctx.addIssue({
6520
+ code: exports_external.ZodIssueCode.custom,
6521
+ message: "Installed scaffold records require generated files, evidence, or proof bundle refs",
6522
+ path: ["generatedFiles"]
6523
+ });
6524
+ }
6525
+ if ((value.status === "failed" || value.status === "partial") && value.evidenceRefs.length === 0 && value.proofBundleRefs.length === 0) {
6526
+ ctx.addIssue({
6527
+ code: exports_external.ZodIssueCode.custom,
6528
+ message: "Failed or partial scaffold records require evidence or proof bundle refs",
6529
+ path: ["evidenceRefs"]
6530
+ });
6531
+ }
6532
+ });
6393
6533
  var ProofCheckResultSchema = exports_external.object({
6394
6534
  checkId: exports_external.string().min(1),
6395
6535
  status: ContractStatusSchema,
@@ -6536,7 +6676,9 @@ var ContractSchemaRegistry = {
6536
6676
  [SCHEMA_IDS.contextPack]: ContextPackSchema,
6537
6677
  [SCHEMA_IDS.agentTrajectory]: AgentTrajectorySchema,
6538
6678
  [SCHEMA_IDS.validationPlan]: ValidationPlanSchema,
6539
- [SCHEMA_IDS.proofBundle]: ProofBundleSchema
6679
+ [SCHEMA_IDS.proofBundle]: ProofBundleSchema,
6680
+ [SCHEMA_IDS.scaffoldManifest]: ScaffoldManifestSchema,
6681
+ [SCHEMA_IDS.scaffoldInstallRecord]: ScaffoldInstallRecordSchema
6540
6682
  };
6541
6683
 
6542
6684
  // src/validators.ts
package/dist/index.js CHANGED
@@ -3989,7 +3989,7 @@ var coerce = {
3989
3989
  var NEVER = INVALID;
3990
3990
  // src/schemas.ts
3991
3991
  var CONTRACTS_PACKAGE_NAME = "@hasna/contracts";
3992
- var CONTRACTS_PACKAGE_VERSION = "0.1.1";
3992
+ var CONTRACTS_PACKAGE_VERSION = "0.2.0";
3993
3993
  var SCHEMA_IDS = {
3994
3994
  actorRef: "hasna.actor_ref.v1",
3995
3995
  resourceRef: "hasna.resource_ref.v1",
@@ -4001,7 +4001,9 @@ var SCHEMA_IDS = {
4001
4001
  contextPack: "hasna.context_pack.v1",
4002
4002
  agentTrajectory: "hasna.agent_trajectory.v1",
4003
4003
  validationPlan: "hasna.validation_plan.v1",
4004
- proofBundle: "hasna.proof_bundle.v1"
4004
+ proofBundle: "hasna.proof_bundle.v1",
4005
+ scaffoldManifest: "hasna.scaffold_manifest.v1",
4006
+ scaffoldInstallRecord: "hasna.scaffold_install_record.v1"
4005
4007
  };
4006
4008
  var SchemaIdSchema = exports_external.string().regex(/^hasna\.[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*\.v[0-9]+$/);
4007
4009
  var TimestampSchema = exports_external.string().datetime();
@@ -4305,6 +4307,144 @@ var ValidationPlanSchema = contractBaseSchema(SCHEMA_IDS.validationPlan).extend(
4305
4307
  verifier: ActorPointerSchema.optional(),
4306
4308
  requiredEvidenceKinds: exports_external.array(EvidenceKindSchema).default([])
4307
4309
  }).strict();
4310
+ var ScaffoldTypeSchema = exports_external.enum([
4311
+ "open_source",
4312
+ "internal_app",
4313
+ "platform",
4314
+ "app",
4315
+ "agent",
4316
+ "content",
4317
+ "overlay",
4318
+ "other"
4319
+ ]);
4320
+ var ScaffoldStatusSchema = exports_external.enum(["draft", "active", "deprecated", "archived"]);
4321
+ var ScaffoldCapabilitySchema = exports_external.enum([
4322
+ "cli",
4323
+ "mcp",
4324
+ "library",
4325
+ "sdk",
4326
+ "rest_api",
4327
+ "dashboard",
4328
+ "database",
4329
+ "auth",
4330
+ "billing",
4331
+ "worker",
4332
+ "daemon",
4333
+ "native",
4334
+ "browser_extension",
4335
+ "ai_provider",
4336
+ "media_pipeline",
4337
+ "data_pipeline",
4338
+ "tests",
4339
+ "ci",
4340
+ "deployment",
4341
+ "docs",
4342
+ "other"
4343
+ ]);
4344
+ var ScaffoldEnvVarSchema = exports_external.object({
4345
+ key: exports_external.string().regex(/^[A-Z][A-Z0-9_]*$/),
4346
+ description: exports_external.string().min(1),
4347
+ required: exports_external.boolean().default(false),
4348
+ secret: exports_external.boolean().default(false),
4349
+ group: exports_external.string().min(1).optional(),
4350
+ default: exports_external.string().optional()
4351
+ }).strict().superRefine((value, ctx) => {
4352
+ if (value.secret && value.default !== undefined) {
4353
+ ctx.addIssue({
4354
+ code: exports_external.ZodIssueCode.custom,
4355
+ message: "Secret scaffold env vars cannot include defaults",
4356
+ path: ["default"]
4357
+ });
4358
+ }
4359
+ });
4360
+ var ScaffoldScriptSchema = exports_external.object({
4361
+ name: exports_external.string().min(1),
4362
+ command: exports_external.string().min(1),
4363
+ description: exports_external.string().min(1).optional(),
4364
+ required: exports_external.boolean().default(false)
4365
+ }).strict();
4366
+ var ScaffoldOutputShapeSchema = exports_external.object({
4367
+ packageManager: exports_external.enum(["bun", "npm", "pnpm", "yarn", "cargo", "pip", "other"]).optional(),
4368
+ languages: exports_external.array(exports_external.string().min(1)).default([]),
4369
+ requiredFiles: exports_external.array(exports_external.string().min(1)).default([]),
4370
+ requiredDirectories: exports_external.array(exports_external.string().min(1)).default([]),
4371
+ optionalDirectories: exports_external.array(exports_external.string().min(1)).default([])
4372
+ }).strict();
4373
+ var ScaffoldManifestSchema = contractBaseSchema(SCHEMA_IDS.scaffoldManifest).extend({
4374
+ name: exports_external.string().min(1),
4375
+ version: exports_external.string().min(1),
4376
+ summary: exports_external.string().min(1),
4377
+ type: ScaffoldTypeSchema,
4378
+ status: ScaffoldStatusSchema.default("draft"),
4379
+ capabilities: exports_external.array(ScaffoldCapabilitySchema).default([]),
4380
+ techStack: exports_external.array(exports_external.string().min(1)).default([]),
4381
+ tags: TagsSchema,
4382
+ source: ResourcePointerSchema.optional(),
4383
+ output: ScaffoldOutputShapeSchema,
4384
+ env: exports_external.array(ScaffoldEnvVarSchema).default([]),
4385
+ scripts: exports_external.array(ScaffoldScriptSchema).default([]),
4386
+ validationChecks: exports_external.array(ValidationCheckSchema).default([]),
4387
+ evidenceRefs: exports_external.array(EvidencePointerSchema).default([])
4388
+ }).strict().superRefine((value, ctx) => {
4389
+ if (value.source?.uri?.startsWith("file://")) {
4390
+ ctx.addIssue({
4391
+ code: exports_external.ZodIssueCode.custom,
4392
+ message: "Public scaffold manifest source refs cannot use local file:// URIs",
4393
+ path: ["source", "uri"]
4394
+ });
4395
+ }
4396
+ if (value.status === "active" && value.validationChecks.length === 0) {
4397
+ ctx.addIssue({
4398
+ code: exports_external.ZodIssueCode.custom,
4399
+ message: "Active scaffold manifests require validation checks",
4400
+ path: ["validationChecks"]
4401
+ });
4402
+ }
4403
+ if (value.status === "active" && value.output.requiredFiles.length === 0 && value.output.requiredDirectories.length === 0) {
4404
+ ctx.addIssue({
4405
+ code: exports_external.ZodIssueCode.custom,
4406
+ message: "Active scaffold manifests require at least one required file or directory",
4407
+ path: ["output"]
4408
+ });
4409
+ }
4410
+ });
4411
+ var ScaffoldInstallStatusSchema = exports_external.enum(["installed", "failed", "cancelled", "partial", "unknown"]);
4412
+ var ScaffoldInstallRecordSchema = contractBaseSchema(SCHEMA_IDS.scaffoldInstallRecord).extend({
4413
+ scaffoldId: exports_external.string().min(1),
4414
+ scaffoldVersion: exports_external.string().min(1).optional(),
4415
+ manifestRef: ResourcePointerSchema.optional(),
4416
+ target: ResourcePointerSchema,
4417
+ status: ScaffoldInstallStatusSchema,
4418
+ installedAt: TimestampSchema.optional(),
4419
+ installer: ActorPointerSchema.optional(),
4420
+ packageManager: exports_external.enum(["bun", "npm", "pnpm", "yarn", "cargo", "pip", "other"]).optional(),
4421
+ options: MetadataSchema.optional(),
4422
+ generatedFiles: exports_external.array(ResourcePointerSchema).default([]),
4423
+ evidenceRefs: exports_external.array(EvidencePointerSchema).default([]),
4424
+ proofBundleRefs: exports_external.array(ResourcePointerSchema).default([])
4425
+ }).strict().superRefine((value, ctx) => {
4426
+ if (value.status === "installed" && !value.installedAt) {
4427
+ ctx.addIssue({
4428
+ code: exports_external.ZodIssueCode.custom,
4429
+ message: "Installed scaffold records require installedAt",
4430
+ path: ["installedAt"]
4431
+ });
4432
+ }
4433
+ if (value.status === "installed" && value.generatedFiles.length === 0 && value.evidenceRefs.length === 0 && value.proofBundleRefs.length === 0) {
4434
+ ctx.addIssue({
4435
+ code: exports_external.ZodIssueCode.custom,
4436
+ message: "Installed scaffold records require generated files, evidence, or proof bundle refs",
4437
+ path: ["generatedFiles"]
4438
+ });
4439
+ }
4440
+ if ((value.status === "failed" || value.status === "partial") && value.evidenceRefs.length === 0 && value.proofBundleRefs.length === 0) {
4441
+ ctx.addIssue({
4442
+ code: exports_external.ZodIssueCode.custom,
4443
+ message: "Failed or partial scaffold records require evidence or proof bundle refs",
4444
+ path: ["evidenceRefs"]
4445
+ });
4446
+ }
4447
+ });
4308
4448
  var ProofCheckResultSchema = exports_external.object({
4309
4449
  checkId: exports_external.string().min(1),
4310
4450
  status: ContractStatusSchema,
@@ -4451,7 +4591,9 @@ var ContractSchemaRegistry = {
4451
4591
  [SCHEMA_IDS.contextPack]: ContextPackSchema,
4452
4592
  [SCHEMA_IDS.agentTrajectory]: AgentTrajectorySchema,
4453
4593
  [SCHEMA_IDS.validationPlan]: ValidationPlanSchema,
4454
- [SCHEMA_IDS.proofBundle]: ProofBundleSchema
4594
+ [SCHEMA_IDS.proofBundle]: ProofBundleSchema,
4595
+ [SCHEMA_IDS.scaffoldManifest]: ScaffoldManifestSchema,
4596
+ [SCHEMA_IDS.scaffoldInstallRecord]: ScaffoldInstallRecordSchema
4455
4597
  };
4456
4598
 
4457
4599
  // src/validators.ts
@@ -4533,6 +4675,15 @@ export {
4533
4675
  TagsSchema,
4534
4676
  Sha256DigestSchema,
4535
4677
  SchemaIdSchema,
4678
+ ScaffoldTypeSchema,
4679
+ ScaffoldStatusSchema,
4680
+ ScaffoldScriptSchema,
4681
+ ScaffoldOutputShapeSchema,
4682
+ ScaffoldManifestSchema,
4683
+ ScaffoldInstallStatusSchema,
4684
+ ScaffoldInstallRecordSchema,
4685
+ ScaffoldEnvVarSchema,
4686
+ ScaffoldCapabilitySchema,
4536
4687
  SCHEMA_IDS,
4537
4688
  ResourceRefSchema,
4538
4689
  ResourcePointerSchema,