@profile-as-code/core 0.1.1 → 0.1.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.
Files changed (60) hide show
  1. package/dist/achievements.d.ts +83 -0
  2. package/dist/achievements.d.ts.map +1 -0
  3. package/dist/achievements.js +207 -0
  4. package/dist/achievements.js.map +1 -0
  5. package/dist/cite.d.ts +91 -0
  6. package/dist/cite.d.ts.map +1 -0
  7. package/dist/cite.js +440 -0
  8. package/dist/cite.js.map +1 -0
  9. package/dist/completeness.d.ts +2 -2
  10. package/dist/completeness.d.ts.map +1 -1
  11. package/dist/completeness.js +22 -5
  12. package/dist/completeness.js.map +1 -1
  13. package/dist/generated/ai-policy.gen.d.ts +36 -0
  14. package/dist/generated/ai-policy.gen.d.ts.map +1 -0
  15. package/dist/generated/ai-policy.gen.js +31 -0
  16. package/dist/generated/ai-policy.gen.js.map +1 -0
  17. package/dist/generated/platforms.gen.d.ts +8 -0
  18. package/dist/generated/platforms.gen.d.ts.map +1 -1
  19. package/dist/generated/platforms.gen.js +68 -0
  20. package/dist/generated/platforms.gen.js.map +1 -1
  21. package/dist/generated/schema.zod.d.ts +57 -0
  22. package/dist/generated/schema.zod.d.ts.map +1 -1
  23. package/dist/generated/schema.zod.js +6 -1
  24. package/dist/generated/schema.zod.js.map +1 -1
  25. package/dist/geo.d.ts +39 -4
  26. package/dist/geo.d.ts.map +1 -1
  27. package/dist/geo.js +127 -43
  28. package/dist/geo.js.map +1 -1
  29. package/dist/index.d.ts +39 -3
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +26 -3
  32. package/dist/index.js.map +1 -1
  33. package/dist/load.d.ts.map +1 -1
  34. package/dist/load.js +17 -0
  35. package/dist/load.js.map +1 -1
  36. package/dist/normalize.d.ts +57 -0
  37. package/dist/normalize.d.ts.map +1 -0
  38. package/dist/normalize.js +133 -0
  39. package/dist/normalize.js.map +1 -0
  40. package/dist/presence.d.ts +113 -0
  41. package/dist/presence.d.ts.map +1 -0
  42. package/dist/presence.js +229 -0
  43. package/dist/presence.js.map +1 -0
  44. package/dist/registry.d.ts +6 -3
  45. package/dist/registry.d.ts.map +1 -1
  46. package/dist/registry.js +8 -4
  47. package/dist/registry.js.map +1 -1
  48. package/dist/structured-data.d.ts +4 -3
  49. package/dist/structured-data.d.ts.map +1 -1
  50. package/dist/structured-data.js +72 -7
  51. package/dist/structured-data.js.map +1 -1
  52. package/dist/types.d.ts +49 -10
  53. package/dist/types.d.ts.map +1 -1
  54. package/dist/types.js +16 -2
  55. package/dist/types.js.map +1 -1
  56. package/package.json +1 -1
  57. package/dist/paste-source.d.ts +0 -14
  58. package/dist/paste-source.d.ts.map +0 -1
  59. package/dist/paste-source.js +0 -17
  60. package/dist/paste-source.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -4,29 +4,65 @@
4
4
  * The contract source is `schema/profile.schema.json` (D3); Zod is generated
5
5
  * from it (packages/core/scripts/gen-zod.ts) and committed.
6
6
  */
7
+ export type { Achievement, AchievementBasis, AchievementDirection, AchievementMetric, AchievementScope, AchievementStatus, } from "./achievements.js";
8
+ /** D24 (§23, #446): the career impact log — the DERIVED status is the one thing
9
+ * the block cannot store. One home for `planned | measured | achieved | partial`
10
+ * and for the post-Zod integrity checks `load()` fails on. */
11
+ export { ACHIEVEMENT_REF_BLOCKS, achievementScope, achievementStatus, checkAchievementIntegrity, DEFAULT_ACHIEVEMENT_DIRECTION, } from "./achievements.js";
7
12
  /** The ONE home of every text-order comparison (D19 byte-parity, #305) —
8
13
  * UTF-16 code units, ICU-free; every engine sort that breaks ties by string
9
14
  * delegates here. */
10
15
  export { byteOrder } from "./byte-order.js";
16
+ export type { CiteAnswer, CiteCitation, CiteConfidence, CiteMatch, CiteSpan, CiteSpanKind, CiteVocabulary, } from "./cite.js";
17
+ /**
18
+ * The deterministic citation matcher over saved answer-engine answers
19
+ * (SPEC §7.4, #291) — pure, offline, no model. `citeVocabulary` is the declared
20
+ * vocabulary it resolves; `citeMatch` is the per-answer result.
21
+ */
22
+ export { citationHost, citeMatch, citeVocabulary } from "./cite.js";
11
23
  export type { CompilePolicy } from "./compile.js";
12
24
  export { compile } from "./compile.js";
13
25
  export type { CompletenessCatalogItem, CompletenessItemResult, CompletenessPolicy, CompletenessReport, CompletenessSignal, } from "./completeness.js";
14
26
  export { COMPLETENESS_CATALOG, completeness, completenessLine, DEFAULT_COMPLETENESS_POLICY, } from "./completeness.js";
15
27
  export { driftCheck } from "./drift.js";
28
+ /**
29
+ * The AI crawler policy, projected from the `ai:` block of
30
+ * `platforms/registry.yaml` (#290) — `pasco export ai-policy` renders it and
31
+ * never keeps a UA list of its own.
32
+ */
33
+ export type { AiCrawler, AiCrawlerFamily } from "./generated/ai-policy.gen.js";
34
+ export { AI_CRAWLERS, AI_POLICY_AS_OF, AI_POLICY_STANCE, AI_POLICY_VERSION, } from "./generated/ai-policy.gen.js";
35
+ export type { SurfaceKind } from "./generated/platforms.gen.js";
16
36
  /** The creator-monetization paste set, projected from `platforms/registry.yaml`
17
37
  * (#154) — the derived test enumeration, never a hand-extended list. */
18
- export { PASTE_PLATFORMS } from "./generated/platforms.gen.js";
19
- export { geoCheck } from "./geo.js";
38
+ export { PASTE_PLATFORMS, PLATFORM_HOSTS, PLATFORM_KINDS } from "./generated/platforms.gen.js";
39
+ /** The profile-contract version this build validates — generated from the schema
40
+ * `$id` (D3, issue #348); `pasco doctor` reports it. */
41
+ export { PROFILE_SCHEMA_VERSION } from "./generated/schema.zod.js";
42
+ /** The GEO index's basis version + the report (SPEC §8, #433): a consumer that
43
+ * quotes `score` compares `basis`, and `measured: false` says it was not
44
+ * observed from citations. */
45
+ export { GEO_BASIS_VERSION, geoCheck } from "./geo.js";
20
46
  export type { CertificationRollup, CertificationState, DeclaredUnverifiable, LedgerIssue, LedgerReport, Origin, SurfaceCapabilities, SurfaceCapability, SurfaceCertification, SyncState, TrackableUnit, UnitKind, UnitStatus, } from "./ledger.js";
21
47
  export { attemptRecord, attestedRecord, canonicalJson, certificationRollup, certificationVerdict, certifiedSurface, certifySurfaces, checkLedgerIntegrity, declaredReason, deployStatus, fetchFailureReason, hashUnit, LEDGER_KEY_PATTERN, trackableUnits, untrackedRows, } from "./ledger.js";
22
48
  export { LoadError, load, normalizeProfile, SchemaValidationError, validateProfile, } from "./load.js";
23
49
  export type { CollectMediaOptions, ManifestEntry, MediaAsset, MediaBundle } from "./media.js";
24
50
  export { artifactAssetTarget, collectMedia, DEFAULT_MAX_BYTES, mediaManifest } from "./media.js";
51
+ export type { FoldedText, TermOccurrence } from "./normalize.js";
52
+ /**
53
+ * The ONE case- and accent-folding every engine comparison uses (SPEC §8,
54
+ * #291) — shared by `geoCheck` and `cite-check`, never re-implemented.
55
+ */
56
+ export { findTerm, foldForMatch, isWordBounded, normalizeText, termOccursIn } from "./normalize.js";
57
+ /** D23 (issue #262): the presence board and the release fan-out — both DERIVED
58
+ * from releases[] + the §19 ledger, with no second state model. */
59
+ export type { BaseText, PresenceBoard, PresenceRow, PresenceState, Release, ReleasePlan, ReleasePlanSurface, ReleaseSurface, } from "./presence.js";
60
+ export { PresenceError, presenceBoard, releasePlan, selectRelease } from "./presence.js";
25
61
  export type { RegistryFinding, RegistryIssue } from "./registry.js";
26
62
  export { checkRegistryIntegrity, credentialLdEntries, isPublicEntry, registryCheck, } from "./registry.js";
27
63
  export type { OmissionReason, SelectionBlock, SelectionFinding, SelectionFindingCode, SelectionMode, SelectionOmission, SelectionPolicy, SelectionReport, SelectionResult, ViewRule, } from "./selection.js";
28
64
  export { resolveView, SELECTION_BLOCKS, selectFacts, } from "./selection.js";
29
65
  export { DEFAULT_LINK_ROLE, entityId, linkRole, linksWithRole, sameAsUrls, structuredData, } from "./structured-data.js";
30
66
  export type { ActiveEntry, Artifact, Bio, BioLength, BrandVoice, Credential, DeploymentRecord, Deployments, EducationalOccupationalCredentialLd, ExperienceItem, Flavor, GeoCheck, GeoReport, GeoSection, Headline, Identity, Issue, Lang, LangMap, LinkRole, LoadedProfile, Newsletter, Platform, PlatformProfile, Podcast, PressItem, Profile, Project, Publication, SemanticAssociationCoverage, Skill, SocialHandle, StructuredDataReadiness, } from "./types.js";
31
- export { LANGS, PLATFORMS } from "./types.js";
67
+ export { LANGS, PLATFORMS, textOf } from "./types.js";
32
68
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;sBAEsB;AACtB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC;yEACyE;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,YAAY,EACZ,MAAM,EACN,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,SAAS,EACT,aAAa,EACb,QAAQ,EACR,UAAU,GACX,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,aAAa,EACb,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,QAAQ,EACR,kBAAkB,EAClB,cAAc,EACd,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,SAAS,EACT,IAAI,EACJ,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9F,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACjG,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,EACb,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,eAAe,EACf,QAAQ,GACT,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,WAAW,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,UAAU,EACV,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,WAAW,EACX,QAAQ,EACR,GAAG,EACH,SAAS,EACT,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,mCAAmC,EACnC,cAAc,EACd,MAAM,EACN,QAAQ,EACR,SAAS,EACT,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,aAAa,EACb,UAAU,EACV,QAAQ,EACR,eAAe,EACf,OAAO,EACP,SAAS,EACT,OAAO,EACP,OAAO,EACP,WAAW,EACX,2BAA2B,EAC3B,KAAK,EACL,YAAY,EACZ,uBAAuB,GACxB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -4,22 +4,45 @@
4
4
  * The contract source is `schema/profile.schema.json` (D3); Zod is generated
5
5
  * from it (packages/core/scripts/gen-zod.ts) and committed.
6
6
  */
7
+ /** D24 (§23, #446): the career impact log — the DERIVED status is the one thing
8
+ * the block cannot store. One home for `planned | measured | achieved | partial`
9
+ * and for the post-Zod integrity checks `load()` fails on. */
10
+ export { ACHIEVEMENT_REF_BLOCKS, achievementScope, achievementStatus, checkAchievementIntegrity, DEFAULT_ACHIEVEMENT_DIRECTION, } from "./achievements.js";
7
11
  /** The ONE home of every text-order comparison (D19 byte-parity, #305) —
8
12
  * UTF-16 code units, ICU-free; every engine sort that breaks ties by string
9
13
  * delegates here. */
10
14
  export { byteOrder } from "./byte-order.js";
15
+ /**
16
+ * The deterministic citation matcher over saved answer-engine answers
17
+ * (SPEC §7.4, #291) — pure, offline, no model. `citeVocabulary` is the declared
18
+ * vocabulary it resolves; `citeMatch` is the per-answer result.
19
+ */
20
+ export { citationHost, citeMatch, citeVocabulary } from "./cite.js";
11
21
  export { compile } from "./compile.js";
12
22
  export { COMPLETENESS_CATALOG, completeness, completenessLine, DEFAULT_COMPLETENESS_POLICY, } from "./completeness.js";
13
23
  export { driftCheck } from "./drift.js";
24
+ export { AI_CRAWLERS, AI_POLICY_AS_OF, AI_POLICY_STANCE, AI_POLICY_VERSION, } from "./generated/ai-policy.gen.js";
14
25
  /** The creator-monetization paste set, projected from `platforms/registry.yaml`
15
26
  * (#154) — the derived test enumeration, never a hand-extended list. */
16
- export { PASTE_PLATFORMS } from "./generated/platforms.gen.js";
17
- export { geoCheck } from "./geo.js";
27
+ export { PASTE_PLATFORMS, PLATFORM_HOSTS, PLATFORM_KINDS } from "./generated/platforms.gen.js";
28
+ /** The profile-contract version this build validates — generated from the schema
29
+ * `$id` (D3, issue #348); `pasco doctor` reports it. */
30
+ export { PROFILE_SCHEMA_VERSION } from "./generated/schema.zod.js";
31
+ /** The GEO index's basis version + the report (SPEC §8, #433): a consumer that
32
+ * quotes `score` compares `basis`, and `measured: false` says it was not
33
+ * observed from citations. */
34
+ export { GEO_BASIS_VERSION, geoCheck } from "./geo.js";
18
35
  export { attemptRecord, attestedRecord, canonicalJson, certificationRollup, certificationVerdict, certifiedSurface, certifySurfaces, checkLedgerIntegrity, declaredReason, deployStatus, fetchFailureReason, hashUnit, LEDGER_KEY_PATTERN, trackableUnits, untrackedRows, } from "./ledger.js";
19
36
  export { LoadError, load, normalizeProfile, SchemaValidationError, validateProfile, } from "./load.js";
20
37
  export { artifactAssetTarget, collectMedia, DEFAULT_MAX_BYTES, mediaManifest } from "./media.js";
38
+ /**
39
+ * The ONE case- and accent-folding every engine comparison uses (SPEC §8,
40
+ * #291) — shared by `geoCheck` and `cite-check`, never re-implemented.
41
+ */
42
+ export { findTerm, foldForMatch, isWordBounded, normalizeText, termOccursIn } from "./normalize.js";
43
+ export { PresenceError, presenceBoard, releasePlan, selectRelease } from "./presence.js";
21
44
  export { checkRegistryIntegrity, credentialLdEntries, isPublicEntry, registryCheck, } from "./registry.js";
22
45
  export { resolveView, SELECTION_BLOCKS, selectFacts, } from "./selection.js";
23
46
  export { DEFAULT_LINK_ROLE, entityId, linkRole, linksWithRole, sameAsUrls, structuredData, } from "./structured-data.js";
24
- export { LANGS, PLATFORMS } from "./types.js";
47
+ export { LANGS, PLATFORMS, textOf } from "./types.js";
25
48
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;sBAEsB;AACtB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAQvC,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC;yEACyE;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAgBpC,OAAO,EACL,aAAa,EACb,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,QAAQ,EACR,kBAAkB,EAClB,cAAc,EACd,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,SAAS,EACT,IAAI,EACJ,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,GAChB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEjG,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,EACb,aAAa,GACd,MAAM,eAAe,CAAC;AAavB,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,WAAW,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,UAAU,EACV,cAAc,GACf,MAAM,sBAAsB,CAAC;AAoC9B,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH;;+DAE+D;AAC/D,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,mBAAmB,CAAC;AAC3B;;sBAEsB;AACtB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAU5C;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEpE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAQvC,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAOxC,OAAO,EACL,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,8BAA8B,CAAC;AAEtC;yEACyE;AACzE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC/F;yDACyD;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE;;+BAE+B;AAC/B,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAgBvD,OAAO,EACL,aAAa,EACb,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,QAAQ,EACR,kBAAkB,EAClB,cAAc,EACd,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,SAAS,EACT,IAAI,EACJ,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,GAChB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEjG;;;GAGG;AACH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAapG,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEzF,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,EACb,aAAa,GACd,MAAM,eAAe,CAAC;AAavB,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,WAAW,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,UAAU,EACV,cAAc,GACf,MAAM,sBAAsB,CAAC;AAoC9B,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEzD,uFAAuF;AACvF,qBAAa,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,EAGlD;CACF;AAED,sFAAsF;AACtF,qBAAa,qBAAsB,SAAQ,SAAS;IAClD,QAAQ,CAAC,MAAM,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAE9D,YAAY,MAAM,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,EAO/D;CACF;AAED,0GAA0G;AAC1G,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAUvD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CAmBhE;AAwCD;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAYrD"}
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AASH,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEzD,uFAAuF;AACvF,qBAAa,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,EAGlD;CACF;AAED,sFAAsF;AACtF,qBAAa,qBAAsB,SAAQ,SAAS;IAClD,QAAQ,CAAC,MAAM,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAE9D,YAAY,MAAM,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,EAO/D;CACF;AAED,0GAA0G;AAC1G,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAUvD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CA+BhE;AAwCD;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAgBrD"}
package/dist/load.js CHANGED
@@ -14,6 +14,7 @@
14
14
  import { existsSync, readdirSync, readFileSync } from "node:fs";
15
15
  import { join } from "node:path";
16
16
  import { parseDocument } from "yaml";
17
+ import { checkAchievementIntegrity } from "./achievements.js";
17
18
  import { profileSchema } from "./generated/schema.zod.js";
18
19
  import { checkLedgerIntegrity } from "./ledger.js";
19
20
  import { checkRegistryIntegrity } from "./registry.js";
@@ -70,6 +71,18 @@ export function normalizeProfile(profile) {
70
71
  deployments: profile.deployments ?? {},
71
72
  credentials: profile.credentials ?? [],
72
73
  artifacts: profile.artifacts ?? [],
74
+ // #348: `faq[]` is the one list root added after `normalizeProfile` was
75
+ // written; leaving it undefined made the loaded shape depend on whether the
76
+ // workspace declares answers. Every list root defaults here, so the one
77
+ // assembler (`load()`, §15.4) returns a shape a consumer reads without a
78
+ // per-root null check.
79
+ faq: profile.faq ?? [],
80
+ // v1.15 (D23): the release events a workspace declares. Optional and additive
81
+ // — an old workspace without it reads the same, now with an empty list.
82
+ releases: profile.releases ?? [],
83
+ // v1.16 (D24, #446): the career impact log. Same rule — the loaded shape never
84
+ // depends on whether the workspace declares results.
85
+ achievements: profile.achievements ?? [],
73
86
  };
74
87
  }
75
88
  /** Read and merge every `content/*.yaml` (or `*.yml`) of a workspace.
@@ -124,6 +137,10 @@ export function load(workspace) {
124
137
  if (registryIssues.length > 0) {
125
138
  throw new SchemaValidationError(registryIssues);
126
139
  }
140
+ const achievementIssues = checkAchievementIntegrity(profile);
141
+ if (achievementIssues.length > 0) {
142
+ throw new SchemaValidationError(achievementIssues);
143
+ }
127
144
  return normalizeProfile(profile);
128
145
  }
129
146
  //# sourceMappingURL=load.js.map
package/dist/load.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"load.js","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAGvD,uFAAuF;AACvF,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe,EAAE,OAAsB;QACjD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,sFAAsF;AACtF,MAAM,OAAO,qBAAsB,SAAQ,SAAS;IACzC,MAAM,CAA+C;IAE9D,YAAY,MAAoD;QAC9D,KAAK,CACH,gEAAgE,MAAM,CAAC,MAAM,kBAAkB;YAC7F,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,QAAQ,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACxE,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,0GAA0G;AAC1G,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACjD,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ;YACzD,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CAAC,CAAC;QACJ,MAAM,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,OAAO;QACL,GAAG,OAAO;QACV,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,QAAQ;QAClC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE;QACxB,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE;QAClC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;QAC5B,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,EAAE;QACpC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE;QAChC,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,EAAE;QACxC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;QAC5B,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,EAAE;QAC1C,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;QAC1B,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE;QAClC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE;QAClC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;QACtC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;QACtC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE;KACnC,CAAC;AACJ,CAAC;AAED;;;yDAGyD;AACzD,SAAS,gBAAgB,CAAC,SAAiB;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC9C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,SAAS,CACjB,wCAAwC,UAAU,iDAAiD,CACpG,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,CAAC,UAAU,CAAC;SAClC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;SACjE,IAAI,EAAE,CAAC;IAEV,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,aAAa,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;QAC1D,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,SAAS,CACjB,WAAW,IAAI,oBAAoB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,aAAa,EAAE,CAC7E,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC;QAC9C,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS;YAAE,SAAS,CAAC,+BAA+B;QAClF,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;YACtB,MAAM,IAAI,SAAS,CACjB,WAAW,IAAI,8BAA8B,OAAO,+FAA+F,CACpJ,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IACzB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,IAAI,CAAC,SAAiB;IACpC,MAAM,MAAM,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACnD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,qBAAqB,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC;IACD,MAAM,cAAc,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;IACvD,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,qBAAqB,CAAC,cAAc,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * normalize.ts — the case- and accent-folding for the citation matcher
3
+ * (SPEC §7.4, issue #291).
4
+ *
5
+ * One reader today: `cite-check` needs an accent-insensitive, word-bounded
6
+ * matcher over text the workspace does not control. `geoCheck` keeps its bare
7
+ * `toLowerCase()` comparisons **by decision** — its published score is a
8
+ * separate contract (§8), and an accent-insensitive GEO check would be its own
9
+ * SPEC change. The two sides may disagree about a folded name; that is
10
+ * declared, not hidden, and the regression test pins the pre-PR reading.
11
+ *
12
+ * The fold is deliberately DUMB and deterministic (D19): NFKD, combining marks
13
+ * dropped, lowercased, a few typographic characters mapped to ASCII. No locale,
14
+ * no `Intl`, no network. It is lossy on purpose; `FoldedText` keeps the map back
15
+ * to the ORIGINAL UTF-16 offsets so a caller can report a real span
16
+ * (`cite-check`'s `spans[]`) instead of an offset into the folded copy.
17
+ */
18
+ /** The folded string plus, per folded UTF-16 code unit, its original span. */
19
+ export interface FoldedText {
20
+ /** The folded text every match runs over. */
21
+ text: string;
22
+ /** `starts[i]` — original offset where folded unit `i` begins. */
23
+ starts: number[];
24
+ /** `ends[i]` — original offset just past the source code point of `i`. */
25
+ ends: number[];
26
+ }
27
+ /**
28
+ * Fold `value` and keep the map back to the original offsets.
29
+ *
30
+ * Iteration is by CODE POINT (surrogate pairs stay one unit) and the map is per
31
+ * emitted UTF-16 unit, so `starts`/`ends` are valid offsets into `value` even when
32
+ * a fold expands one code point into two.
33
+ */
34
+ export declare function foldForMatch(value: string): FoldedText;
35
+ /** The folded text alone — the form every comparison uses. */
36
+ export declare function normalizeText(value: string): string;
37
+ /** Word-bounded in FOLDED text: `pasco` does not match inside `pascoño`. */
38
+ export declare function isWordBounded(folded: string, start: number, end: number): boolean;
39
+ /** One occurrence of a term, in ORIGINAL offsets. */
40
+ export interface TermOccurrence {
41
+ start: number;
42
+ end: number;
43
+ }
44
+ /**
45
+ * Every word-bounded occurrence of `term` in `folded`, as original offsets.
46
+ *
47
+ * The term is folded with the same function, so a caller never pre-normalizes
48
+ * (and never double-folds). Overlapping occurrences are all returned; the
49
+ * caller decides what containment means for its contract.
50
+ */
51
+ export declare function findTerm(folded: FoldedText, term: string): TermOccurrence[];
52
+ /**
53
+ * Does `term` occur word-bounded inside the folded range `[from, to)`?
54
+ * Used for sentence-scoped readings (does this sentence carry a qualifier?).
55
+ */
56
+ export declare function termOccursIn(folded: FoldedText, term: string, from: number, to: number): boolean;
57
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAsCD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAiBtD;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAOD,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAEjF;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAe3E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAWhG"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * normalize.ts — the case- and accent-folding for the citation matcher
3
+ * (SPEC §7.4, issue #291).
4
+ *
5
+ * One reader today: `cite-check` needs an accent-insensitive, word-bounded
6
+ * matcher over text the workspace does not control. `geoCheck` keeps its bare
7
+ * `toLowerCase()` comparisons **by decision** — its published score is a
8
+ * separate contract (§8), and an accent-insensitive GEO check would be its own
9
+ * SPEC change. The two sides may disagree about a folded name; that is
10
+ * declared, not hidden, and the regression test pins the pre-PR reading.
11
+ *
12
+ * The fold is deliberately DUMB and deterministic (D19): NFKD, combining marks
13
+ * dropped, lowercased, a few typographic characters mapped to ASCII. No locale,
14
+ * no `Intl`, no network. It is lossy on purpose; `FoldedText` keeps the map back
15
+ * to the ORIGINAL UTF-16 offsets so a caller can report a real span
16
+ * (`cite-check`'s `spans[]`) instead of an offset into the folded copy.
17
+ */
18
+ /** Typographic characters with one deterministic ASCII reading (1:1, offset-safe). */
19
+ const SINGLE_CHAR_FOLD = {
20
+ "\u2018": "'",
21
+ "\u2019": "'",
22
+ "\u201A": "'",
23
+ "\u201B": "'",
24
+ "\u201C": '"',
25
+ "\u201D": '"',
26
+ "\u201E": '"',
27
+ "\u2013": "-",
28
+ "\u2014": "-",
29
+ "\u2212": "-",
30
+ "\u00A0": " ",
31
+ "\u202F": " ",
32
+ "\u3000": " ",
33
+ };
34
+ const COMBINING_MARK = /\p{M}/u;
35
+ const WORD_CHAR = /[\p{L}\p{N}]/u;
36
+ /**
37
+ * Fold one code point: map the typographic variants, decompose (NFKD), drop the
38
+ * combining marks, lowercase. A code point may fold to zero units (`\u0301`), one
39
+ * (`é` → `e`) or several (`fi` → `fi`) — the caller maps every emitted unit back
40
+ * to the same source code point.
41
+ */
42
+ function foldCodePoint(cp) {
43
+ const mapped = SINGLE_CHAR_FOLD[cp] ?? cp;
44
+ let out = "";
45
+ for (const ch of mapped.normalize("NFKD")) {
46
+ if (COMBINING_MARK.test(ch))
47
+ continue;
48
+ out += ch.toLowerCase();
49
+ }
50
+ return out;
51
+ }
52
+ /**
53
+ * Fold `value` and keep the map back to the original offsets.
54
+ *
55
+ * Iteration is by CODE POINT (surrogate pairs stay one unit) and the map is per
56
+ * emitted UTF-16 unit, so `starts`/`ends` are valid offsets into `value` even when
57
+ * a fold expands one code point into two.
58
+ */
59
+ export function foldForMatch(value) {
60
+ const starts = [];
61
+ const ends = [];
62
+ let text = "";
63
+ let i = 0;
64
+ while (i < value.length) {
65
+ const cp = value.codePointAt(i);
66
+ if (cp === undefined)
67
+ break;
68
+ const width = cp > 0xffff ? 2 : 1;
69
+ for (const unit of foldCodePoint(String.fromCodePoint(cp))) {
70
+ text += unit;
71
+ starts.push(i);
72
+ ends.push(i + width);
73
+ }
74
+ i += width;
75
+ }
76
+ return { text, starts, ends };
77
+ }
78
+ /** The folded text alone — the form every comparison uses. */
79
+ export function normalizeText(value) {
80
+ return foldForMatch(value).text;
81
+ }
82
+ function isWordChar(folded, index) {
83
+ const ch = folded[index];
84
+ return ch !== undefined && WORD_CHAR.test(ch);
85
+ }
86
+ /** Word-bounded in FOLDED text: `pasco` does not match inside `pascoño`. */
87
+ export function isWordBounded(folded, start, end) {
88
+ return !isWordChar(folded, start - 1) && !isWordChar(folded, end);
89
+ }
90
+ /**
91
+ * Every word-bounded occurrence of `term` in `folded`, as original offsets.
92
+ *
93
+ * The term is folded with the same function, so a caller never pre-normalizes
94
+ * (and never double-folds). Overlapping occurrences are all returned; the
95
+ * caller decides what containment means for its contract.
96
+ */
97
+ export function findTerm(folded, term) {
98
+ const needle = normalizeText(term);
99
+ if (needle === "")
100
+ return [];
101
+ const out = [];
102
+ let from = 0;
103
+ for (;;) {
104
+ const at = folded.text.indexOf(needle, from);
105
+ if (at === -1)
106
+ break;
107
+ const end = at + needle.length;
108
+ if (isWordBounded(folded.text, at, end)) {
109
+ out.push({ start: folded.starts[at] ?? 0, end: folded.ends[end - 1] ?? 0 });
110
+ }
111
+ from = at + 1;
112
+ }
113
+ return out;
114
+ }
115
+ /**
116
+ * Does `term` occur word-bounded inside the folded range `[from, to)`?
117
+ * Used for sentence-scoped readings (does this sentence carry a qualifier?).
118
+ */
119
+ export function termOccursIn(folded, term, from, to) {
120
+ const needle = normalizeText(term);
121
+ if (needle === "")
122
+ return false;
123
+ const haystack = folded.text.slice(from, to);
124
+ let at = haystack.indexOf(needle);
125
+ while (at !== -1) {
126
+ const end = at + needle.length;
127
+ if (isWordBounded(haystack, at, end))
128
+ return true;
129
+ at = haystack.indexOf(needle, at + 1);
130
+ }
131
+ return false;
132
+ }
133
+ //# sourceMappingURL=normalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * D23 — the presence surface and the release fan-out (SPEC §22, issue #262).
3
+ *
4
+ * The unit of first class is the **presence surface**, not the profile. Two
5
+ * consequences this module owns, both DERIVED and stored nowhere:
6
+ *
7
+ * presenceBoard(profile) the daily board: every surface a release has
8
+ * addressed, at its newest release, with state;
9
+ * releasePlan(profile, id?) one release's ordered fan-out + base text.
10
+ *
11
+ * **No second state model.** A surface's state is the ledger's own
12
+ * `in-sync` / `stale` / `never` (§19), derived from `deployments` for the release's
13
+ * own `changedUnits`:
14
+ *
15
+ * ANY changed unit has no ledger record on that surface → never
16
+ * every changed unit has a record, and some record's
17
+ * contentHash != the unit's current hash → stale
18
+ * every record matches → in-sync
19
+ *
20
+ * Partial coverage is NEVER in-sync: a release that changed two units and the
21
+ * surface confirmed only one still owes the other, and `missingUnits` names it.
22
+ *
23
+ * **Two causes, two fields (#408).** "No ledger record" and "no such SSOT unit"
24
+ * both make a surface `never`, but they mean opposite things to the operator: the
25
+ * first is a pending fan-out of a CORRECT row, the second is the row being wrong.
26
+ * They travel separately (`missingUnits` / `unknownUnits`) so a consumer never
27
+ * reports one as the other.
28
+ *
29
+ * A surface the ledger cannot record (a repo-meta/distribution slug outside the
30
+ * platform enum) therefore reads `never`: the honest v1 answer — the plan names
31
+ * what must be touched; closing that loop is a later contract change, never a
32
+ * second state invented here.
33
+ *
34
+ * Offline, deterministic, no clock: ordering is kind rank → registry slug.
35
+ */
36
+ import { type SurfaceKind } from "./generated/platforms.gen.js";
37
+ import type { LoadedProfile } from "./types.js";
38
+ /** A release row from the workspace (schema v1.15, D23). */
39
+ export type Release = NonNullable<LoadedProfile["releases"]>[number];
40
+ /** The state a surface carries for a release — the §19 ledger vocabulary. */
41
+ export type PresenceState = "in-sync" | "stale" | "never";
42
+ /** An addressed surface that the registry does not know is a typo, not a kind. */
43
+ export declare class PresenceError extends Error {
44
+ constructor(message: string);
45
+ }
46
+ export interface ReleaseSurface {
47
+ surface: string;
48
+ kind: SurfaceKind;
49
+ state: PresenceState;
50
+ /** changedUnits this surface still owes: the key IS an SSOT unit, but the
51
+ * ledger has no record of it on THIS surface yet. Any entry here means the
52
+ * surface is `never`, never a partial `in-sync` — and it is a pending
53
+ * fan-out, not a defect in the release row (#408). */
54
+ missingUnits: string[];
55
+ /** changedUnits that resolve to no SSOT unit at all: a release row citing a
56
+ * deleted or mistyped key. This one IS a defect in the row — reported apart
57
+ * from `missingUnits` so a correct row is never sent to be "fixed" (#408). */
58
+ unknownUnits: string[];
59
+ }
60
+ /** A plan row: the derived state plus its 1-based fan-out position. `order` is
61
+ * the SAME number the human plan prints in its ORDER column (#421), so a
62
+ * machine consumer reads it instead of counting array indices — an implicit
63
+ * contract a consumer can get wrong. Additive: the array order is unchanged. */
64
+ export interface ReleasePlanSurface extends ReleaseSurface {
65
+ order: number;
66
+ }
67
+ export interface BaseText {
68
+ kind: SurfaceKind;
69
+ /** The factual spine: `"<frame>: v<version> (<date>) — <summary.en | id>"`. */
70
+ text: string;
71
+ }
72
+ export interface ReleasePlan {
73
+ release: {
74
+ id: string;
75
+ version: string;
76
+ date: string;
77
+ summary: string;
78
+ changedUnits: string[];
79
+ };
80
+ /** Ordered by kind (repo-meta → profile → distribution), then slug; each row
81
+ * carries its 1-based `order` (the human ORDER column, #421). */
82
+ surfaces: ReleasePlanSurface[];
83
+ /** One entry per kind PRESENT in `surfaces`, in fan-out order. */
84
+ baseText: BaseText[];
85
+ }
86
+ export interface PresenceRow extends ReleaseSurface {
87
+ /** The newest release that declares this surface. */
88
+ releaseId: string;
89
+ version: string;
90
+ }
91
+ export interface PresenceBoard {
92
+ releases: number;
93
+ latest: {
94
+ id: string;
95
+ version: string;
96
+ date: string;
97
+ } | null;
98
+ /** One row per surface, at the newest release that declares it. */
99
+ surfaces: PresenceRow[];
100
+ counts: Record<PresenceState, number>;
101
+ }
102
+ /** The release a caller asked for, or the newest one (no clock, no guess). */
103
+ export declare function selectRelease(profile: LoadedProfile, id?: string): Release;
104
+ /** One release's ordered fan-out and the per-kind factual spine. */
105
+ export declare function releasePlan(profile: LoadedProfile, id?: string): ReleasePlan;
106
+ /**
107
+ * The daily board (option B, operator 2026-10-28): every surface the workspace's
108
+ * releases have addressed, at its NEWEST release, with the same ledger-derived
109
+ * state. Deriving from the newest release keeps the board a reading of the
110
+ * releases, never a second ledger.
111
+ */
112
+ export declare function presenceBoard(profile: LoadedProfile): PresenceBoard;
113
+ //# sourceMappingURL=presence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../src/presence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,4DAA4D;AAC5D,MAAM,MAAM,OAAO,GAAG,WAAW,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAErE,6EAA6E;AAC7E,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAkB1D,kFAAkF;AAClF,qBAAa,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB;;;2DAGuD;IACvD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB;;mFAE+E;IAC/E,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;iFAGiF;AACjF,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACxD,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,WAAW,CAAC;IAClB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;IACF;sEACkE;IAClE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,EAAE,QAAQ,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,WAAY,SAAQ,cAAc;IACjD,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7D,mEAAmE;IACnE,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;CACvC;AAoGD,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAgB1E;AAED,oEAAoE;AACpE,wBAAgB,WAAW,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,WAAW,CAgC5E;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CA8BnE"}