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,157 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "team-plan.schema.json",
|
|
4
|
+
"title": "Team plan",
|
|
5
|
+
"description": "Who the venture needs, agent or person, when, with what authority, and where a human stays in the loop (EE-029), at <venture>/operations/team-plan.json. Tasks cite the agent capability register; recruiting briefs say what each open person role is for.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"venture",
|
|
9
|
+
"roles"
|
|
10
|
+
],
|
|
11
|
+
"additionalProperties": false,
|
|
12
|
+
"properties": {
|
|
13
|
+
"venture": {
|
|
14
|
+
"type": "string"
|
|
15
|
+
},
|
|
16
|
+
"updated": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"format": "date"
|
|
19
|
+
},
|
|
20
|
+
"note": {
|
|
21
|
+
"type": "string"
|
|
22
|
+
},
|
|
23
|
+
"roles": {
|
|
24
|
+
"type": "array",
|
|
25
|
+
"minItems": 1,
|
|
26
|
+
"items": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"required": [
|
|
29
|
+
"id",
|
|
30
|
+
"occupant",
|
|
31
|
+
"needed_by",
|
|
32
|
+
"status"
|
|
33
|
+
],
|
|
34
|
+
"additionalProperties": false,
|
|
35
|
+
"properties": {
|
|
36
|
+
"id": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "A role id from the role registry, or the venture's own"
|
|
39
|
+
},
|
|
40
|
+
"name": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"description": "Required for a role not in the registry"
|
|
43
|
+
},
|
|
44
|
+
"occupant": {
|
|
45
|
+
"enum": [
|
|
46
|
+
"agent",
|
|
47
|
+
"person"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"needed_by": {
|
|
51
|
+
"enum": [
|
|
52
|
+
"discovery",
|
|
53
|
+
"validation",
|
|
54
|
+
"beachhead",
|
|
55
|
+
"scale",
|
|
56
|
+
"platform"
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
"status": {
|
|
60
|
+
"enum": [
|
|
61
|
+
"filled",
|
|
62
|
+
"open",
|
|
63
|
+
"planned"
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
"why": {
|
|
67
|
+
"type": "string"
|
|
68
|
+
},
|
|
69
|
+
"authority": {
|
|
70
|
+
"type": "array",
|
|
71
|
+
"items": {
|
|
72
|
+
"type": "string"
|
|
73
|
+
},
|
|
74
|
+
"description": "Decision classes delegated to this role"
|
|
75
|
+
},
|
|
76
|
+
"tasks": {
|
|
77
|
+
"type": "array",
|
|
78
|
+
"items": {
|
|
79
|
+
"type": "object",
|
|
80
|
+
"required": [
|
|
81
|
+
"capability"
|
|
82
|
+
],
|
|
83
|
+
"additionalProperties": false,
|
|
84
|
+
"properties": {
|
|
85
|
+
"capability": {
|
|
86
|
+
"type": "string"
|
|
87
|
+
},
|
|
88
|
+
"human_loop": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"description": "The person role that decides, reviews or does the part agents cannot"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"routes": {
|
|
96
|
+
"type": "object",
|
|
97
|
+
"additionalProperties": false,
|
|
98
|
+
"description": "The routes this role may reach (robots, EE-032), as globs over routes such as purpose/** or purpose/product/*. Left out, the role may reach every route; gates still apply. When given, read defaults to every route and write to none.",
|
|
99
|
+
"properties": {
|
|
100
|
+
"read": {
|
|
101
|
+
"type": "array",
|
|
102
|
+
"items": {
|
|
103
|
+
"type": "string"
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"write": {
|
|
107
|
+
"type": "array",
|
|
108
|
+
"items": {
|
|
109
|
+
"type": "string"
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"recruiting": {
|
|
118
|
+
"type": "array",
|
|
119
|
+
"items": {
|
|
120
|
+
"type": "object",
|
|
121
|
+
"required": [
|
|
122
|
+
"role",
|
|
123
|
+
"brief"
|
|
124
|
+
],
|
|
125
|
+
"additionalProperties": false,
|
|
126
|
+
"properties": {
|
|
127
|
+
"role": {
|
|
128
|
+
"type": "string"
|
|
129
|
+
},
|
|
130
|
+
"kind": {
|
|
131
|
+
"enum": [
|
|
132
|
+
"cofounder",
|
|
133
|
+
"hire",
|
|
134
|
+
"contractor",
|
|
135
|
+
"advisor",
|
|
136
|
+
"investor"
|
|
137
|
+
]
|
|
138
|
+
},
|
|
139
|
+
"brief": {
|
|
140
|
+
"type": "string",
|
|
141
|
+
"description": "A recruiting brief, relative to the venture folder"
|
|
142
|
+
},
|
|
143
|
+
"channels": {
|
|
144
|
+
"type": "array",
|
|
145
|
+
"items": {
|
|
146
|
+
"type": "string"
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
"assisted_by": {
|
|
150
|
+
"type": "string",
|
|
151
|
+
"description": "The agent role that drafts, searches and screens"
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "telos.schema.json",
|
|
4
|
+
"title": "Telos",
|
|
5
|
+
"description": "The end a venture exists to reach, at <venture>/purpose/telos.json (EE-023): start with the end. It states the end state, how anyone would know it was reached (measures), what the owners intend to happen when it is reached (owner outcome), and, for each phase of the Succession Matrix, the exit criteria that must be true to leave it, each serving at least one measure. Other layers read it instead of asking again: the governance layer's exit.json prefers the owner outcome's path, and MAD's governance tier takes its success measure from the primary measure. schema/check-telos.mjs checks it. Written by the owner; an agent may draft it but not settle it.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"statement",
|
|
9
|
+
"end_state",
|
|
10
|
+
"measures",
|
|
11
|
+
"owner_outcome"
|
|
12
|
+
],
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"properties": {
|
|
15
|
+
"statement": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"description": "The end, in one sentence: what the venture is for when it has done its job"
|
|
18
|
+
},
|
|
19
|
+
"end_state": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "What is true in the world when the end is reached"
|
|
22
|
+
},
|
|
23
|
+
"horizon": {
|
|
24
|
+
"type": [
|
|
25
|
+
"integer",
|
|
26
|
+
"string"
|
|
27
|
+
],
|
|
28
|
+
"description": "The year the end should be reached by, or 'open'"
|
|
29
|
+
},
|
|
30
|
+
"measures": {
|
|
31
|
+
"type": "array",
|
|
32
|
+
"minItems": 1,
|
|
33
|
+
"items": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"required": [
|
|
36
|
+
"id",
|
|
37
|
+
"statement",
|
|
38
|
+
"kind"
|
|
39
|
+
],
|
|
40
|
+
"additionalProperties": false,
|
|
41
|
+
"properties": {
|
|
42
|
+
"id": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"pattern": "^[a-z0-9-]+$"
|
|
45
|
+
},
|
|
46
|
+
"statement": {
|
|
47
|
+
"type": "string"
|
|
48
|
+
},
|
|
49
|
+
"target": {
|
|
50
|
+
"type": "string"
|
|
51
|
+
},
|
|
52
|
+
"kind": {
|
|
53
|
+
"enum": [
|
|
54
|
+
"revenue",
|
|
55
|
+
"usage_or_adoption",
|
|
56
|
+
"cost_or_time_saved",
|
|
57
|
+
"compliance_met",
|
|
58
|
+
"learning",
|
|
59
|
+
"flow_and_lead_time",
|
|
60
|
+
"impact"
|
|
61
|
+
],
|
|
62
|
+
"description": "The kind of measure; the first six match MAD's success_measure answers, impact is a change in the world beyond the venture"
|
|
63
|
+
},
|
|
64
|
+
"primary": {
|
|
65
|
+
"type": "boolean",
|
|
66
|
+
"description": "Exactly one measure is primary"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"owner_outcome": {
|
|
72
|
+
"type": "object",
|
|
73
|
+
"required": [
|
|
74
|
+
"path"
|
|
75
|
+
],
|
|
76
|
+
"additionalProperties": false,
|
|
77
|
+
"properties": {
|
|
78
|
+
"path": {
|
|
79
|
+
"enum": [
|
|
80
|
+
"acquisition",
|
|
81
|
+
"ipo",
|
|
82
|
+
"secondary-sale",
|
|
83
|
+
"merger",
|
|
84
|
+
"management-buyout",
|
|
85
|
+
"wind-down",
|
|
86
|
+
"hold"
|
|
87
|
+
],
|
|
88
|
+
"description": "What the owners intend to happen once the end is reached; hold means they keep it"
|
|
89
|
+
},
|
|
90
|
+
"why": {
|
|
91
|
+
"type": "string"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"phases": {
|
|
96
|
+
"type": "array",
|
|
97
|
+
"items": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"required": [
|
|
100
|
+
"phase",
|
|
101
|
+
"exit_criteria"
|
|
102
|
+
],
|
|
103
|
+
"additionalProperties": false,
|
|
104
|
+
"properties": {
|
|
105
|
+
"phase": {
|
|
106
|
+
"enum": [
|
|
107
|
+
"discovery",
|
|
108
|
+
"validation",
|
|
109
|
+
"beachhead",
|
|
110
|
+
"scale",
|
|
111
|
+
"platform"
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
"exit_criteria": {
|
|
115
|
+
"type": "array",
|
|
116
|
+
"minItems": 1,
|
|
117
|
+
"items": {
|
|
118
|
+
"type": "object",
|
|
119
|
+
"required": [
|
|
120
|
+
"id",
|
|
121
|
+
"statement",
|
|
122
|
+
"serves"
|
|
123
|
+
],
|
|
124
|
+
"additionalProperties": false,
|
|
125
|
+
"properties": {
|
|
126
|
+
"id": {
|
|
127
|
+
"type": "string",
|
|
128
|
+
"pattern": "^[a-z0-9-]+$"
|
|
129
|
+
},
|
|
130
|
+
"statement": {
|
|
131
|
+
"type": "string"
|
|
132
|
+
},
|
|
133
|
+
"serves": {
|
|
134
|
+
"type": "array",
|
|
135
|
+
"minItems": 1,
|
|
136
|
+
"items": {
|
|
137
|
+
"type": "string"
|
|
138
|
+
},
|
|
139
|
+
"description": "Measure ids this criterion moves the venture toward"
|
|
140
|
+
},
|
|
141
|
+
"evidence": {
|
|
142
|
+
"type": "string",
|
|
143
|
+
"description": "How it is shown: a check command, an evidence record, or a metric"
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
"description": "Per phase, what must be true to leave it; refines that phase's generic gate in purpose/frameworks/product-anatomy/phases.json for this venture"
|
|
151
|
+
},
|
|
152
|
+
"steering": {
|
|
153
|
+
"type": "object",
|
|
154
|
+
"additionalProperties": false,
|
|
155
|
+
"description": "How the venture decides to start, keep going or stop, when it reviews that, and what happens when evidence says the direction is wrong (EE-040; MAD's governance tier reads these as go_decision, review_cadence and change_of_direction). Who may make each call is in the decision rights: continue-or-stop and change-direction.",
|
|
156
|
+
"properties": {
|
|
157
|
+
"go_decision": {
|
|
158
|
+
"enum": [
|
|
159
|
+
"test-hypotheses-first",
|
|
160
|
+
"business-case-upfront",
|
|
161
|
+
"owner-judgment",
|
|
162
|
+
"last-responsible-moment",
|
|
163
|
+
"other"
|
|
164
|
+
],
|
|
165
|
+
"description": "test-hypotheses-first: assumptions are written down and tested with real people before committing. business-case-upfront: a case is approved before work starts. owner-judgment: the owner decides as they go. last-responsible-moment: commitments wait until delay costs more than deciding."
|
|
166
|
+
},
|
|
167
|
+
"review": {
|
|
168
|
+
"enum": [
|
|
169
|
+
"per-experiment",
|
|
170
|
+
"per-release",
|
|
171
|
+
"fixed-period",
|
|
172
|
+
"continuous",
|
|
173
|
+
"none"
|
|
174
|
+
],
|
|
175
|
+
"description": "When the decision to continue is reviewed: after each experiment or customer test, at each release or milestone, on a calendar, continuously from watched measures, or never formally"
|
|
176
|
+
},
|
|
177
|
+
"review_period": {
|
|
178
|
+
"type": "string",
|
|
179
|
+
"description": "For fixed-period: the period, such as quarterly"
|
|
180
|
+
},
|
|
181
|
+
"change_of_direction": {
|
|
182
|
+
"enum": [
|
|
183
|
+
"pivot-on-evidence",
|
|
184
|
+
"formal-change-control",
|
|
185
|
+
"owner-decides",
|
|
186
|
+
"public-proposal",
|
|
187
|
+
"other"
|
|
188
|
+
],
|
|
189
|
+
"description": "pivot-on-evidence: changing the product, customer or model is expected and planned for. formal-change-control: a change request the deciders approve or reject. owner-decides: the owner adjusts as they see fit. public-proposal: anyone proposes in public and maintainers decide by a published rule."
|
|
190
|
+
},
|
|
191
|
+
"note": {
|
|
192
|
+
"type": "string"
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// Time to running, and time to ready per layer and per MAD tier (the telos's Option B measure).
|
|
2
|
+
//
|
|
3
|
+
// running: the venture is operating when its core promise is written, a product is live with at
|
|
4
|
+
// least one account, and the next phase's exit criteria exist in the telos.
|
|
5
|
+
// The date is the latest of the dates those records first appeared.
|
|
6
|
+
// layer ready: every record the need-now score suggests for the current phase exists in that
|
|
7
|
+
// layer; the date is when the last of them first appeared. A layer still missing one is not
|
|
8
|
+
// ready, and the missing records are listed.
|
|
9
|
+
// tier ready: the operations-readiness record's ready_on per MAD tier.
|
|
10
|
+
// A record's date is when git first saw the file, else the file's own updated or opened date.
|
|
11
|
+
//
|
|
12
|
+
// node schema/time-to-ready.mjs <venture dir> [--json]
|
|
13
|
+
|
|
14
|
+
import { execFileSync } from "node:child_process";
|
|
15
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
16
|
+
import { join, dirname } from "node:path";
|
|
17
|
+
import { needNow } from "./need-now.mjs";
|
|
18
|
+
|
|
19
|
+
const load = (p) => JSON.parse(readFileSync(p, "utf8"));
|
|
20
|
+
const day = (d) => d ? d.slice(0, 10) : null;
|
|
21
|
+
const days = (a, b) => a && b ? Math.round((new Date(b) - new Date(a)) / 864e5) : null;
|
|
22
|
+
|
|
23
|
+
function firstSeen(file) {
|
|
24
|
+
try {
|
|
25
|
+
const out = execFileSync("git", ["log", "--diff-filter=A", "--follow", "--format=%as", "--", file], { cwd: dirname(file), encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim().split("\n").filter(Boolean);
|
|
26
|
+
if (out.length) return out[out.length - 1];
|
|
27
|
+
} catch {}
|
|
28
|
+
try { const j = load(file); if (j.updated || j.opened) return day(j.updated ?? j.opened); } catch {}
|
|
29
|
+
return day(statSync(file).mtime.toISOString());
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const files = (d, base = d) => existsSync(d) ? readdirSync(d, { withFileTypes: true }).flatMap((e) =>
|
|
33
|
+
e.isDirectory() ? files(join(d, e.name), base) : [join(d, e.name).slice(base.length + 1)]) : [];
|
|
34
|
+
const glob = (g) => new RegExp("^" + g.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*\//g, "\0").replace(/\*/g, "[^/]*").replace(/\0/g, "(?:[^/]+/)*") + "$");
|
|
35
|
+
|
|
36
|
+
export function timeToReady(dir) {
|
|
37
|
+
const repo = new URL("..", import.meta.url).pathname;
|
|
38
|
+
const model = load(join(repo, "schema/data-model.json"));
|
|
39
|
+
const v = load(join(dir, "venture.json"));
|
|
40
|
+
const start = day(v.opened) ?? firstSeen(join(dir, "venture.json"));
|
|
41
|
+
const here = files(dir);
|
|
42
|
+
const where = (type) => {
|
|
43
|
+
const rels = (model.records.find((r) => r.id === type)?.paths ?? []).filter((p) => p.startsWith("instance/**/")).map((p) => p.slice("instance/**/".length));
|
|
44
|
+
return here.filter((x) => rels.some((g) => glob(g).test(x)));
|
|
45
|
+
};
|
|
46
|
+
const seen = (type) => { const fs = where(type); return fs.length ? fs.map((f) => firstSeen(join(dir, f))).sort()[0] : null; };
|
|
47
|
+
|
|
48
|
+
// Running.
|
|
49
|
+
const nn = needNow(dir);
|
|
50
|
+
const products = where("product").map((f) => ({ f, p: load(join(dir, f)) }));
|
|
51
|
+
const offered = products.filter(({ p }) => p.status === "live");
|
|
52
|
+
const telosFile = where("telos")[0];
|
|
53
|
+
const telos = telosFile ? load(join(dir, telosFile)) : null;
|
|
54
|
+
const conditions = {
|
|
55
|
+
promise: v.core?.promise ? firstSeen(join(dir, "venture.json")) : null,
|
|
56
|
+
product_offered: offered.length ? offered.map(({ f }) => firstSeen(join(dir, f))).sort()[0] : null,
|
|
57
|
+
first_account: seen("account"),
|
|
58
|
+
next_exit_criteria: nn.next && telos?.phases?.some((p) => p.phase === nn.next) ? firstSeen(join(dir, telosFile)) : null,
|
|
59
|
+
};
|
|
60
|
+
const missing = Object.entries(conditions).filter(([, d]) => !d).map(([k]) => k);
|
|
61
|
+
const runningOn = missing.length ? null : Object.values(conditions).sort().at(-1);
|
|
62
|
+
|
|
63
|
+
// Layers.
|
|
64
|
+
const layers = {};
|
|
65
|
+
for (const row of nn.rows.filter((r) => r.status === "held" || r.status === "suggest now")) {
|
|
66
|
+
const l = row.layer ?? "system";
|
|
67
|
+
layers[l] ??= { dates: [], missing: [] };
|
|
68
|
+
const d = seen(row.type);
|
|
69
|
+
if (d) layers[l].dates.push(d); else layers[l].missing.push(row.type);
|
|
70
|
+
}
|
|
71
|
+
const layerRows = Object.entries(layers).map(([layer, x]) => {
|
|
72
|
+
const on = x.missing.length ? null : x.dates.sort().at(-1) ?? null;
|
|
73
|
+
return { layer, ready_on: on, days: days(start, on), missing: x.missing };
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// MAD tiers.
|
|
77
|
+
const opsFile = where("validation-operations-readiness")[0];
|
|
78
|
+
const tiers = opsFile ? load(join(dir, opsFile)).tiers.map((t) => ({ tier: t.tier, ready_on: t.ready_on ?? null, days: days(start, t.ready_on) })) : [];
|
|
79
|
+
|
|
80
|
+
return { venture: v.id, phase: nn.phase, started: start, running: { on: runningOn, days: days(start, runningOn), missing, conditions }, layers: layerRows, tiers };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
84
|
+
const dir = process.argv[2];
|
|
85
|
+
if (!dir || !existsSync(join(dir, "venture.json"))) { console.error("usage: node schema/time-to-ready.mjs <venture dir> [--json]"); process.exit(2); }
|
|
86
|
+
const r = timeToReady(dir);
|
|
87
|
+
if (process.argv.includes("--json")) { console.log(JSON.stringify(r, null, 2)); process.exit(0); }
|
|
88
|
+
console.log(`${r.venture}: started ${r.started}, phase ${r.phase}`);
|
|
89
|
+
console.log(r.running.on ? `running since ${r.running.on} (${r.running.days} days to running)` : `not running yet: missing ${r.running.missing.join(", ")}`);
|
|
90
|
+
console.log("\nlayer ready (for what the current phase needs)");
|
|
91
|
+
for (const l of r.layers) console.log(` ${l.layer.padEnd(12)} ${l.ready_on ? `${l.ready_on} (${l.days} days)` : `not ready: ${l.missing.join(", ")}`}`);
|
|
92
|
+
if (r.tiers.length) { console.log("\nMAD tier ready"); for (const t of r.tiers) console.log(` ${t.tier.padEnd(22)} ${t.ready_on ? `${t.ready_on} (${t.days} days)` : "not ready"}`); }
|
|
93
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// naive upgrade: moves one venture onto the next Naive layout, here the package folder layout
|
|
3
|
+
// (EE-070), like next upgrade and its codemods (EE-076). Files move with git mv when git tracks
|
|
4
|
+
// them, wherever the venture's repository is, and with a plain rename when it does not.
|
|
5
|
+
// Provenance is appended, never rewritten: each move is a new line, and the set of moves
|
|
6
|
+
// is one release under .release/. Old routes keep resolving through interface/route-aliases.json.
|
|
7
|
+
//
|
|
8
|
+
// node schema/upgrade-venture.mjs <venture dir>
|
|
9
|
+
|
|
10
|
+
import { execSync } from "node:child_process";
|
|
11
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
12
|
+
import { dirname, join } from "node:path";
|
|
13
|
+
import { record } from "../interface/provenance.mjs";
|
|
14
|
+
|
|
15
|
+
const dir = process.argv[2];
|
|
16
|
+
if (!dir || !existsSync(join(dir, "venture.json"))) {
|
|
17
|
+
console.error("usage: node schema/upgrade-venture.mjs <venture dir>");
|
|
18
|
+
process.exit(2);
|
|
19
|
+
}
|
|
20
|
+
const load = (p) => JSON.parse(readFileSync(p, "utf8"));
|
|
21
|
+
const moved = [];
|
|
22
|
+
const escalated = [];
|
|
23
|
+
|
|
24
|
+
function mv(fromRel, toRel) {
|
|
25
|
+
const from = join(dir, fromRel), to = join(dir, toRel);
|
|
26
|
+
if (!existsSync(from)) return;
|
|
27
|
+
if (existsSync(to)) { console.error(`${toRel} already exists`); process.exit(1); }
|
|
28
|
+
mkdirSync(dirname(to), { recursive: true });
|
|
29
|
+
try { execSync(`git mv ${JSON.stringify(from)} ${JSON.stringify(to)}`, { cwd: dir, stdio: "pipe" }); }
|
|
30
|
+
catch { renameSync(from, to); }
|
|
31
|
+
moved.push([fromRel, toRel]);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// A decision file infers its target from the folder it sits in. Stamp that path before the
|
|
35
|
+
// file moves, so the decision still points at the same record.
|
|
36
|
+
function stampDecisions(folder) {
|
|
37
|
+
const d = join(dir, folder);
|
|
38
|
+
if (!existsSync(d)) return;
|
|
39
|
+
for (const f of readdirSync(d).filter((x) => x.endsWith(".decision.json"))) {
|
|
40
|
+
const path = join(d, f);
|
|
41
|
+
const rec = load(path);
|
|
42
|
+
if (rec.decides?.path) continue;
|
|
43
|
+
const at = folder.split("/").slice(0, -1).join("/");
|
|
44
|
+
const base = f.split(".")[0];
|
|
45
|
+
rec.decides = { ...(rec.decides ?? {}), path: at ? `${at}/${base}.json` : `${base}.json` };
|
|
46
|
+
writeFileSync(path, JSON.stringify(rec, null, 2) + "\n");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const pairs = [
|
|
51
|
+
["purpose/validation/problem.json", "foundation/problem.json"],
|
|
52
|
+
["purpose/icp.json", "foundation/icp.json"],
|
|
53
|
+
["purpose/alignment.json", "foundation/alignment.json"],
|
|
54
|
+
["purpose/telos.draft.md", "foundation/telos.draft.md"],
|
|
55
|
+
["purpose/validation/solution.json", "validation/solution.json"],
|
|
56
|
+
["purpose/validation/go-to-market.json", "validation/go-to-market.json"],
|
|
57
|
+
["operations/team-plan.json", "people/team-plan.json"],
|
|
58
|
+
["pillars/brand.md", "marketing/brand.md"],
|
|
59
|
+
// A venture made since init writes a root AGENTS.md keeps it; the old README becomes the knowledge layout.
|
|
60
|
+
["knowledge/README.md", existsSync(join(dir, "AGENTS.md")) ? "knowledge/AGENTS.md" : "AGENTS.md"],
|
|
61
|
+
["purpose/anatomy.answers.reasoned.json", "product/anatomy.answers.reasoned.json"],
|
|
62
|
+
["purpose/anatomy.matrix.md", "product/anatomy.matrix.md"],
|
|
63
|
+
];
|
|
64
|
+
for (const [a, b] of pairs) mv(a, b);
|
|
65
|
+
|
|
66
|
+
const products = existsSync(join(dir, "products")) ? readdirSync(join(dir, "products")).filter((f) => f.endsWith(".json")) : [];
|
|
67
|
+
for (const f of products) mv(`products/${f}`, `product/${f}`);
|
|
68
|
+
|
|
69
|
+
const anatomy = existsSync(join(dir, "purpose/anatomy")) ? readdirSync(join(dir, "purpose/anatomy")).filter((f) => f.endsWith(".json")) : [];
|
|
70
|
+
for (const f of anatomy) mv(`purpose/anatomy/${f}`, `product/anatomy/${f}`);
|
|
71
|
+
|
|
72
|
+
for (const folder of ["purpose/decisions", "purpose/anatomy/decisions", "operations/decisions"]) {
|
|
73
|
+
stampDecisions(folder);
|
|
74
|
+
const d = join(dir, folder);
|
|
75
|
+
if (!existsSync(d)) continue;
|
|
76
|
+
for (const f of readdirSync(d).filter((x) => x.endsWith(".decision.json"))) mv(`${folder}/${f}`, `decisions/${f}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (const f of ["product.md", "business.md"]) {
|
|
80
|
+
if (existsSync(join(dir, "pillars", f))) {
|
|
81
|
+
mv(`pillars/${f}`, `_private/pillars/${f}`);
|
|
82
|
+
escalated.push(`${f.replace(".md", "")} pillar: the brief names a home only for brand (marketing/). Archived at _private/pillars/${f} rather than guessed.`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const research = join(dir, "purpose/research");
|
|
86
|
+
if (existsSync(research)) {
|
|
87
|
+
for (const f of readdirSync(research)) {
|
|
88
|
+
mv(`purpose/research/${f}`, `_private/research/${f}`);
|
|
89
|
+
escalated.push(`purpose/research/${f}: no package home in the route table. Archived at _private/research/${f}.`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function removeEmpty(p) {
|
|
94
|
+
if (!existsSync(p)) return;
|
|
95
|
+
for (const e of readdirSync(p, { withFileTypes: true })) if (e.isDirectory()) removeEmpty(join(p, e.name));
|
|
96
|
+
if (readdirSync(p).length === 0) rmSync(p, { recursive: true });
|
|
97
|
+
}
|
|
98
|
+
for (const gone of ["purpose", "pillars", "knowledge", "products"]) removeEmpty(join(dir, gone));
|
|
99
|
+
|
|
100
|
+
const policy = join(dir, "governance/publication-policy.json");
|
|
101
|
+
if (existsSync(policy)) {
|
|
102
|
+
const text = readFileSync(policy, "utf8");
|
|
103
|
+
if (text.includes("pillars/brand.md")) writeFileSync(policy, text.replaceAll("pillars/brand.md", "marketing/brand.md"));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
for (const sub of ["raw/dump", "raw/sources", "ideas", "finance", "customers", "investors", "money", "public"]) {
|
|
107
|
+
const p = join(dir, sub);
|
|
108
|
+
if (!existsSync(p)) { mkdirSync(p, { recursive: true }); writeFileSync(join(p, ".gitkeep"), ""); }
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const release = {
|
|
112
|
+
version: 1,
|
|
113
|
+
at: new Date().toISOString().replace(/\.\d+Z$/, "Z"),
|
|
114
|
+
note: "Moved onto the package folder layout (EE-070). Old routes stay as aliases for one release.",
|
|
115
|
+
moves: moved.map(([from, to]) => ({ from, to })),
|
|
116
|
+
escalated,
|
|
117
|
+
};
|
|
118
|
+
mkdirSync(join(dir, ".release"), { recursive: true });
|
|
119
|
+
const releaseRel = ".release/layout.json";
|
|
120
|
+
writeFileSync(join(dir, releaseRel), JSON.stringify(release, null, 2) + "\n");
|
|
121
|
+
|
|
122
|
+
const agent = { kind: "agent", id: "grokbot", via: "cli" };
|
|
123
|
+
for (const [from, to] of moved) {
|
|
124
|
+
record(dir, { entity: to, activity: "move", agent, derived_from: [from], note: `moved from ${from} (EE-070)` });
|
|
125
|
+
}
|
|
126
|
+
record(dir, { entity: releaseRel, activity: "release", agent, derived_from: moved.map(([, to]) => to), note: "package folder layout" });
|
|
127
|
+
|
|
128
|
+
console.log(`upgraded ${load(join(dir, "venture.json")).id}: ${moved.length} files moved, ${escalated.length} archived for a decision.`);
|
|
129
|
+
for (const e of escalated) console.log(`escalate ${e}`);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// "use model" (EE-073): a package lists the steps that call a model. A record written
|
|
2
|
+
// downstream of one of those steps carries agent provenance until a person confirms it
|
|
3
|
+
// or its checks pass.
|
|
4
|
+
|
|
5
|
+
/** "clear" once a person confirmed it or its checks passed. Otherwise "agent". */
|
|
6
|
+
export function provenanceOf({ use_model, confirmed, checksPass }) {
|
|
7
|
+
if (!Array.isArray(use_model) || use_model.length === 0) return "clear";
|
|
8
|
+
if (confirmed || checksPass) return "clear";
|
|
9
|
+
return "agent";
|
|
10
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Validates every record in the repository against its JSON Schema (EE-017).
|
|
2
|
+
|
|
3
|
+
python3 schema/validate.py
|
|
4
|
+
python3 schema/validate.py --schema <name>.schema.json --file <path> one file (used by the interfaces before a write)
|
|
5
|
+
|
|
6
|
+
Needs the jsonschema package (pip install jsonschema). Which files each schema governs comes from schema/data-model.json;
|
|
7
|
+
schema/check-data-model.mjs makes sure no JSON file is left without a record type.
|
|
8
|
+
"""
|
|
9
|
+
import glob, json, sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
import jsonschema
|
|
14
|
+
except ImportError:
|
|
15
|
+
sys.exit("validate.py needs jsonschema: pip install jsonschema")
|
|
16
|
+
|
|
17
|
+
root = Path(__file__).resolve().parent.parent
|
|
18
|
+
# The data model names every record type, its schema and where its records live (EE-018).
|
|
19
|
+
# Only JSON records with a schema under schema/ are validated here; the methodology catalog's
|
|
20
|
+
# Markdown records are validated by ee.mjs.
|
|
21
|
+
model = json.loads((root / "schema/data-model.json").read_text())
|
|
22
|
+
RULES = [(r["id"], r["schema"], r.get("form", "json"), r["paths"]) for r in model["records"]
|
|
23
|
+
if r["schema"] and r["schema"].startswith("schema/") and r.get("form", "json") in ("json", "json-list", "json-lines")]
|
|
24
|
+
from referencing import Registry, Resource
|
|
25
|
+
|
|
26
|
+
# Every schema is registered by its $id, so one may $ref another (or itself) by file name.
|
|
27
|
+
schemas = {p.name: json.loads(p.read_text()) for p in (root / "schema").glob("*.schema.json")}
|
|
28
|
+
registry = Registry().with_resources((s.get("$id", n), Resource.from_contents(s)) for n, s in schemas.items())
|
|
29
|
+
failed = checked = 0
|
|
30
|
+
if "--file" in sys.argv:
|
|
31
|
+
one = json.loads(Path(sys.argv[sys.argv.index("--file") + 1]).read_text())
|
|
32
|
+
v = jsonschema.Draft202012Validator(schemas[sys.argv[sys.argv.index("--schema") + 1]], registry=registry, format_checker=jsonschema.FormatChecker())
|
|
33
|
+
errs = [f"{'/'.join(map(str, e.absolute_path)) or '(root)'}: {e.message}" for e in v.iter_errors(one)]
|
|
34
|
+
print("\n".join(errs) if errs else "valid")
|
|
35
|
+
sys.exit(1 if errs else 0)
|
|
36
|
+
for name, schema, form, globs in RULES:
|
|
37
|
+
v = jsonschema.Draft202012Validator(schemas[Path(schema).name], registry=registry, format_checker=jsonschema.FormatChecker())
|
|
38
|
+
for g in globs:
|
|
39
|
+
for f in sorted(glob.glob(str(root / g), recursive=True)):
|
|
40
|
+
text = Path(f).read_text()
|
|
41
|
+
docs = [json.loads(l) for l in text.splitlines() if l.strip()] if form == "json-lines" else json.loads(text)
|
|
42
|
+
docs = docs if form != "json" else [docs]
|
|
43
|
+
for d in docs:
|
|
44
|
+
checked += 1
|
|
45
|
+
for e in v.iter_errors(d):
|
|
46
|
+
failed += 1
|
|
47
|
+
print(f"{Path(f).relative_to(root)}: {'/'.join(map(str, e.absolute_path)) or '(root)'}: {e.message}")
|
|
48
|
+
print(f"{checked} records checked against their schemas: {'all valid' if not failed else f'{failed} error(s)'}.")
|
|
49
|
+
sys.exit(1 if failed else 0)
|