stylegallery 0.1.3 → 0.1.4

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 (40) hide show
  1. package/AGENTS.md +2 -1
  2. package/DOMAINS.md +3 -1
  3. package/GOVERNANCE.md +3 -1
  4. package/README.md +8 -5
  5. package/consumer-reference/agent-native/README.md +12 -1
  6. package/consumer-reference/agent-native/v2/admission-policy.json +106 -1
  7. package/consumer-reference/agent-native/v2/material-registry.json +1 -1
  8. package/consumer-reference/agent-native/v2/schema/admission-policy.schema.json +3 -3
  9. package/consumer-reference/agent-native/v2/schema/material-record.schema.json +1 -1
  10. package/design-engineering/consumer-migration-readiness.md +124 -0
  11. package/design-engineering/interface-craft.md +107 -0
  12. package/design-terminology/concept-families.md +78 -0
  13. package/design-terminology/conflict-cases.md +120 -0
  14. package/design-terminology/index.md +65 -0
  15. package/design-terminology/relation-types.md +103 -0
  16. package/design-terminology/source-kinds.md +77 -0
  17. package/design-terminology/source-vocabularies.md +79 -0
  18. package/game-ui/classification.md +82 -0
  19. package/game-ui/reference-record.md +62 -0
  20. package/game-ui/screen-hierarchy.md +107 -0
  21. package/game-ui/unity/architecture.md +166 -0
  22. package/game-ui/unity/cli-loop.md +84 -0
  23. package/game-ui/unity/org-wiki.md +146 -0
  24. package/game-ui/unity/repository-map.md +102 -0
  25. package/game-ui/unity/ui-systems.md +85 -0
  26. package/guides/vocabulary.md +1 -1
  27. package/index.md +2 -1
  28. package/log.md +5 -0
  29. package/motion/practice-reference.md +145 -0
  30. package/motion/review-workflow.md +86 -0
  31. package/motion/vocabulary.md +82 -0
  32. package/package.json +22 -1
  33. package/platform-guides/apple-interaction.md +89 -0
  34. package/quality/claim-records/design-terminology-domain-scope.md +57 -0
  35. package/quality/evidence/executable-evidence.md +1 -1
  36. package/quality/index.md +2 -2
  37. package/scripts/agent-native/v2/material-admission.mjs +1 -1
  38. package/scripts/agent-native/v2/material-identity.mjs +2 -2
  39. package/scripts/agent-native/v2/material-mcp-adapter.mjs +1 -1
  40. package/scripts/agent-native/v2/material-queries.mjs +60 -12
@@ -0,0 +1,82 @@
1
+ ---
2
+ type: Domain Guide
3
+ title: Motion Vocabulary
4
+ description: Evidence-bounded method and reference for naming observable interface motion.
5
+ domain: motion
6
+ lifecycle: experimental
7
+ source_repository: https://github.com/emilkowalski/skills
8
+ source_path: skills/animation-vocabulary/SKILL.md
9
+ source_revision: 220e8607c90b17337d210125777b7b695f26c221
10
+ ---
11
+
12
+ # Motion Vocabulary
13
+
14
+ Primary role: motion terminology reference.
15
+
16
+ ## Repository Boundary
17
+
18
+ This page helps a reader name observed motion. It does not prescribe implementation, authorize motion in reusable Layout CSS, or make a product-quality judgment.
19
+
20
+ The terms are implementation-neutral. A framework, operating-system behavior, or branded example may illustrate a term only when clearly labeled and separately verified.
21
+
22
+ ## Reusable Method
23
+
24
+ 1. Record what changes: presence, position, scale, shape, state, scroll relationship, or feedback.
25
+ 2. Record what coordinates the change: time, sequence, input, velocity, or viewport progress.
26
+ 3. Compare the observation with the closest term families below.
27
+ 4. Return one exact term only when the observed cues distinguish it.
28
+ 5. When multiple terms remain plausible, return ordered candidates and state the missing observation.
29
+ 6. When nothing matches, return `unknown`; do not invent a canonical winner.
30
+
31
+ ## Term Families
32
+
33
+ | Term | Observed cues | Distinguish from | Implementation-neutral meaning | Evidence boundary |
34
+ | --- | --- | --- | --- | --- |
35
+ | Fade | Visibility changes without a necessary spatial path. | Reveal | A gradual visibility change. | Does not imply opacity is the implementation. |
36
+ | Slide | The element follows a directional path into, out of, or within a region. | Shared-element transition | A positional transition without necessarily preserving identity across views. | Direction and clipping must be observed. |
37
+ | Scale transition | Apparent size changes around an origin. | Morph | Size changes while the element's basic identity remains stable. | Does not establish the correct origin or amount. |
38
+ | Reveal | A boundary progressively exposes content. | Fade | Visibility is controlled by an advancing edge, mask, or equivalent boundary. | The masking mechanism may be unknown. |
39
+ | Stagger | Similar elements begin related changes at distinct offsets. | Orchestration | A repeated sequence pattern, usually across peers. | The offset value is product-specific. |
40
+ | Orchestration | Several motion events form one coordinated sequence. | Stagger | Coordination may include different elements, jobs, and timings. | Intent must be documented, not inferred from timing alone. |
41
+ | Crossfade | One state loses visibility while another gains it in the same region. | Morph | Identity is exchanged rather than geometrically transformed. | Overlap and source order need inspection. |
42
+ | Shared-element transition | A recognizable element appears to retain identity between states or views. | Layout animation | Continuity connects a source representation with a destination representation. | Identity continuity is a perception claim requiring rendered evidence. |
43
+ | Layout animation | A spatial change is visually interpolated instead of appearing instantly. | Shared-element transition | Position or size changes within the layout state of an element. | Does not endorse animating layout-triggering CSS properties. |
44
+ | Scroll-driven motion | Progress corresponds to scroll progress. | Scroll reveal | The scroll position continuously controls progress rather than merely triggering entry. | Browser and input behavior require local testing. |
45
+ | Parallax | Layers appear to travel at different rates during a shared movement. | Ordinary scroll | Relative speed creates a depth cue. | Depth, comfort, and reduced-motion outcomes are not guaranteed. |
46
+ | Spring motion | Response is modeled as a target-seeking dynamic system rather than a fixed timeline. | Bounce | A spring may settle without visible overshoot. | Parameters and perceived duration remain implementation-specific. |
47
+ | Bounce | Motion overshoots or reverses before settling. | Spring motion | Visible overshoot is the defining cue, regardless of implementation. | Playfulness and appropriateness are product judgments. |
48
+ | Interruptible motion | New input redirects a change from its current presented state. | Restarted animation | Continuity is maintained when the target changes mid-flight. | Requires interaction evidence, not source inspection alone. |
49
+ | Rubber-band response | Movement continues beyond a boundary with increasing resistance, then returns. | Bounce | Resistance is tied to boundary overshoot and direct manipulation. | Platform examples are not a universal physics contract. |
50
+ | Jank | Motion visibly misses expected visual continuity. | Intentional stepped motion | The discontinuity is unintended and associated with delivery or computation limits. | Frame or performance evidence is needed to attribute cause. |
51
+
52
+ ## Opinionated Guidance
53
+
54
+ The family ordering favors what a reader can observe before implementation details. It is useful for retrieval, but it is not a complete ontology. Add a term only after a reader task demonstrates that existing terms and aliases cannot express the distinction.
55
+
56
+ ## Platform-Specific Guidance
57
+
58
+ Names tied to iOS, macOS, a browser API, Motion, Framer Motion, React, or a component library are examples or implementation facets. Keep the cross-platform term primary and label the platform context separately.
59
+
60
+ ## Unsupported Absolutes
61
+
62
+ - Do not call this vocabulary authoritative outside StyleGallery.
63
+ - Do not force the nearest term when the observation is incomplete.
64
+ - Do not attach universal FPS, GPU, duration, easing, or reduced-motion rules to a definition.
65
+ - Do not infer implementation technology from rendered appearance alone.
66
+
67
+ ## Verification Contract
68
+
69
+ A vocabulary lookup should exercise exact, ambiguous, and unknown cases. Pass requires one justified term, an ordered candidate set with a stated distinction, or `unknown`; invented winners fail. A new term also requires a findability task showing the current route cannot reach an adequate term within two hops.
70
+
71
+ ## Source, License, And Attribution
72
+
73
+ - Upstream inspiration: [animation-vocabulary/SKILL.md](https://github.com/emilkowalski/skills/blob/220e8607c90b17337d210125777b7b695f26c221/skills/animation-vocabulary/SKILL.md)
74
+ - Snapshot: `220e8607c90b17337d210125777b7b695f26c221`
75
+ - Upstream license: MIT, Copyright (c) 2026 Emil Kowalski.
76
+ - Reuse form: independent method rewrite; upstream prose, tables, code, examples, and distinctive ordering were not retained.
77
+ - Evidence boundary: the upstream artifact records practitioner terminology; it does not prove local performance, accessibility, usability, or quality.
78
+
79
+ ## IA Navigation
80
+
81
+ Parent: [Motion](index.md).
82
+ Next: [Motion Review Workflow](review-workflow.md).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stylegallery",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "A governed gallery of portable interface knowledge with deterministic CLIs and read-only MCP servers.",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/changeroa/StyleGallery#readme",
@@ -47,11 +47,27 @@
47
47
  "consumer-reference/agent-native/v2/schema/material-record.schema.json",
48
48
  "consumer-reference/contract.md",
49
49
  "consumer-reference/index.md",
50
+ "design-engineering/consumer-migration-readiness.md",
50
51
  "design-engineering/index.md",
52
+ "design-engineering/interface-craft.md",
51
53
  "design-engineering/reference-profiles/governed-local/editorial/profile.json",
52
54
  "design-engineering/reference-profiles/governed-local/index.md",
53
55
  "design-engineering/reference-profiles/index.md",
56
+ "design-terminology/concept-families.md",
57
+ "design-terminology/conflict-cases.md",
58
+ "design-terminology/index.md",
59
+ "design-terminology/relation-types.md",
60
+ "design-terminology/source-kinds.md",
61
+ "design-terminology/source-vocabularies.md",
62
+ "game-ui/classification.md",
54
63
  "game-ui/index.md",
64
+ "game-ui/reference-record.md",
65
+ "game-ui/screen-hierarchy.md",
66
+ "game-ui/unity/architecture.md",
67
+ "game-ui/unity/cli-loop.md",
68
+ "game-ui/unity/org-wiki.md",
69
+ "game-ui/unity/repository-map.md",
70
+ "game-ui/unity/ui-systems.md",
55
71
  "guides/decision-tree.md",
56
72
  "guides/documentation-mode-taxonomy.md",
57
73
  "guides/layout-brief.md",
@@ -61,6 +77,9 @@
61
77
  "layout/index.md",
62
78
  "log.md",
63
79
  "motion/index.md",
80
+ "motion/practice-reference.md",
81
+ "motion/review-workflow.md",
82
+ "motion/vocabulary.md",
64
83
  "patterns/centering/center.md",
65
84
  "patterns/centering/index.md",
66
85
  "patterns/centering/super-center.md",
@@ -117,7 +136,9 @@
117
136
  "patterns/viewport-shell/scroll-body-shell.md",
118
137
  "patterns/viewport-shell/sticky-footer.md",
119
138
  "patterns/viewport-shell/sticky-header.md",
139
+ "platform-guides/apple-interaction.md",
120
140
  "platform-guides/index.md",
141
+ "quality/claim-records/design-terminology-domain-scope.md",
121
142
  "quality/claim-records/index.md",
122
143
  "quality/claim-records/samples.md",
123
144
  "quality/claim-records/stylegallery-multidomain-scope.md",
@@ -0,0 +1,89 @@
1
+ ---
2
+ type: Domain Guide
3
+ title: Apple Interaction As A Comparative Reference
4
+ description: Bounded comparison of Apple interaction themes with explicit web-adaptation and provenance limits.
5
+ domain: platform-guides
6
+ lifecycle: experimental
7
+ source_repository: https://github.com/emilkowalski/skills
8
+ source_path: skills/apple-design/SKILL.md
9
+ source_revision: 220e8607c90b17337d210125777b7b695f26c221
10
+ platform: Apple platforms
11
+ platform_version: verify-current
12
+ reviewed_on: 2026-07-11
13
+ ---
14
+
15
+ # Apple Interaction As A Comparative Reference
16
+
17
+ Primary role: platform comparison guide.
18
+
19
+ ## Repository Boundary
20
+
21
+ This page uses selected Apple-platform interaction themes as comparative questions. It does not reproduce Apple guidance, establish affiliation, prescribe imitation, or treat a native implementation value as valid for the web.
22
+
23
+ Current official Apple documentation is required for Apple-specific claims. Current web standards and browser documentation are required for web adaptation. Local rendered, device, accessibility, and performance evidence is required for product conclusions.
24
+
25
+ ## Reusable Method
26
+
27
+ For each proposed comparison:
28
+
29
+ 1. Name the user task, platform, OS/API version, input method, and state transition.
30
+ 2. Describe the observable behavior without branded terminology.
31
+ 3. Identify the platform convention and its current official source.
32
+ 4. Separate the reusable interaction question from native implementation details.
33
+ 5. Define the web adaptation, including unavailable or materially different capabilities.
34
+ 6. Verify the adapted behavior on its real surface and record what remains unproven.
35
+
36
+ ## Comparative Questions
37
+
38
+ | Theme | Question to investigate | Required evidence | Boundary |
39
+ | --- | --- | --- | --- |
40
+ | Response | Does feedback begin close enough to input to preserve cause and effect? | Interaction recording and input-state trace | No universal latency value is implied. |
41
+ | Direct manipulation | Does the presented state follow, cancel, and resume from user input coherently? | Repeated drag/reversal test on target input modes | One-to-one tracking is not always required. |
42
+ | Interruption | Can new input redirect a transition without jumping or locking control? | Mid-transition retarget and reversal evidence | Springs are one option, not a requirement. |
43
+ | Velocity continuity | Does release-to-settle behavior avoid an observable seam? | Gesture and presented-state recording | Native velocity APIs and web libraries differ. |
44
+ | Spatial consistency | Can the reader understand where content came from and where it returns? | Before/intermediate/after render plus source/focus order | Visual path cannot override semantic order. |
45
+ | Recoverability | Can a user cancel, reverse, undo, or safely recover where the task requires it? | Task and error-path evidence | Confirmation is not universally preferable to undo. |
46
+ | Wayfinding | Can the interface answer location, available destinations, contents, and exit? | Navigation task evidence | Familiar platform placement may not transfer across products. |
47
+ | Soft boundaries | Would progressive resistance communicate a limit better than a hard stop? | Comparative prototype and input/device evidence | The resistance curve is not standardized across platforms. |
48
+ | Multimodal feedback | Do visual, audio, and haptic cues share a clear cause and useful purpose? | Device timing and accessibility evidence | Web haptics/audio are not native equivalents and may be unavailable. |
49
+ | Adaptive presentation | Does the interface remain usable across text size, contrast, transparency, motion preference, input, and viewport changes? | Relevant preference and constraint matrix | A platform feature name does not prove web accessibility. |
50
+
51
+ ## Opinionated Guidance
52
+
53
+ Momentum-aware settling, source-anchored transitions, progressive boundary resistance, and carefully coordinated feedback can be useful hypotheses for directly manipulated interfaces. Translucent materials, system typography, haptics, and visual delight are product and platform choices outside reusable Layout pattern CSS.
54
+
55
+ ## Platform-Specific Guidance
56
+
57
+ - iOS/macOS gesture physics, native spring APIs, Dynamic Type, system materials, haptics, and SwiftUI/UIKit behavior must be labeled as Apple-specific.
58
+ - Any value described as shipped by Apple requires a direct, current official source and version.
59
+ - A web mapping must identify browser support, input differences, accessibility behavior, and fallback semantics.
60
+ - `backdrop-filter`, the Vibration API, web media queries, and JavaScript animation libraries are not equivalents merely because they can approximate one visible effect.
61
+
62
+ ## Unsupported Absolutes
63
+
64
+ - Do not call an upstream formula or parameter an exact Apple implementation without a primary official source.
65
+ - Do not require direct manipulation to track one-to-one in every context.
66
+ - Do not require audio and haptic events on one exact frame as a universal web contract.
67
+ - Do not claim translucent chrome is generally superior to opaque structure.
68
+ - Do not adopt a single spring configuration as a safe default across tasks.
69
+ - Do not import a named set of Apple principles as StyleGallery's shared principles.
70
+ - Do not infer native behavior, platform affiliation, or accessibility from visual similarity.
71
+
72
+ ## Verification Contract
73
+
74
+ Record the official platform source and version, the web-standard or browser source for adaptation, the exact target devices and input modes, relevant user preferences, and the observed pass/fail behavior. Use a real interactive prototype for interaction claims. State explicitly when native behavior cannot be reproduced or verified on the web.
75
+
76
+ Review this page when Apple changes the cited convention, the web platform changes the adaptation surface, the source revision changes, or local testing contradicts the guidance. `platform_version: verify-current` prevents this experimental page from masquerading as a version-pinned platform contract.
77
+
78
+ ## Source, License, And Attribution
79
+
80
+ - Upstream inspiration: [apple-design/SKILL.md](https://github.com/emilkowalski/skills/blob/220e8607c90b17337d210125777b7b695f26c221/skills/apple-design/SKILL.md)
81
+ - Snapshot: `220e8607c90b17337d210125777b7b695f26c221`
82
+ - Upstream license: MIT, Copyright (c) 2026 Emil Kowalski.
83
+ - Reuse form: independent method rewrite; upstream prose, tables, code, exact-value sequences, Apple/WWDC-derived expression, and quotations were not retained.
84
+ - Evidence boundary: the upstream artifact is a practitioner interpretation and provenance record, not an official Apple or web-platform source.
85
+
86
+ ## IA Navigation
87
+
88
+ Parent: [Platform Guides](index.md).
89
+ Next: [Layout](../layout/index.md).
@@ -0,0 +1,57 @@
1
+ ---
2
+ type: Decision Record
3
+ title: Design Terminology Domain Scope Decision
4
+ description: Decision to add Design Terminology as the sixth StyleGallery domain, with four placement alternatives compared and the domain's independent decision surface defined.
5
+ ---
6
+
7
+ # Design Terminology Domain Scope Decision
8
+
9
+ ## Decision
10
+
11
+ StyleGallery adds Design Terminology as a sixth explicit domain. The domain's independent decision surface, in one sentence:
12
+
13
+ > Design Terminology binds design terms to their named sources, classifies them by source kind and concept family, and judges typed semantic relations and conflicts between terms from different sources.
14
+
15
+ Concretely, this domain and only this domain decides: which named source a term belongs to, what kind of source that is, which concept family the term serves, and which typed relation with which boundary holds between two terms. The five existing domains keep their boundaries unchanged.
16
+
17
+ The domain does not own: StyleGallery's internal canonical naming (the [Controlled Vocabulary](../../guides/vocabulary.md) keeps it), actual UI behavior or implementation methods, accessibility rules, platform-specific interaction adaptation (Platform Guides keeps it), and any universal prescription about which term is generally better.
18
+
19
+ ## Alternatives Compared
20
+
21
+ | Candidate | Strength | Weakness | Disposition |
22
+ | --- | --- | --- | --- |
23
+ | Extend `guides/vocabulary.md` | Close to existing terminology stewardship | Mixes StyleGallery's internal canonical word set with external systems' term meanings on one authoritative page; the vocabulary would then compete with external definitions it is supposed to route around | Rejected: internal canonical control and external comparative meaning are different decisions with different evidence and freshness rules |
24
+ | `platform-guides/terminology/` | Reuses an existing comparative domain | Tools (Figma), specifications (DTCG Format), and pattern libraries are not platforms; hosting them under Platform Guides would erase the source-kind axis this domain depends on | Rejected: source kind, not platform comparison, is the primary axis |
25
+ | Shared non-domain `terminology/` | Easy to reference across domains | No named owner, lifecycle, validator, or review authority; consumer-reference already carries the no-second-authority rule for shared infrastructure | Rejected: ungoverned placement reproduces the silent-collision problem the content exists to solve |
26
+ | New sixth domain `design-terminology/` | Owns an independent lifecycle, review owner, validator coverage, and experimental-to-stable promotion path | Widest infrastructure blast radius: manifest, validators, schemas, sealed material cardinality, and package inventory all change | Adopted, with the conditions below |
27
+
28
+ Adoption conditions: content starts `experimental`; a machine-readable term/concept/source/relation registry is a promotion prerequisite; every external meaning claim carries an official source and review date; typed relations replace plain term-pair tables.
29
+
30
+ ## Naming
31
+
32
+ Terminology, not topology: topology suggests a formal relation graph or ontology that this domain does not yet provide; v0.1 compares definitions, usage scope, and conflicts. Terminology, not vocabulary: the [Controlled Vocabulary](../../guides/vocabulary.md) owns StyleGallery's canonical internal word set; this domain compares the meanings and relations of terms used by external named sources.
33
+
34
+ ## Context
35
+
36
+ Named design systems, platform guidelines, specifications, and design tools define overlapping terms differently, and handoffs between them fail on silent term collisions. Recording these definitions inside Layout would violate the pattern boundary; the controlled vocabulary page is for internal canonical terms; Platform Guides compares interaction conventions rather than terminology.
37
+
38
+ ## Warrant
39
+
40
+ A separate domain lets terminology comparison name its own evidence boundary: cited official sources, dated structural readings, typed relations with boundaries, and working translations that never override repository policy.
41
+
42
+ ## Consequences
43
+
44
+ - `design-terminology/**` begins `experimental` with a named review owner and validator coverage.
45
+ - The domain manifest, root routes, quality scope, vocabulary domain list, and governance rows record six domains; Consumer Reference remains shared infrastructure and still cannot add a domain row.
46
+ - Record consistency is machine-enforced from v0.1 by `scripts/validate-design-terminology.mjs` (closed relation types, recorded terms on both sides, non-trivial boundaries, contradiction pairs, date and status shape, no orphan terms). Human semantic review is required at stable promotion only, per the repository promotion rules; it is not a merge gate for `experimental` content.
47
+ - Domain identity and cardinality are currently sealed in multiple surfaces (closed schema enums, identity sets, discover cardinality, package inventory, snapshot tests) requiring synchronized manual edits when a domain is added. This is recorded technical debt, not tamper evidence alone: one author changing all copies in one commit weakens duplication as independent evidence while keeping drift risk. Revisit triggers: a seventh domain id is added, manual-change sites exceed twelve, a cardinality drift incident occurs, or registry generation changes. Target structure when triggered: one canonical domain registry generating enums, lists, and package inventory, with an independently reviewed sealed digest as the tamper check. Named review owner for this debt: the Design Terminology domain owner until a governance owner is designated.
48
+ - Term relations recorded by the domain are working judgments, not repository policy for other domains.
49
+
50
+ ## Boundary Or Limitation
51
+
52
+ This decision establishes ownership and governance only. It does not verify that any cited external vocabulary is current beyond each record's review date, does not make any external definition authoritative for product implementation, and does not claim the typed relation model is complete beyond the recorded cases.
53
+
54
+ ## IA Navigation
55
+
56
+ Parent: [Claim Records](index.md) in [Quality Gates](../index.md).
57
+ Next: [StyleGallery Domains](../../DOMAINS.md) for the active domain manifest.
@@ -32,7 +32,7 @@ Executable evidence identifies which claims are machine-enforced, which are only
32
32
  | Markdown links resolve inside the repository. | `scripts/validate-links.mjs` | `node scripts/validate-links.mjs --json` | All checked Markdown links resolve to local files or are intentionally external or anchors. | A local link that escapes the repository or points at a missing file must fail. | Proves link targets exist, not that the target content supports a claim. |
33
33
  | Catalog and generated pattern indexes match the pattern data source. | `scripts/validate-catalog.mjs` | `node scripts/validate-catalog.mjs --json` | `CATALOG.md`, category indexes, and expected pattern files match `scripts/pattern-data.mjs`. | Missing, unexpected, or unlisted pattern files must fail. | Proves catalog consistency, not pattern usefulness. |
34
34
  | Governance, lifecycle, generated-file, ownership, and stale-content policy remain discoverable and CI-enforced. | `scripts/validate-governance.mjs` and `scripts/test-validate-governance.mjs` | `node scripts/validate-governance.mjs --json`; `node scripts/test-validate-governance.mjs --json` | `GOVERNANCE.md`, `.github/CODEOWNERS`, generated warnings, generated metadata, root link targets, lifecycle states, `scheduled_stale_audit` metadata, and CI wiring are present. | Missing governance file, generated warning, generated metadata, CODEOWNERS coverage, or stale policy fixtures must fail. Preferred governance prose and link labels emit warnings. | Proves governance policy is present and linked, not that CODEOWNERS users have verified repository write access. |
35
- | Domain topology, metadata, provenance, scope boundaries, and root routes remain enforced. | `scripts/validate-domains.mjs` and `scripts/test-validate-domains.mjs` | `node scripts/validate-domains.mjs --json`; `node scripts/test-validate-domains.mjs` | Five governed domains and their declared leaves are reachable and attributed. | Domain metadata, immutable provenance, scope boundaries, and root-route fixtures must fail. | A full SHA proves content identity syntax, not publisher authenticity, source ownership, or local quality. |
35
+ | Domain topology, metadata, provenance, scope boundaries, and root routes remain enforced. | `scripts/validate-domains.mjs` and `scripts/test-validate-domains.mjs` | `node scripts/validate-domains.mjs --json`; `node scripts/test-validate-domains.mjs` | Six governed domains and their declared leaves are reachable and attributed. | Domain metadata, immutable provenance, scope boundaries, and root-route fixtures must fail. | A full SHA proves content identity syntax, not publisher authenticity, source ownership, or local quality. |
36
36
  | Consumer-reference handoffs, schema/runtime parity, repository-local record paths, lifecycle separation, ownership truth, and dependency direction remain enforced. | `scripts/validate-consumer-reference.mjs` and `scripts/test-validate-consumer-reference.mjs` | `node scripts/validate-consumer-reference.mjs --json`; `node scripts/test-validate-consumer-reference.mjs --json` | Declared and reasoned-not-applicable fixtures exit zero, every shipped schema rule has accepted/rejected parity coverage, all repository handoffs declare applicability, fixtures remain related, and ownership discloses placeholder single-account review. | Unknown top-level or nested properties, invalid schema fields, missing handoff or reason, stable with ended support, boolean independence, unresolved/absolute/scheme/network/parent/item-or-record-symlink/non-JSON paths, scaffold success, sixth-domain classification, literal or supported computed reverse imports, and repository handoff omissions must fail with named finding codes and non-zero child exit. | Proves receiver-contract consistency, bounded static dependency detection, and path containment, not general JavaScript data-flow safety, visual quality, independent adoption, verified owner permissions, or consumer implementation conformance. |
37
37
  | Promotion governance remains a closed JSON-only, invariant-scoped, deferred example contract. | `scripts/validate-promotion-rfc.mjs` and `scripts/test-validate-promotion-rfc.mjs` | `node scripts/validate-promotion-rfc.mjs --json`; `node scripts/test-validate-promotion-rfc.mjs --json` | The manifest-declared policy and two canonical examples pass with deferred decisions, zero attestations, exact support commitment, and no promotion claim. | Manifest-declared invalid fixtures plus forged, unregistered, duplicate, path, extension, support, evidence, canonical-drift, and lifecycle mutations exit non-zero with named findings. | Synthetic validation does not authenticate adoption, organizations, owners, support capacity, provenance, or a promotion decision; the current canonical inventory supplies no real independent consumers. |
38
38
  | Portable token source and generated CSS agree through the pinned restricted adapter. | `scripts/build-reference-artifacts.mjs`, `scripts/validate-reference-artifacts.mjs`, and `scripts/test-reference-adapters.mjs` | Build with `--fail-on-warning`, validate the generated manifest, then run the adapter fixture harness. | Dimension, color, duration, tested border values, and whole-token curly aliases emit nonzero CSS declarations with matching counts and hashes; output references remain CSS variable references. | `$extends`, JSON Pointer, resolver/modifier/theme documents, unknown reserved fields, non-string descriptions, adapter-unsafe path segments, untested type/unit, partial/dangling/cyclic/type-mismatched aliases, missing output, zero count, warning, scaffold/unknown manifest fields, missing/duplicate declaration, object sentinel, unresolved or forged value, and count drift must fail with named findings and non-zero child exit. | Proves the pinned adapter preserves this tested subset and that committed artifacts independently rebuild from their canonical source, not that tokens are product defaults, portable beyond the tested adapters, visually suitable, or adopted by a consumer. |
package/quality/index.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Quality Gates
2
2
 
3
- `quality/` is shared StyleGallery infrastructure for deciding whether Layout, Motion, Design Engineering, Game UI, and Platform Guides claims are admissible.
3
+ `quality/` is shared StyleGallery infrastructure for deciding whether Layout, Motion, Design Engineering, Game UI, Platform Guides, and Design Terminology claims are admissible.
4
4
 
5
5
  This shared layer does not make the repository a visual design system. Layout pattern files still own spatial structure only; domain guidance cannot bypass these gates. Quality gates explain how claims are framed, what evidence can support them, and when review or debt is required.
6
6
 
@@ -48,7 +48,7 @@ Use this script for lightweight tree tests:
48
48
  | Name an observed motion effect. | [README](../README.md) | [Motion Vocabulary](../motion/vocabulary.md) | The first selected route is Motion and the term reference is reached within two hops. |
49
49
  | Review product-level interface craft. | [README](../README.md) | [Interface Craft Decisions](../design-engineering/interface-craft.md) | The first selected route is Design Engineering and shared quality gates remain visible. |
50
50
  | Compare an Apple interaction convention. | [README](../README.md) | [Apple Interaction](../platform-guides/apple-interaction.md) | The first selected route is Platform Guides and source/version limits are reached within two hops. |
51
- | Declare whether a consumer reference applies. | [README](../README.md) | [Consumer Reference](../consumer-reference/index.md) | The handoff reaches the shared contract without classifying it as a sixth domain. |
51
+ | Declare whether a consumer reference applies. | [README](../README.md) | [Consumer Reference](../consumer-reference/index.md) | The handoff reaches the shared contract without classifying it as a seventh domain. |
52
52
  | Prove a consumer migration preserves declared behavior. | [README](../README.md) | [Consumer Migration Readiness](../design-engineering/consumer-migration-readiness.md) | The reader reaches the Design Engineering method and its evidence gate within two hops. |
53
53
  | Find the authority route for uGUI, UI Toolkit, or NGUI. | [README](../README.md) | [Unity UI Systems](../game-ui/unity/ui-systems.md) | The first selected route is Game UI, and the system-specific source and version boundary is reached within three hops. |
54
54
 
@@ -17,7 +17,7 @@ const MANIFEST_REF = "sg:manifest/material-admission-v2";
17
17
  const MATERIAL_REF_PATTERN = /^sg:material\/path-sha256-[a-f0-9]{64}$/;
18
18
  const MATERIAL_VERSION_PATTERN = /^sg:material\/path-sha256-[a-f0-9]{64}@sha256:[a-f0-9]{64}$/;
19
19
  const HASH_PATTERN = /^[a-f0-9]{64}$/;
20
- const DOMAINS = new Set(["layout", "motion", "design-engineering", "game-ui", "platform-guides", "shared"]);
20
+ const DOMAINS = new Set(["layout", "motion", "design-engineering", "game-ui", "platform-guides", "design-terminology", "shared"]);
21
21
  const LIFECYCLES = new Set(["draft", "stable", "deprecated", "experimental", "generated"]);
22
22
  const RECORD_KEYS = new Set(["schema_version", "record_kind", "stable_ref", "version_id", "repository_path", "media_type", "source_sha256", "byte_length", "lifecycle", "domain"]);
23
23
  const MANIFEST_KEYS = new Set(["schema_version", "record_kind", "stable_ref", "version_id", "admission_policy_ref", "admission_policy_version_id", "materials"]);
@@ -6,7 +6,7 @@ export const MATERIAL_STABLE_REF_KINDS = Object.freeze(["domain", "page", "patte
6
6
  const KIND_SET = new Set(MATERIAL_STABLE_REF_KINDS);
7
7
  const KEBAB = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
8
8
  const PATH_ID = /^path-sha256-[a-f0-9]{64}$/;
9
- const DOMAIN_IDS = new Set(["layout", "motion", "design-engineering", "game-ui", "platform-guides"]);
9
+ const DOMAIN_IDS = new Set(["layout", "motion", "design-engineering", "game-ui", "platform-guides", "design-terminology"]);
10
10
  const MATERIAL_ID = PATH_ID;
11
11
 
12
12
  export class MaterialIdentityError extends TypeError {
@@ -56,7 +56,7 @@ export function materialIdentityForRecord(record) {
56
56
  if (typeof repositoryPath !== "string") fail("material_record_identity_invalid", "record has no bound source path");
57
57
  let kind = "page";
58
58
  let id = `path-sha256-${sha256(Buffer.from(repositoryPath, "utf8"))}`;
59
- const domainMatch = /^(layout|motion|design-engineering|game-ui|platform-guides)\/index\.md$/.exec(repositoryPath);
59
+ const domainMatch = /^(layout|motion|design-engineering|game-ui|platform-guides|design-terminology)\/index\.md$/.exec(repositoryPath);
60
60
  if (domainMatch) { kind = "domain"; id = domainMatch[1]; }
61
61
  else if (/^patterns\/[^/]+\/[^/]+\.md$/.test(repositoryPath)) kind = "pattern";
62
62
  return deepFreeze({
@@ -16,7 +16,7 @@ const manifestPath = path.join(repositoryRoot, "consumer-reference", "agent-nati
16
16
  const exposedNames = new Set(["material-context", "material-discover", "material-get", "material-search"]);
17
17
  const descriptions = Object.freeze({
18
18
  "material-context": "Build a deterministic, provenance-bound material context within a token budget.",
19
- "material-discover": "Discover the five governed StyleGallery domain entries.",
19
+ "material-discover": "Discover the six governed StyleGallery domain entries.",
20
20
  "material-get": "Read bounded UTF-8 bytes for one canonical v2 material StableRef.",
21
21
  "material-search": "Search admitted material deterministically, optionally returning only repository-relative paths.",
22
22
  });
@@ -310,11 +310,36 @@ function titleOf(text) {
310
310
  return /^#{1,6}\s+(.+?)\s*$/m.exec(text)?.[1] ?? "";
311
311
  }
312
312
  function fieldMembership(fieldTokens, queryTokens) {
313
- const members = new Set(fieldTokens);
314
313
  let count = 0;
315
- for (const token of queryTokens) if (members.has(token)) count += 1;
314
+ for (const token of queryTokens) if (fieldTokens.has(token)) count += 1;
316
315
  return count;
317
316
  }
317
+ function queryTokenMembership(value, queryTokenSet) {
318
+ const matches = new Set();
319
+ for (const token of tokenizeMaterialText(value)) {
320
+ if (queryTokenSet.has(token)) matches.add(token);
321
+ }
322
+ return matches;
323
+ }
324
+ function rarityWeightsFor(documents, queryTokens) {
325
+ return queryTokens.map((token) => {
326
+ const documentFrequency = documents.reduce((count, document) => count + Number(
327
+ document.titleTokens.has(token) || document.pathTokens.has(token) || document.bodyTokens.has(token),
328
+ ), 0);
329
+ return {
330
+ document_frequency: documentFrequency,
331
+ multiplier: Math.ceil(documents.length / Math.max(1, documentFrequency)),
332
+ token,
333
+ };
334
+ });
335
+ }
336
+ function weightedFieldMembership(fieldTokens, rarityByToken, fieldWeight) {
337
+ let score = 0;
338
+ for (const [token, multiplier] of rarityByToken) {
339
+ if (fieldTokens.has(token)) score += multiplier * fieldWeight;
340
+ }
341
+ return score;
342
+ }
318
343
  function sourceIdentity(record) {
319
344
  return { stable_ref: record.stable_ref, version_id: record.version_id, source_sha256: record.source_sha256, byte_length: record.byte_length };
320
345
  }
@@ -325,7 +350,7 @@ export function materialDiscover({ repositoryRoot, fileSystem = fs }) {
325
350
  .filter(({ identity }) => identity.kind === "domain")
326
351
  .map(({ record, identity }) => ({ identity, source: sourceIdentity(record), lifecycle: record.lifecycle }))
327
352
  .sort((left, right) => compare(left.identity.stable_ref, right.identity.stable_ref));
328
- if (domains.length !== 5) fail("material_domain_set_invalid", "material manifest does not contain the five governed domains");
353
+ if (domains.length !== 6) fail("material_domain_set_invalid", "material manifest does not contain the six governed domains");
329
354
  return deepFreeze({ schema_version: "2.0", manifest_version_id: manifest.version_id, domains });
330
355
  }
331
356
 
@@ -334,20 +359,19 @@ export function materialSearch({ repositoryRoot, input, fileSystem = fs, sourceR
334
359
  const state = snapshot ? requireSnapshot(snapshot) : loadMetadata(repositoryRoot, fileSystem);
335
360
  const { root, manifest } = state;
336
361
  const beforeInventory = snapshot ? state.inventory : trackedInventory(repositoryRoot, gitRunner);
337
- const ranked = [];
362
+ const queryTokenSet = new Set(normalized.scoringTokens);
363
+ const documents = [];
338
364
  for (const record of manifest.materials) {
339
365
  const bytes = readRecord({ repositoryRoot, root, record, fileSystem, sourceReader, gitRunner, inventory: beforeInventory });
340
366
  let body;
341
367
  try { body = utf8Fatal.decode(bytes); } catch { fail("material_source_utf8_invalid", "material source is not valid UTF-8"); }
342
368
  const title = titleOf(body);
343
- const titleCount = fieldMembership(tokenizeMaterialText(title), normalized.scoringTokens);
344
- const pathCount = fieldMembership(tokenizeMaterialText(record.repository_path), normalized.scoringTokens);
345
- const bodyCount = fieldMembership(tokenizeMaterialText(body), normalized.scoringTokens);
346
- const score = titleCount * MATERIAL_SEARCH_WEIGHTS.title + pathCount * MATERIAL_SEARCH_WEIGHTS.path + bodyCount * MATERIAL_SEARCH_WEIGHTS.body;
347
- if (score === 0) continue;
348
- ranked.push({
349
- repositoryPath: record.repository_path,
350
- result: { identity: materialIdentityForRecord(record), source: sourceIdentity(record), title, score, match_counts: { title: titleCount, path: pathCount, body: bodyCount } },
369
+ documents.push({
370
+ bodyTokens: queryTokenMembership(body, queryTokenSet),
371
+ pathTokens: queryTokenMembership(record.repository_path, queryTokenSet),
372
+ record,
373
+ title,
374
+ titleTokens: queryTokenMembership(title, queryTokenSet),
351
375
  });
352
376
  }
353
377
  const afterInventory = trackedInventory(repositoryRoot, gitRunner);
@@ -355,6 +379,28 @@ export function materialSearch({ repositoryRoot, input, fileSystem = fs, sourceR
355
379
  assertTracked(record, afterInventory);
356
380
  if (canonicalize(beforeInventory.get(record.repository_path)) !== canonicalize(afterInventory.get(record.repository_path))) fail("material_source_race", "material source tracking changed during read");
357
381
  }
382
+ const rarityWeights = rarityWeightsFor(documents, normalized.scoringTokens);
383
+ const rarityByToken = new Map(rarityWeights.map(({ token, multiplier }) => [token, multiplier]));
384
+ const ranked = [];
385
+ for (const document of documents) {
386
+ const titleCount = fieldMembership(document.titleTokens, normalized.scoringTokens);
387
+ const pathCount = fieldMembership(document.pathTokens, normalized.scoringTokens);
388
+ const bodyCount = fieldMembership(document.bodyTokens, normalized.scoringTokens);
389
+ const score = weightedFieldMembership(document.titleTokens, rarityByToken, MATERIAL_SEARCH_WEIGHTS.title)
390
+ + weightedFieldMembership(document.pathTokens, rarityByToken, MATERIAL_SEARCH_WEIGHTS.path)
391
+ + weightedFieldMembership(document.bodyTokens, rarityByToken, MATERIAL_SEARCH_WEIGHTS.body);
392
+ if (score === 0) continue;
393
+ ranked.push({
394
+ repositoryPath: document.record.repository_path,
395
+ result: {
396
+ identity: materialIdentityForRecord(document.record),
397
+ source: sourceIdentity(document.record),
398
+ title: document.title,
399
+ score,
400
+ match_counts: { title: titleCount, path: pathCount, body: bodyCount },
401
+ },
402
+ });
403
+ }
358
404
  ranked.sort((left, right) => right.result.score - left.result.score || compare(left.result.identity.stable_ref, right.result.identity.stable_ref));
359
405
  const selected = ranked.slice(0, normalized.limit);
360
406
  const envelope = {
@@ -362,6 +408,8 @@ export function materialSearch({ repositoryRoot, input, fileSystem = fs, sourceR
362
408
  normalization: "Unicode NFKC; ECMAScript locale-independent lowercase; Letter/Number-led Unicode words retaining attached Marks; unique query-token field membership",
363
409
  query: normalized.query.normalize("NFKC").toLowerCase(), tokens: normalized.tokens,
364
410
  scoring_tokens: normalized.scoringTokens, weights: MATERIAL_SEARCH_WEIGHTS,
411
+ rarity_weighting: "ceil(material_count / max(1, token_document_frequency))",
412
+ rarity_weights: rarityWeights,
365
413
  };
366
414
  if (normalized.pathsOnly) return deepFreeze({ ...envelope, paths_only: true, paths: selected.map(({ repositoryPath }) => repositoryPath), total_matches: ranked.length });
367
415
  return deepFreeze({ ...envelope, results: selected.map(({ result }) => result), total_matches: ranked.length });