naive-framework 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +61 -0
- package/LICENSE +21 -0
- package/README.md +37 -2
- package/docs/decisions/decisions.json +861 -0
- package/docs/ontology.json +796 -0
- package/docs/ontology.md +163 -0
- package/docs/reference/ROUTES.md +125 -0
- package/evidence/benchmarks/2026-10-27-golden.jev.after-catalog-fix.json +558 -0
- package/evidence/benchmarks/2026-10-27-golden.jev.json +501 -0
- package/evidence/benchmarks/2026-10-27-golden.reasoning-answers.json +177 -0
- package/evidence/benchmarks/JEV_VS_REASONING_MODEL_2026-10-27.md +68 -0
- package/evidence/capabilities/agent-capabilities.json +86 -0
- package/evidence/design-documents.registry.json +2896 -0
- package/evidence/evals/evals.json +25 -0
- package/evidence/evals/harness-evals.json +140 -0
- package/evidence/layer.json +51 -0
- package/evidence/skills/agent-capabilities/SKILL.md +35 -0
- package/evidence/skills/design-coverage/SKILL.md +57 -0
- package/evidence/skills/design-coverage/check.mjs +192 -0
- package/evidence/skills/design-coverage/scan.mjs +45 -0
- package/evidence/skills/fidelity-ladder-audit/SKILL.md +121 -0
- package/evidence/skills/fidelity-ladder-audit/ladder-census.mjs +180 -0
- package/evidence/skills/findability/SKILL.md +32 -0
- package/evidence/skills/findability/inventory.rb +41 -0
- package/evidence/skills/foreshadowing-audit/SKILL.md +183 -0
- package/evidence/skills/metrics-review/SKILL.md +177 -0
- package/evidence/tooling/integrations.json +153 -0
- package/governance/layer.json +101 -0
- package/governance/references/references.json +26 -0
- package/governance/skills/board-design/SKILL.md +68 -0
- package/governance/skills/brand-pillar/SKILL.md +90 -0
- package/governance/skills/business-pillar/SKILL.md +96 -0
- package/governance/skills/chief-of-staff/SKILL.md +45 -0
- package/governance/skills/cofounder-structure/SKILL.md +64 -0
- package/governance/skills/cross-pillar-tradeoff/SKILL.md +168 -0
- package/governance/skills/equity-and-share-classes/SKILL.md +68 -0
- package/governance/skills/executive-roles/SKILL.md +95 -0
- package/governance/skills/exit-planning/SKILL.md +66 -0
- package/governance/skills/financing-and-investor-rights/SKILL.md +73 -0
- package/governance/skills/office-hours-mode/SKILL.md +113 -0
- package/governance/skills/product-pillar/SKILL.md +81 -0
- package/governance/skills/publication-policy/SKILL.md +63 -0
- package/governance/skills/role-and-candidate-authoring/SKILL.md +198 -0
- package/governance/skills/stakeholder-update/SKILL.md +177 -0
- package/governance/tooling/integrations.json +37 -0
- package/governance/venture-template/AGENT_ROLES_AND_DECISION_RIGHTS.md +58 -0
- package/governance/venture-template/COMPANY_VAULT_DEFINITION_2026-10-25.md +204 -0
- package/governance/venture-template/README.md +74 -0
- package/governance/venture-template/decision-rights.json +186 -0
- package/governance/venture-template/index.md +151 -0
- package/governance/venture-template/pillars/brand.md +209 -0
- package/governance/venture-template/pillars/business.md +255 -0
- package/governance/venture-template/pillars/product.md +254 -0
- package/governance/venture-template/render-roles.py +11 -0
- package/governance/venture-template/roles/README.md +85 -0
- package/governance/venture-template/roles/agent-roles.json +202 -0
- package/governance/venture-template/roles/ceo.md +163 -0
- package/governance/venture-template/roles/chief-of-staff.md +153 -0
- package/governance/venture-template/roles/cmo.md +165 -0
- package/governance/venture-template/roles/coo.md +189 -0
- package/governance/venture-template/roles/cto.md +158 -0
- package/governance/venture-template/roles/department-head.md +47 -0
- package/governance/venture-template/roles/forward-deployed-engineer.md +51 -0
- package/governance/venture-template/roles/founder.md +173 -0
- package/governance/venture-template/roles/hr-manager.md +49 -0
- package/governance/venture-template/roles/talent-acquisition-manager.md +50 -0
- package/interface/api/server.mjs +69 -0
- package/interface/cli/find-venture.mjs +15 -0
- package/interface/cli/mentura.mjs +271 -0
- package/interface/cli/naive.mjs +169 -0
- package/interface/demo/board.mjs +581 -0
- package/interface/demo/decision-harness.mjs +91 -0
- package/interface/demo/live-agent.mjs +47 -0
- package/interface/harness/evals.mjs +90 -0
- package/interface/harness/examples/pt-no-shows.dump.md +19 -0
- package/interface/harness/run.mjs +313 -0
- package/interface/harness/site.mjs +59 -0
- package/interface/layer.json +31 -0
- package/interface/mcp/server.mjs +122 -0
- package/interface/operator-console/README.md +58 -0
- package/interface/provenance.mjs +42 -0
- package/interface/references/references.json +28 -0
- package/interface/route-aliases.json +32 -0
- package/interface/router.mjs +580 -0
- package/interface/skills/install-mentura/SKILL.md +88 -0
- package/interface/tooling/integrations.json +112 -0
- package/knowledge/connectors/README.md +54 -0
- package/knowledge/connectors/catalog.mjs +118 -0
- package/knowledge/connectors/contract.mjs +56 -0
- package/knowledge/connectors/eval.mjs +176 -0
- package/knowledge/connectors/filesystem.mjs +79 -0
- package/knowledge/connectors/index.mjs +102 -0
- package/knowledge/connectors/resolve.mjs +44 -0
- package/knowledge/connectors/suite.mjs +80 -0
- package/knowledge/layer.json +42 -0
- package/knowledge/skills/find-reference/SKILL.md +38 -0
- package/knowledge/skills/industry-awareness/SKILL.md +277 -0
- package/knowledge/tooling/integrations.json +127 -0
- package/knowledge/tooling/questions.md +46 -0
- package/operations/FOUNDER_OPERATING_MODEL_CAMPAIGN_2026-10-14.md +16 -0
- package/operations/departments.json +162 -0
- package/operations/handoff-v2.md +93 -0
- package/operations/layer.json +60 -0
- package/operations/marketing/check-public.mjs +68 -0
- package/operations/marketing/site/README.md +86 -0
- package/operations/marketing/site/matrix.json +731 -0
- package/operations/marketing/site/plan.mjs +117 -0
- package/operations/marketing/site/presence.mjs +252 -0
- package/operations/references/references.json +45 -0
- package/operations/skills/recruiting/SKILL.md +32 -0
- package/operations/skills/team-design/SKILL.md +36 -0
- package/operations/skills/tool-selection/SKILL.md +46 -0
- package/operations/templates/recruiting-brief.md +35 -0
- package/operations/tooling/integrations.json +158 -0
- package/package.json +57 -4
- package/packages/catalog.json +272 -0
- package/packages/cofounder/package.json +42 -0
- package/packages/counsel/package.json +47 -0
- package/packages/customers/package.json +21 -0
- package/packages/decisions/package.json +17 -0
- package/packages/engineering/package.json +41 -0
- package/packages/evidence/package.json +17 -0
- package/packages/finance/package.json +48 -0
- package/packages/foundation/package.json +52 -0
- package/packages/investor/package.json +57 -0
- package/packages/investors/package.json +21 -0
- package/packages/legal/package.json +73 -0
- package/packages/marketing/package.json +57 -0
- package/packages/money/package.json +21 -0
- package/packages/operations/package.json +74 -0
- package/packages/partner/package.json +38 -0
- package/packages/people/package.json +64 -0
- package/packages/product/package.json +49 -0
- package/packages/raw/package.json +19 -0
- package/packages/relationships/package.json +52 -0
- package/packages/validation/package.json +99 -0
- package/platform/README.md +45 -0
- package/platform/connectors/eval.mjs +154 -0
- package/platform/connectors/fake-github.mjs +91 -0
- package/platform/connectors/github.mjs +105 -0
- package/platform/integrations/jev.mjs +30 -0
- package/platform/integrations/langsmith-docket.mjs +53 -0
- package/platform/integrations/langsmith-setup.mjs +115 -0
- package/platform/integrations/langsmith.mjs +47 -0
- package/platform/integrations/rho.mjs +145 -0
- package/platform/integrations/site.mjs +75 -0
- package/platform/kits/README.md +7 -0
- package/platform/mcp/research.mjs +64 -0
- package/purpose/checklists/vault-and-tooling-consultancy-setup.md +216 -0
- package/purpose/frameworks/business-discovery-framework-amendments-2026-05-20.md +181 -0
- package/purpose/frameworks/business-discovery-framework.html +938 -0
- package/purpose/frameworks/business-discovery-framework.md +326 -0
- package/purpose/frameworks/idea-map/README.md +74 -0
- package/purpose/frameworks/idea-map/conventions.json +146 -0
- package/purpose/frameworks/idea-map/graph.mjs +182 -0
- package/purpose/frameworks/idea-map/ideamap.mjs +179 -0
- package/purpose/frameworks/idea-map/route.mjs +140 -0
- package/purpose/frameworks/onboarding-handoff-framework.md +269 -0
- package/purpose/frameworks/post-discovery-deliverable-playbook.md +274 -0
- package/purpose/frameworks/product-anatomy/README.md +63 -0
- package/purpose/frameworks/product-anatomy/anatomy.mjs +195 -0
- package/purpose/frameworks/product-anatomy/examples/polity.answers.reasoned.json +11 -0
- package/purpose/frameworks/product-anatomy/examples/polity.json +89 -0
- package/purpose/frameworks/product-anatomy/phases.json +107 -0
- package/purpose/frameworks/product-anatomy/questions.json +74 -0
- package/purpose/kits/validation/README.md +14 -0
- package/purpose/kits/validation/references/references.json +122 -0
- package/purpose/kits/validation/skills/problem-validation/SKILL.md +43 -0
- package/purpose/kits/validation/skills/validation-score/SKILL.md +35 -0
- package/purpose/kits/validation/templates/go-to-market.md +19 -0
- package/purpose/kits/validation/templates/operations-readiness.md +20 -0
- package/purpose/kits/validation/templates/pricing.md +22 -0
- package/purpose/kits/validation/templates/problem-interview.md +36 -0
- package/purpose/kits/validation/templates/problem.md +45 -0
- package/purpose/kits/validation/templates/product-market-fit.md +23 -0
- package/purpose/kits/validation/templates/solution.md +18 -0
- package/purpose/kits/validation/templates/team.md +19 -0
- package/purpose/kits/validation/weights.json +22 -0
- package/purpose/layer.json +53 -0
- package/purpose/references/references.json +324 -0
- package/purpose/skills/ambition-tier/SKILL.md +205 -0
- package/purpose/skills/telos/SKILL.md +52 -0
- package/purpose/strategic-foundation.json +133 -0
- package/purpose/templates/telos-based-smart.md +39 -0
- package/purpose/tooling/integrations.json +48 -0
- package/schema/README.md +61 -0
- package/schema/VERSION +1 -0
- package/schema/account.schema.json +79 -0
- package/schema/add-department.mjs +41 -0
- package/schema/agent-capability.schema.json +94 -0
- package/schema/alignment.schema.json +61 -0
- package/schema/assess-problem.mjs +131 -0
- package/schema/bdd.mjs +56 -0
- package/schema/board.schema.json +101 -0
- package/schema/check-boundary.mjs +54 -0
- package/schema/check-data-model.mjs +170 -0
- package/schema/check-data-packages.mjs +83 -0
- package/schema/check-departments.mjs +45 -0
- package/schema/check-execution.mjs +85 -0
- package/schema/check-governance.mjs +98 -0
- package/schema/check-integrations.mjs +33 -0
- package/schema/check-nextjs-status.mjs +77 -0
- package/schema/check-nouns.mjs +49 -0
- package/schema/check-private.mjs +61 -0
- package/schema/check-provenance.mjs +55 -0
- package/schema/check-publication.mjs +96 -0
- package/schema/check-ready.mjs +89 -0
- package/schema/check-sources.mjs +66 -0
- package/schema/check-team.mjs +94 -0
- package/schema/check-telos.mjs +59 -0
- package/schema/check-validation.mjs +165 -0
- package/schema/check-ventures.mjs +81 -0
- package/schema/check-where-used.mjs +58 -0
- package/schema/data-master.schema.json +14 -0
- package/schema/data-model.json +1258 -0
- package/schema/data-model.schema.json +152 -0
- package/schema/decision-analytics.mjs +77 -0
- package/schema/decision-record.schema.json +290 -0
- package/schema/decision-rights.schema.json +34 -0
- package/schema/decision.schema.json +30 -0
- package/schema/decisions.mjs +321 -0
- package/schema/department-catalog.schema.json +55 -0
- package/schema/department.schema.json +15 -0
- package/schema/departments.mjs +32 -0
- package/schema/docket-eval.mjs +89 -0
- package/schema/docket.mjs +135 -0
- package/schema/eval-suite.schema.json +45 -0
- package/schema/evidence.schema.json +110 -0
- package/schema/examples/migrate/agent.mjs +12 -0
- package/schema/examples/workspace/ventures/studio/accounts/bakery/account.json +18 -0
- package/schema/examples/workspace/ventures/studio/evidence/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/studio/governance/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/studio/knowledge/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/studio/operations/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/studio/print/knowledge/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/studio/print/purpose/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/studio/print/venture.json +37 -0
- package/schema/examples/workspace/ventures/studio/products/brand-care.json +19 -0
- package/schema/examples/workspace/ventures/studio/products/brand-kit.json +23 -0
- package/schema/examples/workspace/ventures/studio/provenance.jsonl +3 -0
- package/schema/examples/workspace/ventures/studio/purpose/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/studio/venture.json +43 -0
- package/schema/examples/workspace/ventures/tandem/accounts/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/tandem/evidence/README.md +3 -0
- package/schema/examples/workspace/ventures/tandem/governance/README.md +3 -0
- package/schema/examples/workspace/ventures/tandem/governance/agreements/dee-fast.md +3 -0
- package/schema/examples/workspace/ventures/tandem/governance/board.json +51 -0
- package/schema/examples/workspace/ventures/tandem/governance/departments/finance/charter.md +5 -0
- package/schema/examples/workspace/ventures/tandem/governance/departments/finance/department.json +5 -0
- package/schema/examples/workspace/ventures/tandem/governance/departments/primary/marketing-and-sales/charter.md +5 -0
- package/schema/examples/workspace/ventures/tandem/governance/departments/primary/marketing-and-sales/department.json +5 -0
- package/schema/examples/workspace/ventures/tandem/governance/exit.json +33 -0
- package/schema/examples/workspace/ventures/tandem/governance/founder-agreement.json +24 -0
- package/schema/examples/workspace/ventures/tandem/governance/founder-agreement.md +3 -0
- package/schema/examples/workspace/ventures/tandem/governance/ownership.json +131 -0
- package/schema/examples/workspace/ventures/tandem/governance/publication-policy.json +171 -0
- package/schema/examples/workspace/ventures/tandem/knowledge/README.md +3 -0
- package/schema/examples/workspace/ventures/tandem/knowledge/research/friends-feedback-2026-08.md +3 -0
- package/schema/examples/workspace/ventures/tandem/knowledge/research/pilot-2026-10.md +3 -0
- package/schema/examples/workspace/ventures/tandem/knowledge/research/problem-interviews-2026-09.md +20 -0
- package/schema/examples/workspace/ventures/tandem/knowledge/sources.json +8 -0
- package/schema/examples/workspace/ventures/tandem/knowledge/where-used.json +13 -0
- package/schema/examples/workspace/ventures/tandem/operations/README.md +3 -0
- package/schema/examples/workspace/ventures/tandem/operations/departments/finance/README.md +5 -0
- package/schema/examples/workspace/ventures/tandem/operations/departments/finance/department.json +5 -0
- package/schema/examples/workspace/ventures/tandem/operations/departments/primary/marketing-and-sales/README.md +5 -0
- package/schema/examples/workspace/ventures/tandem/operations/departments/primary/marketing-and-sales/department.json +5 -0
- package/schema/examples/workspace/ventures/tandem/pillars/brand.md +5 -0
- package/schema/examples/workspace/ventures/tandem/pillars/business.md +5 -0
- package/schema/examples/workspace/ventures/tandem/pillars/product.md +5 -0
- package/schema/examples/workspace/ventures/tandem/products/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/tandem/products/shop-app.json +22 -0
- package/schema/examples/workspace/ventures/tandem/profile.md +5 -0
- package/schema/examples/workspace/ventures/tandem/provenance.jsonl +13 -0
- package/schema/examples/workspace/ventures/tandem/purpose/README.md +3 -0
- package/schema/examples/workspace/ventures/tandem/purpose/telos.json +78 -0
- package/schema/examples/workspace/ventures/tandem/purpose/validation/go-to-market.json +35 -0
- package/schema/examples/workspace/ventures/tandem/purpose/validation/pricing.json +37 -0
- package/schema/examples/workspace/ventures/tandem/purpose/validation/problem.json +74 -0
- package/schema/examples/workspace/ventures/tandem/purpose/validation/product-market-fit.json +66 -0
- package/schema/examples/workspace/ventures/tandem/purpose/validation/solution.json +33 -0
- package/schema/examples/workspace/ventures/tandem/purpose/validation/team.json +52 -0
- package/schema/examples/workspace/ventures/tandem/venture.json +79 -0
- package/schema/examples/workspace/ventures/woodworking/knowledge/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/woodworking/venture.json +21 -0
- package/schema/examples/workspace/workspace.json +8 -0
- package/schema/exit.schema.json +74 -0
- package/schema/foundation.mjs +118 -0
- package/schema/founder-agreement.schema.json +83 -0
- package/schema/gate.mjs +39 -0
- package/schema/handoff.schema.json +239 -0
- package/schema/icp.schema.json +136 -0
- package/schema/idea-graph.schema.json +61 -0
- package/schema/init-venture.mjs +98 -0
- package/schema/integration.schema.json +143 -0
- package/schema/knowledge-sources.schema.json +130 -0
- package/schema/layer.json +46 -0
- package/schema/layer.schema.json +119 -0
- package/schema/load-packages.mjs +26 -0
- package/schema/marketing-sitemap.schema.json +232 -0
- package/schema/migrate-venture.mjs +192 -0
- package/schema/need-now.json +601 -0
- package/schema/need-now.mjs +107 -0
- package/schema/nextjs-status.schema.json +29 -0
- package/schema/ownership.schema.json +282 -0
- package/schema/packages.json +4 -0
- package/schema/packages.mjs +247 -0
- package/schema/payouts.mjs +91 -0
- package/schema/port-venture.mjs +161 -0
- package/schema/product.schema.json +223 -0
- package/schema/provenance-entry.schema.json +154 -0
- package/schema/publication-policy.schema.json +293 -0
- package/schema/raw-source.schema.json +15 -0
- package/schema/reference.schema.json +115 -0
- package/schema/route-aliases.schema.json +25 -0
- package/schema/run-handoff.mjs +51 -0
- package/schema/scaffold/defaults.json +54 -0
- package/schema/site-presence.schema.json +337 -0
- package/schema/strategic-foundation.schema.json +74 -0
- package/schema/stream.schema.json +14 -0
- package/schema/team-plan.schema.json +157 -0
- package/schema/telos.schema.json +197 -0
- package/schema/time-to-ready.mjs +93 -0
- package/schema/upgrade-venture.mjs +129 -0
- package/schema/use-model.mjs +10 -0
- package/schema/validate.py +49 -0
- package/schema/validation-evidence.schema.json +123 -0
- package/schema/validation-go-to-market.schema.json +110 -0
- package/schema/validation-operations-readiness.schema.json +91 -0
- package/schema/validation-pricing.schema.json +114 -0
- package/schema/validation-problem.schema.json +118 -0
- package/schema/validation-product-market-fit.schema.json +135 -0
- package/schema/validation-solution.schema.json +79 -0
- package/schema/validation-team.schema.json +116 -0
- package/schema/venture.schema.json +407 -0
- package/schema/vocab/business-models.json +298 -0
- package/schema/where-used.schema.json +56 -0
- package/schema/workspace.schema.json +38 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: knowledge
|
|
3
|
+
tags: [everything-ecosystem, skills, fidelity-ladders, design-system, audit]
|
|
4
|
+
ai-model: claude-opus-5
|
|
5
|
+
created: 2026-09-09
|
|
6
|
+
source: hybrid
|
|
7
|
+
name: fidelity-ladder-audit
|
|
8
|
+
description: >
|
|
9
|
+
Audit a project's component tree as a set of fidelity ladders — one domain
|
|
10
|
+
object, many renderings ordered by how much of the object each shows — and
|
|
11
|
+
produce the field-projection matrix, kernel, and gap list for each. Use when
|
|
12
|
+
auditing a design system, cataloguing components, reconciling a component
|
|
13
|
+
library against a data model, planning a new surface, or asking "how many
|
|
14
|
+
ways do we render X?" Also use before adding a rendering of an object that
|
|
15
|
+
already has one. Implements [[FIDELITY_LADDERS]]. MANDATORY TRIGGERS: fidelity
|
|
16
|
+
ladder, component bundle, component audit, design system audit, component
|
|
17
|
+
inventory, representation, view mode, kernel, projection matrix, how many
|
|
18
|
+
ways do we render, object model, card variants, component gaps.
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Fidelity Ladder Audit
|
|
22
|
+
|
|
23
|
+
Audits a codebase against [[FIDELITY_LADDERS]]. The census is mechanical; the matrix is not.
|
|
24
|
+
|
|
25
|
+
## What this skill will and will not do
|
|
26
|
+
|
|
27
|
+
It **will** inventory a component tree, propose ladders from naming and prop shapes, and find components that render the same object at the same tier while disagreeing about its fields.
|
|
28
|
+
|
|
29
|
+
It **will not** decide what a component renders. Names and props are evidence, not truth. Every candidate the script emits is a question for a human, and the matrix is always hand-built from reading the components.
|
|
30
|
+
|
|
31
|
+
## Procedure
|
|
32
|
+
|
|
33
|
+
### Step 0 · Ground the session
|
|
34
|
+
|
|
35
|
+
Invoke [[skills/time-awareness/SKILL|time-awareness]]. The audit produces dated artifacts.
|
|
36
|
+
|
|
37
|
+
### Step 1 · Get the object lexicon from the data model, not from intuition
|
|
38
|
+
|
|
39
|
+
The object axis comes from the project's own vocabulary. In order of preference:
|
|
40
|
+
|
|
41
|
+
1. An entity-type enum in the code (`ENTITY_TYPES`, a discriminated union, a table list). This is authoritative — it is what the system already believes its objects are.
|
|
42
|
+
2. `DATA_MODEL_SPEC` headings or table names.
|
|
43
|
+
3. Frequency analysis of domain nouns in the data model, as a fallback.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
grep -rn "ENTITY_TYPES\|EntityType =" <repo>/packages <repo>/apps --include=*.ts | grep -v node_modules
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**If more than one entity-type enum exists, stop and record it.** Competing enums mean the system disagrees with itself about what its objects are, and no ladder built on either one is trustworthy. This is a finding, not an obstacle.
|
|
50
|
+
|
|
51
|
+
### Step 2 · Run the census
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
node ladder-census.mjs <components-dir> --json out.json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
It reports three sections:
|
|
58
|
+
|
|
59
|
+
- **Candidate ladders** — components grouped by object, sorted by fidelity tier, with props and absent rungs.
|
|
60
|
+
- **Object-named, no representation suffix** — named for an object but not declaring a fidelity. Each is a question: a rung that needs renaming, or not a rendering at all?
|
|
61
|
+
- **Representation suffix, no object** — generic primitives, or objects missing from the lexicon.
|
|
62
|
+
|
|
63
|
+
### Step 3 · Re-run with the codebase's own nouns
|
|
64
|
+
|
|
65
|
+
The default lexicon is the *specified* vocabulary. Codebases drift from it, and the drift is where ladders hide. In one audit the largest ladder was invisible on the first pass because the spec says `officeholder` and the components say `Rep`.
|
|
66
|
+
|
|
67
|
+
Scan the third section for recurring nouns the lexicon missed, then re-run:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
node ladder-census.mjs <components-dir> --objects Rep,Post,Event,Vault
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**A ladder found only on the second pass is itself a finding** — it means the component names and the data model use different words for the same object.
|
|
74
|
+
|
|
75
|
+
### Step 4 · Read the top ladders and build the matrix by hand
|
|
76
|
+
|
|
77
|
+
Take the three or four objects with the most rungs. For each, open every rung and record what it actually renders. Then build the matrix from [[FIDELITY_LADDERS]] §4: fields down the side, rungs across the top, cells as full / reduced / promoted / absent.
|
|
78
|
+
|
|
79
|
+
Two things to watch for that the script cannot see:
|
|
80
|
+
|
|
81
|
+
- **Same-tier forks.** Two components at the same rung rendering the same object under different names. Compare their prop lists directly — near-identical shapes with different field names are the signature.
|
|
82
|
+
- **Encoding disagreements.** The same fact carried at different resolutions in different rungs — a boolean in one, a six-value enum in another. The richest encoding is usually the correct one, and the flattened ones are lossy.
|
|
83
|
+
|
|
84
|
+
### Step 5 · Name the kernel
|
|
85
|
+
|
|
86
|
+
For each ladder, the fields present in every rung. The script offers a `kernelCandidate` from prop intersection; treat it as a starting point, since props and rendered fields are not the same thing.
|
|
87
|
+
|
|
88
|
+
Then apply Rule K1: does every rung actually render the whole kernel? A rung that does not is either a defect or proof the kernel is drawn too wide.
|
|
89
|
+
|
|
90
|
+
### Step 6 · Add the machine rungs
|
|
91
|
+
|
|
92
|
+
The census only sees components. Find the non-visual renderings by hand — embed fragments, OG tags, JSON-LD, public API responses — and add them as columns. Per Rule K4 an audit without them is half an audit.
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
ls <repo>/apps/*/src/app/embed <repo>/apps/*/src/app/api 2>/dev/null
|
|
96
|
+
grep -rn "openGraph\|application/ld+json" <repo>/apps --include=*.tsx | grep -v node_modules
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Step 7 · Write the gap list
|
|
100
|
+
|
|
101
|
+
Per object, in this order of severity:
|
|
102
|
+
|
|
103
|
+
1. **Forked rungs** — same object, same tier, two components, disagreeing fields.
|
|
104
|
+
2. **Kernel violations** — a rung missing a kernel field.
|
|
105
|
+
3. **Lossy encodings** — a fact carried at lower resolution than the object supports.
|
|
106
|
+
4. **Missing rungs** — a fidelity the product needs and does not have.
|
|
107
|
+
5. **Naming drift** — components whose names do not state object and fidelity.
|
|
108
|
+
|
|
109
|
+
Missing rungs rank fourth deliberately. An absent rung is a gap; a forked rung is a bug that is already shipping.
|
|
110
|
+
|
|
111
|
+
## Output
|
|
112
|
+
|
|
113
|
+
An audit artifact with, per object: the ladder, the kernel, the projection matrix, and the gap list. Plus one project-level section for cross-cutting findings — competing enums, vocabulary drift, subsystems that implement the method in isolation.
|
|
114
|
+
|
|
115
|
+
File it per the vault's document-placement rule. An audit is a finding, not a contract: `product/research/` while it is a report, `product/spec/` only once it is elevated to a binding ladder contract — and per the authority gate, elevation and relocation are one edit.
|
|
116
|
+
|
|
117
|
+
## Notes
|
|
118
|
+
|
|
119
|
+
- The tier list in the script (page / panel / card / row / glyph / preview) is a default, not a truth. Projects with a genuinely different fidelity vocabulary should edit `TIERS` rather than force their components into these six.
|
|
120
|
+
- `NON_REPRESENTATION` filters infrastructure — filters, providers, shells. When the census looks empty for an object, check whether its components are being filtered out as infrastructure.
|
|
121
|
+
- The script never writes to the audited repo.
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// ladder-census — inventory a component tree and propose fidelity ladders.
|
|
3
|
+
//
|
|
4
|
+
// Usage:
|
|
5
|
+
// node ladder-census.mjs <components-dir> [--objects a,b,c] [--json out.json]
|
|
6
|
+
//
|
|
7
|
+
// Emits, for each domain object in the lexicon, the components that render it,
|
|
8
|
+
// bucketed into fidelity tiers by their representation suffix. Components that
|
|
9
|
+
// name an object but carry no representation suffix are reported separately —
|
|
10
|
+
// they are the ambiguous middle where ladders usually go wrong.
|
|
11
|
+
//
|
|
12
|
+
// This is a *proposal* generator, not an authority. It reads names and prop
|
|
13
|
+
// shapes; it cannot see what a component actually renders. Every candidate it
|
|
14
|
+
// emits is a question for a human, and the field matrix is always hand-built.
|
|
15
|
+
|
|
16
|
+
import { readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
17
|
+
import { join, extname, basename } from "node:path";
|
|
18
|
+
|
|
19
|
+
// ---------------------------------------------------------------- lexicons
|
|
20
|
+
|
|
21
|
+
// Representation suffixes, ordered richest to thinnest. The tier number is the
|
|
22
|
+
// rung on the ladder; L1 is always the canonical full rendering.
|
|
23
|
+
const TIERS = [
|
|
24
|
+
{ tier: 1, name: "page", match: /(Page|View|Screen|Detail|Article|Profile)$/ },
|
|
25
|
+
{ tier: 2, name: "panel", match: /(Panel|Sheet|Modal|Drawer|Dialog|Section|Block)$/ },
|
|
26
|
+
{ tier: 3, name: "card", match: /(Card|Tile|Cell)$/ },
|
|
27
|
+
{ tier: 4, name: "row", match: /(Row|Item|ListItem|Entry|Line)$/ },
|
|
28
|
+
{ tier: 5, name: "glyph", match: /(Chip|Pill|Badge|Tag|Marker|Avatar|Portrait|Dot|Icon)$/ },
|
|
29
|
+
{ tier: 6, name: "preview", match: /(Preview|Tooltip|Hover|Popover|Summary|Snippet)$/ },
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
// Components that are infrastructure, not renderings of a domain object.
|
|
33
|
+
const NON_REPRESENTATION = /(Filters?|Provider|Context|Boundary|Shell|Nav|Menu|Form|Manager|Controls?|Handler|Wrapper|Layout|Skeleton|Loader|Portal|Toggle|Switch|Selector|Picker|Search|Pagination|Breadcrumb)$/;
|
|
34
|
+
|
|
35
|
+
const DEFAULT_OBJECTS = [
|
|
36
|
+
"Officeholder", "Bill", "Address", "Position", "Citation", "Source",
|
|
37
|
+
"Committee", "Chamber", "District", "Person", "Office", "Body", "Vote",
|
|
38
|
+
"Term", "Party", "Election", "Court", "Race", "Measure", "Candidate",
|
|
39
|
+
"Agency", "Jurisdiction",
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
// ---------------------------------------------------------------- arguments
|
|
43
|
+
|
|
44
|
+
const argv = process.argv.slice(2);
|
|
45
|
+
const root = argv.find((a) => !a.startsWith("--"));
|
|
46
|
+
if (!root) {
|
|
47
|
+
console.error("usage: node ladder-census.mjs <components-dir> [--objects a,b] [--json out.json]");
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
const flag = (name) => {
|
|
51
|
+
const i = argv.indexOf(`--${name}`);
|
|
52
|
+
return i === -1 ? null : argv[i + 1];
|
|
53
|
+
};
|
|
54
|
+
const objects = (flag("objects")?.split(",").map((s) => s.trim()).filter(Boolean)) ?? DEFAULT_OBJECTS;
|
|
55
|
+
const jsonOut = flag("json");
|
|
56
|
+
|
|
57
|
+
// ---------------------------------------------------------------- traversal
|
|
58
|
+
|
|
59
|
+
function walk(dir, acc = []) {
|
|
60
|
+
for (const entry of readdirSync(dir)) {
|
|
61
|
+
if (entry === "node_modules" || entry.startsWith(".")) continue;
|
|
62
|
+
const full = join(dir, entry);
|
|
63
|
+
const st = statSync(full);
|
|
64
|
+
if (st.isDirectory()) walk(full, acc);
|
|
65
|
+
else if (extname(entry) === ".tsx" && !/\.(test|spec|stories)\.tsx$/.test(entry)) acc.push(full);
|
|
66
|
+
}
|
|
67
|
+
return acc;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Pull prop names off the component's props type. Deliberately shallow: this is
|
|
71
|
+
// a signal for comparing siblings on one ladder, not a type checker.
|
|
72
|
+
function extractProps(src, componentName) {
|
|
73
|
+
const patterns = [
|
|
74
|
+
new RegExp(`(?:interface|type)\\s+${componentName}Props\\s*=?\\s*\\{([\\s\\S]*?)\\n\\}`),
|
|
75
|
+
/(?:interface|type)\s+Props\s*=?\s*\{([\s\S]*?)\n\}/,
|
|
76
|
+
];
|
|
77
|
+
for (const re of patterns) {
|
|
78
|
+
const m = src.match(re);
|
|
79
|
+
if (!m) continue;
|
|
80
|
+
return [...m[1].matchAll(/^\s*(?:readonly\s+)?([a-zA-Z_][\w]*)\??\s*:/gm)].map((x) => x[1]);
|
|
81
|
+
}
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function classify(name) {
|
|
86
|
+
for (const t of TIERS) if (t.match.test(name)) return t;
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ---------------------------------------------------------------- census
|
|
91
|
+
|
|
92
|
+
const files = walk(root);
|
|
93
|
+
const components = files.map((f) => {
|
|
94
|
+
const name = basename(f, ".tsx");
|
|
95
|
+
const src = readFileSync(f, "utf8");
|
|
96
|
+
return {
|
|
97
|
+
name,
|
|
98
|
+
file: f.replace(root, "").replace(/^\//, ""),
|
|
99
|
+
props: extractProps(src, name),
|
|
100
|
+
lines: src.split("\n").length,
|
|
101
|
+
tier: classify(name),
|
|
102
|
+
infra: NON_REPRESENTATION.test(name),
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const ladders = {};
|
|
107
|
+
const unsuffixed = {};
|
|
108
|
+
|
|
109
|
+
for (const obj of objects) {
|
|
110
|
+
const owned = components.filter((c) => c.name.toLowerCase().includes(obj.toLowerCase()));
|
|
111
|
+
if (!owned.length) continue;
|
|
112
|
+
const rungs = owned.filter((c) => c.tier && !c.infra);
|
|
113
|
+
const loose = owned.filter((c) => !c.tier && !c.infra);
|
|
114
|
+
if (rungs.length) {
|
|
115
|
+
ladders[obj] = rungs
|
|
116
|
+
.sort((a, b) => a.tier.tier - b.tier.tier)
|
|
117
|
+
.map((c) => ({ tier: `L${c.tier.tier}`, kind: c.tier.name, component: c.name, file: c.file, props: c.props }));
|
|
118
|
+
}
|
|
119
|
+
if (loose.length) unsuffixed[obj] = loose.map((c) => ({ component: c.name, file: c.file, props: c.props }));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// A component carrying a representation suffix but matching no object in the
|
|
123
|
+
// lexicon is either a generic primitive or an object the lexicon is missing.
|
|
124
|
+
const unclaimed = components
|
|
125
|
+
.filter((c) => c.tier && !c.infra)
|
|
126
|
+
.filter((c) => !objects.some((o) => c.name.toLowerCase().includes(o.toLowerCase())))
|
|
127
|
+
.map((c) => ({ tier: `L${c.tier.tier}`, component: c.name, file: c.file }));
|
|
128
|
+
|
|
129
|
+
// ---------------------------------------------------------------- shared-field analysis
|
|
130
|
+
|
|
131
|
+
// Where a ladder has two or more rungs, the props common to every rung are the
|
|
132
|
+
// candidate kernel; props on exactly one rung are candidate context fields.
|
|
133
|
+
for (const [obj, rungs] of Object.entries(ladders)) {
|
|
134
|
+
const withProps = rungs.filter((r) => r.props.length);
|
|
135
|
+
if (withProps.length < 2) continue;
|
|
136
|
+
const common = withProps
|
|
137
|
+
.map((r) => new Set(r.props))
|
|
138
|
+
.reduce((a, b) => new Set([...a].filter((x) => b.has(x))));
|
|
139
|
+
ladders[obj].kernelCandidate = [...common];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ---------------------------------------------------------------- report
|
|
143
|
+
|
|
144
|
+
const pad = (s, n) => String(s).padEnd(n);
|
|
145
|
+
const out = [];
|
|
146
|
+
out.push(`ladder census · ${root}`);
|
|
147
|
+
out.push(`${files.length} components scanned · ${Object.keys(ladders).length} candidate ladders\n`);
|
|
148
|
+
|
|
149
|
+
out.push("CANDIDATE LADDERS");
|
|
150
|
+
out.push("-".repeat(72));
|
|
151
|
+
for (const [obj, rungs] of Object.entries(ladders)) {
|
|
152
|
+
out.push(`\n${obj} (${rungs.length} rung${rungs.length > 1 ? "s" : ""})`);
|
|
153
|
+
for (const r of rungs) {
|
|
154
|
+
out.push(` ${pad(r.tier, 4)} ${pad(r.kind, 8)} ${pad(r.component, 30)} ${r.props.length ? r.props.join(", ") : "—"}`);
|
|
155
|
+
}
|
|
156
|
+
if (rungs.kernelCandidate?.length) out.push(` kernel candidate: ${rungs.kernelCandidate.join(", ")}`);
|
|
157
|
+
const present = new Set(rungs.map((r) => r.tier));
|
|
158
|
+
const missing = TIERS.filter((t) => !present.has(`L${t.tier}`)).map((t) => `L${t.tier}/${t.name}`);
|
|
159
|
+
if (missing.length) out.push(` absent rungs: ${missing.join(" ")}`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
out.push(`\n\nOBJECT-NAMED, NO REPRESENTATION SUFFIX`);
|
|
163
|
+
out.push("-".repeat(72));
|
|
164
|
+
out.push("Named for an object but not declaring a fidelity. Each is a question:");
|
|
165
|
+
out.push("is it a rung that should be renamed, or not a rendering at all?\n");
|
|
166
|
+
for (const [obj, list] of Object.entries(unsuffixed)) {
|
|
167
|
+
out.push(`${obj}: ${list.map((c) => c.component).join(", ")}`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
out.push(`\n\nREPRESENTATION SUFFIX, NO OBJECT`);
|
|
171
|
+
out.push("-".repeat(72));
|
|
172
|
+
out.push("Generic primitives, or objects missing from the lexicon.\n");
|
|
173
|
+
out.push(unclaimed.map((c) => `${c.tier} ${c.component}`).join("\n"));
|
|
174
|
+
|
|
175
|
+
console.log(out.join("\n"));
|
|
176
|
+
|
|
177
|
+
if (jsonOut) {
|
|
178
|
+
writeFileSync(jsonOut, JSON.stringify({ root, scanned: files.length, ladders, unsuffixed, unclaimed }, null, 2));
|
|
179
|
+
console.error(`\nwrote ${jsonOut}`);
|
|
180
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: findability
|
|
3
|
+
type: reference
|
|
4
|
+
source: hybrid
|
|
5
|
+
created: 2026-10-14T03:30:00Z
|
|
6
|
+
ai-model: claude-opus-5.5
|
|
7
|
+
description: "Check whether an entity's documents and decisions can be found (SAD v3.0.16 §NEW.26). Free structural inventory at every phase boundary; paid TypeSafe deep pass for domain classification and decision contradictions. Use when the owner says findability, orphans, rediscovery, scattered, discombobulated, vault audit, or at phase boundaries."
|
|
8
|
+
tags: [skill, methodology, findability, registries, rediscovery]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Findability
|
|
12
|
+
|
|
13
|
+
Ratified in [[SAD_SKILL_v3_AMENDMENT_2026-10-13_findability-product-harness-and-repository-structure]] (v3.0.16). Built from an organization campaign.
|
|
14
|
+
|
|
15
|
+
## 1. Structural inventory (free, every phase boundary)
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
ruby -E UTF-8 evidence/skills/findability/inventory.rb <vault>/projects/<entity>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Reports: notes without frontmatter, YAML errors, orphans, governance notes missing `governed-by` or `authority`, authority-gate violations, wholly superseded notes not archived (partly superseded notes are excluded on purpose), and governance notes with lock language but no D- or ADR number. `--json out.json` writes the full rows.
|
|
22
|
+
|
|
23
|
+
## 2. Rediscovery check (every session, SAD PART 4 step 4d)
|
|
24
|
+
|
|
25
|
+
Before creating a decision, ADR, term, source, dependency, skill, contract, risk or open question, search the entity's ledger, ADR register and `_meta/registers/`; cite what exists.
|
|
26
|
+
|
|
27
|
+
## 3. Deep pass (paid, phase boundaries and campaigns)
|
|
28
|
+
|
|
29
|
+
Reference implementation: a private synthesis project (`synth.mjs` classifies notes by domain, product, layer and kind; `decisions.mjs` compares ledger decisions pairwise within a domain). TypeSafe Jev, cached; key from the repo's `.env.local`, never printed. Lessons from the first run:
|
|
30
|
+
- Ask *wholly* versus *partly* superseded; 11 of 12 "superseded" flags were partial.
|
|
31
|
+
- A domain list that misses areas leaves decisions uncompared (27 of 120 in the first run); include company-structure and peer-company domains.
|
|
32
|
+
- Treat results as leads to confirm, not findings.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Findability inventory (SAD v3.0.16 §NEW.26). Free; no model calls.
|
|
2
|
+
# Usage: ruby -E UTF-8 inventory.rb <entity folder> [vault root, default $VAULT_ROOT or the Documents folder] [--json out.json]
|
|
3
|
+
require 'yaml'; require 'date'; require 'json'
|
|
4
|
+
root = File.expand_path(ARGV[0] || abort("usage: inventory.rb <entity folder> [vault root] [--json out]"))
|
|
5
|
+
vault = File.expand_path(ARGV[1] && !ARGV[1].start_with?('--') ? ARGV[1] : ENV['VAULT_ROOT'] || File.join(Dir.home, 'Documents'))
|
|
6
|
+
jout = (i = ARGV.index('--json')) ? ARGV[i + 1] : nil
|
|
7
|
+
files = Dir.glob("#{root}/**/*.md").reject { |f| f.include?('/_archive/') || f.include?('/node_modules/') }
|
|
8
|
+
inbound = Hash.new(0)
|
|
9
|
+
Dir.glob("#{vault}/**/*.md").each do |f|
|
|
10
|
+
next if f.include?('/node_modules/')
|
|
11
|
+
t = (File.read(f, encoding: 'UTF-8') rescue ''); me = File.basename(f, '.md')
|
|
12
|
+
t.scan(/\[\[([^\]|#]+)/) { |m| n = File.basename(m[0].strip); inbound[n] += 1 unless n == me }
|
|
13
|
+
end
|
|
14
|
+
gov = %w[planning planning-note architecture-spec spec research policy]
|
|
15
|
+
lock = /\b(locked|lock\b|decided|in force|ratified)\b/i
|
|
16
|
+
rows = files.map do |f|
|
|
17
|
+
t = File.read(f, encoding: 'UTF-8'); fm = nil; err = false
|
|
18
|
+
if t.start_with?('---')
|
|
19
|
+
begin; fm = YAML.safe_load(t.split(/^---\s*$/, 3)[1], permitted_classes: [Date, Time]) || {}; rescue StandardError; err = true; fm = {}; end
|
|
20
|
+
end
|
|
21
|
+
fm = {} unless fm.is_a?(Hash) || fm.nil?
|
|
22
|
+
rel = f.sub(root + '/', ''); body = t.split(/^---\s*$/, 3)[2] || t
|
|
23
|
+
{ path: rel, folder: File.dirname(rel), type: fm&.dig('type'), authority: fm&.dig('authority'), governed: !!fm&.dig('governed-by'),
|
|
24
|
+
status: [fm&.dig('decision-status'), fm&.dig('status')].compact.join(' '), nofm: fm.nil?, yaml_error: err,
|
|
25
|
+
inbound: inbound[File.basename(f, '.md')], lock_language: !!(body =~ lock), cites_decision: !!(body =~ /\bD-\d{3}\b|ADR-\d{4}/) }
|
|
26
|
+
end
|
|
27
|
+
g = rows.select { |r| gov.include?(r[:type].to_s) }
|
|
28
|
+
checks = {
|
|
29
|
+
'no frontmatter' => rows.select { |r| r[:nofm] },
|
|
30
|
+
'YAML errors' => rows.select { |r| r[:yaml_error] },
|
|
31
|
+
'orphans (no inbound wikilink)' => rows.select { |r| r[:inbound].zero? },
|
|
32
|
+
'governance docs missing governed-by' => g.reject { |r| r[:governed] },
|
|
33
|
+
'governance docs missing authority' => g.reject { |r| r[:authority] },
|
|
34
|
+
'authority gate (architectural+ in research/ or planning/)' => rows.select { |r| %w[constitutional strategic architectural].include?(r[:authority].to_s) && r[:folder] =~ %r{(^|/)(research|planning)(/|$)} },
|
|
35
|
+
'wholly superseded but not archived' => rows.select { |r| r[:status] =~ /\b(superseded|withdrawn)\b/i && r[:status] !~ /in part|partly/i },
|
|
36
|
+
'lock language without a D- or ADR number' => g.select { |r| r[:lock_language] && !r[:cites_decision] && r[:authority].to_s != 'exploratory' },
|
|
37
|
+
}
|
|
38
|
+
puts "Findability inventory: #{root} (#{rows.size} notes)"
|
|
39
|
+
checks.each { |k, v| puts format(' %-58s %d', k, v.size) }
|
|
40
|
+
checks.each { |k, v| next if v.empty? || k.start_with?('orphans'); puts "\n#{k}:"; v.first(15).each { |r| puts " #{r[:path]}" } }
|
|
41
|
+
File.write(jout, JSON.pretty_generate(rows: rows, checks: checks.transform_values { |v| v.map { |r| r[:path] } })) if jout
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: knowledge
|
|
3
|
+
tags: [everything-ecosystem, skills, foreshadowing-audit]
|
|
4
|
+
ai-model: claude
|
|
5
|
+
created: 2026-05-15
|
|
6
|
+
source: hybrid
|
|
7
|
+
name: foreshadowing-audit
|
|
8
|
+
description: >
|
|
9
|
+
Run the V[N] → V[N+1] foreshadowing audit. Verify that V[N] foreshadows
|
|
10
|
+
V[N+1]'s audience and capabilities — anything that will exist later must be
|
|
11
|
+
named or hinted at now, or V[N]'s identity gets revised when V[N+1] ships.
|
|
12
|
+
Also verify brand continuity invariants (I-series) hold across versions.
|
|
13
|
+
Brand-pillar discipline; CMO-sponsored. Per SAD foreshadowing discipline
|
|
14
|
+
(encoded in build-roadmap §19) + version-identity skill.
|
|
15
|
+
MANDATORY TRIGGERS: foreshadowing, foreshadowing audit, V1 to V2, V2 to V3,
|
|
16
|
+
version evolution, audience evolution, brand continuity, brand invariants,
|
|
17
|
+
one persona per version, what does V[N+1] add, version boundary, /foreshadowing-audit.
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Foreshadowing Audit Skill
|
|
21
|
+
|
|
22
|
+
The Brand-pillar discipline that prevents brand whiplash across product versions. Runs at every version boundary.
|
|
23
|
+
|
|
24
|
+
## Why foreshadowing-audit exists
|
|
25
|
+
|
|
26
|
+
V[N] establishes an audience, a persona, a register. V[N+1] expands or shifts. If V[N+1] introduces audience or capabilities V[N] didn't foreshadow at all, existing users experience whiplash: "this isn't the product I signed up for."
|
|
27
|
+
|
|
28
|
+
The discipline: **V[N] must foreshadow V[N+1]'s audience and capabilities.** Anything that will exist later must be named or hinted at now. The brand audit is what catches this.
|
|
29
|
+
|
|
30
|
+
Companion to the [[../version-identity/SKILL|version-identity skill]] (one-new-persona-per-version rule). Together they prevent the two major brand-evolution failure modes:
|
|
31
|
+
|
|
32
|
+
- **Surprise pivot** — V[N+1] introduces a persona V[N] didn't foreshadow → existing audience leaves
|
|
33
|
+
- **Identity drift** — V[N+1] silently changes invariants V[N] established → trust erosion
|
|
34
|
+
|
|
35
|
+
## When to invoke
|
|
36
|
+
|
|
37
|
+
- **Approaching a version boundary** (authoring VERSION_SPEC for V[N+1])
|
|
38
|
+
- **V[N] ship is imminent and V[N+1] articulation has begun** (parallel-track work)
|
|
39
|
+
- **Brand changes are being proposed for an existing version** (e.g., V1.x patches that touch identity)
|
|
40
|
+
- **The user explicitly asks for a foreshadowing audit**
|
|
41
|
+
|
|
42
|
+
## The two audits
|
|
43
|
+
|
|
44
|
+
### Audit 1 — Audience foreshadowing
|
|
45
|
+
|
|
46
|
+
For each new audience V[N+1] introduces:
|
|
47
|
+
|
|
48
|
+
1. **Is this audience visible in V[N]?** Either:
|
|
49
|
+
- Explicitly named (e.g., "V2 is for citizens who want to annotate the wiki")
|
|
50
|
+
- Hinted via affordances (e.g., V1 includes a "save for later" button that hints at the V2 personalization layer)
|
|
51
|
+
- Visible in the wiki / public artifacts (e.g., a roadmap page that shows the version-identities arc)
|
|
52
|
+
2. **If not, what's the foreshadowing gap?** Surface specifically:
|
|
53
|
+
- "V2 introduces X audience. V1 has no mention of X. The closest hint is Y, which doesn't really cover this."
|
|
54
|
+
3. **What can be added to V[N] (or V[N+1] articulation) to close the gap?** Concrete options:
|
|
55
|
+
- Add an affordance to V[N] that hints at X
|
|
56
|
+
- Reword V[N]'s public copy to acknowledge X is coming
|
|
57
|
+
- Explicitly name X in V[N]'s "what's next" / roadmap surfaces
|
|
58
|
+
|
|
59
|
+
### Audit 2 — Invariant verification
|
|
60
|
+
|
|
61
|
+
Brand invariants (I-series; a typical project defines I1–I9) are the things that must hold across versions. For each invariant:
|
|
62
|
+
|
|
63
|
+
1. **Does V[N+1] preserve this invariant?** Check the V[N+1] artifacts (brand identity, voice, key surfaces) against the invariant statement.
|
|
64
|
+
2. **If not, is this a deliberate change?** Either:
|
|
65
|
+
- The invariant needs updating (and the change is documented)
|
|
66
|
+
- V[N+1] needs adjustment to preserve the invariant
|
|
67
|
+
3. **For deliberate changes:** is the change foreshadowed in V[N]? Same audit as Audit 1, applied to invariants rather than audiences.
|
|
68
|
+
|
|
69
|
+
## The invariant pattern (I-series)
|
|
70
|
+
|
|
71
|
+
A brand invariant has the form:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
I1: <Invariant statement>
|
|
75
|
+
- What it means in practice: <concrete description>
|
|
76
|
+
- How V[N] expresses it: <specific surfaces / artifacts>
|
|
77
|
+
- Risk if broken: <what happens to the audience's trust>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Example:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
I3: The product speaks in the user's register, not the institution's.
|
|
84
|
+
- What it means in practice: copy uses second-person + active voice + concrete
|
|
85
|
+
scenarios; doesn't sound like government documentation.
|
|
86
|
+
- How V1 expresses it: every wiki article opens with "When you ___" or
|
|
87
|
+
"Your ___" framing; microcopy in error states is human, not stilted.
|
|
88
|
+
- Risk if broken: The product reads like another corporate website; existing
|
|
89
|
+
audience disengages because the differentiator is the register.
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
V[N+1]'s foreshadowing audit verifies I3 still holds in every V[N+1] surface.
|
|
93
|
+
|
|
94
|
+
## How to run a foreshadowing audit
|
|
95
|
+
|
|
96
|
+
When this skill is loaded, the AI should:
|
|
97
|
+
|
|
98
|
+
### Step 1 — Load the version-identities document
|
|
99
|
+
|
|
100
|
+
Read `<entity>/brand/version-identities*.md` (or equivalent). Identify:
|
|
101
|
+
- V[N]'s declared persona / audience
|
|
102
|
+
- V[N+1]'s declared persona / audience
|
|
103
|
+
- The continuity invariants (I-series)
|
|
104
|
+
|
|
105
|
+
If no version-identities document exists, surface the gap — the audit needs this as input.
|
|
106
|
+
|
|
107
|
+
### Step 2 — Run Audit 1 (audience foreshadowing)
|
|
108
|
+
|
|
109
|
+
For each new audience or capability V[N+1] introduces, walk the visibility check. Produce:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
Audience Foreshadowing Audit · V[N] → V[N+1]
|
|
113
|
+
|
|
114
|
+
| V[N+1] addition | Foreshadowed in V[N]? | Gap | Proposed fix |
|
|
115
|
+
|---|---|---|---|
|
|
116
|
+
| <addition 1> | ✓ / ↺ / ✗ | <if not, what's missing> | <concrete option> |
|
|
117
|
+
| ...
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Step 3 — Run Audit 2 (invariant verification)
|
|
121
|
+
|
|
122
|
+
For each I-series invariant, walk the preservation check. Produce:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
Invariant Verification · V[N+1]
|
|
126
|
+
|
|
127
|
+
| Invariant | Preserved in V[N+1]? | Notes | Action |
|
|
128
|
+
|---|---|---|---|
|
|
129
|
+
| I1: <statement> | ✓ / ↺ / ✗ | <specific evidence or gap> | <action if needed> |
|
|
130
|
+
| ...
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Step 4 — Surface the audit results
|
|
134
|
+
|
|
135
|
+
Walk the operator through:
|
|
136
|
+
- Which audiences need additional foreshadowing in V[N]
|
|
137
|
+
- Which invariants are at risk in V[N+1]
|
|
138
|
+
- Which gaps can be closed before V[N] ships (vs. which require V[N+1] adjustment)
|
|
139
|
+
|
|
140
|
+
### Step 5 — Update artifacts
|
|
141
|
+
|
|
142
|
+
For each accepted fix:
|
|
143
|
+
- Update V[N] artifacts (if foreshadowing-by-adding-to-V[N])
|
|
144
|
+
- Update V[N+1] artifacts (if adjusting V[N+1])
|
|
145
|
+
- Update the version-identities document to reflect the audit
|
|
146
|
+
- Update the brand foreshadowing inventory
|
|
147
|
+
|
|
148
|
+
### Step 6 — Update the per-project orchestration HTML
|
|
149
|
+
|
|
150
|
+
Per [[../../_ideas/build-roadmap-and-html-orchestration-2026-05-12|§32]], surface the audit results in the brand-pillar deliverables section of the orchestration HTML.
|
|
151
|
+
|
|
152
|
+
## Posture
|
|
153
|
+
|
|
154
|
+
Foreshadowing-audit runs in **office-hours mode**. The work is convergent (verifying invariants, finding gaps); sharp framing is appropriate.
|
|
155
|
+
|
|
156
|
+
## What foreshadowing-audit is NOT
|
|
157
|
+
|
|
158
|
+
- **Not a one-shot.** Audits run at every version boundary and whenever V[N+1] articulation surfaces a major change.
|
|
159
|
+
- **Not a substitute for brand discipline.** The audit catches drift; it doesn't author the version-identities document or the invariants. Those are upstream.
|
|
160
|
+
- **Not a Product-pillar check.** It's Brand-pillar work. Product-pillar capability changes that don't affect brand identity / persona / audience don't trigger it.
|
|
161
|
+
|
|
162
|
+
## Relationship to other skills
|
|
163
|
+
|
|
164
|
+
- [[../version-identity/SKILL|version-identity]] — produces the version-identities document this audit reads
|
|
165
|
+
- [[../brand-pillar/SKILL|brand-pillar]] — auto-loads when brand work surfaces; foreshadowing-audit is one of its workflows
|
|
166
|
+
- [[../articulation-closure/SKILL|articulation-closure]] — V[N+1]'s articulation closure should include a passed foreshadowing audit before Phase 2 begins
|
|
167
|
+
|
|
168
|
+
## Backfill / missing assets
|
|
169
|
+
|
|
170
|
+
Follow `operations/skills/_patterns/gate-backfill.md`. Skill-specific notes:
|
|
171
|
+
|
|
172
|
+
1. **Detect** — V[N+1]+ capabilities vs foreshadowed / gap / N/A on shipped V[N].
|
|
173
|
+
2. **Triage** — brand-discontinuity on shipping surfaces = blocker; pure V[N+1]
|
|
174
|
+
gaps = queued with version trigger.
|
|
175
|
+
3. **Order** — audit shipped affordances first; patch foreshadowing only where
|
|
176
|
+
cheap; else record discontinuity + brand decision.
|
|
177
|
+
4. **Freeze** — do not market or UI-promise red V[N+1] capabilities without a plan.
|
|
178
|
+
5. **Exit** — audit grid exists; red cells have fix or recorded brand decision.
|
|
179
|
+
|
|
180
|
+
## Status
|
|
181
|
+
|
|
182
|
+
- **2026-05-14:** Initial authoring per build-roadmap §19 foreshadowing discipline.
|
|
183
|
+
- **2026-07-26:** Backfill / missing-assets recovery mode added.
|