@klickd/core 4.0.1 → 4.0.3

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/dist/index.cjs CHANGED
@@ -333,16 +333,696 @@ async function loadKlickd(input, options = {}) {
333
333
  return payload;
334
334
  }
335
335
 
336
+ // src/schemas/klickd-payload-v4.schema.json
337
+ var klickd_payload_v4_schema_default = {
338
+ $schema: "https://json-schema.org/draft/2020-12/schema",
339
+ $id: "https://klickd.app/schemas/v4/klickd-payload.schema.json",
340
+ title: "klickd Payload v4 (Strict GA candidate, normative)",
341
+ description: "Strict JSON Schema for the .klickd v4 inner payload. This schema is the GA strict equivalent of the permissive klickd-payload-v4-preview.schema.json. Strict blocks correspond to RFC-001 (media_profile v1, Accepted) and RFC-002 v1 core (verification_gates, human_veto_policy, claim_sources v1, Accepted). Sections that remain Draft (RFC-002 v2-additive: contract_tests, success_criteria, reversibility, blast_radius, verification_artifacts, error_journal.rule_created; RFC-004 migration runtime) are accepted but left permissive so they can be tightened by a future strict schema bump without breaking GA writers. Top-level additionalProperties is TRUE to preserve unknown fields verbatim (SPEC.md \xA733.7 forward-compatibility invariant). Strict shape on frozen sub-objects uses additionalProperties: false locally. Does NOT supersede the permissive preview schema (klickd-payload-v4-preview.schema.json) \u2014 both coexist until the preview sunset announced separately.",
342
+ type: "object",
343
+ required: [
344
+ "payload_schema_version"
345
+ ],
346
+ additionalProperties: true,
347
+ properties: {
348
+ payload_schema_version: {
349
+ type: "string",
350
+ description: "Payload schema version. For GA strict files, the canonical value is '4.0'. The preview value '4.0.0-preview.1' is also accepted so a preview file already in the wild round-trips against the strict schema without forcing a rewrite. A future strict bump (4.1, etc.) MAY tighten this enum.",
351
+ enum: ["4.0", "4.0.0-preview.1"]
352
+ },
353
+ domain_schema_version: {
354
+ type: "string",
355
+ description: "Domain-specific schema version. Two accepted forms: (a) v3-style '{domain}-{major}.{minor}' (e.g. 'education-1.2'); (b) bare semver-ish '{major}.{minor}(.{patch})?' for domain-agnostic profiles (e.g. '1.0.0').",
356
+ pattern: "^([a-z][a-z0-9_-]*-\\d+\\.\\d+|\\d+\\.\\d+(\\.\\d+)?)$"
357
+ },
358
+ preview: {
359
+ type: "string",
360
+ description: "OPTIONAL preview marker. Present only on files written against a preview iteration (e.g. 'v4.0.0-preview.1'). Absent on GA strict files."
361
+ },
362
+ profile_kind: {
363
+ type: "string",
364
+ description: "Top-level discriminator for the profile shape. Reserved canonical values: 'learner', 'agent', 'team', 'robot', 'creator'. Custom strings are permitted (extension space). v3.x is implicitly 'learner'."
365
+ },
366
+ injection_target: {
367
+ type: "string",
368
+ enum: ["system_prompt", "user_message", "both"],
369
+ description: "Where to inject the .klickd context (carried over from v3.x \xA720.2)."
370
+ },
371
+ identity: {
372
+ type: "object",
373
+ description: "Persistent user identity attributes. Carried over from v3 SPEC \xA78; same strictness as v3 payload schema. All sub-fields are OPTIONAL.",
374
+ additionalProperties: true,
375
+ properties: {
376
+ name: { type: "string", maxLength: 256 },
377
+ display_name: { type: "string", maxLength: 256, description: "v4 GA preferred user-facing alias. Either 'name' or 'display_name' may be used; producers SHOULD pick one." },
378
+ language: { type: "string", description: "BCP 47 language tag." },
379
+ timezone: { type: "string", description: "IANA time zone identifier." },
380
+ communication_style: { type: "string" }
381
+ }
382
+ },
383
+ companion_identity: {
384
+ type: "object",
385
+ description: "Optional companion / co-agent persona. Same surface as v3.4 \xA727. Permissive.",
386
+ additionalProperties: true
387
+ },
388
+ context: {
389
+ type: "object",
390
+ description: "Operational session state. Carried over from v3 SPEC \xA79. Permissive (unevaluatedProperties policy of v3 retained).",
391
+ additionalProperties: true
392
+ },
393
+ knowledge: {
394
+ type: "object",
395
+ description: "Structured knowledge state. Carried over from v3 SPEC \xA710. Permissive.",
396
+ additionalProperties: true
397
+ },
398
+ memory: {
399
+ type: "array",
400
+ maxItems: 1e3,
401
+ description: "Structured conversation/event log. Same v3 \xA711 constraints retained.",
402
+ items: { type: "object", additionalProperties: true }
403
+ },
404
+ learning_goal: {
405
+ type: "object",
406
+ description: "User's stated learning / delivery goal. Same surface as v3 \xA727. Permissive.",
407
+ additionalProperties: true,
408
+ properties: {
409
+ type: { type: "string" },
410
+ deadline: { type: "string" },
411
+ stakes: { type: "string", enum: ["low", "medium", "high"] }
412
+ }
413
+ },
414
+ user_preferences: {
415
+ oneOf: [
416
+ { type: "string", maxLength: 32768 },
417
+ { type: "object", additionalProperties: true }
418
+ ],
419
+ description: "Canonical type is string (v3.5 \xA722.6). Object form retained for backward compatibility."
420
+ },
421
+ agent_instructions: {
422
+ type: "string",
423
+ maxLength: 32768,
424
+ description: "System-prompt injection string. Same v3 \xA77.2 contract."
425
+ },
426
+ onboarding_trigger: {
427
+ type: "string",
428
+ description: "Optional onboarding trigger (v3.4 \xA729b). Common values: 'on_new_agent', 'manual'."
429
+ },
430
+ ethics: {
431
+ type: "object",
432
+ description: "Ethical guard surface (v3.x). Permissive in this schema; safety / locked fields are governed by docs/spec/DEPRECATION_POLICY_V4.md \xA79.",
433
+ additionalProperties: true
434
+ },
435
+ media_profile: {
436
+ description: "RFC-001 v1 (Accepted): portable, hash-referenced media context. Strict on the v1 frozen surface (versioned + entries[]); a permissive 'summary' form (preview-era) is also accepted for round-trip compatibility. New modalities / fields land via additive RFC bumps.",
437
+ oneOf: [
438
+ {
439
+ type: "object",
440
+ additionalProperties: false,
441
+ required: ["version", "entries"],
442
+ properties: {
443
+ version: { type: "integer", const: 1, description: "media_profile schema version. v1 per RFC-001." },
444
+ entries: {
445
+ type: "array",
446
+ maxItems: 256,
447
+ items: { $ref: "#/$defs/mediaProfileEntry" }
448
+ }
449
+ }
450
+ },
451
+ {
452
+ type: "object",
453
+ description: "Permissive summary form (preview-era). Strict producers SHOULD migrate to the versioned + entries[] form. Kept for round-trip parity with vectors_v40_preview.json.",
454
+ additionalProperties: true,
455
+ not: { required: ["version", "entries"] }
456
+ },
457
+ {
458
+ type: "null"
459
+ }
460
+ ]
461
+ },
462
+ verification_gates: {
463
+ description: "RFC-002 v1 core (Accepted): user's preferred friction profile per action class. Two accepted shapes: (a) structured form (recommended) with version + gates[]; (b) flat map {action_class: level} for compactness (used by \xA733.5 minimal example and preview readers).",
464
+ oneOf: [
465
+ {
466
+ type: "object",
467
+ additionalProperties: false,
468
+ required: ["version", "gates"],
469
+ properties: {
470
+ version: { type: "integer", const: 1 },
471
+ user_default: { $ref: "#/$defs/gateLevel" },
472
+ gates: {
473
+ type: "array",
474
+ maxItems: 256,
475
+ items: { $ref: "#/$defs/gateEntry" }
476
+ }
477
+ }
478
+ },
479
+ {
480
+ type: "object",
481
+ description: "Flat map form: {action_class: gate_level}. Each value MUST be one of the five canonical levels.",
482
+ additionalProperties: { $ref: "#/$defs/gateLevel" }
483
+ }
484
+ ]
485
+ },
486
+ human_veto_policy: {
487
+ description: "RFC-002 v1 (Accepted): standing rules about when a human MUST be in the loop. Overrides any lower gate.",
488
+ type: ["object", "null"],
489
+ additionalProperties: false,
490
+ properties: {
491
+ applies_to: {
492
+ type: "array",
493
+ items: { type: "string" },
494
+ maxItems: 64,
495
+ description: "List of action classes for which a human veto is required."
496
+ },
497
+ second_party: {
498
+ type: ["string", "null"],
499
+ description: "Optional named second party who may unlock. null means owner-only."
500
+ },
501
+ min_level: {
502
+ $ref: "#/$defs/gateLevel",
503
+ description: "Floor gate level. The policy MUST NOT resolve below this level for any action class in 'applies_to'. RFC-002 v1 \xA74 #6 \u2014 human veto is sacred."
504
+ },
505
+ rationale: { type: "string", maxLength: 1024 }
506
+ }
507
+ },
508
+ claim_sources: {
509
+ description: "RFC-002 v1 (Accepted) + v2-additive (Draft). Strict on v1 fields ('prefer', 'require_citation_for'); 'records' and extended fields remain permissive (v2 still Draft).",
510
+ type: ["object", "null"],
511
+ additionalProperties: true,
512
+ properties: {
513
+ prefer: {
514
+ type: "array",
515
+ items: { type: "string" },
516
+ maxItems: 64,
517
+ description: "Ordered preference list. Each entry is a free-form source identifier; common values: 'user_supplied', 'tool:web_search', 'tool:doi_resolver'."
518
+ },
519
+ require_citation_for: {
520
+ type: "array",
521
+ items: { type: "string" },
522
+ maxItems: 64
523
+ },
524
+ records: {
525
+ type: "array",
526
+ description: "v2-additive (Draft). Permissive until promoted.",
527
+ items: { type: "object", additionalProperties: true }
528
+ }
529
+ }
530
+ },
531
+ risk_thresholds: {
532
+ description: "RFC-002 v1 (Accepted): numeric / categorical knobs. Permissive on inner shape \u2014 extension space.",
533
+ type: ["object", "null"],
534
+ additionalProperties: true
535
+ },
536
+ preflight_checks: {
537
+ description: "RFC-002 v1 (Accepted): small named checks to run before acting. Each entry is an object with at minimum 'name'.",
538
+ type: ["array", "null"],
539
+ items: { type: ["object", "string"], additionalProperties: true }
540
+ },
541
+ error_journal: {
542
+ description: "RFC-002 v1 (Accepted): append-only lessons learned. Permissive on entry shape ('rule_created' remains Draft in v2-additive).",
543
+ type: ["array", "null"],
544
+ items: { type: "object", additionalProperties: true }
545
+ },
546
+ verification_artifacts: {
547
+ description: "RFC-002 \xA78b.8 (Draft, v2-additive). Permissive: pointer ledger, not a payload sink. Accepted as null or array.",
548
+ type: ["array", "null"],
549
+ items: { type: "object", additionalProperties: true }
550
+ },
551
+ contract_tests: {
552
+ description: "RFC-002 v2-additive (Draft). Permissive.",
553
+ type: ["array", "null"],
554
+ items: { type: "object", additionalProperties: true }
555
+ },
556
+ success_criteria: {
557
+ description: "RFC-002 v2-additive (Draft). Permissive.",
558
+ type: ["object", "array", "null"],
559
+ additionalProperties: true
560
+ },
561
+ reversibility: {
562
+ description: "RFC-002 v2-additive (Draft). Permissive \u2014 typical shape is {action_class: enum<reversible|costly_to_reverse|irreversible|low|none|high>} but enums are not yet frozen.",
563
+ type: ["object", "null"],
564
+ additionalProperties: true
565
+ },
566
+ blast_radius: {
567
+ description: "RFC-002 v2-additive (Draft). Permissive.",
568
+ type: ["object", "null"],
569
+ additionalProperties: true
570
+ },
571
+ migration: {
572
+ description: "RFC-004 (Draft): optional migration metadata block. Audit-only \u2014 no migration tooling ships with the strict schema. Strict on v1 frozen fields; extension fields permitted.",
573
+ type: ["object", "null"],
574
+ additionalProperties: true,
575
+ properties: {
576
+ source_version: { type: "string" },
577
+ migrated_at: {
578
+ type: "string",
579
+ pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"
580
+ },
581
+ migration_report_ref: { type: "string" },
582
+ backup_ref: { type: "string" }
583
+ }
584
+ },
585
+ context_cost: {
586
+ description: "Research/benchmark track (benchmarks/context_cost/RFC.md). No spec semantics depend on this field. Permissive.",
587
+ type: ["object", "null"],
588
+ additionalProperties: true
589
+ },
590
+ gaming_profile: {
591
+ description: "R4-P1-4 gaming.klickd baseline (preview, registry-based). NOT a v4 MUST. Accepted as a registry-defined optional profile; permissive structure.",
592
+ type: ["object", "null"],
593
+ additionalProperties: true
594
+ },
595
+ deprecated_fields: {
596
+ description: "OPTIONAL informational block defined by docs/spec/DEPRECATION_POLICY_V4.md \xA76. Lists fields the producer has emitted as 'deprecated' status. Readers that don't understand it MUST silently ignore (\xA733.7).",
597
+ type: ["array", "null"],
598
+ items: {
599
+ type: "object",
600
+ additionalProperties: true,
601
+ required: ["name"],
602
+ properties: {
603
+ name: { type: "string" },
604
+ since: { type: "string" },
605
+ replacement: { type: ["string", "null"] },
606
+ removal_target: { type: ["string", "null"] }
607
+ }
608
+ }
609
+ },
610
+ _example_metadata: {
611
+ description: "Optional non-normative block used by repository examples (see examples/v4/personas/README.md). Carries 'persona', 'non_normative', 'contains_real_pii', 'contains_secrets', etc. A reader MUST NOT use this block as a trust signal.",
612
+ type: "object",
613
+ additionalProperties: true
614
+ }
615
+ },
616
+ $defs: {
617
+ gateLevel: {
618
+ type: "string",
619
+ enum: ["silent", "warn", "confirm", "block", "require-owner"],
620
+ description: "RFC-002 v1 \xA76 \u2014 fixed enum of five gate levels. No new levels are added in GA."
621
+ },
622
+ gateEntry: {
623
+ type: "object",
624
+ additionalProperties: false,
625
+ required: ["action_class", "level"],
626
+ properties: {
627
+ id: { type: "string", maxLength: 128 },
628
+ action_class: { type: "string", maxLength: 128 },
629
+ level: { $ref: "#/$defs/gateLevel" },
630
+ reason: { type: "string", maxLength: 1024 }
631
+ }
632
+ },
633
+ mediaProfileEntry: {
634
+ type: "object",
635
+ additionalProperties: true,
636
+ required: ["id", "modality", "hash"],
637
+ description: "RFC-001 v1 entry. Strict on v1 frozen fields (id, modality, hash). Additional metadata (consent, producer, etc.) is permitted as extension surface.",
638
+ properties: {
639
+ id: { type: "string", maxLength: 128 },
640
+ modality: {
641
+ type: "string",
642
+ enum: ["voice", "image", "document", "embedding"],
643
+ description: "RFC-001 v1 \xA74 #3 \u2014 closed enum at v1. Custom modalities live under 'x_*' namespaces (outside this entry)."
644
+ },
645
+ label: { type: "string", maxLength: 256 },
646
+ language: { type: "string" },
647
+ uri: { type: "string", description: "May be file://, https://, ipfs://, cas://<hash>, or a relative path. Reader chooses how to resolve." },
648
+ media_type: { type: "string" },
649
+ byte_size: { type: "integer", minimum: 0 },
650
+ duration_ms: { type: "integer", minimum: 0 },
651
+ bytes_b64: {
652
+ type: "string",
653
+ contentEncoding: "base64",
654
+ description: "Inline base64 PERMITTED ONLY for entries \u2264 16 KiB total (RFC-001 v1 \xA74 #1). Strict enforcement of the 16 KiB cap is not expressible in JSON Schema and is enforced by reader-side logic."
655
+ },
656
+ hash: {
657
+ type: "object",
658
+ additionalProperties: false,
659
+ required: ["algo", "value"],
660
+ properties: {
661
+ algo: { type: "string", const: "blake3", description: "RFC-001 v1 \xA74 #2 \u2014 one hash, one algorithm: BLAKE3." },
662
+ value: { type: "string", description: "Hash value, encoding per RFC-001 (base64 or hex-prefixed). Strict format enforcement is reader-side." }
663
+ }
664
+ },
665
+ producer: {
666
+ type: "object",
667
+ additionalProperties: true,
668
+ properties: {
669
+ kind: { type: "string" },
670
+ device: { type: "string" }
671
+ }
672
+ },
673
+ consent: {
674
+ type: "object",
675
+ additionalProperties: true,
676
+ description: "RFC-001 v1 \xA74 #5 \u2014 consent is per-entry, not per-file.",
677
+ properties: {
678
+ purposes: {
679
+ type: "array",
680
+ items: { type: "string" },
681
+ maxItems: 64
682
+ },
683
+ expires_at: { type: "string" },
684
+ revocable: { type: "boolean" }
685
+ }
686
+ }
687
+ }
688
+ }
689
+ }
690
+ };
691
+
692
+ // src/schemas/klickd-payload-v4-preview.schema.json
693
+ var klickd_payload_v4_preview_schema_default = {
694
+ $schema: "https://json-schema.org/draft/2020-12/schema",
695
+ $id: "https://klickd.app/schemas/v4-preview/klickd-payload.schema.json",
696
+ title: "klickd Payload v4 Preview (PERMISSIVE, NON-NORMATIVE)",
697
+ description: "PREVIEW schema for the .klickd v4 inner payload, targeting v4.0.0-preview.1. This schema is INTENTIONALLY PERMISSIVE: it accepts and preserves draft v4 structures (media_profile, verification_gates, human_veto_policy, claim_sources, verification_artifacts, migration, context_cost, profile_kind) without performing strict validation. additionalProperties is true at every level so that unknown fields round-trip verbatim. This schema MUST NOT be used to reject a file that is otherwise a valid v3.5.1 file. The normative schemas remain klickd-envelope-v3.schema.json and klickd-payload-v3.schema.json. See SPEC.md \xA733 and docs/rfcs/ for the design source.",
698
+ type: "object",
699
+ additionalProperties: true,
700
+ properties: {
701
+ preview: {
702
+ type: "string",
703
+ description: "Marks a file as belonging to a specific preview iteration. Recommended value for files written against this schema: 'v4.0.0-preview.1'. Absent in v3.x files."
704
+ },
705
+ payload_schema_version: {
706
+ type: "string",
707
+ description: "Payload schema version. PERMISSIVE in this preview: any string is accepted. A future strict v4 schema MAY pin this to a concrete value."
708
+ },
709
+ domain_schema_version: {
710
+ type: "string",
711
+ description: "Domain-specific schema version (e.g. 'education-1.2'). PERMISSIVE in this preview."
712
+ },
713
+ profile_kind: {
714
+ type: "string",
715
+ description: "Top-level discriminator for the profile shape. Common values: 'learner', 'agent', 'team', 'robot'. v3.x is implicitly 'learner'; the preview makes this explicit and extensible. Custom strings are permitted."
716
+ },
717
+ media_profile: {
718
+ description: "RFC-001: portable, hash-referenced media context. Bytes live outside the .klickd file by default; the payload carries metadata, hashes, and (optionally) inline base64 below a documented threshold. PERMISSIVE: structure is not enforced here.",
719
+ type: ["object", "array", "null"],
720
+ additionalProperties: true
721
+ },
722
+ verification_gates: {
723
+ description: "RFC-002 v1: user's preferred friction profile, mapping action class to gate level (silent / warn / confirm / block / require-owner). PERMISSIVE: not enforced here.",
724
+ type: ["object", "array", "null"],
725
+ additionalProperties: true
726
+ },
727
+ human_veto_policy: {
728
+ description: "RFC-002 v1: standing rules about when a human MUST be in the loop, regardless of agent confidence. Overrides any lower gate. PERMISSIVE: not enforced here.",
729
+ type: ["object", "null"],
730
+ additionalProperties: true
731
+ },
732
+ claim_sources: {
733
+ description: "RFC-002 v1 + v2-additive: declarative preferences for where to ground factual claims, and records of what was actually used. PERMISSIVE: not enforced here.",
734
+ type: ["object", "null"],
735
+ additionalProperties: true
736
+ },
737
+ verification_artifacts: {
738
+ description: "RFC-002 \xA78b.8: pointer ledger of outputs already produced by expensive verification commands (test suites, builds, web fetches, DOI resolutions). MUST be a pointer ledger, not a payload sink. PERMISSIVE: structure is not enforced here.",
739
+ type: ["array", "null"]
740
+ },
741
+ error_journal: {
742
+ description: "RFC-002 v1: append-only lessons learned that should influence future gate evaluation. PERMISSIVE: not enforced here.",
743
+ type: ["array", "null"]
744
+ },
745
+ risk_thresholds: {
746
+ description: "RFC-002 v1: numeric / categorical knobs (e.g. public_reach, financial_amount_eur_max_silent). PERMISSIVE.",
747
+ type: ["object", "null"],
748
+ additionalProperties: true
749
+ },
750
+ preflight_checks: {
751
+ description: "RFC-002 v1: small, named checks an agent SHOULD run before acting on certain classes. PERMISSIVE.",
752
+ type: ["array", "null"]
753
+ },
754
+ contract_tests: {
755
+ description: "RFC-002 v2-additive: machine-checkable contract tests bound to action classes. PERMISSIVE.",
756
+ type: ["array", "null"]
757
+ },
758
+ success_criteria: {
759
+ description: "RFC-002 v2-additive: declarative success criteria per action class. PERMISSIVE.",
760
+ type: ["object", "array", "null"],
761
+ additionalProperties: true
762
+ },
763
+ reversibility: {
764
+ description: "RFC-002 v2-additive: declared reversibility for action classes. PERMISSIVE.",
765
+ type: ["object", "null"],
766
+ additionalProperties: true
767
+ },
768
+ blast_radius: {
769
+ description: "RFC-002 v2-additive: declared blast radius for action classes. PERMISSIVE.",
770
+ type: ["object", "null"],
771
+ additionalProperties: true
772
+ },
773
+ migration: {
774
+ description: "RFC-004: optional migration metadata block. Audit-only in this preview \u2014 no migration tooling ships with v4.0.0-preview.1. PERMISSIVE.",
775
+ type: ["object", "null"],
776
+ additionalProperties: true,
777
+ properties: {
778
+ source_version: { type: "string" },
779
+ migrated_at: { type: "string" },
780
+ migration_report_ref: { type: "string" },
781
+ backup_ref: { type: "string" }
782
+ }
783
+ },
784
+ context_cost: {
785
+ description: "Research/benchmark track (benchmarks/context_cost/RFC.md): optional fields recording measured 'repeated context waste' for this profile. No normative semantics depend on this field. PERMISSIVE.",
786
+ type: ["object", "null"],
787
+ additionalProperties: true
788
+ }
789
+ }
790
+ };
791
+
792
+ // src/schemas/klickd-v4.schema.json
793
+ var klickd_v4_schema_default = {
794
+ $schema: "https://json-schema.org/draft/2020-12/schema",
795
+ $id: "https://klickd.app/schema/v4/klickd.schema.json",
796
+ title: "klickd v4 \u2014 Unified (Strict GA candidate, normative)",
797
+ description: "Strict unified JSON Schema for a .klickd v4 document (envelope + optional inline payload). This schema is the GA strict equivalent of the permissive klickd-v4-preview.schema.json. It validates the envelope shape strictly (mirroring the v3 envelope contract \u2014 Argon2id + AES-256-GCM is unchanged in v4 per SPEC.md \xA733.10 #2) and, for unencrypted files, validates the inline payload against the strict v4 payload schema (klickd-payload-v4.schema.json). Top-level additionalProperties is TRUE to preserve unknown fields verbatim (SPEC.md \xA733.7 forward-compatibility invariant). Does NOT supersede the permissive preview schema (klickd-v4-preview.schema.json) \u2014 both coexist.",
798
+ type: "object",
799
+ additionalProperties: true,
800
+ required: ["klickd_version", "created_at", "encrypted"],
801
+ properties: {
802
+ klickd_version: {
803
+ type: "string",
804
+ description: "Wire / envelope version. Strict v4 GA producers SHOULD emit '4.0'. v3.x values are also accepted because the v3 envelope contract is unchanged (\xA733.10 #2) and a v3.x file remains readable by a v4 reader.",
805
+ pattern: "^(3|4)\\.\\d+(\\.[0-9A-Za-z-.]+)?$"
806
+ },
807
+ preview: {
808
+ type: "string",
809
+ description: "OPTIONAL preview marker. Absent on GA strict files. If present, this file was written against a preview iteration (e.g. 'v4.0.0-preview.1')."
810
+ },
811
+ created_at: {
812
+ type: "string",
813
+ description: "RFC 3339 UTC timestamp of file creation. Z-suffix only, no fractional seconds (matches v3 envelope strict contract).",
814
+ pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"
815
+ },
816
+ encrypted: {
817
+ type: "boolean"
818
+ },
819
+ domain: {
820
+ type: "string",
821
+ minLength: 1,
822
+ description: "Semantic category. Registered values follow v3 (education, work, finance, legal, creative, health, research, robotics, gaming, creator). Custom non-empty strings are permitted."
823
+ },
824
+ profile_kind: {
825
+ type: "string",
826
+ description: "Top-level discriminator for the profile shape. Reserved canonical values: 'learner', 'agent', 'team', 'robot', 'creator'."
827
+ },
828
+ domain_schema_version: {
829
+ type: "string",
830
+ pattern: "^([a-z][a-z0-9_-]*-\\d+\\.\\d+|\\d+\\.\\d+(\\.\\d+)?)$"
831
+ },
832
+ kdf: {
833
+ type: "object",
834
+ description: "Structured KDF block \u2014 same contract as envelope-v3 \xA715.",
835
+ required: ["name", "params", "salt"],
836
+ additionalProperties: false,
837
+ properties: {
838
+ name: { type: "string", enum: ["argon2id", "pbkdf2-sha256"] },
839
+ params: {
840
+ oneOf: [
841
+ {
842
+ type: "object",
843
+ required: ["m", "t", "p"],
844
+ additionalProperties: false,
845
+ properties: {
846
+ m: { type: "integer", minimum: 65536 },
847
+ t: { type: "integer", minimum: 1 },
848
+ p: { type: "integer", minimum: 1 }
849
+ }
850
+ },
851
+ {
852
+ type: "object",
853
+ required: ["iterations"],
854
+ additionalProperties: false,
855
+ properties: {
856
+ iterations: { type: "integer", minimum: 6e5 }
857
+ }
858
+ }
859
+ ]
860
+ },
861
+ salt: { type: "string" }
862
+ }
863
+ },
864
+ cipher: {
865
+ type: "object",
866
+ description: "Structured cipher block \u2014 same contract as envelope-v3 \xA716. v4 does not introduce a new cipher.",
867
+ required: ["name", "iv"],
868
+ additionalProperties: false,
869
+ properties: {
870
+ name: { type: "string", const: "AES-256-GCM" },
871
+ iv: { type: "string" }
872
+ }
873
+ },
874
+ ciphertext: {
875
+ type: "string",
876
+ description: "AES-256-GCM ciphertext (base64 padded). Required when encrypted=true."
877
+ },
878
+ iv: {
879
+ type: "string",
880
+ description: "Legacy top-level IV mirror, retained for v3.0 round-trip parity. New producers SHOULD place IV inside the structured cipher block."
881
+ },
882
+ kdf_salt: {
883
+ type: "string",
884
+ description: "Legacy top-level salt mirror, retained for v3.0 round-trip parity."
885
+ },
886
+ payload_schema_version: {
887
+ type: "string",
888
+ description: "Payload schema version when the payload is inline (encrypted=false). Strict v4 GA value: '4.0'. Preview '4.0.0-preview.1' accepted for round-trip.",
889
+ enum: ["4.0", "4.0.0-preview.1"]
890
+ },
891
+ media_profile: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/media_profile" },
892
+ verification_gates: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/verification_gates" },
893
+ human_veto_policy: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/human_veto_policy" },
894
+ claim_sources: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/claim_sources" },
895
+ verification_artifacts: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/verification_artifacts" },
896
+ contract_tests: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/contract_tests" },
897
+ success_criteria: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/success_criteria" },
898
+ reversibility: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/reversibility" },
899
+ blast_radius: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/blast_radius" },
900
+ risk_thresholds: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/risk_thresholds" },
901
+ preflight_checks: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/preflight_checks" },
902
+ error_journal: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/error_journal" },
903
+ migration: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/migration" },
904
+ context_cost: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/context_cost" },
905
+ gaming_profile: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/gaming_profile" },
906
+ deprecated_fields: { $ref: "https://klickd.app/schemas/v4/klickd-payload.schema.json#/properties/deprecated_fields" }
907
+ },
908
+ allOf: [
909
+ {
910
+ if: {
911
+ type: "object",
912
+ properties: { encrypted: { const: true } },
913
+ required: ["encrypted"]
914
+ },
915
+ then: {
916
+ required: ["kdf", "cipher", "ciphertext"],
917
+ description: "Encrypted v4 file MUST carry kdf + cipher + ciphertext (envelope-v3 contract retained)."
918
+ }
919
+ }
920
+ ]
921
+ };
922
+
923
+ // src/schemas/klickd-v4-preview.schema.json
924
+ var klickd_v4_preview_schema_default = {
925
+ $schema: "https://json-schema.org/draft/2020-12/schema",
926
+ $id: "https://klickd.app/schema/v4-preview/klickd.schema.json",
927
+ title: "klickd v4 Preview \u2014 Unified (PERMISSIVE, NON-NORMATIVE)",
928
+ description: "PREVIEW unified schema for .klickd v4, targeting v4.0.0-preview.1. This schema is INTENTIONALLY PERMISSIVE: it validates the top-level shape of a v4-preview file (envelope + optional preview hooks) without enforcing strict v4 semantics. additionalProperties is true so unknown fields round-trip verbatim. Use this for single-pass acceptance of draft v4 documents. For pre-/post-decrypt validation, see schemas/klickd-payload-v4-preview.schema.json. The normative production schemas remain schema/klickd-v3.4.schema.json (unified) and schemas/klickd-envelope-v3.schema.json + schemas/klickd-payload-v3.schema.json (split). See SPEC.md \xA733.",
929
+ type: "object",
930
+ additionalProperties: true,
931
+ required: ["klickd_version", "created_at", "encrypted"],
932
+ properties: {
933
+ klickd_version: {
934
+ type: "string",
935
+ description: "Wire / envelope version. PERMISSIVE in this preview \u2014 any MAJOR.MINOR string is accepted. Preview producers SHOULD emit '4.0' and pair it with a 'preview' field. v3.x producers MUST continue to emit '3.x' and MUST NOT emit a 'preview' field.",
936
+ pattern: "^\\d+\\.\\d+(\\.[0-9A-Za-z-.]+)?$"
937
+ },
938
+ preview: {
939
+ type: "string",
940
+ description: "Marks a file as belonging to a specific preview iteration. Recommended value for files written against this schema: 'v4.0.0-preview.1'. Absent in v3.x and in a future GA v4.0."
941
+ },
942
+ created_at: {
943
+ type: "string",
944
+ description: "RFC 3339 UTC timestamp of file creation. Same contract as v3.x.",
945
+ pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$",
946
+ format: "date-time"
947
+ },
948
+ encrypted: {
949
+ type: "boolean",
950
+ description: "Whether the payload is AES-256-GCM encrypted. Envelope cryptography is unchanged from v3.x in this preview."
951
+ },
952
+ domain: {
953
+ type: "string",
954
+ description: "Semantic category of the context. Same surface as v3.x; custom strings remain permitted."
955
+ },
956
+ profile_kind: {
957
+ type: "string",
958
+ description: "Top-level discriminator for the profile shape. Common values: 'learner', 'agent', 'team', 'robot'. Custom strings are permitted."
959
+ },
960
+ ciphertext: {
961
+ type: "string",
962
+ description: "AES-256-GCM ciphertext when encrypted is true. Same contract as v3.x.",
963
+ contentEncoding: "base64"
964
+ },
965
+ iv: {
966
+ type: "string",
967
+ contentEncoding: "base64"
968
+ },
969
+ kdf_salt: {
970
+ type: "string",
971
+ contentEncoding: "base64"
972
+ },
973
+ kdf: {
974
+ type: "object",
975
+ additionalProperties: true,
976
+ description: "Structured KDF block as in envelope-v3. Unchanged in this preview."
977
+ },
978
+ cipher: {
979
+ type: "object",
980
+ additionalProperties: true,
981
+ description: "Structured cipher block as in envelope-v3. Unchanged in this preview."
982
+ },
983
+ media_profile: {
984
+ description: "RFC-001 (preview hook). PERMISSIVE \u2014 see schemas/klickd-payload-v4-preview.schema.json.",
985
+ type: ["object", "array", "null"],
986
+ additionalProperties: true
987
+ },
988
+ verification_gates: {
989
+ description: "RFC-002 (preview hook). PERMISSIVE.",
990
+ type: ["object", "array", "null"],
991
+ additionalProperties: true
992
+ },
993
+ human_veto_policy: {
994
+ description: "RFC-002 (preview hook). PERMISSIVE.",
995
+ type: ["object", "null"],
996
+ additionalProperties: true
997
+ },
998
+ claim_sources: {
999
+ description: "RFC-002 (preview hook). PERMISSIVE.",
1000
+ type: ["object", "null"],
1001
+ additionalProperties: true
1002
+ },
1003
+ verification_artifacts: {
1004
+ description: "RFC-002 \xA78b.8 (preview hook). PERMISSIVE \u2014 pointer ledger, not a payload sink.",
1005
+ type: ["array", "null"]
1006
+ },
1007
+ migration: {
1008
+ description: "RFC-004 (preview hook). Audit-only in v4.0.0-preview.1.",
1009
+ type: ["object", "null"],
1010
+ additionalProperties: true
1011
+ },
1012
+ context_cost: {
1013
+ description: "Research/benchmark track (preview hook). No normative semantics.",
1014
+ type: ["object", "null"],
1015
+ additionalProperties: true
1016
+ }
1017
+ }
1018
+ };
1019
+
336
1020
  // src/validate.ts
337
- var import_klickd_payload_v4_schema = __toESM(require("./klickd-payload-v4.schema-7UPTEJOY.json"), 1);
338
- var import_klickd_payload_v4_preview_schema = __toESM(require("./klickd-payload-v4-preview.schema-W7RY72VP.json"), 1);
339
- var import_klickd_v4_schema = __toESM(require("./klickd-v4.schema-ZZGRYTLY.json"), 1);
340
- var import_klickd_v4_preview_schema = __toESM(require("./klickd-v4-preview.schema-QHITWMK6.json"), 1);
341
1021
  var SCHEMAS = {
342
- "payload-strict": import_klickd_payload_v4_schema.default,
343
- "payload-preview": import_klickd_payload_v4_preview_schema.default,
344
- "unified-strict": import_klickd_v4_schema.default,
345
- "unified-preview": import_klickd_v4_preview_schema.default
1022
+ "payload-strict": klickd_payload_v4_schema_default,
1023
+ "payload-preview": klickd_payload_v4_preview_schema_default,
1024
+ "unified-strict": klickd_v4_schema_default,
1025
+ "unified-preview": klickd_v4_preview_schema_default
346
1026
  };
347
1027
  function getBundledSchema(key) {
348
1028
  const s = SCHEMAS[key];
@@ -586,9 +1266,30 @@ var import_node_url = require("url");
586
1266
  var import_node_path = require("path");
587
1267
  var import_node_fs = require("fs");
588
1268
  var import_meta = {};
1269
+ function moduleDir() {
1270
+ if (typeof __dirname !== "undefined") {
1271
+ return __dirname;
1272
+ }
1273
+ const metaUrl = import_meta?.url;
1274
+ if (typeof metaUrl === "string" && metaUrl.length > 0) {
1275
+ return (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(metaUrl));
1276
+ }
1277
+ throw new Error(
1278
+ "@klickd/core: unable to resolve module directory for starter-skills"
1279
+ );
1280
+ }
589
1281
  function starterSkillsDir() {
590
- const here = (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
591
- return (0, import_node_path.join)(here, "..", "starter-skills");
1282
+ const here = moduleDir();
1283
+ const candidates = [
1284
+ (0, import_node_path.join)(here, "..", "starter-skills"),
1285
+ (0, import_node_path.join)(here, "starter-skills")
1286
+ ];
1287
+ for (const candidate of candidates) {
1288
+ if ((0, import_node_fs.existsSync)(candidate)) {
1289
+ return candidate;
1290
+ }
1291
+ }
1292
+ return candidates[0];
592
1293
  }
593
1294
  function getStarterSkillsDir() {
594
1295
  return starterSkillsDir();