naive-framework 0.0.0-stage → 0.2.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 +62 -0
- package/LICENSE +21 -0
- package/README.md +37 -2
- package/docs/decisions/decisions.json +888 -0
- package/docs/ontology.json +796 -0
- package/docs/ontology.md +163 -0
- package/docs/reference/ROUTES.md +124 -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 +102 -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/governance/venture-template/roles/venture-roles.json +62 -0
- package/interface/acting.mjs +83 -0
- package/interface/adapters/claude-code.json +16 -0
- package/interface/adapters/codex.json +14 -0
- package/interface/adapters/cursor.json +16 -0
- package/interface/adapters.mjs +182 -0
- package/interface/api/server.mjs +71 -0
- package/interface/boundaries.mjs +218 -0
- package/interface/brand.mjs +214 -0
- package/interface/cli/find-venture.mjs +15 -0
- package/interface/cli/freshness.mjs +59 -0
- package/interface/cli/guard.mjs +6 -0
- package/interface/cli/mentura.mjs +341 -0
- package/interface/cli/naive.mjs +194 -0
- package/interface/context.mjs +524 -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/dev/setup.mjs +84 -0
- package/interface/gate-hooks.mjs +36 -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/instrumentation.mjs +86 -0
- package/interface/kit-boundary.mjs +73 -0
- package/interface/layer.json +37 -0
- package/interface/mcp/server.mjs +162 -0
- package/interface/operator-console/README.md +58 -0
- package/interface/package-routes.mjs +196 -0
- package/interface/provenance.mjs +65 -0
- package/interface/reads.mjs +173 -0
- package/interface/references/references.json +28 -0
- package/interface/release-card.mjs +42 -0
- package/interface/route-aliases.json +32 -0
- package/interface/router.mjs +653 -0
- package/interface/skills/install-mentura/SKILL.md +88 -0
- package/interface/skills/naive-setup/SKILL.md +71 -0
- package/interface/skills/naive-setup/artifact.html +83 -0
- package/interface/tooling/integrations.json +112 -0
- package/interface/vitals.mjs +115 -0
- package/interface/writes.mjs +190 -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/freshness.json +85 -0
- package/knowledge/layer.json +50 -0
- package/knowledge/skills/find-reference/SKILL.md +38 -0
- package/knowledge/skills/industry-awareness/SKILL.md +277 -0
- package/knowledge/templates/glossary.md +23 -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 +67 -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/marketing-brand.md +46 -0
- package/operations/templates/public-assets.md +39 -0
- package/operations/templates/recruiting-brief.md +35 -0
- package/operations/tooling/integrations.json +158 -0
- package/package.json +59 -4
- package/packages/catalog.json +280 -0
- package/packages/cofounder/package.json +42 -0
- package/packages/counsel/package.json +47 -0
- package/packages/customers/package.json +41 -0
- package/packages/deals/package.json +27 -0
- package/packages/decisions/package.json +28 -0
- package/packages/engineering/package.json +41 -0
- package/packages/evidence/package.json +17 -0
- package/packages/finance/frames/fund-without-ceding-control.frame.json +177 -0
- package/packages/finance/package.json +48 -0
- package/packages/foundation/package.json +59 -0
- package/packages/fund/package.json +48 -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 +63 -0
- package/packages/money/package.json +42 -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 +112 -0
- package/platform/README.md +51 -0
- package/platform/adapter.json +15 -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/remote-image.mjs +79 -0
- package/platform/integrations/rho.mjs +146 -0
- package/platform/integrations/site.mjs +75 -0
- package/platform/kits/README.md +14 -0
- package/platform/kits/agent-upgrade/kit.json +15 -0
- package/platform/kits/agent-upgrade/run.mjs +82 -0
- package/platform/kits/agent-upgrade/stand-in-agent.mjs +32 -0
- package/platform/kits/validation-kickoff/kit.json +29 -0
- package/platform/mcp/research.mjs +64 -0
- package/platform/webhooks/server.mjs +70 -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 +181 -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 +62 -0
- package/schema/VERSION +1 -0
- package/schema/access.mjs +57 -0
- package/schema/account.schema.json +79 -0
- package/schema/adapter.schema.json +33 -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/assets.mjs +212 -0
- package/schema/bdd.mjs +56 -0
- package/schema/board.schema.json +101 -0
- package/schema/brand.mjs +373 -0
- package/schema/build-release.mjs +61 -0
- package/schema/caching.mjs +505 -0
- package/schema/check-assets.mjs +24 -0
- package/schema/check-boundary.mjs +54 -0
- package/schema/check-brand.mjs +24 -0
- package/schema/check-config.mjs +110 -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 +79 -0
- package/schema/check-nouns.mjs +49 -0
- package/schema/check-people.mjs +70 -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 +74 -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 +1584 -0
- package/schema/data-model.schema.json +152 -0
- package/schema/deal.schema.json +80 -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 +327 -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/frames/judge.mjs +10 -0
- package/schema/examples/migrate/agent.mjs +12 -0
- package/schema/examples/venture-type/jev.mjs +12 -0
- package/schema/examples/workspace/ventures/acme-labs/AGENTS.md +17 -0
- package/schema/examples/workspace/ventures/acme-labs/accounts/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/acme-labs/decisions/discovery-goal.decision.json +23 -0
- package/schema/examples/workspace/ventures/acme-labs/decisions/statement-icp.decision.json +22 -0
- package/schema/examples/workspace/ventures/acme-labs/decisions/statement-problem.decision.json +22 -0
- package/schema/examples/workspace/ventures/acme-labs/decisions/venture.team.decision.json +37 -0
- package/schema/examples/workspace/ventures/acme-labs/knowledge/README.md +3 -0
- package/schema/examples/workspace/ventures/acme-labs/knowledge/sources.json +46 -0
- package/schema/examples/workspace/ventures/acme-labs/money/30000000-0000-4000-8000-000000000001.json +12 -0
- package/schema/examples/workspace/ventures/acme-labs/money/30000000-0000-4000-8000-000000000002.json +12 -0
- package/schema/examples/workspace/ventures/acme-labs/money/30000000-0000-4000-8000-000000000003.json +12 -0
- package/schema/examples/workspace/ventures/acme-labs/money/30000000-0000-4000-8000-000000000004.json +12 -0
- package/schema/examples/workspace/ventures/acme-labs/money/30000000-0000-4000-8000-000000000005.json +12 -0
- package/schema/examples/workspace/ventures/acme-labs/money/30000000-0000-4000-8000-000000000006.json +12 -0
- package/schema/examples/workspace/ventures/acme-labs/money/30000000-0000-4000-8000-000000000007.json +12 -0
- package/schema/examples/workspace/ventures/acme-labs/money/30000000-0000-4000-8000-000000000008.json +12 -0
- package/schema/examples/workspace/ventures/acme-labs/money/30000000-0000-4000-8000-000000000009.json +12 -0
- package/schema/examples/workspace/ventures/acme-labs/money/30000000-0000-4000-8000-000000000010.json +12 -0
- package/schema/examples/workspace/ventures/acme-labs/money/30000000-0000-4000-8000-000000000011.json +12 -0
- package/schema/examples/workspace/ventures/acme-labs/money/30000000-0000-4000-8000-000000000012.json +12 -0
- package/schema/examples/workspace/ventures/acme-labs/money/30000000-0000-4000-8000-000000000013.json +12 -0
- package/schema/examples/workspace/ventures/acme-labs/money/30000000-0000-4000-8000-000000000014.json +12 -0
- package/schema/examples/workspace/ventures/acme-labs/money/_streams/transactions/stream.json +5 -0
- package/schema/examples/workspace/ventures/acme-labs/money/_summary.json +30 -0
- package/schema/examples/workspace/ventures/acme-labs/operations/departments/customer-service/README.md +5 -0
- package/schema/examples/workspace/ventures/acme-labs/operations/departments/customer-service/department.json +5 -0
- package/schema/examples/workspace/ventures/acme-labs/operations/departments/finance/README.md +5 -0
- package/schema/examples/workspace/ventures/acme-labs/operations/departments/finance/department.json +5 -0
- package/schema/examples/workspace/ventures/acme-labs/operations/departments/human-capital/README.md +5 -0
- package/schema/examples/workspace/ventures/acme-labs/operations/departments/human-capital/department.json +5 -0
- package/schema/examples/workspace/ventures/acme-labs/operations/departments/it/README.md +5 -0
- package/schema/examples/workspace/ventures/acme-labs/operations/departments/it/department.json +5 -0
- package/schema/examples/workspace/ventures/acme-labs/operations/departments/marketing-and-sales/README.md +5 -0
- package/schema/examples/workspace/ventures/acme-labs/operations/departments/marketing-and-sales/department.json +5 -0
- package/schema/examples/workspace/ventures/acme-labs/operations/departments/products/README.md +5 -0
- package/schema/examples/workspace/ventures/acme-labs/operations/departments/products/department.json +5 -0
- package/schema/examples/workspace/ventures/acme-labs/operations/departments/strategy/README.md +5 -0
- package/schema/examples/workspace/ventures/acme-labs/operations/departments/strategy/department.json +5 -0
- package/schema/examples/workspace/ventures/acme-labs/people/founders/maya-chen.json +15 -0
- package/schema/examples/workspace/ventures/acme-labs/people/people.json +22 -0
- package/schema/examples/workspace/ventures/acme-labs/pillars/brand.md +5 -0
- package/schema/examples/workspace/ventures/acme-labs/pillars/business.md +5 -0
- package/schema/examples/workspace/ventures/acme-labs/pillars/product.md +5 -0
- package/schema/examples/workspace/ventures/acme-labs/products/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/acme-labs/products/decisions/product.core-product.decision.json +28 -0
- package/schema/examples/workspace/ventures/acme-labs/products/decisions/product.exists.decision.json +38 -0
- package/schema/examples/workspace/ventures/acme-labs/products/decisions/product.flagship.decision.json +27 -0
- package/schema/examples/workspace/ventures/acme-labs/profile.md +12 -0
- package/schema/examples/workspace/ventures/acme-labs/provenance.jsonl +12 -0
- package/schema/examples/workspace/ventures/acme-labs/raw/dump.md +6 -0
- package/schema/examples/workspace/ventures/acme-labs/venture.json +27 -0
- package/schema/examples/workspace/ventures/northstar/AGENTS.md +17 -0
- package/schema/examples/workspace/ventures/northstar/accounts/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/northstar/deals/ductline.json +8 -0
- package/schema/examples/workspace/ventures/northstar/deals/kilnworks.json +14 -0
- package/schema/examples/workspace/ventures/northstar/decisions/venture.team.decision.json +31 -0
- package/schema/examples/workspace/ventures/northstar/evidence/README.md +3 -0
- package/schema/examples/workspace/ventures/northstar/fund/decisions/terms.decision.json +27 -0
- package/schema/examples/workspace/ventures/northstar/fund/decisions/terms.first-close.decision.json +27 -0
- package/schema/examples/workspace/ventures/northstar/fund/decisions/thesis.decision.json +26 -0
- package/schema/examples/workspace/ventures/northstar/fund/terms.json +22 -0
- package/schema/examples/workspace/ventures/northstar/fund/thesis.json +22 -0
- package/schema/examples/workspace/ventures/northstar/governance/README.md +3 -0
- package/schema/examples/workspace/ventures/northstar/governance/departments/external-relationships/charter.md +5 -0
- package/schema/examples/workspace/ventures/northstar/governance/departments/external-relationships/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/governance/departments/finance/charter.md +5 -0
- package/schema/examples/workspace/ventures/northstar/governance/departments/finance/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/governance/departments/human-capital/charter.md +5 -0
- package/schema/examples/workspace/ventures/northstar/governance/departments/human-capital/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/governance/departments/risk-and-compliance/charter.md +5 -0
- package/schema/examples/workspace/ventures/northstar/governance/departments/risk-and-compliance/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/governance/departments/strategy/charter.md +5 -0
- package/schema/examples/workspace/ventures/northstar/governance/departments/strategy/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/knowledge/README.md +3 -0
- package/schema/examples/workspace/ventures/northstar/operations/README.md +3 -0
- package/schema/examples/workspace/ventures/northstar/operations/departments/external-relationships/README.md +5 -0
- package/schema/examples/workspace/ventures/northstar/operations/departments/external-relationships/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/operations/departments/finance/README.md +5 -0
- package/schema/examples/workspace/ventures/northstar/operations/departments/finance/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/operations/departments/human-capital/README.md +5 -0
- package/schema/examples/workspace/ventures/northstar/operations/departments/human-capital/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/operations/departments/risk-and-compliance/README.md +5 -0
- package/schema/examples/workspace/ventures/northstar/operations/departments/risk-and-compliance/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/operations/departments/strategy/README.md +5 -0
- package/schema/examples/workspace/ventures/northstar/operations/departments/strategy/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/people/founders/ana-ruiz.json +13 -0
- package/schema/examples/workspace/ventures/northstar/people/founders/ben-okafor.json +7 -0
- package/schema/examples/workspace/ventures/northstar/people/people.json +27 -0
- package/schema/examples/workspace/ventures/northstar/pillars/brand.md +5 -0
- package/schema/examples/workspace/ventures/northstar/pillars/business.md +5 -0
- package/schema/examples/workspace/ventures/northstar/pillars/product.md +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/AGENTS.md +17 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/accounts/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/decisions/venture.team.decision.json +31 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/knowledge/README.md +3 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/operations/departments/customer-service/README.md +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/operations/departments/customer-service/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/operations/departments/finance/README.md +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/operations/departments/finance/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/operations/departments/human-capital/README.md +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/operations/departments/human-capital/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/operations/departments/it/README.md +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/operations/departments/it/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/operations/departments/marketing-and-sales/README.md +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/operations/departments/marketing-and-sales/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/operations/departments/products/README.md +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/operations/departments/products/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/operations/departments/strategy/README.md +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/operations/departments/strategy/department.json +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/pillars/brand.md +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/pillars/business.md +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/pillars/product.md +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/products/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/products/decisions/product.core-product.decision.json +28 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/products/decisions/product.exists.decision.json +32 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/products/decisions/product.flagship.decision.json +27 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/profile.md +5 -0
- package/schema/examples/workspace/ventures/northstar/portfolio/kilnworks/venture.json +27 -0
- package/schema/examples/workspace/ventures/northstar/products/.gitkeep +0 -0
- package/schema/examples/workspace/ventures/northstar/profile.md +5 -0
- package/schema/examples/workspace/ventures/northstar/provenance.jsonl +3 -0
- package/schema/examples/workspace/ventures/northstar/purpose/README.md +3 -0
- package/schema/examples/workspace/ventures/northstar/venture.json +49 -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/founder.schema.json +72 -0
- package/schema/frame.schema.json +240 -0
- package/schema/frames.mjs +228 -0
- package/schema/freshness-log.schema.json +40 -0
- package/schema/freshness-profiles.schema.json +44 -0
- package/schema/freshness.mjs +473 -0
- package/schema/fund-terms.schema.json +107 -0
- package/schema/fund-thesis.schema.json +87 -0
- package/schema/gate-drafts.mjs +130 -0
- package/schema/gate.mjs +133 -0
- package/schema/glossary.schema.json +25 -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 +128 -0
- package/schema/integration.schema.json +143 -0
- package/schema/judgment.schema.json +38 -0
- package/schema/kit.schema.json +47 -0
- package/schema/kits.mjs +24 -0
- package/schema/knowledge-sources.schema.json +260 -0
- package/schema/layer.json +59 -0
- package/schema/layer.schema.json +119 -0
- package/schema/load-packages.mjs +26 -0
- package/schema/marketing-brand.schema.json +116 -0
- package/schema/marketing-sitemap.schema.json +232 -0
- package/schema/migrate-venture.mjs +192 -0
- package/schema/migrations/kit-to-package.mjs +94 -0
- package/schema/migrations/package-layout.mjs +86 -0
- package/schema/model-steps.mjs +717 -0
- package/schema/money-summary.schema.json +138 -0
- package/schema/naive-config.mjs +165 -0
- package/schema/naive-config.schema.json +268 -0
- package/schema/need-now.json +772 -0
- package/schema/need-now.mjs +108 -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 +252 -0
- package/schema/payouts.mjs +91 -0
- package/schema/people.schema.json +86 -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/public-assets.schema.json +76 -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/release-read.mjs +111 -0
- package/schema/releases.mjs +497 -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/setup.mjs +164 -0
- package/schema/site-presence.schema.json +337 -0
- package/schema/stale.mjs +111 -0
- package/schema/start-release.mjs +41 -0
- package/schema/strategic-foundation.schema.json +74 -0
- package/schema/stream.schema.json +14 -0
- package/schema/structure.mjs +186 -0
- package/schema/systems-catalog.json +126 -0
- package/schema/systems-catalog.schema.json +78 -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/trigger.schema.json +44 -0
- package/schema/triggers.mjs +237 -0
- package/schema/upgrade-registry.schema.json +60 -0
- package/schema/upgrade-venture.mjs +107 -0
- package/schema/upgrades.json +69 -0
- package/schema/upgrades.mjs +385 -0
- package/schema/use-model.mjs +10 -0
- package/schema/validate.py +58 -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-role.schema.json +64 -0
- package/schema/venture-type.mjs +62 -0
- package/schema/venture-types.json +346 -0
- package/schema/venture-types.schema.json +129 -0
- package/schema/venture.schema.json +460 -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,313 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The Naive agent harness (EE-054, EE-058, EE-059): takes a founder's idea dump through Discovery with
|
|
3
|
+
// a real agent, start to end. The dump is not a prompt: it is every idea the founder has about the
|
|
4
|
+
// venture, kept verbatim. Naive maps it onto its conventions (the idea map), asks its own product
|
|
5
|
+
// questions first and fails closed on them, and decides what the agent sees and may do: need-now
|
|
6
|
+
// picks the kit, the router gates every write, the agent's proposals wait for the founder, and routes
|
|
7
|
+
// an open decision unlocks stay closed. The agent is one the founder already has (Claude Code,
|
|
8
|
+
// headless); Naive holds no model key. Platform tools are handed to the agent beside Naive's own MCP
|
|
9
|
+
// server, or spawned by path, never imported: Jev tags the ideas when TYPESAFE_API_KEY is set, and
|
|
10
|
+
// Firecrawl researches the market when FIRECRAWL_API_KEY is set. With --money, the founder's money source
|
|
11
|
+
// (Rho; its sandbox by default) fills the venture's money package, and the agent sees only its summary.
|
|
12
|
+
//
|
|
13
|
+
// node interface/harness/run.mjs discovery --dump <ideas.md> [--id <slug>] [--name <name>] [--founder <name>]
|
|
14
|
+
// [--workspace <dir>] [--board] [--yes] [--steps <n>] [--money sandbox|live|<fixture.json>]
|
|
15
|
+
//
|
|
16
|
+
// --board serves the decision board at http://127.0.0.1:4331/ and the idea map at /map
|
|
17
|
+
// --yes the founder settles the top-ranked decisions as worded (rehearsals and tests)
|
|
18
|
+
// --steps how many decisions the founder settles between the agent's passes (default 3)
|
|
19
|
+
// --money syncs money/ from Rho (sandbox, live with RHO_API_TOKEN, or a saved fixture) before pass 1
|
|
20
|
+
//
|
|
21
|
+
// 1. Naive maps the dump (Jev, else the agent tags it with the same conventions), then structures the
|
|
22
|
+
// map as an idea graph: a Merkle DAG with signal and lanes (EE-060).
|
|
23
|
+
// 2. Pass 1: the agent reads the idea map, drafts answers to Naive's product questions and the problem
|
|
24
|
+
// record from the founder's own ideas, researches the market, and proposes the decisions the founder
|
|
25
|
+
// owes.
|
|
26
|
+
// 3. The founder settles the top-ranked decisions, one at a time, in the order Naive ranks them.
|
|
27
|
+
// 4. Pass 2: the agent assesses the accepted problem, does the work the decisions unlocked, and reports
|
|
28
|
+
// what comes next.
|
|
29
|
+
// 5. Naive writes the venture package view: the packages open now, each record confirmed, to review or
|
|
30
|
+
// to write, what moves now and what waits (EE-067, EE-069). The founder confirms Mentura's
|
|
31
|
+
// understanding of the ideas between the graph and the agent's first pass (Understand, EE-069).
|
|
32
|
+
|
|
33
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
34
|
+
import { copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
|
|
35
|
+
import { tmpdir } from "node:os";
|
|
36
|
+
import { basename, join, resolve } from "node:path";
|
|
37
|
+
import { decisions } from "../../schema/decisions.mjs";
|
|
38
|
+
import { docket } from "../../schema/docket.mjs";
|
|
39
|
+
import { CONVENTIONS, DUMP, MAP, parse, render, split, summary, clean, request, fromAnswers } from "../../purpose/frameworks/idea-map/ideamap.mjs";
|
|
40
|
+
import { GRAPH, build as buildGraph, request as graphRequest } from "../../purpose/frameworks/idea-map/graph.mjs";
|
|
41
|
+
import { understood } from "../../purpose/frameworks/idea-map/route.mjs";
|
|
42
|
+
import { createHash } from "node:crypto";
|
|
43
|
+
import { agentFromEnv, record as prov } from "../provenance.mjs";
|
|
44
|
+
import { evaluate } from "./evals.mjs";
|
|
45
|
+
|
|
46
|
+
const repo = new URL("../../", import.meta.url).pathname;
|
|
47
|
+
const argv = process.argv.slice(2);
|
|
48
|
+
const opt = (n) => { const i = argv.indexOf(`--${n}`); return i >= 0 ? argv[i + 1] : undefined; };
|
|
49
|
+
const flag = (n) => argv.includes(`--${n}`);
|
|
50
|
+
const phase = argv[0];
|
|
51
|
+
const dumpFile = opt("dump");
|
|
52
|
+
if (phase !== "discovery" || !dumpFile || !existsSync(dumpFile)) {
|
|
53
|
+
console.error("usage: node interface/harness/run.mjs discovery --dump <ideas.md> [--id <slug>] [--name <name>] [--founder <name>] [--workspace <dir>] [--board] [--yes] [--steps <n>]");
|
|
54
|
+
process.exit(2);
|
|
55
|
+
}
|
|
56
|
+
const id = opt("id") ?? basename(dumpFile).replace(/\..*$/, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
57
|
+
const founder = opt("founder") ?? process.env.MENTURA_PERSON ?? "Founder";
|
|
58
|
+
const ws = resolve(opt("workspace") ?? join(mkdtempSync(join(tmpdir(), "naive-run-")), "workspace"));
|
|
59
|
+
const dir = join(ws, "ventures", id);
|
|
60
|
+
const steps = Number(opt("steps") ?? 3);
|
|
61
|
+
const jev = Boolean(process.env.TYPESAFE_API_KEY ?? process.env.TYPESAFEAI_API_KEY);
|
|
62
|
+
const research = Boolean(process.env.FIRECRAWL_API_KEY);
|
|
63
|
+
const t0 = Date.now();
|
|
64
|
+
const laps = [];
|
|
65
|
+
const lap = (what) => { const s = (Date.now() - t0) / 1000; laps.push({ at: s, what }); console.log(`\n[${s.toFixed(1)}s] ${what}`); };
|
|
66
|
+
const cli = (...args) => spawnSync("node", [join(repo, "interface/cli/mentura.mjs"), ...args], { env: { ...process.env, MENTURA_WORKSPACE: ws }, encoding: "utf8" });
|
|
67
|
+
|
|
68
|
+
// The venture, scaffolded by Naive, and the founder's dump, kept as they wrote it.
|
|
69
|
+
if (!existsSync(join(dir, "venture.json"))) {
|
|
70
|
+
const p = spawnSync("node", [join(repo, "schema/init-venture.mjs"), dir, id, "--phase", phase], { encoding: "utf8" });
|
|
71
|
+
if (p.status !== 0) { console.error(p.stderr || p.stdout); process.exit(1); }
|
|
72
|
+
if (opt("name")) { const v = JSON.parse(readFileSync(join(dir, "venture.json"), "utf8")); v.name = opt("name"); writeFileSync(join(dir, "venture.json"), JSON.stringify(v, null, 2) + "\n"); }
|
|
73
|
+
}
|
|
74
|
+
mkdirSync(join(dir, "purpose/ideas"), { recursive: true });
|
|
75
|
+
copyFileSync(dumpFile, join(dir, DUMP));
|
|
76
|
+
prov(dir, { entity: DUMP, route: "purpose/idea-dump", activity: "create", agent: agentFromEnv("person", "harness", { id: founder }), note: "the founder's idea dump, verbatim" });
|
|
77
|
+
lap(`venture ${id} scaffolded in ${ws}; idea dump saved (${readFileSync(dumpFile, "utf8").length} characters)`);
|
|
78
|
+
|
|
79
|
+
// Money (EE-070): the money source stays the system of record. Naive syncs pointers and a summary into
|
|
80
|
+
// the money data package; transactions stay in a sensitive stream that neither the agent nor the trace sees.
|
|
81
|
+
let money = null;
|
|
82
|
+
if (opt("money")) {
|
|
83
|
+
const m = opt("money");
|
|
84
|
+
const src = m === "live" ? ["--live"] : m === "sandbox" ? [] : ["--fixture", resolve(m)];
|
|
85
|
+
const p = spawnSync("node", [join(repo, "platform/integrations/rho.mjs"), "sync", "--venture", dir, ...src], { encoding: "utf8" });
|
|
86
|
+
if (p.status === 0 && existsSync(join(dir, "money/_summary.json"))) {
|
|
87
|
+
money = JSON.parse(readFileSync(join(dir, "money/_summary.json"), "utf8"));
|
|
88
|
+
prov(dir, { entity: "money/_summary.json", route: "money/_summary", activity: "create", agent: agentFromEnv("agent", "harness", { id: "naive-money" }), note: `synced from ${money.source}; ${money.transactions} transactions kept as pointers in a sensitive stream` });
|
|
89
|
+
lap(`money synced from ${money.source}${money.business ? ` (${money.business})` : ""}: cash ${(money.cash.amount / 100).toFixed(2)} ${money.cash.currency}, monthly net ${(money.monthly_net.amount / 100).toFixed(2)}, runway ${money.runway_months ?? "not limited by burn"}, as of ${money.as_of}`);
|
|
90
|
+
} else console.log(` money sync failed, so the run goes on without it: ${(p.stderr || p.stdout).trim().slice(0, 300)}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const servers = { naive: { command: "node", args: [join(repo, "interface/mcp/server.mjs")], env: { MENTURA_WORKSPACE: ws, MENTURA_PERSON: founder } } };
|
|
94
|
+
if (research) servers.research = { command: "node", args: [join(repo, "platform/mcp/research.mjs")], env: { FIRECRAWL_API_KEY: process.env.FIRECRAWL_API_KEY } };
|
|
95
|
+
const mcp = join(ws, ".mcp-harness.json");
|
|
96
|
+
writeFileSync(mcp, JSON.stringify({ mcpServers: servers }));
|
|
97
|
+
|
|
98
|
+
let board = null;
|
|
99
|
+
if (flag("board")) { process.env.MENTURA_WORKSPACE = ws; board = (await import("../demo/board.mjs")).serve(4331, id); console.log("Decision board: http://127.0.0.1:4331/ Idea map: http://127.0.0.1:4331/map"); }
|
|
100
|
+
|
|
101
|
+
// The trace (EE-058): every step and every tool call the agent made, with timings, for LangSmith.
|
|
102
|
+
const iso = () => new Date().toISOString();
|
|
103
|
+
const trace = { name: `naive discovery: ${id}`, run_type: "chain", start: iso(), inputs: { dump: DUMP, ideas: readFileSync(join(dir, DUMP), "utf8"), founder, phase }, children: [], metadata: {
|
|
104
|
+
venture: id, venture_id: id, pipeline_step: phase, money: money?.source ?? null,
|
|
105
|
+
// LangSmith groups a founder's runs into one thread by thread_id: one session per venture per day.
|
|
106
|
+
thread_id: process.env.NAIVE_SESSION ?? `${id}-${new Date().toISOString().slice(0, 10)}`,
|
|
107
|
+
harness_version: spawnSync("git", ["rev-parse", "--short", "HEAD"], { cwd: repo, encoding: "utf8" }).stdout.trim() || null,
|
|
108
|
+
} };
|
|
109
|
+
const researched = [];
|
|
110
|
+
if (money) trace.children.push({ name: "money: sync", run_type: "tool", start: iso(), end: iso(), inputs: { source: money.source }, outputs: { summary: money } });
|
|
111
|
+
|
|
112
|
+
// The agent runs headless and streams what it does; each tool call becomes a child run.
|
|
113
|
+
async function agent(prompt, label, { tools = "mcp__naive__*,mcp__research__*", quiet = false } = {}) {
|
|
114
|
+
lap(`agent: ${label}`);
|
|
115
|
+
const node = { name: label, run_type: "chain", start: iso(), inputs: { prompt }, children: [] };
|
|
116
|
+
trace.children.push(node);
|
|
117
|
+
// No built-in tools (no shell, no file access): the agent works only through the MCP servers it is handed.
|
|
118
|
+
const args = ["-p", prompt, "--output-format", "stream-json", "--verbose", "--tools", "", ...(tools ? ["--mcp-config", mcp, "--strict-mcp-config", "--allowedTools", tools] : ["--strict-mcp-config"])];
|
|
119
|
+
const child = spawn("claude", args, { stdio: ["ignore", "pipe", "inherit"], env: { ...process.env, MENTURA_WORKSPACE: ws } });
|
|
120
|
+
const open = new Map();
|
|
121
|
+
let result = null, buf = "";
|
|
122
|
+
child.stdout.on("data", (chunk) => {
|
|
123
|
+
buf += chunk;
|
|
124
|
+
let nl;
|
|
125
|
+
while ((nl = buf.indexOf("\n")) >= 0) {
|
|
126
|
+
const line = buf.slice(0, nl); buf = buf.slice(nl + 1);
|
|
127
|
+
let ev; try { ev = JSON.parse(line); } catch { continue; }
|
|
128
|
+
for (const c of ev.message?.content ?? []) {
|
|
129
|
+
if (c.type === "tool_use") {
|
|
130
|
+
const t = { name: c.name.replace(/^mcp__/, ""), run_type: "tool", start: iso(), inputs: c.input ?? {}, children: [] };
|
|
131
|
+
open.set(c.id, t); node.children.push(t);
|
|
132
|
+
if (!quiet) console.log(` > ${t.name}${c.input?.route ? ` ${c.input.route}` : c.input?.queries ? ` ${JSON.stringify(c.input.queries)}` : c.input?.id ? ` ${c.input.id}` : ""}`);
|
|
133
|
+
} else if (c.type === "tool_result" && open.has(c.tool_use_id)) {
|
|
134
|
+
const t = open.get(c.tool_use_id);
|
|
135
|
+
const text = Array.isArray(c.content) ? c.content.map((x) => x.text ?? "").join("") : String(c.content ?? "");
|
|
136
|
+
Object.assign(t, { end: iso(), outputs: { result: text.slice(0, 20000) }, ...(c.is_error ? { error: text.slice(0, 2000) } : {}) });
|
|
137
|
+
if (t.name.startsWith("research__")) for (const m of text.matchAll(/"url":\s*"([^"]+)"/g)) researched.push(m[1]);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (ev.type === "result") result = ev;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
const code = await new Promise((r) => child.on("close", r));
|
|
144
|
+
if (code !== 0 || !result || result.is_error) {
|
|
145
|
+
// Say why: the reason is in the agent's own result (an expired login, a refused tool), not in its exit code.
|
|
146
|
+
const why = (result?.result ?? "").trim();
|
|
147
|
+
node.error = `the agent stopped with status ${code}${why ? `: ${why}` : ""}${/log ?in|\/login|authenticat/i.test(why) ? " (run claude, then /login, and start again)" : ""}`;
|
|
148
|
+
console.error(node.error); finish(1); if (!board) process.exit(1); await new Promise(() => {});
|
|
149
|
+
}
|
|
150
|
+
Object.assign(node, { end: iso(), outputs: { report: result.result }, metadata: { cost_usd: result.total_cost_usd, turns: result.num_turns, usage: result.usage } });
|
|
151
|
+
if (!quiet) console.log(result.result.trim().split("\n").map((l) => ` ${l}`).join("\n"));
|
|
152
|
+
return result.result;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// The run's evals and trace: written beside the workspace, and sent to LangSmith when a key is set.
|
|
156
|
+
function finish(code = 0) {
|
|
157
|
+
trace.end = iso();
|
|
158
|
+
const evals = existsSync(join(dir, DUMP)) ? evaluate(dir, { researched, settled }) : [];
|
|
159
|
+
trace.feedback = evals;
|
|
160
|
+
// What the run drafted, so a judge reading only the root run (LangSmith's online evaluators, Jev)
|
|
161
|
+
// sees the problem record and the agent's reports beside the founder's dump in the inputs.
|
|
162
|
+
const problem = join(dir, "purpose/validation/problem.json");
|
|
163
|
+
const drafted = { problem: existsSync(problem) ? JSON.parse(readFileSync(problem, "utf8")) : null, reports: trace.children.filter((c) => c.outputs?.report).map((c) => ({ pass: c.name, report: c.outputs.report })) };
|
|
164
|
+
trace.outputs = { settled, docket: { steps: docketSteps, now: compact(docket(dir)) }, drafted, evals: Object.fromEntries(evals.map((e) => [e.key, e.score])), laps };
|
|
165
|
+
writeFileSync(join(ws, "trace.json"), JSON.stringify(trace, null, 2) + "\n");
|
|
166
|
+
console.log(`\nEvals:\n${evals.map((e) => ` ${e.score === 1 ? "pass" : e.score === 0 ? "FAIL" : "part"} ${e.key.padEnd(26)} ${e.score} ${e.comment}`).join("\n")}`);
|
|
167
|
+
if (process.env.LANGSMITH_API_KEY) {
|
|
168
|
+
const p = spawnSync("node", [join(repo, "platform/integrations/langsmith.mjs"), join(ws, "trace.json")], { encoding: "utf8" });
|
|
169
|
+
console.log(p.status === 0 ? `LangSmith: ${p.stdout.trim()}` : `LangSmith upload failed: ${(p.stderr || p.stdout).trim()}`);
|
|
170
|
+
}
|
|
171
|
+
// The board keeps serving the finished run, or the stopped one, so the founder can see where it got to.
|
|
172
|
+
if (board) { console.log(`\nThe board keeps serving${code ? " what the run got to" : ""}: http://127.0.0.1:4331/ and /map. Ctrl-C to stop. Workspace: ${ws}`); return; }
|
|
173
|
+
board?.close();
|
|
174
|
+
process.exit(code);
|
|
175
|
+
}
|
|
176
|
+
const settled = [];
|
|
177
|
+
const docketSteps = [];
|
|
178
|
+
const compact = (k) => ({ leading: k.functions[0]?.function ?? null, functions: k.functions.map((f) => ({ function: f.function, attention: f.attention,
|
|
179
|
+
decisions: f.decisions.slice(0, 3).map((d) => ({ id: d.id, question: d.question, value: d.value, dominant: d.dominant, why: d.why })) })) });
|
|
180
|
+
|
|
181
|
+
// 1. The idea map: Jev tags each idea with Naive's conventions; without Jev, the agent does, with the
|
|
182
|
+
// same vocabulary. Either way the ideas stay verbatim and unknown tags are dropped.
|
|
183
|
+
const ideas = split(readFileSync(join(dir, DUMP), "utf8"));
|
|
184
|
+
const venture = JSON.parse(readFileSync(join(dir, "venture.json"), "utf8"));
|
|
185
|
+
let tags, tagger;
|
|
186
|
+
const mapNode = { name: "idea map", run_type: "tool", start: iso(), inputs: { ideas: ideas.length }, children: [] };
|
|
187
|
+
if (jev) {
|
|
188
|
+
const p = spawnSync("node", [join(repo, "platform/integrations/jev.mjs")], { input: JSON.stringify(request(ideas, venture)), encoding: "utf8", maxBuffer: 1 << 26 });
|
|
189
|
+
if (p.status !== 0) { console.error(p.stderr); process.exit(1); }
|
|
190
|
+
const out = JSON.parse(p.stdout);
|
|
191
|
+
tags = fromAnswers(out.answers);
|
|
192
|
+
tagger = out.model ?? "jev";
|
|
193
|
+
console.log(` Jev answered ${Object.keys(out.answers).length} typed questions in ${out.ms} ms (${out.requests} requests)`);
|
|
194
|
+
} else {
|
|
195
|
+
const text = await agent(`Tag each idea below with Naive's conventions. Answer with JSON only, no prose: {"<idea id>": {"departments": [...], "records": [...], "exists": true|false}}.
|
|
196
|
+
departments (at most ${CONVENTIONS.max.departments}, the ones the idea is mainly about): ${JSON.stringify(CONVENTIONS.departments)}
|
|
197
|
+
records (at most ${CONVENTIONS.max.records}, the ones it mainly feeds): ${JSON.stringify(Object.fromEntries(Object.entries(CONVENTIONS.records).map(([k, v]) => [k, v.about])))}
|
|
198
|
+
exists: true only if ${CONVENTIONS.exists}.
|
|
199
|
+
Ideas: ${JSON.stringify(Object.fromEntries(ideas.map((i) => [i.id, i.section ? `[${i.section}] ${i.text}` : i.text])))}`, "tagging the ideas (no Jev key)", { tools: null, quiet: true });
|
|
200
|
+
tags = JSON.parse(text.slice(text.indexOf("{"), text.lastIndexOf("}") + 1));
|
|
201
|
+
tagger = "claude-code";
|
|
202
|
+
}
|
|
203
|
+
writeFileSync(join(dir, MAP), render(ideas, clean(tags), { venture: id, tagger }));
|
|
204
|
+
prov(dir, { entity: MAP, route: "purpose/idea-map", activity: "create", derived_from: [DUMP], agent: agentFromEnv("agent", "harness", { id: tagger }), note: `${ideas.length} ideas tagged with Naive's conventions` });
|
|
205
|
+
const sum = summary(parse(readFileSync(join(dir, MAP), "utf8")), phase);
|
|
206
|
+
trace.children.push(Object.assign(mapNode, { end: iso(), outputs: { tagger, summary: sum }, metadata: { tagger } }));
|
|
207
|
+
lap(`idea map: ${sum.ideas} ideas; ${Object.entries(sum.by_pillar).map(([k, v]) => `${k} ${v}`).join(", ")}; clusters ${sum.strengths.map((s) => s.department).join(", ")}; ${sum.product.reading}`);
|
|
208
|
+
|
|
209
|
+
// 1b. The idea graph: the map's structured form. Jev judges which ideas build on which; without Jev,
|
|
210
|
+
// Naive's record order does. Signal, lanes and layout follow in code.
|
|
211
|
+
const graphNode = { name: "idea graph", run_type: "tool", start: iso(), inputs: { ideas: ideas.length }, children: [] };
|
|
212
|
+
const mapIdeas = parse(readFileSync(join(dir, MAP), "utf8")).ideas;
|
|
213
|
+
let graphAnswers = null;
|
|
214
|
+
if (jev) {
|
|
215
|
+
const p = spawnSync("node", [join(repo, "platform/integrations/jev.mjs")], { input: JSON.stringify(graphRequest(mapIdeas, venture)), encoding: "utf8", maxBuffer: 1 << 26 });
|
|
216
|
+
if (p.status === 0) { const out = JSON.parse(p.stdout); graphAnswers = out.answers; console.log(` Jev answered ${Object.keys(out.answers).length} dependency and concreteness questions in ${out.ms} ms`); }
|
|
217
|
+
else console.log(` Jev could not judge the dependencies (${p.stderr.trim().slice(0, 200)}); using Naive's record order`);
|
|
218
|
+
}
|
|
219
|
+
const g = buildGraph(mapIdeas, { answers: graphAnswers, phase, venture: id, source: `${MAP}@${createHash("sha256").update(readFileSync(join(dir, MAP))).digest("hex").slice(0, 16)}` });
|
|
220
|
+
writeFileSync(join(dir, GRAPH), JSON.stringify(g, null, 2) + "\n");
|
|
221
|
+
prov(dir, { entity: GRAPH, route: "purpose/idea-graph", activity: "create", derived_from: [MAP], agent: agentFromEnv("agent", "harness", { id: g.judged_by }), note: `Merkle root ${g.root}` });
|
|
222
|
+
trace.children.push(Object.assign(graphNode, { end: iso(), outputs: { root: g.root, edges: g.edges.length, lanes: g.lanes.map((l) => ({ mode: l.mode, ideas: l.ideas.length })), next: g.next } }));
|
|
223
|
+
lap(`idea graph: ${g.edges.length} dependencies (${g.judged_by}); ${g.lanes.filter((l) => l.mode === "sync").length} lane(s) in order, ${g.lanes.filter((l) => l.mode === "async").length} on their own; develop next: ${g.next.join(", ")}; root ${g.root}`);
|
|
224
|
+
|
|
225
|
+
// 1c. Understand (EE-069): the founder confirms Mentura read their ideas right, after correcting the
|
|
226
|
+
// map or the graph, before anything is routed.
|
|
227
|
+
if (flag("yes")) {
|
|
228
|
+
const u = cli("understand", "--venture", id, "--confirm", "ideas", "--note", "rehearsal: confirmed as mapped");
|
|
229
|
+
if (u.status !== 0) { console.error(u.stderr || u.stdout); process.exit(1); }
|
|
230
|
+
} else {
|
|
231
|
+
lap("waiting for the founder to confirm the understanding of their ideas (mentura understand)");
|
|
232
|
+
while (!understood(dir)) await new Promise((r) => setTimeout(r, 1000));
|
|
233
|
+
}
|
|
234
|
+
trace.children.push({ name: "founder: understand", run_type: "chain", start: iso(), end: iso(), inputs: { map: MAP, graph: GRAPH }, outputs: { understood: true } });
|
|
235
|
+
lap("the founder confirmed Mentura's understanding of the ideas; routing them");
|
|
236
|
+
|
|
237
|
+
const rules = `You are the builder agent (agent_id builder) for the venture ${id}. Work only through the naive MCP tools${research ? " and the research tools" : ""}; pass agent_id "builder" on every naive call.
|
|
238
|
+
Rules: the founder's idea dump is theirs. Quote it, cite ideas by id (i-01...), never put words in their mouth. Never invent evidence: every evidence item cites a URL a research result gave you${research ? "" : " (you have no research tool in this run, so leave evidence empty and say so)"}. Records Naive treats as the founder's are written as drafts for the founder to accept; that is expected. You never decide; you propose. knowledge/venture-profile cannot be written over MCP; skip it.${money ? `
|
|
239
|
+
Money: Naive synced the venture's money summary from ${money.source}, the system of record (money/_summary.json): ${JSON.stringify(money)}. Amounts are in minor units (cents). Any proposal or record that touches money (pricing, spend, hiring, runway, fundraising) cites "money/_summary.json as of ${money.as_of}" and uses only the figures the summary gives; never estimate the founder's finances.` : ""}`;
|
|
240
|
+
|
|
241
|
+
await agent(`${rules}
|
|
242
|
+
The founder has just submitted an idea dump. Naive mapped it onto its conventions.
|
|
243
|
+
1. mentura_run purpose/ideas: read every idea, where they cluster and what the dump never mentions. mentura_run purpose/ideas/graph: which ideas build on which, the lanes that move in order and the ones that can move on their own, and the highest-signal ideas to develop next. mentura_run purpose/ideas/routes: where each idea goes in the framework, each destination's stage and its next step. Then mentura_decisions: Naive's own product questions come first (product-exists, then core-product, then flagship) and fail closed.
|
|
244
|
+
2. Propose an answer to product-exists with mentura_propose_decision (id "product-exists", at "products", name "product.exists", same question), worded from the ideas tagged exists and citing them by id. Do not change its parent, boundary or unlocks.
|
|
245
|
+
2b. If the dump says anything about a team or cofounders, propose wording for founding-team (id "founding-team", at "", name "venture.team", same question), starting with Solo, Cofounders or Looking and quoting the idea; if it says nothing, leave it for the founder.
|
|
246
|
+
3. Write the problem record (purpose/validation/problem) from the founder's ideas: the problem in their words, who has it, and the assumptions to test. Read mentura_layout first.${research ? `
|
|
247
|
+
4. Research the market with research_search: existing alternatives and competitors the dump names or implies, prices, and people describing the problem. Add what you find to the problem record as evidence with URLs.` : ""}
|
|
248
|
+
5. Propose two or three more decisions the founder owes from what the dump leaves open (at "purpose/validation", name "problem.<topic>"), each with your proposed answer, the ids of the ideas it comes from in "ideas", a due time within 72 hours if urgent, one or two projected outcomes, and unlocks for ["builder"].
|
|
249
|
+
6. mentura_decisions and report, in at most eight lines: what the idea map shows (clusters and gaps), your answer to product-exists, what the evidence supports, and the founder's decisions in rank order.`, "pass 1: idea map, product questions, problem, research, proposals");
|
|
250
|
+
|
|
251
|
+
// 3. The founder settles what the docket ranks first, one decision at a time (EE-075): the function that
|
|
252
|
+
// needs attention most, then its highest-value decision the founder can settle now. Each step's docket
|
|
253
|
+
// goes in the trace, so a judge can check that the ranking was the right next step.
|
|
254
|
+
for (let n = 0; n < steps; n++) {
|
|
255
|
+
const r = decisions(dir);
|
|
256
|
+
const k = docket(dir);
|
|
257
|
+
const pick = k.functions.flatMap((f) => f.decisions).find((d) => d.action && ["decide", "accept", "confirm"].includes(d.action.kind) && !settled.includes(d.id));
|
|
258
|
+
const next = pick && r.decisions.find((d) => d.id === pick.id);
|
|
259
|
+
if (!next) break;
|
|
260
|
+
next.why = pick.why;
|
|
261
|
+
docketSteps.push({ step: n + 1, ...compact(k), chose: pick.id });
|
|
262
|
+
trace.children.push({ name: `docket: step ${n + 1}`, run_type: "chain", start: iso(), end: iso(), inputs: { venture: id }, outputs: docketSteps.at(-1) });
|
|
263
|
+
lap(`docket: ${k.functions.map((f) => `${f.function} ${f.attention}`).join(" · ")}; next ${pick.id} (${pick.function}, value ${pick.value}${pick.dominant ? ", outweighs every other function" : ""})`);
|
|
264
|
+
console.log(`\nFOUNDER #${n + 1}: ${next.id}: ${next.question}\n Why now: ${(next.why ?? []).join("; ")}${next.answer ? `\n Proposed: ${next.answer}` : ""}\n ${next.action.command.replace(/^mentura /, `MENTURA_WORKSPACE=${ws} node ${join(repo, "interface/cli/mentura.mjs")} `)}`);
|
|
265
|
+
const before = JSON.stringify(r.decisions.find((d) => d.id === next.id));
|
|
266
|
+
if (flag("yes")) {
|
|
267
|
+
const a = next.action;
|
|
268
|
+
const p = a.kind === "decide" ? cli("decide", next.id, "--venture", id, "--by", founder, ...(next.answer ? [] : ["--answer", "Not yet: it is still an idea"]), "--confirm", a.confirm)
|
|
269
|
+
: a.kind === "accept" ? cli("accept", a.route, "--venture", id, "--confirm", a.confirm) : cli("confirm", a.statement, "--venture", id, "--confirm", a.confirm);
|
|
270
|
+
if (p.status !== 0) { console.error(` could not settle ${next.id}: ${(p.stderr || p.stdout).trim()}`); settled.push(next.id); continue; }
|
|
271
|
+
} else {
|
|
272
|
+
lap(`waiting for the founder to settle ${next.id}`);
|
|
273
|
+
while (JSON.stringify(decisions(dir).decisions.find((d) => d.id === next.id)) === before) await new Promise((r) => setTimeout(r, 1000));
|
|
274
|
+
}
|
|
275
|
+
settled.push(next.id);
|
|
276
|
+
const now = decisions(dir).decisions.find((d) => d.id === next.id);
|
|
277
|
+
trace.children.push({ name: `founder: ${next.id}`, run_type: "chain", start: iso(), end: iso(), inputs: { question: next.question, why: next.why, proposed: next.answer ?? null, action: next.action.kind }, outputs: { status: now?.status, provenance: now?.provenance ?? null } });
|
|
278
|
+
lap(`${next.id} settled${now?.provenance?.approved_by ? ` by ${now.provenance.approved_by} (${now.provenance.wording} the wording)` : ""}`);
|
|
279
|
+
}
|
|
280
|
+
if (!settled.length) { lap("nothing for the founder to settle; stopping"); finish(1); process.exit(1); }
|
|
281
|
+
|
|
282
|
+
// 4. The work the founder's decisions unlocked.
|
|
283
|
+
await agent(`${rules}
|
|
284
|
+
The founder settled: ${settled.join(", ")}. mentura_decisions shows what that unlocked. First, if the founder accepted the problem record, mentura_run purpose/validation/assess with as_is true and note what the evidence supports. Then do the work the decisions unlock for you: if product-exists is decided, write product cards (purpose/product/<id>) for what exists or is planned, from the founder's ideas, citing them; then propose wording for core-product with mentura_propose_decision (id "core-product", at "products", name "product.core", the same question; mentura_decisions shows it), from the ideas tagged venture-core, citing them. Then mentura_run purpose/ideas/routes and draft the highest-signal destination still in Routed that moves in order and has no record yet (not the problem, not products), from its ideas, citing them. Then mentura_decisions again and report in at most six lines: what the assessment says, what you did, and the founder's next decision with why it ranks first.`, "pass 2: the work the decisions unlocked");
|
|
285
|
+
|
|
286
|
+
// 5. The venture package (EE-067, EE-069): the question matrix settles which packages are open (Jev
|
|
287
|
+
// answers what the records leave open), and the view shows each package's state, what moves now and
|
|
288
|
+
// what waits. The sitemap is a marketing record: it is planned only once the marketing package is open.
|
|
289
|
+
let pkgArgs = [];
|
|
290
|
+
if (jev) {
|
|
291
|
+
const rq = spawnSync("node", [join(repo, "schema/packages.mjs"), "request", dir], { encoding: "utf8" });
|
|
292
|
+
const q = rq.status === 0 ? JSON.parse(rq.stdout) : null;
|
|
293
|
+
if (q && Object.keys(q.questions).length) {
|
|
294
|
+
const p = spawnSync("node", [join(repo, "platform/integrations/jev.mjs")], { input: JSON.stringify(q), encoding: "utf8" });
|
|
295
|
+
if (p.status === 0) { writeFileSync(join(ws, "package-answers.json"), p.stdout); pkgArgs = ["--answers", join(ws, "package-answers.json")]; console.log(` Jev answered ${Object.keys(q.questions).length} of the question matrix's questions`); }
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
let pk = spawnSync("node", [join(repo, "schema/packages.mjs"), dir, ...pkgArgs, "--json"], { encoding: "utf8" });
|
|
299
|
+
if (pk.status === 0 && JSON.parse(pk.stdout).core.some((x) => x.id === "marketing" && x.in === "now")) {
|
|
300
|
+
const sp = spawnSync("node", [join(repo, "operations/marketing/site/plan.mjs"), dir, "--write"], { encoding: "utf8" });
|
|
301
|
+
if (sp.status === 0) prov(dir, { entity: "operations/marketing/sitemap.json", route: "operations/marketing/sitemap", activity: "create", derived_from: ["purpose/icp.json", "products/"], agent: agentFromEnv("agent", "harness", { id: "naive-planner" }), note: "the site planned from the venture's records: the marketing package is open" });
|
|
302
|
+
}
|
|
303
|
+
pk = spawnSync("node", [join(repo, "schema/packages.mjs"), dir, ...pkgArgs, "--write", "--json"], { encoding: "utf8" });
|
|
304
|
+
if (pk.status === 0) {
|
|
305
|
+
const r = JSON.parse(pk.stdout);
|
|
306
|
+
const open = r.core.filter((x) => x.in === "now");
|
|
307
|
+
trace.children.push({ name: "venture package", run_type: "tool", start: iso(), end: iso(), inputs: { phase: r.phase }, outputs: { progress: r.progress, open: open.map((x) => ({ id: x.id, state: x.state, progress: x.progress, moving: x.moving, missing: x.missing })), questions_open: r.situation.questions.filter((x) => x.value == null).map((x) => x.id) } });
|
|
308
|
+
lap(`venture package: ${Math.round(r.progress * 100)}% across ${open.map((x) => `${x.title} (${x.state}, ${Math.round(x.progress * 100)}%)`).join(", ")}; next phase: ${r.core.filter((x) => x.in === "next").map((x) => x.title).join(", ") || "none"}; view in ${join(dir, "package")}`);
|
|
309
|
+
} else console.log(` the venture package failed: ${pk.stderr.trim().slice(0, 300)}`);
|
|
310
|
+
|
|
311
|
+
const end = decisions(dir);
|
|
312
|
+
lap(`done. ${end.decisions.filter((d) => d.source === "file").length} decision records, ${end.decisions.filter((d) => d.rank != null).length} ranked for the founder, ${settled.length} settled; workspace ${ws}`);
|
|
313
|
+
finish(0);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Site presence, end to end (EE-062): read a venture's website, have Jev judge which pages say what,
|
|
3
|
+
// and score how present the venture's public records are, weighed by who the site must speak to now.
|
|
4
|
+
// The reading and the judging are platform scripts, spawned by path (EE-041); the scoring is Naive's.
|
|
5
|
+
// Without a Jev key the scoring falls back to the matrix's keywords and says so.
|
|
6
|
+
//
|
|
7
|
+
// node interface/harness/site.mjs <url> [--venture <dir>] [--raising] [--hiring] [--contributors] [--pages 10] [--json]
|
|
8
|
+
|
|
9
|
+
import { spawn } from "node:child_process";
|
|
10
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
11
|
+
import { dirname, join } from "node:path";
|
|
12
|
+
import { fileURLToPath } from "node:url";
|
|
13
|
+
import { factsOf, icpOf, request, score, PRESENCE } from "../../operations/marketing/site/presence.mjs";
|
|
14
|
+
|
|
15
|
+
const repo = join(dirname(fileURLToPath(import.meta.url)), "../..");
|
|
16
|
+
const run = (script, args, input) => new Promise((resolve) => {
|
|
17
|
+
const p = spawn("node", [join(repo, script), ...args], { stdio: ["pipe", "pipe", "pipe"] });
|
|
18
|
+
let out = "", err = "";
|
|
19
|
+
p.stdout.on("data", (d) => (out += d)); p.stderr.on("data", (d) => (err += d));
|
|
20
|
+
p.on("close", (code) => resolve({ code, out, err }));
|
|
21
|
+
p.stdin.end(input ?? "");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
/** Read, judge and score one site. Returns the presence result; writes it into the venture if given. */
|
|
25
|
+
export async function scan(url, { venture = null, flags = {}, pages = 10, log = () => {} } = {}) {
|
|
26
|
+
const t0 = Date.now();
|
|
27
|
+
const r = await run("platform/integrations/site.mjs", [url, "--pages", String(pages)]);
|
|
28
|
+
if (r.code !== 0) throw new Error(`could not read ${url}: ${r.err.trim() || `exit ${r.code}`}`);
|
|
29
|
+
const site = JSON.parse(r.out);
|
|
30
|
+
log(`read ${site.pages.filter((p) => !p.error).length} pages of ${site.site} via ${site.via} in ${Date.now() - t0} ms`);
|
|
31
|
+
const icp = icpOf(venture, site);
|
|
32
|
+
let answers = null;
|
|
33
|
+
if (process.env.TYPESAFE_API_KEY || process.env.TYPESAFEAI_API_KEY) {
|
|
34
|
+
const j = await run("platform/integrations/jev.mjs", [], JSON.stringify(request(site, icp)));
|
|
35
|
+
if (j.code === 0) { const a = JSON.parse(j.out); answers = a.answers; log(`Jev answered ${Object.keys(answers).length} typed questions in ${a.ms} ms`); }
|
|
36
|
+
else log(`Jev failed (${j.err.trim().slice(0, 200)}); judging by keywords instead`);
|
|
37
|
+
} else log("no Jev key: judging by keywords, which is rougher");
|
|
38
|
+
const facts = factsOf(venture, flags);
|
|
39
|
+
const result = score(site, { answers, facts, icp, venture: venture ? JSON.parse(readFileSync(join(venture, "venture.json"), "utf8")).id : null });
|
|
40
|
+
if (venture) { mkdirSync(join(venture, dirname(PRESENCE)), { recursive: true }); writeFileSync(join(venture, PRESENCE), JSON.stringify(result, null, 2) + "\n"); }
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
45
|
+
const url = process.argv[2];
|
|
46
|
+
const opt = (n) => { const i = process.argv.indexOf(`--${n}`); return i > 0 ? process.argv[i + 1] : null; };
|
|
47
|
+
const has = (n) => process.argv.includes(`--${n}`);
|
|
48
|
+
if (!url || url.startsWith("--")) { console.error("usage: node interface/harness/site.mjs <url> [--venture <dir>] [--raising] [--hiring] [--contributors] [--pages 10] [--json]"); process.exit(2); }
|
|
49
|
+
const flags = Object.fromEntries(["raising", "hiring", "contributors"].filter(has).map((k) => [k, true]));
|
|
50
|
+
scan(url, { venture: opt("venture"), flags, pages: Number(opt("pages") ?? 10), log: (m) => console.error(m) }).then((r) => {
|
|
51
|
+
if (has("json")) return console.log(JSON.stringify(r, null, 2));
|
|
52
|
+
console.log(`${r.site}: site presence ${r.score}/100 (${r.judged_by})`);
|
|
53
|
+
console.log(`Customers: ${r.icp.types.map((t) => `${t.label}${t.p != null ? ` ${t.p}` : ""}`).join(", ")}; ICP from ${r.icp.cite}`);
|
|
54
|
+
for (const n of r.sitemap) console.log(` ${n.ghost ? "+" : " "} ${n.path.padEnd(28)} ${n.type.padEnd(9)} ${n.rating == null ? (n.read ? "-" : "not read") : n.rating}${n.missing.length ? ` missing: ${n.missing.join(", ")}` : ""}`);
|
|
55
|
+
console.log(`By audience: ${Object.entries(r.audiences).map(([k, v]) => `${k} ${v.score}${v.weight >= 0.5 ? "" : " (not a priority)"}`).join(", ")}`);
|
|
56
|
+
for (const x of r.items) console.log(`${x.score === 1 ? "ok " : x.score ? "low " : "miss"} ${x.label.padEnd(28)} ${x.note}`);
|
|
57
|
+
console.log(`Fix first: ${r.fix_first.join(", ") || "nothing"}`);
|
|
58
|
+
}, (e) => { console.error(e.message); process.exit(1); });
|
|
59
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Instrumentation (Naive's instrumentation.ts, P-4; logging fetches in development, F-4). One hook
|
|
2
|
+
// where every router call, every judgment and every provenance entry (write, draft, accept,
|
|
3
|
+
// confirm, decision) emits an event. Listeners registered in-process get every event. When a venture
|
|
4
|
+
// turns instrumentation on, events are also appended to <venture>/.naive/events.jsonl, which agent
|
|
5
|
+
// vitals read (interface/vitals.mjs, N-6). Provenance stays the record of what changed; events are
|
|
6
|
+
// what it cost. A platform exporter (platform/integrations/langsmith.mjs) can ship a trace made from
|
|
7
|
+
// the events; the framework names no vendor.
|
|
8
|
+
//
|
|
9
|
+
// Turn it on in the venture's naive.config.json, like adding instrumentation.ts to a Next.js app:
|
|
10
|
+
//
|
|
11
|
+
// { "instrumentation": { "events": true } }
|
|
12
|
+
//
|
|
13
|
+
// NAIVE_INSTRUMENT=1 turns it on for every venture in this process, and NAIVE_INSTRUMENT=0 off.
|
|
14
|
+
// No dependencies and no network. An event holds routes, sizes and times, never record content.
|
|
15
|
+
|
|
16
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
17
|
+
import { randomUUID } from "node:crypto";
|
|
18
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
|
|
21
|
+
export const EVENTS = ".naive/events.jsonl";
|
|
22
|
+
const listeners = new Set();
|
|
23
|
+
const scope = new AsyncLocalStorage();
|
|
24
|
+
|
|
25
|
+
/** Tokens a payload costs an agent, estimated as characters / 4 (the common rule of thumb). */
|
|
26
|
+
export const tokens = (x) => Math.ceil((x === undefined ? 0 : typeof x === "string" ? x.length : (JSON.stringify(x) ?? "").length) / 4);
|
|
27
|
+
|
|
28
|
+
/** Registers a listener for every event, like register() in instrumentation.ts. Returns the unregister. */
|
|
29
|
+
export function register(fn) { listeners.add(fn); return () => listeners.delete(fn); }
|
|
30
|
+
|
|
31
|
+
const configOf = (dir) => {
|
|
32
|
+
const f = dir && join(dir, "naive.config.json");
|
|
33
|
+
if (!f || !existsSync(f)) return {};
|
|
34
|
+
try { return JSON.parse(readFileSync(f, "utf8")); } catch { return {}; }
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/** Whether a venture writes its events log. */
|
|
38
|
+
export function enabled(dir) {
|
|
39
|
+
if (process.env.NAIVE_INSTRUMENT === "0") return false;
|
|
40
|
+
if (process.env.NAIVE_INSTRUMENT === "1") return !!dir;
|
|
41
|
+
const i = configOf(dir).instrumentation;
|
|
42
|
+
return i === true || i?.events === true;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Emits one event: to every listener, and to the venture's events log when it is on. */
|
|
46
|
+
export function emit(dir, event) {
|
|
47
|
+
const e = { at: new Date().toISOString(), id: randomUUID(), session: process.env.MENTURA_SESSION ?? null, ...event };
|
|
48
|
+
for (const k of Object.keys(e)) if (e[k] === undefined) delete e[k];
|
|
49
|
+
for (const fn of listeners) { try { fn(e, dir); } catch {} }
|
|
50
|
+
if (dir && enabled(dir)) {
|
|
51
|
+
try { mkdirSync(join(dir, ".naive"), { recursive: true }); appendFileSync(join(dir, EVENTS), JSON.stringify(e) + "\n"); } catch {}
|
|
52
|
+
}
|
|
53
|
+
return e;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The venture's events, oldest first. */
|
|
57
|
+
export function events(dir) {
|
|
58
|
+
const f = join(dir, EVENTS);
|
|
59
|
+
if (!existsSync(f)) return [];
|
|
60
|
+
return readFileSync(f, "utf8").split("\n").filter((l) => l.trim()).flatMap((l) => { try { return [JSON.parse(l)]; } catch { return []; } });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Wraps one router call: times it, measures what it sends back, and emits a call event. A call made
|
|
65
|
+
* inside another (a view reads its record, the overview runs its slots) carries its parent's id, so
|
|
66
|
+
* vitals count only what the agent asked for. dirOf resolves the venture folder.
|
|
67
|
+
*/
|
|
68
|
+
export async function instrumented(args, fn, dirOf) {
|
|
69
|
+
const parent = scope.getStore() ?? null;
|
|
70
|
+
const id = randomUUID();
|
|
71
|
+
const t0 = performance.now();
|
|
72
|
+
const r = await scope.run(id, () => fn(args));
|
|
73
|
+
if (process.env.NAIVE_INSTRUMENT === "0" && !listeners.size) return r;
|
|
74
|
+
let dir = null;
|
|
75
|
+
try { dir = args.venture ? dirOf(args.venture, args.workspace) : null; } catch {}
|
|
76
|
+
if (!dir && !listeners.size) return r;
|
|
77
|
+
const useful = !!r?.ok && r.result !== null && r.result !== undefined && !r.needs_input;
|
|
78
|
+
emit(dir, { kind: "call", id, parent, session: args.session ?? args.input?.session ?? process.env.MENTURA_SESSION ?? null, venture: args.venture ?? null, route: args.route, action: args.action,
|
|
79
|
+
ok: !!r?.ok, useful, ms: Math.round(performance.now() - t0), tokens: tokens(r?.result ?? r?.error), actor: args.actor ?? "agent", via: args.via ?? "router" });
|
|
80
|
+
return r;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Records one judgment (a System 1 call or a scored check): what was asked, the score and the outcome. */
|
|
84
|
+
export function judgment(dir, { question, score, threshold, outcome, owner, model, route, ms }) {
|
|
85
|
+
return emit(dir, { kind: "judgment", question, score, threshold, outcome, owner, model, route, ms });
|
|
86
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// The boundary around a kit's agent workflow (S-15): the Next.js advice to wrap a third-party component
|
|
2
|
+
// that uses client features, with the library author declaring "use client". A kit (Mentura's enhanced
|
|
3
|
+
// package, platform/kits/<name>/kit.json) declares, under boundary, what its workflow reads, what it
|
|
4
|
+
// writes and which of its steps use a model:
|
|
5
|
+
//
|
|
6
|
+
// { "name": "...", "package": "<the package it extends>",
|
|
7
|
+
// "boundary": { "reads": [<route globs>], "writes": [<route globs>], "use_model": [<model steps>] } }
|
|
8
|
+
//
|
|
9
|
+
// wrap(kit) returns the router's call with that boundary around it: a read outside reads or writes, a
|
|
10
|
+
// write outside writes, or a command it does not read is refused as an expected error, and every call
|
|
11
|
+
// acts as the kit's agent, never as a person. A kit that uses a model writes judgments, so it declares
|
|
12
|
+
// knowledge/judgment/** in writes. This module reads kit.json as data and never imports from platform/.
|
|
13
|
+
//
|
|
14
|
+
// node interface/kit-boundary.mjs <kit.json> check one kit's boundary
|
|
15
|
+
|
|
16
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
import { call as routerCall, glob, repo, routes } from "./router.mjs";
|
|
19
|
+
// schema/model-steps.mjs is imported inside checkKit, not here, because it imports wrap from this module.
|
|
20
|
+
|
|
21
|
+
const ID = /^[a-z0-9][a-z0-9-]*$/;
|
|
22
|
+
export const actorOf = (kit) => `kit-${kit.name}`;
|
|
23
|
+
const any = (globs, route) => (globs ?? []).some((g) => glob(g).test(route));
|
|
24
|
+
const reachable = (b, route) => any(b.reads, route) || any(b.writes, route);
|
|
25
|
+
|
|
26
|
+
/** Errors in a kit's declared boundary, its model steps included. */
|
|
27
|
+
export async function checkKit(kit) {
|
|
28
|
+
const { checkSteps, inputOf } = await import("../schema/model-steps.mjs");
|
|
29
|
+
const e = [];
|
|
30
|
+
if (!kit || typeof kit !== "object") return ["a kit.json is an object"];
|
|
31
|
+
if (typeof kit.name !== "string" || !ID.test(kit.name)) e.push("a kit has a name of lowercase letters, digits and hyphens");
|
|
32
|
+
if (typeof kit.package !== "string" || !existsSync(join(repo, "packages", kit.package, "package.json"))) e.push(`kit ${kit.name}: package ${kit.package} is not a package in packages/ (a kit extends one package and never replaces it)`);
|
|
33
|
+
const b = kit.boundary;
|
|
34
|
+
if (!b || typeof b !== "object") { e.push(`kit ${kit.name}: declares a boundary: what it reads, what it writes, which steps use a model`); return e; }
|
|
35
|
+
for (const k of ["reads", "writes", "use_model"]) if (!Array.isArray(b[k])) e.push(`kit ${kit.name}: boundary.${k} is an array${k === "use_model" ? ", empty when it calls no model" : ""}`);
|
|
36
|
+
if (e.length) return e;
|
|
37
|
+
const all = routes().map((r) => r.route);
|
|
38
|
+
for (const g of [...b.reads, ...b.writes]) if (!all.some((r) => glob(g).test(r) || glob(g).test(r.replace("[id]", "x")))) e.push(`kit ${kit.name}: ${g} matches no route`);
|
|
39
|
+
const steps = b.use_model.map((s) => ({ ...s, package: kit.name }));
|
|
40
|
+
e.push(...(await checkSteps(steps)).map((x) => `kit ${x}`));
|
|
41
|
+
for (const s of steps) {
|
|
42
|
+
if (s.for_each && !reachable(b, s.for_each)) e.push(`kit ${kit.name}/${s.step}: reads ${s.for_each}, outside the kit's reads`);
|
|
43
|
+
for (const i of s.inputs ?? []) { const p = inputOf(i); if (p.form === "route" && !reachable(b, p.route)) e.push(`kit ${kit.name}/${s.step}: input ${i} is outside the kit's reads`); }
|
|
44
|
+
for (const spec of Object.values(s.computed ?? {})) {
|
|
45
|
+
const route = spec?.count ?? (spec?.read ? String(spec.read).split("#")[0] : null);
|
|
46
|
+
if (route && !reachable(b, route)) e.push(`kit ${kit.name}/${s.step}: computes from ${route}, outside the kit's reads`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (steps.length && !any(b.writes, "knowledge/judgment/x")) e.push(`kit ${kit.name}: uses a model, so it writes judgments: declare knowledge/judgment/** in boundary.writes`);
|
|
50
|
+
return e;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** The router's call, wrapped in the kit's boundary. */
|
|
54
|
+
export function wrap(kit, call = routerCall) {
|
|
55
|
+
const b = kit.boundary ?? { reads: [], writes: [], use_model: [] };
|
|
56
|
+
return async (args) => {
|
|
57
|
+
const route = args.route;
|
|
58
|
+
const act = args.action === "write" ? "write" : "read";
|
|
59
|
+
const ok = act === "write" ? any(b.writes, route) : reachable(b, route);
|
|
60
|
+
if (!ok) return { ok: false, outcome: "expected", error: `kit ${kit.name} declares no ${act} of ${route} (boundary.${act === "write" ? "writes" : "reads"} in its kit.json)` };
|
|
61
|
+
// The kit's workflow is an agent, whatever the caller passed.
|
|
62
|
+
return call({ ...args, actor: "agent", actor_id: actorOf(kit), provenance: { ...(args.provenance ?? {}), note: `kit ${kit.name}${args.provenance?.note ? `: ${args.provenance.note}` : ""}` } });
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
67
|
+
const f = process.argv[2];
|
|
68
|
+
if (!f) { console.error("usage: node interface/kit-boundary.mjs <kit.json>"); process.exit(2); }
|
|
69
|
+
const kit = JSON.parse(readFileSync(f, "utf8"));
|
|
70
|
+
const e = await checkKit(kit);
|
|
71
|
+
if (e.length) { console.error(e.join("\n")); process.exit(1); }
|
|
72
|
+
console.log(`kit ${kit.name}: reads ${kit.boundary.reads.length} route patterns, writes ${kit.boundary.writes.length}, ${kit.boundary.use_model.length} model steps, inside its boundary.`);
|
|
73
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"layer": "interface",
|
|
3
|
+
"purpose": "Let a person, with agents, work across at least three of the five other layers in one session: agent harnesses (Claude Code, Cursor) and custom interfaces (the operator console), all reaching the system through one route table that a CLI, an MCP server and an HTTP API share (EE-030).",
|
|
4
|
+
"product": "everything-ecosystem/console",
|
|
5
|
+
"skills": [
|
|
6
|
+
{
|
|
7
|
+
"id": "install-mentura",
|
|
8
|
+
"path": "interface/skills/install-mentura/SKILL.md"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"id": "naive-setup",
|
|
12
|
+
"path": "interface/skills/naive-setup/SKILL.md"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"records": [
|
|
16
|
+
"route-aliases",
|
|
17
|
+
"adapter"
|
|
18
|
+
],
|
|
19
|
+
"reads": [
|
|
20
|
+
"integration"
|
|
21
|
+
],
|
|
22
|
+
"writes": [],
|
|
23
|
+
"checks": [
|
|
24
|
+
"schema/check-integrations.mjs",
|
|
25
|
+
"interface/test.mjs",
|
|
26
|
+
"interface/adapters.mjs"
|
|
27
|
+
],
|
|
28
|
+
"gaps": [
|
|
29
|
+
"The operator console is a folder, not part of the layer yet",
|
|
30
|
+
"Cannot yet run roles in separate sessions, so one agent can play builder and reviewer",
|
|
31
|
+
"The CLI cannot tell a person from an agent; the pull request a person merges is the gate that holds",
|
|
32
|
+
"The HTTP API has no authentication and binds to 127.0.0.1 only",
|
|
33
|
+
"Views are Markdown; the operator console does not render them yet",
|
|
34
|
+
"Route groups cover phases only; MAD tiers become groups once record types declare a tier"
|
|
35
|
+
],
|
|
36
|
+
"name": "interface"
|
|
37
|
+
}
|