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,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"venture": "tandem",
|
|
3
|
+
"updated": "2026-10-27",
|
|
4
|
+
"statement": "Running bookings, stock and payroll in separate tools eats five to ten hours a week that the owner should spend serving customers",
|
|
5
|
+
"segment": "Owners of two-to-ten-person service shops (salons, repair shops, studios) in the US",
|
|
6
|
+
"frequency": "Weekly, at payroll and stock counts; daily for bookings",
|
|
7
|
+
"cost": "Five to ten owner hours a week, plus subscriptions to three or more tools",
|
|
8
|
+
"workarounds": [
|
|
9
|
+
"A booking app, a spreadsheet for stock and a payroll service, reconciled by hand",
|
|
10
|
+
"Paper diaries in the smallest shops"
|
|
11
|
+
],
|
|
12
|
+
"evidence": [
|
|
13
|
+
{
|
|
14
|
+
"id": "tool-spend",
|
|
15
|
+
"kind": "behavior",
|
|
16
|
+
"summary": "9 of 12 owners already pay for three or more separate tools for bookings, stock and payroll",
|
|
17
|
+
"source": {
|
|
18
|
+
"title": "Problem interviews, September 2026",
|
|
19
|
+
"path": "knowledge/research/problem-interviews-2026-09.md"
|
|
20
|
+
},
|
|
21
|
+
"audience": "target",
|
|
22
|
+
"sample": {
|
|
23
|
+
"n": 12,
|
|
24
|
+
"types": [
|
|
25
|
+
"salon",
|
|
26
|
+
"repair",
|
|
27
|
+
"studio"
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
"collected": "2026-09-20"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "admin-hours",
|
|
34
|
+
"kind": "stated",
|
|
35
|
+
"summary": "Owners described last week's admin in detail: a median of 6 hours reconciling the three tools",
|
|
36
|
+
"source": {
|
|
37
|
+
"title": "Problem interviews, September 2026",
|
|
38
|
+
"path": "knowledge/research/problem-interviews-2026-09.md"
|
|
39
|
+
},
|
|
40
|
+
"audience": "target",
|
|
41
|
+
"sample": {
|
|
42
|
+
"n": 12,
|
|
43
|
+
"types": [
|
|
44
|
+
"salon",
|
|
45
|
+
"repair",
|
|
46
|
+
"studio"
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
"specificity": "specific",
|
|
50
|
+
"collected": "2026-09-20"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": "friends-praise",
|
|
54
|
+
"kind": "opinion",
|
|
55
|
+
"summary": "Six friends who run no shop said the idea sounds useful",
|
|
56
|
+
"source": {
|
|
57
|
+
"title": "Feedback from friends, August 2026",
|
|
58
|
+
"path": "knowledge/research/friends-feedback-2026-08.md"
|
|
59
|
+
},
|
|
60
|
+
"audience": "wrong",
|
|
61
|
+
"sample": {
|
|
62
|
+
"n": 6
|
|
63
|
+
},
|
|
64
|
+
"specificity": "general",
|
|
65
|
+
"collected": "2026-08-10"
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"probability": {
|
|
69
|
+
"p": 0.75,
|
|
70
|
+
"by": "owner",
|
|
71
|
+
"scored": "2026-10-27",
|
|
72
|
+
"note": "Example value; Jev scores it once the scorer runs"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"venture": "tandem",
|
|
3
|
+
"updated": "2026-10-27",
|
|
4
|
+
"product": "shop-app",
|
|
5
|
+
"segment": "Two-to-ten-person service shops",
|
|
6
|
+
"retention": {
|
|
7
|
+
"period": "week",
|
|
8
|
+
"cohorts": [
|
|
9
|
+
{
|
|
10
|
+
"start": "2026-07-06",
|
|
11
|
+
"size": 11,
|
|
12
|
+
"active": [
|
|
13
|
+
11,
|
|
14
|
+
10,
|
|
15
|
+
9,
|
|
16
|
+
9,
|
|
17
|
+
9,
|
|
18
|
+
9,
|
|
19
|
+
9
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
"ellis": {
|
|
25
|
+
"asked": 34,
|
|
26
|
+
"very_disappointed": 16,
|
|
27
|
+
"collected": "2026-10-15"
|
|
28
|
+
},
|
|
29
|
+
"evidence": [
|
|
30
|
+
{
|
|
31
|
+
"id": "pilot-retention",
|
|
32
|
+
"kind": "behavior",
|
|
33
|
+
"summary": "9 of 11 shops still active weekly after seven weeks; the curve is flat from week three",
|
|
34
|
+
"source": {
|
|
35
|
+
"title": "Pilot, July to October 2026",
|
|
36
|
+
"path": "knowledge/research/pilot-2026-10.md"
|
|
37
|
+
},
|
|
38
|
+
"audience": "target",
|
|
39
|
+
"sample": {
|
|
40
|
+
"n": 11
|
|
41
|
+
},
|
|
42
|
+
"collected": "2026-10-20"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "ellis-survey",
|
|
46
|
+
"kind": "stated",
|
|
47
|
+
"summary": "16 of 34 active users (47%) would be very disappointed without the app",
|
|
48
|
+
"source": {
|
|
49
|
+
"title": "Pilot, July to October 2026",
|
|
50
|
+
"path": "knowledge/research/pilot-2026-10.md"
|
|
51
|
+
},
|
|
52
|
+
"audience": "target",
|
|
53
|
+
"sample": {
|
|
54
|
+
"n": 34
|
|
55
|
+
},
|
|
56
|
+
"specificity": "specific",
|
|
57
|
+
"collected": "2026-10-15"
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"probability": {
|
|
61
|
+
"p": 0.6,
|
|
62
|
+
"by": "owner",
|
|
63
|
+
"scored": "2026-10-27",
|
|
64
|
+
"note": "Example value"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"venture": "tandem",
|
|
3
|
+
"updated": "2026-10-27",
|
|
4
|
+
"statement": "One phone app that keeps bookings, stock and payroll in one record, so nothing needs reconciling",
|
|
5
|
+
"product": "shop-app",
|
|
6
|
+
"alternatives": [
|
|
7
|
+
"Three separate tools reconciled by hand",
|
|
8
|
+
"Paper diaries"
|
|
9
|
+
],
|
|
10
|
+
"difference": "No weekly reconciliation; one subscription instead of three",
|
|
11
|
+
"evidence": [
|
|
12
|
+
{
|
|
13
|
+
"id": "switched",
|
|
14
|
+
"kind": "behavior",
|
|
15
|
+
"summary": "9 of 11 pilot shops stopped using their separate booking tool within a month",
|
|
16
|
+
"source": {
|
|
17
|
+
"title": "Pilot, July to October 2026",
|
|
18
|
+
"path": "knowledge/research/pilot-2026-10.md"
|
|
19
|
+
},
|
|
20
|
+
"audience": "target",
|
|
21
|
+
"sample": {
|
|
22
|
+
"n": 11
|
|
23
|
+
},
|
|
24
|
+
"collected": "2026-10-20"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"probability": {
|
|
28
|
+
"p": 0.7,
|
|
29
|
+
"by": "owner",
|
|
30
|
+
"scored": "2026-10-27",
|
|
31
|
+
"note": "Example value"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"venture": "tandem",
|
|
3
|
+
"updated": "2026-10-27",
|
|
4
|
+
"needed": [
|
|
5
|
+
{
|
|
6
|
+
"skill": "mobile engineering",
|
|
7
|
+
"by_phase": "validation"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"skill": "small-business sales",
|
|
11
|
+
"by_phase": "validation"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"skill": "payroll compliance",
|
|
15
|
+
"by_phase": "beachhead",
|
|
16
|
+
"why": "Payroll rules differ by state"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"held": [
|
|
20
|
+
{
|
|
21
|
+
"skill": "mobile engineering",
|
|
22
|
+
"by": "founder"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"skill": "small-business sales",
|
|
26
|
+
"by": "founder"
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"cofounder_sought": false,
|
|
30
|
+
"evidence": [
|
|
31
|
+
{
|
|
32
|
+
"id": "shipped-pilot",
|
|
33
|
+
"kind": "behavior",
|
|
34
|
+
"summary": "The two founders built and sold the pilot without outside help",
|
|
35
|
+
"source": {
|
|
36
|
+
"title": "Pilot, July to October 2026",
|
|
37
|
+
"path": "knowledge/research/pilot-2026-10.md"
|
|
38
|
+
},
|
|
39
|
+
"audience": "target",
|
|
40
|
+
"sample": {
|
|
41
|
+
"n": 11
|
|
42
|
+
},
|
|
43
|
+
"collected": "2026-10-20"
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"probability": {
|
|
47
|
+
"p": 0.6,
|
|
48
|
+
"by": "owner",
|
|
49
|
+
"scored": "2026-10-27",
|
|
50
|
+
"note": "Example value"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "tandem",
|
|
3
|
+
"name": "Tandem",
|
|
4
|
+
"parent": null,
|
|
5
|
+
"phase": "validation",
|
|
6
|
+
"form": {
|
|
7
|
+
"legal_form": "c-corp",
|
|
8
|
+
"funding": "venture-capital"
|
|
9
|
+
},
|
|
10
|
+
"core": {
|
|
11
|
+
"promise": "Two people can run a shop's bookings, stock and payroll from one phone",
|
|
12
|
+
"promised_to": "Owners of two-to-ten-person service shops",
|
|
13
|
+
"must_not": "Lock a shop's records into a format it cannot export",
|
|
14
|
+
"competence": "Turning small-shop paperwork into one mobile workflow"
|
|
15
|
+
},
|
|
16
|
+
"owner": "shared",
|
|
17
|
+
"status": "active",
|
|
18
|
+
"profile": "profile.md",
|
|
19
|
+
"layers": {
|
|
20
|
+
"purpose": {
|
|
21
|
+
"location": "purpose/"
|
|
22
|
+
},
|
|
23
|
+
"knowledge": {
|
|
24
|
+
"location": "knowledge/"
|
|
25
|
+
},
|
|
26
|
+
"operations": {
|
|
27
|
+
"location": "operations/"
|
|
28
|
+
},
|
|
29
|
+
"evidence": {
|
|
30
|
+
"location": "evidence/"
|
|
31
|
+
},
|
|
32
|
+
"governance": {
|
|
33
|
+
"location": "governance/"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"repos": [
|
|
37
|
+
{
|
|
38
|
+
"id": "tandem-app",
|
|
39
|
+
"url": "https://example.com/tandem/tandem-app",
|
|
40
|
+
"products": [
|
|
41
|
+
"shop-app"
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"ambition": "aggressive-growth",
|
|
46
|
+
"industry": {
|
|
47
|
+
"system": "naics",
|
|
48
|
+
"code": "513210",
|
|
49
|
+
"label": "Software Publishers"
|
|
50
|
+
},
|
|
51
|
+
"opened": "2026-03-02",
|
|
52
|
+
"members": [
|
|
53
|
+
{
|
|
54
|
+
"role": "founder",
|
|
55
|
+
"kind": "person"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"role": "founder",
|
|
59
|
+
"kind": "person"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"role": "builder",
|
|
63
|
+
"kind": "agent",
|
|
64
|
+
"tools": [
|
|
65
|
+
"claude-code"
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
"regulation": {
|
|
70
|
+
"exposure": "some",
|
|
71
|
+
"regimes": [
|
|
72
|
+
"GDPR"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
"departments": [
|
|
76
|
+
"marketing-and-sales",
|
|
77
|
+
"finance"
|
|
78
|
+
]
|
|
79
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "woodworking",
|
|
3
|
+
"name": "Woodworking",
|
|
4
|
+
"parent": null,
|
|
5
|
+
"phase": "discovery",
|
|
6
|
+
"ambition": "hobby",
|
|
7
|
+
"form": {
|
|
8
|
+
"legal_form": "none"
|
|
9
|
+
},
|
|
10
|
+
"owner": "self",
|
|
11
|
+
"status": "active",
|
|
12
|
+
"profile": "profile.md",
|
|
13
|
+
"layers": {
|
|
14
|
+
"purpose": false,
|
|
15
|
+
"knowledge": {
|
|
16
|
+
"location": "knowledge/"
|
|
17
|
+
},
|
|
18
|
+
"operations": false,
|
|
19
|
+
"evidence": false
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "exit.schema.json",
|
|
4
|
+
"title": "Exit",
|
|
5
|
+
"description": "How the venture might end and what each owner would get, at <venture>/governance/exit.json (EE-022): the exit paths it keeps open and the sale values to model. Payouts are never typed here: schema/payouts.mjs computes them from ownership.json for each scenario.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"paths"
|
|
9
|
+
],
|
|
10
|
+
"additionalProperties": false,
|
|
11
|
+
"properties": {
|
|
12
|
+
"paths": {
|
|
13
|
+
"type": "array",
|
|
14
|
+
"minItems": 1,
|
|
15
|
+
"items": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"required": [
|
|
18
|
+
"kind",
|
|
19
|
+
"stance"
|
|
20
|
+
],
|
|
21
|
+
"additionalProperties": false,
|
|
22
|
+
"properties": {
|
|
23
|
+
"kind": {
|
|
24
|
+
"enum": [
|
|
25
|
+
"acquisition",
|
|
26
|
+
"ipo",
|
|
27
|
+
"secondary-sale",
|
|
28
|
+
"merger",
|
|
29
|
+
"management-buyout",
|
|
30
|
+
"wind-down",
|
|
31
|
+
"hold"
|
|
32
|
+
],
|
|
33
|
+
"description": "hold: no exit, the owners keep it"
|
|
34
|
+
},
|
|
35
|
+
"stance": {
|
|
36
|
+
"enum": [
|
|
37
|
+
"preferred",
|
|
38
|
+
"open",
|
|
39
|
+
"ruled-out"
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"note": {
|
|
43
|
+
"type": "string"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"scenarios": {
|
|
49
|
+
"type": "array",
|
|
50
|
+
"items": {
|
|
51
|
+
"type": "object",
|
|
52
|
+
"required": [
|
|
53
|
+
"id",
|
|
54
|
+
"value"
|
|
55
|
+
],
|
|
56
|
+
"additionalProperties": false,
|
|
57
|
+
"properties": {
|
|
58
|
+
"id": {
|
|
59
|
+
"type": "string",
|
|
60
|
+
"pattern": "^[a-z0-9-]+$"
|
|
61
|
+
},
|
|
62
|
+
"value": {
|
|
63
|
+
"type": "number",
|
|
64
|
+
"minimum": 0,
|
|
65
|
+
"description": "Proceeds to the owners after debts and costs"
|
|
66
|
+
},
|
|
67
|
+
"note": {
|
|
68
|
+
"type": "string"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Reports a venture's strategic foundation (EE-051, EE-052): for each question of the Five Ws and How plus
|
|
3
|
+
// whether (purpose/strategic-foundation.json), the record attributes that answer it, and whether
|
|
4
|
+
// each is confirmed, drafted by an agent, waiting as a draft, or missing. This is what a founder
|
|
5
|
+
// keeps in front of them; a platform renders it always visible. Behaviors:
|
|
6
|
+
// purpose/kits/validation/features/strategic-foundation.feature.
|
|
7
|
+
//
|
|
8
|
+
// node schema/foundation.mjs <venture dir> [--json]
|
|
9
|
+
//
|
|
10
|
+
// Status: confirmed (the last write was a person's, or a person accepted it), agent (an agent
|
|
11
|
+
// wrote it and no person has confirmed it), draft (a draft waits in _drafts/), missing, planned
|
|
12
|
+
// (no record type yet). A statement an agent drafted is not the founder's until confirmed.
|
|
13
|
+
// Exit 1 when the frame names a record type the data model lacks, or an ICP names a problem form
|
|
14
|
+
// the problem record lacks.
|
|
15
|
+
|
|
16
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
|
|
19
|
+
const repo = new URL("..", import.meta.url).pathname;
|
|
20
|
+
const load = (f) => JSON.parse(readFileSync(f, "utf8"));
|
|
21
|
+
export const FRAME = load(join(repo, "purpose/strategic-foundation.json"));
|
|
22
|
+
const MODEL = load(join(repo, "schema/data-model.json"));
|
|
23
|
+
|
|
24
|
+
const get = (o, path) => path.split(".").reduce((x, k) => (x == null ? undefined : x[k]), o);
|
|
25
|
+
const filled = (v) => v !== undefined && v !== null && v !== "" && !(Array.isArray(v) && !v.length);
|
|
26
|
+
|
|
27
|
+
/** Venture-relative files of a record type: one file, or every item of a collection. */
|
|
28
|
+
export function filesOf(dir, type) {
|
|
29
|
+
const r = MODEL.records.find((x) => x.id === type);
|
|
30
|
+
const gs = (r?.paths ?? []).filter((p) => p.startsWith("instance/**/")).map((p) => p.slice("instance/**/".length));
|
|
31
|
+
const found = [];
|
|
32
|
+
for (const g of gs) {
|
|
33
|
+
if (!g.includes("*")) { if (existsSync(join(dir, g))) found.push(g); continue; }
|
|
34
|
+
const star = g.indexOf("*");
|
|
35
|
+
const folder = g.slice(0, star), rest = g.slice(star + 1);
|
|
36
|
+
if (rest.includes("*")) continue;
|
|
37
|
+
const d = join(dir, folder);
|
|
38
|
+
if (existsSync(d)) for (const f of readdirSync(d)) if (f.endsWith(rest)) found.push(folder + f);
|
|
39
|
+
}
|
|
40
|
+
if (found.length) return found;
|
|
41
|
+
const drafted = gs.filter((g) => !g.includes("*") && existsSync(join(dir, `_drafts/${g.replace(/\//g, "__")}.draft`)));
|
|
42
|
+
return drafted.length ? drafted : gs.slice(0, 1);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Whether a person confirmed one statement in a file: their write or accept of the file, or a
|
|
46
|
+
* confirm of that statement, after the last write by anyone else. */
|
|
47
|
+
export function confirmedIn(dir, file, id, seen = new Set()) {
|
|
48
|
+
if (seen.has(file)) return false;
|
|
49
|
+
seen.add(file);
|
|
50
|
+
const log = join(dir, "provenance.jsonl");
|
|
51
|
+
if (!existsSync(log)) return false;
|
|
52
|
+
const draft = `_drafts/${file.replace(/\//g, "__")}.draft`;
|
|
53
|
+
const es = readFileSync(log, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter((e) => e.entity === file || e.entity === draft);
|
|
54
|
+
const lastAgentWrite = es.findLastIndex((e) => e.entity === file && e.activity !== "confirm" && e.activity !== "move" && e.activity !== "release" && e.agent?.kind !== "person" && e.activity !== "accept");
|
|
55
|
+
const direct = es.some((e, i) => i > lastAgentWrite && e.entity === file && (e.activity === "accept" || (e.agent?.kind === "person" && e.activity !== "confirm" && e.activity !== "move") || (e.activity === "confirm" && e.statement === id)));
|
|
56
|
+
if (direct) return true;
|
|
57
|
+
return es.filter((e) => e.activity === "move" && e.entity === file).flatMap((e) => e.derived_from ?? []).some((p) => confirmedIn(dir, p, id, seen));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Each foundation statement of a venture, with its status and value. */
|
|
61
|
+
export function foundation(dir) {
|
|
62
|
+
const report = FRAME.questions.map((q) => ({ question: q.id, ask: q.ask, statements: q.statements.map((s) => {
|
|
63
|
+
if (s.derived_from) return s;
|
|
64
|
+
if (!s.record) return { id: s.id, status: "planned", note: s.note ?? null };
|
|
65
|
+
const files = filesOf(dir, s.record);
|
|
66
|
+
// A retired product no longer answers for the venture.
|
|
67
|
+
const values = files.filter((f) => existsSync(join(dir, f)) && load(join(dir, f)).status !== "retired").map((f) => ({ f, v: get(load(join(dir, f)), s.attribute) })).filter((x) => filled(x.v));
|
|
68
|
+
const drafts = files.filter((f) => existsSync(join(dir, `_drafts/${f.replace(/\//g, "__")}.draft`)));
|
|
69
|
+
if (!values.length) return { id: s.id, record: s.record, attribute: s.attribute, status: drafts.length ? "draft" : "missing" };
|
|
70
|
+
// A record with no log entry existed before the log; a person's baseline or write confirms it.
|
|
71
|
+
const confirmed = values.every(({ f }) => confirmedIn(dir, f, s.id));
|
|
72
|
+
return { id: s.id, record: s.record, attribute: s.attribute, status: drafts.length ? "draft" : confirmed ? "confirmed" : "agent",
|
|
73
|
+
value: values.length === 1 && !files[0].includes("products/") ? values[0].v : Object.fromEntries(values.map(({ f, v }) => [f, v])) };
|
|
74
|
+
}) }));
|
|
75
|
+
// A derived statement takes its source's status and shows the primary ICP profile's short form.
|
|
76
|
+
const all = report.flatMap((q) => q.statements);
|
|
77
|
+
for (const q of report) q.statements = q.statements.map((s) => {
|
|
78
|
+
if (!s.derived_from) return s;
|
|
79
|
+
const src = all.find((x) => x.id === s.derived_from) ?? { status: "missing" };
|
|
80
|
+
const out = { id: s.id, record: s.record, attribute: s.attribute, derived_from: s.derived_from, status: src.status };
|
|
81
|
+
const primary = Array.isArray(src.value) ? (src.value.find((p) => p.primary) ?? src.value[0]) : null;
|
|
82
|
+
if (primary) out.value = primary.short ?? primary.who;
|
|
83
|
+
return out;
|
|
84
|
+
});
|
|
85
|
+
return report;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function problems(dir) {
|
|
89
|
+
const out = FRAME.questions.flatMap((q) => q.statements).filter((s) => s.record && !MODEL.records.some((r) => r.id === s.record)).map((s) => `frame: ${s.id} names record type ${s.record}, which the data model lacks`);
|
|
90
|
+
const there = (...fs) => fs.map((f) => join(dir, f)).find((p) => existsSync(p));
|
|
91
|
+
const icp = there("foundation/icp.json", "purpose/icp.json"), prob = there("foundation/problem.json", "purpose/validation/problem.json");
|
|
92
|
+
if (icp) {
|
|
93
|
+
const forms = new Set(existsSync(prob) ? (load(prob).forms ?? []).map((f) => f.id) : []);
|
|
94
|
+
for (const p of load(icp).profiles) for (const f of p.problem_forms ?? []) if (!forms.has(f)) out.push(`icp ${p.id}: problem form ${f} is not in the problem record`);
|
|
95
|
+
const primaries = load(icp).profiles.filter((p) => p.primary).length;
|
|
96
|
+
if (load(icp).profiles.length > 1 && primaries !== 1) out.push(`icp: ${primaries} primary profiles; exactly one is primary`);
|
|
97
|
+
// promised-to is derived from the ICP; a hand-written one that differs has drifted.
|
|
98
|
+
const p = load(icp).profiles.find((x) => x.primary) ?? load(icp).profiles[0];
|
|
99
|
+
const said = existsSync(join(dir, "venture.json")) ? load(join(dir, "venture.json")).core?.promised_to : undefined;
|
|
100
|
+
if (p && filled(said) && said !== (p.short ?? p.who)) out.push(`venture core.promised_to differs from the ICP's short form ("${p.short ?? p.who}"); it is derived from the ICP`);
|
|
101
|
+
}
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
106
|
+
const arg = process.argv[2];
|
|
107
|
+
if (!arg) { console.error("usage: node schema/foundation.mjs <venture or workspace dir> [--json]"); process.exit(2); }
|
|
108
|
+
const walk = (d) => existsSync(join(d, "venture.json")) ? [d] : readdirSync(d, { withFileTypes: true }).filter((e) => e.isDirectory() && !e.name.startsWith(".") && !e.name.startsWith("_")).flatMap((e) => walk(join(d, e.name)));
|
|
109
|
+
const dirs = walk(arg);
|
|
110
|
+
const errs = dirs.flatMap((d) => problems(d).map((p) => `${d}: ${p}`));
|
|
111
|
+
if (process.argv.includes("--json")) console.log(JSON.stringify(dirs.length === 1 ? foundation(dirs[0]) : Object.fromEntries(dirs.map((d) => [d, foundation(d)])), null, 2));
|
|
112
|
+
else for (const d of dirs) {
|
|
113
|
+
if (dirs.length > 1) console.log(`\n${d}`);
|
|
114
|
+
for (const q of foundation(d)) console.log(`${q.question.padEnd(8)} ${q.ask}\n${q.statements.map((s) => ` ${s.id.padEnd(16)} ${s.status}${s.value !== undefined ? `: ${JSON.stringify(s.value).slice(0, 90)}` : ""}`).join("\n")}`);
|
|
115
|
+
}
|
|
116
|
+
for (const e of errs) console.error(`FAIL ${e}`);
|
|
117
|
+
process.exit(errs.length ? 1 : 0);
|
|
118
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "founder-agreement.schema.json",
|
|
4
|
+
"title": "Founder agreement",
|
|
5
|
+
"description": "The summary of what founders agreed with each other, at <venture>/governance/founder-agreement.json (EE-022), with the full text (or the signed document's location) in founder-agreement.md beside it. Equity and vesting live in ownership.json and are not repeated here. Required once two or more founders share ownership.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"founders",
|
|
9
|
+
"signed",
|
|
10
|
+
"document"
|
|
11
|
+
],
|
|
12
|
+
"additionalProperties": false,
|
|
13
|
+
"properties": {
|
|
14
|
+
"signed": {
|
|
15
|
+
"type": [
|
|
16
|
+
"string",
|
|
17
|
+
"null"
|
|
18
|
+
],
|
|
19
|
+
"format": "date",
|
|
20
|
+
"description": "null until every founder has signed"
|
|
21
|
+
},
|
|
22
|
+
"document": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"description": "Path to the prose agreement or the signed document"
|
|
25
|
+
},
|
|
26
|
+
"founders": {
|
|
27
|
+
"type": "array",
|
|
28
|
+
"minItems": 1,
|
|
29
|
+
"items": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"required": [
|
|
32
|
+
"holder",
|
|
33
|
+
"role",
|
|
34
|
+
"commitment",
|
|
35
|
+
"ip_assigned"
|
|
36
|
+
],
|
|
37
|
+
"additionalProperties": false,
|
|
38
|
+
"properties": {
|
|
39
|
+
"holder": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"description": "Holder id in ownership.json"
|
|
42
|
+
},
|
|
43
|
+
"role": {
|
|
44
|
+
"type": "string"
|
|
45
|
+
},
|
|
46
|
+
"commitment": {
|
|
47
|
+
"enum": [
|
|
48
|
+
"full-time",
|
|
49
|
+
"part-time"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"ip_assigned": {
|
|
53
|
+
"type": "boolean",
|
|
54
|
+
"description": "Has assigned to the venture the work and ideas they brought or make"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"departure": {
|
|
60
|
+
"type": "object",
|
|
61
|
+
"additionalProperties": false,
|
|
62
|
+
"properties": {
|
|
63
|
+
"good_leaver": {
|
|
64
|
+
"type": "string"
|
|
65
|
+
},
|
|
66
|
+
"bad_leaver": {
|
|
67
|
+
"type": "string"
|
|
68
|
+
},
|
|
69
|
+
"buyback": {
|
|
70
|
+
"enum": [
|
|
71
|
+
"unvested-only",
|
|
72
|
+
"unvested-at-cost",
|
|
73
|
+
"none"
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"deadlock": {
|
|
79
|
+
"type": "string",
|
|
80
|
+
"description": "How founders break a tie"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
package/schema/gate.mjs
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// The gate (EE-073): checks that run before a write. One per venture. Static rules live in
|
|
2
|
+
// naive.config.json. Per-package rules are the gates on each package definition. The gate
|
|
3
|
+
// matches the router's path patterns and never calls a model. Confidence routing reads a
|
|
4
|
+
// score that was already computed.
|
|
5
|
+
|
|
6
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
|
|
9
|
+
const repo = new URL("..", import.meta.url).pathname;
|
|
10
|
+
|
|
11
|
+
/** Package gates, imported from packages/<name>/package.json. No model, no network. */
|
|
12
|
+
export function packageGates() {
|
|
13
|
+
const dir = join(repo, "packages");
|
|
14
|
+
if (!existsSync(dir)) return [];
|
|
15
|
+
return readdirSync(dir).flatMap((name) => {
|
|
16
|
+
const p = join(dir, name, "package.json");
|
|
17
|
+
if (!existsSync(p)) return [];
|
|
18
|
+
const pkg = JSON.parse(readFileSync(p, "utf8"));
|
|
19
|
+
return (pkg.gates ?? []).map((rule) => ({ package: pkg.name, rule }));
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Whether an agent write is held as a draft. fail_closed names path prefixes
|
|
25
|
+
* (foundation, or foundation/problem). A person is not held.
|
|
26
|
+
*/
|
|
27
|
+
export function hold(config, route, actor) {
|
|
28
|
+
if (actor === "person") return null;
|
|
29
|
+
const closed = config?.fail_closed ?? [];
|
|
30
|
+
const hit = closed.find((g) => route === g || route.startsWith(`${g}/`));
|
|
31
|
+
return hit ? { hold: "draft", rule: hit } : null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** The venture's naive.config.json, or an empty config. */
|
|
35
|
+
export function configOf(dir) {
|
|
36
|
+
const f = dir && join(dir, "naive.config.json");
|
|
37
|
+
if (!f || !existsSync(f)) return { fail_closed: [] };
|
|
38
|
+
return JSON.parse(readFileSync(f, "utf8")).gate ?? { fail_closed: [] };
|
|
39
|
+
}
|