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,79 @@
|
|
|
1
|
+
// The file system connector (EE-037): a folder, inside a git repository or not. It is the default
|
|
2
|
+
// source: a venture without a source map keeps every record in its own folder, through this.
|
|
3
|
+
//
|
|
4
|
+
// root the folder (absolute)
|
|
5
|
+
// writes direct (default) or none
|
|
6
|
+
// venture true when the root is a venture folder: listing stops at a nested venture (it has
|
|
7
|
+
// its own records) and skips the venture's private _ folders, as the router always has
|
|
8
|
+
//
|
|
9
|
+
// version is the git blob SHA-1 of the content. When the file is committed and unchanged, read
|
|
10
|
+
// also gives the last commit that touched it.
|
|
11
|
+
|
|
12
|
+
import { spawnSync } from "node:child_process";
|
|
13
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, writeFileSync } from "node:fs";
|
|
14
|
+
import { dirname, join } from "node:path";
|
|
15
|
+
import { blobSha, isText, matches, safePath } from "./contract.mjs";
|
|
16
|
+
|
|
17
|
+
const SKIP = new Set(["node_modules"]);
|
|
18
|
+
|
|
19
|
+
export function connect({ id = "venture", root, writes = "direct", venture = false } = {}) {
|
|
20
|
+
if (!root) throw new Error("the filesystem connector needs a root folder");
|
|
21
|
+
if (writes === "pull-request") throw new Error("the filesystem connector writes direct or none");
|
|
22
|
+
|
|
23
|
+
const walk = (d, rel = "") => !existsSync(d) ? [] : readdirSync(d, { withFileTypes: true }).flatMap((e) => {
|
|
24
|
+
if (e.name.startsWith(".") || SKIP.has(e.name)) return [];
|
|
25
|
+
const r = rel ? `${rel}/${e.name}` : e.name;
|
|
26
|
+
if (e.isDirectory()) {
|
|
27
|
+
if (venture && (existsSync(join(d, e.name, "venture.json")) || (!rel && e.name.startsWith("_")))) return [];
|
|
28
|
+
return walk(join(d, e.name), r);
|
|
29
|
+
}
|
|
30
|
+
return e.isFile() ? [r] : [];
|
|
31
|
+
});
|
|
32
|
+
const file = (p) => join(root, safePath(p));
|
|
33
|
+
const git = (...args) => spawnSync("git", ["-C", root, ...args], { encoding: "utf8" });
|
|
34
|
+
const lastCommit = (p, content) => {
|
|
35
|
+
const tracked = git("ls-files", "-s", "--", p);
|
|
36
|
+
if (tracked.status !== 0 || !tracked.stdout) return null;
|
|
37
|
+
if (tracked.stdout.split(/\s+/)[1] !== blobSha(content) || git("diff", "--quiet", "HEAD", "--", p).status !== 0) return null;
|
|
38
|
+
return git("log", "-1", "--format=%H", "--", p).stdout.trim() || null;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const c = {
|
|
42
|
+
id, kind: "filesystem", writes, root,
|
|
43
|
+
async list(prefix = "") {
|
|
44
|
+
const pre = prefix ? safePath(prefix) : "";
|
|
45
|
+
return walk(root).filter((p) => !pre || p === pre || p.startsWith(`${pre}/`)).sort()
|
|
46
|
+
.map((path) => ({ path, version: blobSha(readFileSync(join(root, path))) }));
|
|
47
|
+
},
|
|
48
|
+
async read(p) {
|
|
49
|
+
const f = file(p);
|
|
50
|
+
if (!existsSync(f) || !statSync(f).isFile()) return null;
|
|
51
|
+
const content = readFileSync(f, "utf8");
|
|
52
|
+
const commit = lastCommit(safePath(p), content);
|
|
53
|
+
return { path: safePath(p), content, version: blobSha(readFileSync(f)), ...(commit ? { commit } : {}) };
|
|
54
|
+
},
|
|
55
|
+
async version(p) {
|
|
56
|
+
const f = file(p);
|
|
57
|
+
return existsSync(f) && statSync(f).isFile() ? blobSha(readFileSync(f)) : null;
|
|
58
|
+
},
|
|
59
|
+
async search(query, { limit = 50 } = {}) {
|
|
60
|
+
const out = [];
|
|
61
|
+
for (const path of walk(root).sort()) {
|
|
62
|
+
if (out.length >= limit) break;
|
|
63
|
+
const content = readFileSync(join(root, path), "utf8");
|
|
64
|
+
if (isText(path, content) && matches(`${path}\n${content}`, query)) out.push({ path, version: blobSha(content) });
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
},
|
|
68
|
+
async write(p, content, _opts = {}) {
|
|
69
|
+
if (writes === "none") throw new Error(`${id} is read-only`);
|
|
70
|
+
const f = file(p);
|
|
71
|
+
mkdirSync(dirname(f), { recursive: true });
|
|
72
|
+
const tmp = `${f}.tmp-${process.pid}`;
|
|
73
|
+
writeFileSync(tmp, content);
|
|
74
|
+
renameSync(tmp, f);
|
|
75
|
+
return { path: safePath(p), version: blobSha(content) };
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
return c;
|
|
79
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Sources and connectors (EE-037). The knowledge layer federates: records stay in the sources a
|
|
2
|
+
// venture already uses, and the router reaches each through a connector with one contract
|
|
3
|
+
// (contract.mjs). Nothing is copied.
|
|
4
|
+
//
|
|
5
|
+
// The registry knowledge/tooling/integrations.json: an integration with a `connector` names
|
|
6
|
+
// the module that implements the contract for it.
|
|
7
|
+
// A source map <venture>/knowledge/sources.json (optional): the venture's sources, and which
|
|
8
|
+
// record types live in which source. A record type it does not name, and every
|
|
9
|
+
// record of a venture without a map, lives in the venture's own folder (the
|
|
10
|
+
// `venture` source). The venture folder itself (venture.json, the provenance log,
|
|
11
|
+
// drafts) always stays on the file system.
|
|
12
|
+
//
|
|
13
|
+
// A record keeps its route's file path inside whatever source holds it: products/kettle.json is
|
|
14
|
+
// products/kettle.json under the source's root.
|
|
15
|
+
|
|
16
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
17
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
18
|
+
import { conformance } from "./contract.mjs";
|
|
19
|
+
import { ANY, resolve as resolveRule } from "./resolve.mjs";
|
|
20
|
+
|
|
21
|
+
const repo = new URL("../..", import.meta.url).pathname;
|
|
22
|
+
const load = (p) => JSON.parse(readFileSync(p, "utf8"));
|
|
23
|
+
export const MAP = "knowledge/sources.json";
|
|
24
|
+
export const LOCAL = "venture";
|
|
25
|
+
|
|
26
|
+
let fetchImpl = null;
|
|
27
|
+
/** Points every GitHub-style connector at another fetch (the evals' fake GitHub); null restores the real one. */
|
|
28
|
+
export const useFetch = (f) => { fetchImpl = f; };
|
|
29
|
+
|
|
30
|
+
/** The connector registry: integration id -> { module, writes, ... } from knowledge/tooling/integrations.json. */
|
|
31
|
+
export function registry() {
|
|
32
|
+
return new Map(load(join(repo, "knowledge/tooling/integrations.json")).filter((t) => t.connector).map((t) => [t.id, { id: t.id, name: t.name, ...t.connector }]));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** A venture's source map, with the implicit venture source first. */
|
|
36
|
+
export function sourcesOf(dir) {
|
|
37
|
+
const own = existsSync(join(dir, MAP)) ? load(join(dir, MAP)) : { sources: [], records: {} };
|
|
38
|
+
return { sources: [{ id: LOCAL, connector: "filesystem", root: ".", writes: "direct", implicit: true }, ...(own.sources ?? [])], records: own.records ?? {}, rules: own.rules ?? [], mapped: existsSync(join(dir, MAP)) };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The source a record type lives in, for a context (EE-042): the system of record of the most
|
|
43
|
+
* specific rule that holds (resolve.mjs). The venture's phase comes from venture.json; product,
|
|
44
|
+
* account and actor come from the caller. With no rule, the venture's own folder.
|
|
45
|
+
*/
|
|
46
|
+
export function sourceFor(dir, recordType, context = {}) {
|
|
47
|
+
const m = sourcesOf(dir);
|
|
48
|
+
let phase;
|
|
49
|
+
try { phase = JSON.parse(readFileSync(join(dir, "venture.json"), "utf8")).phase; } catch {}
|
|
50
|
+
const hit = resolveRule(m, { record: recordType, ...(phase ? { phase } : {}), ...context });
|
|
51
|
+
if (hit?.ties.length) throw new Error(`${MAP}: ${hit.ties.length} rules for ${recordType} tie at the same specificity; make one more specific`);
|
|
52
|
+
const id = hit?.rule.system_of_record ?? LOCAL;
|
|
53
|
+
const s = m.sources.find((x) => x.id === id);
|
|
54
|
+
if (!s) throw new Error(`${MAP} puts ${recordType} in ${id}, which is not one of its sources`);
|
|
55
|
+
return s;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The attributes of a record type mastered somewhere other than the record itself, for a context
|
|
60
|
+
* (EE-042): [{ attribute, source }]. Such an attribute is kept in its source at the record's own
|
|
61
|
+
* path, as a JSON object holding only that attribute ({ "price": 12 }); a vendor's connector maps
|
|
62
|
+
* that onto its own system. The router reads each one from there and writes it there.
|
|
63
|
+
*/
|
|
64
|
+
export function attributeSources(dir, recordType, context = {}) {
|
|
65
|
+
const m = sourcesOf(dir);
|
|
66
|
+
const whole = sourceFor(dir, recordType, context);
|
|
67
|
+
let phase;
|
|
68
|
+
try { phase = JSON.parse(readFileSync(join(dir, "venture.json"), "utf8")).phase; } catch {}
|
|
69
|
+
const names = [...new Set((m.rules ?? []).filter((r) => r.record === recordType && r.attribute !== ANY).map((r) => r.attribute))];
|
|
70
|
+
return names.flatMap((attribute) => {
|
|
71
|
+
const hit = resolveRule(m, { record: recordType, attribute, ...(phase ? { phase } : {}), ...context });
|
|
72
|
+
if (!hit || hit.rule.attribute === ANY) return [];
|
|
73
|
+
if (hit.ties.length) throw new Error(`${MAP}: ${hit.ties.length} rules for ${recordType}.${attribute} tie at the same specificity; make one more specific`);
|
|
74
|
+
const source = m.sources.find((x) => x.id === hit.rule.system_of_record);
|
|
75
|
+
if (!source) throw new Error(`${MAP} masters ${recordType}.${attribute} in ${hit.rule.system_of_record}, which is not one of its sources`);
|
|
76
|
+
return source.id === whole.id ? [] : [{ attribute, source }];
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const cache = new Map();
|
|
81
|
+
/** A connected connector for one source of one venture. */
|
|
82
|
+
export async function connect(source, dir) {
|
|
83
|
+
const reg = registry().get(source.connector);
|
|
84
|
+
if (!reg) throw new Error(`no connector ${source.connector}: knowledge/tooling/integrations.json has ${[...registry().keys()].join(", ")}`);
|
|
85
|
+
const mod = cache.get(reg.module) ?? await import(join(repo, reg.module));
|
|
86
|
+
cache.set(reg.module, mod);
|
|
87
|
+
const opts = { ...source };
|
|
88
|
+
delete opts.connector; delete opts.implicit;
|
|
89
|
+
if (source.connector === "filesystem") {
|
|
90
|
+
opts.root = isAbsolute(source.root ?? ".") ? source.root : resolve(dir, source.root ?? ".");
|
|
91
|
+
opts.venture = source.id === LOCAL;
|
|
92
|
+
} else if (fetchImpl) opts.fetch = fetchImpl;
|
|
93
|
+
const c = mod.connect(opts);
|
|
94
|
+
const problems = conformance(c);
|
|
95
|
+
if (problems.length) throw new Error(`${reg.module} does not meet the connector contract: ${problems.join("; ")}`);
|
|
96
|
+
return c;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Every source of a venture, connected. */
|
|
100
|
+
export async function connectAll(dir) {
|
|
101
|
+
return Promise.all(sourcesOf(dir).sources.map(async (s) => ({ source: s, connector: await connect(s, dir) })));
|
|
102
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// The source-of-truth matrix (EE-042). A venture's source map may hold rules: each names, for one
|
|
2
|
+
// record type in one context, its system of record (the source reads come from and writes go to)
|
|
3
|
+
// and its owner. Rules are written for a fast model to read: flat, one context per rule, every
|
|
4
|
+
// context field present, "*" meaning any. Resolution itself is deterministic and needs no model:
|
|
5
|
+
// the matching rule with the most fields that are not "*" wins; a tie is an error the check
|
|
6
|
+
// reports. A record type no rule names falls back to `records` (the EE-037 shorthand) and then to
|
|
7
|
+
// the venture's own folder.
|
|
8
|
+
//
|
|
9
|
+
// context phase the venture's phase (venture.json), or "*"
|
|
10
|
+
// product the product id the record is about, or "*"
|
|
11
|
+
// account the account id the record is about, or "*"
|
|
12
|
+
// actor person or agent, or "*"
|
|
13
|
+
// attribute "*" for the whole record, or one top-level field; an attribute rule
|
|
14
|
+
// names where that field is mastered (a price in Stripe, say). The router
|
|
15
|
+
// reads that field from there and writes it there (index.mjs,
|
|
16
|
+
// attributeSources), so the record's own file never holds a second copy.
|
|
17
|
+
|
|
18
|
+
export const ANY = "*";
|
|
19
|
+
export const CONTEXT = ["phase", "product", "account", "actor"];
|
|
20
|
+
export const FIELDS = ["record", "attribute", ...CONTEXT];
|
|
21
|
+
|
|
22
|
+
/** How many fields of a rule narrow it (the record type itself always matches). */
|
|
23
|
+
export const specificity = (rule) => ["attribute", ...CONTEXT].filter((k) => rule[k] !== ANY).length;
|
|
24
|
+
|
|
25
|
+
/** The rules a map states, the `records` shorthand included as rules that match anything. */
|
|
26
|
+
export function rulesOf(map) {
|
|
27
|
+
const short = Object.entries(map.records ?? {}).map(([record, system_of_record]) => ({ record, attribute: ANY, phase: ANY, product: ANY, account: ANY, actor: ANY, system_of_record, shorthand: true }));
|
|
28
|
+
return [...(map.rules ?? []), ...short];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The rule that holds for a query: { record, attribute?, phase?, product?, account?, actor? }.
|
|
33
|
+
* A field left out of the query matches only "*" in a rule, so a rule narrowed to a product never
|
|
34
|
+
* applies to a read that names no product. Returns { rule, specificity, ties } or null.
|
|
35
|
+
*/
|
|
36
|
+
export function resolve(map, query) {
|
|
37
|
+
const q = { attribute: ANY, ...query };
|
|
38
|
+
const fits = (rule) => rule.record === q.record && ["attribute", ...CONTEXT].every((k) => rule[k] === ANY || rule[k] === q[k]);
|
|
39
|
+
const hits = rulesOf(map).filter(fits).map((rule) => ({ rule, specificity: specificity(rule) - (rule.shorthand ? 0.5 : 0) }));
|
|
40
|
+
if (!hits.length) return null;
|
|
41
|
+
hits.sort((a, b) => b.specificity - a.specificity);
|
|
42
|
+
const ties = hits.filter((h) => h.specificity === hits[0].specificity).map((h) => h.rule);
|
|
43
|
+
return { rule: hits[0].rule, specificity: Math.ceil(hits[0].specificity), ties: ties.length > 1 ? ties : [] };
|
|
44
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// The connector contract suite (EE-037), shared by every connector's evals: the framework's
|
|
2
|
+
// (knowledge/connectors/eval.mjs) and the platform's (platform/connectors/eval.mjs). A connector
|
|
3
|
+
// written anywhere proves itself against this one suite (EE-041).
|
|
4
|
+
//
|
|
5
|
+
// const h = harness("name"); expect, throws, gitHash, write, scratch, finish
|
|
6
|
+
// await contract(h, "label", make); make(opts) -> { c, base(path), later(path, branch), pulls() }
|
|
7
|
+
|
|
8
|
+
import { spawnSync } from "node:child_process";
|
|
9
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
10
|
+
import { tmpdir } from "node:os";
|
|
11
|
+
import { dirname, join } from "node:path";
|
|
12
|
+
import { blobSha, conformance } from "./contract.mjs";
|
|
13
|
+
|
|
14
|
+
export function harness(name) {
|
|
15
|
+
let failed = 0, passed = 0, skipped = 0;
|
|
16
|
+
const scratch = mkdtempSync(join(tmpdir(), `mentura-${name}-`));
|
|
17
|
+
return {
|
|
18
|
+
scratch,
|
|
19
|
+
expect: (n, ok, detail = "") => { console.log(`${ok ? "ok " : "FAIL"} ${n}${!ok && detail ? `\n ${detail}` : ""}`); ok ? passed++ : failed++; },
|
|
20
|
+
throws: async (f, re) => { try { await f(); return false; } catch (e) { return re ? re.test(e.message) : true; } },
|
|
21
|
+
skip: (why) => { console.log(`skip ${why}`); skipped++; },
|
|
22
|
+
gitHash: (content) => spawnSync("git", ["hash-object", "--stdin"], { input: content, encoding: "utf8" }).stdout.trim(),
|
|
23
|
+
write: (root, files) => { for (const [p, c] of Object.entries(files)) { mkdirSync(dirname(join(root, p)), { recursive: true }); writeFileSync(join(root, p), c); } },
|
|
24
|
+
finish: () => {
|
|
25
|
+
rmSync(scratch, { recursive: true, force: true });
|
|
26
|
+
console.log(`\n${passed} passed, ${failed} failing${skipped ? `, ${skipped} skipped` : ""}`);
|
|
27
|
+
process.exit(failed ? 1 : 0);
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// The fixture: three items under the source's root, one outside it that must never show.
|
|
33
|
+
export const FIXTURE = {
|
|
34
|
+
"notes/alpha.md": "# Alpha\n\nThe kettle pilot ran in October with nine households.\n",
|
|
35
|
+
"notes/beta.md": "# Beta\n\nPricing interviews: most would pay monthly.\n",
|
|
36
|
+
"records/item.json": JSON.stringify({ id: "item", name: "Item one", tags: ["fixture"] }, null, 2) + "\n",
|
|
37
|
+
};
|
|
38
|
+
export const OUTSIDE = { "other/secret.md": "# Outside\n\nkettle text outside the root\n" };
|
|
39
|
+
export const UNICODE = "# Café ☕\n\nLine one\nLine two with ünïcode, emoji 🫖 and a tab\tend\n";
|
|
40
|
+
|
|
41
|
+
// ---- Contract ----------------------------------------------------------------------------------
|
|
42
|
+
// make() gives { c, base(path) -> content on the branch or folder reads come from, later(path) ->
|
|
43
|
+
// content where a write lands (the folder, or the pull request's branch), pulls() }.
|
|
44
|
+
export async function contract({ expect, throws, gitHash }, name, make) {
|
|
45
|
+
console.log(`\n# contract: ${name}`);
|
|
46
|
+
const t = await make();
|
|
47
|
+
const { c } = t;
|
|
48
|
+
expect(`${name}: meets the contract (list, read, version, search, write; writes ${c.writes})`, conformance(c).length === 0, conformance(c).join("; "));
|
|
49
|
+
const listed = await c.list();
|
|
50
|
+
expect(`${name}: list gives every item under the root and nothing outside it, sorted`, JSON.stringify(listed.map((x) => x.path)) === JSON.stringify(Object.keys(FIXTURE).sort()), JSON.stringify(listed.map((x) => x.path)));
|
|
51
|
+
expect(`${name}: list gives each item's version as its git blob SHA-1`, listed.every((x) => x.version === blobSha(FIXTURE[x.path])));
|
|
52
|
+
expect(`${name}: list(prefix) keeps to the prefix`, JSON.stringify((await c.list("notes")).map((x) => x.path)) === JSON.stringify(["notes/alpha.md", "notes/beta.md"]));
|
|
53
|
+
const a = await c.read("notes/alpha.md");
|
|
54
|
+
expect(`${name}: read gives the exact content`, a?.content === FIXTURE["notes/alpha.md"]);
|
|
55
|
+
expect(`${name}: read's version is what git hash-object prints for the content`, a?.version === gitHash(FIXTURE["notes/alpha.md"]), `${a?.version} vs ${gitHash(FIXTURE["notes/alpha.md"])}`);
|
|
56
|
+
expect(`${name}: version(path) matches read`, (await c.version("notes/alpha.md")) === a?.version);
|
|
57
|
+
expect(`${name}: JSON reads back as the same JSON`, JSON.parse((await c.read("records/item.json"))?.content ?? "null")?.name === "Item one");
|
|
58
|
+
expect(`${name}: a missing item reads as null, and has no version`, (await c.read("notes/nope.md")) === null && (await c.version("notes/nope.md")) === null);
|
|
59
|
+
expect(`${name}: a path that leaves the root is refused`, await throws(() => c.read("../other/secret.md"), /not a path inside/) && await throws(() => c.read("/etc/passwd"), /not a path inside/) && await throws(() => c.write("a/../../x.md", "x"), /not a path inside/));
|
|
60
|
+
const hits = await c.search("kettle pilot");
|
|
61
|
+
expect(`${name}: search finds the item holding every word, and only inside the root`, JSON.stringify(hits.map((x) => x.path)) === JSON.stringify(["notes/alpha.md"]) && hits[0].version === a?.version, JSON.stringify(hits));
|
|
62
|
+
expect(`${name}: search for words in no item finds nothing`, (await c.search("zebra quantum")).length === 0);
|
|
63
|
+
if (c.writes === "direct") {
|
|
64
|
+
const w = await c.write("notes/gamma.md", UNICODE);
|
|
65
|
+
expect(`${name}: a direct write lands in place and returns the new version`, w.version === blobSha(UNICODE) && (await c.read("notes/gamma.md"))?.content === UNICODE);
|
|
66
|
+
const w2 = await c.write("notes/alpha.md", FIXTURE["notes/alpha.md"] + "Added.\n");
|
|
67
|
+
expect(`${name}: overwriting changes the version`, w2.version !== a.version && (await c.version("notes/alpha.md")) === w2.version);
|
|
68
|
+
expect(`${name}: a written item is listed`, (await c.list()).some((x) => x.path === "notes/gamma.md"));
|
|
69
|
+
} else if (c.writes === "pull-request") {
|
|
70
|
+
const w = await c.write("notes/gamma.md", UNICODE, { message: "Add gamma" });
|
|
71
|
+
expect(`${name}: a write opens a draft pull request and returns its link and the new version`, /\/pull\/\d+$/.test(w.pull_request?.url ?? "") && w.version === blobSha(UNICODE) && t.pulls().at(-1)?.draft === true, JSON.stringify(w));
|
|
72
|
+
expect(`${name}: the branch reads come from is unchanged until the pull request is merged`, (await c.read("notes/gamma.md")) === null && t.base("notes/gamma.md") === null);
|
|
73
|
+
expect(`${name}: the pull request's branch holds the exact content`, t.later("notes/gamma.md", w.pull_request.branch) === UNICODE);
|
|
74
|
+
const w2 = await c.write("notes/alpha.md", FIXTURE["notes/alpha.md"] + "Added.\n");
|
|
75
|
+
expect(`${name}: overwriting an existing item opens its own pull request`, w2.pull_request.branch !== w.pull_request.branch && t.later("notes/alpha.md", w2.pull_request.branch).endsWith("Added.\n") && t.base("notes/alpha.md") === FIXTURE["notes/alpha.md"]);
|
|
76
|
+
}
|
|
77
|
+
const ro = await make({ writes: "none" });
|
|
78
|
+
expect(`${name}: a read-only source refuses writes`, await throws(() => ro.c.write("notes/x.md", "x"), /read-only/));
|
|
79
|
+
return t;
|
|
80
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"layer": "knowledge",
|
|
3
|
+
"purpose": "The memory layer: where every record is stored. The other layers each define the records they write here and the conventions for them; this layer defines only how a record is stored and found (route, schema, provenance), the decision log, the venture profile, design documents and the sources behind them. Storage is federated: records stay in the sources a venture already uses (its own folder by default, or a GitHub repository), reached through connectors with one contract, found through a catalog that copies no content (EE-036, EE-037).",
|
|
4
|
+
"product": "everything-ecosystem/knowledge-kit",
|
|
5
|
+
"skills": [
|
|
6
|
+
{
|
|
7
|
+
"id": "find-reference",
|
|
8
|
+
"path": "knowledge/skills/find-reference/SKILL.md",
|
|
9
|
+
"standalone": true
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"id": "industry-awareness",
|
|
13
|
+
"path": "knowledge/skills/industry-awareness/SKILL.md"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"records": [
|
|
17
|
+
"venture-profile",
|
|
18
|
+
"decision",
|
|
19
|
+
"design-document",
|
|
20
|
+
"nextjs-status",
|
|
21
|
+
"knowledge-sources",
|
|
22
|
+
"where-used"
|
|
23
|
+
],
|
|
24
|
+
"reads": [
|
|
25
|
+
"venture",
|
|
26
|
+
"product"
|
|
27
|
+
],
|
|
28
|
+
"writes": [
|
|
29
|
+
"reference"
|
|
30
|
+
],
|
|
31
|
+
"checks": [
|
|
32
|
+
"schema/check-sources.mjs",
|
|
33
|
+
"schema/check-where-used.mjs"
|
|
34
|
+
],
|
|
35
|
+
"gaps": [
|
|
36
|
+
"No check on the venture profile or design documents of its own; design-coverage (evidence) is the only one",
|
|
37
|
+
"Two connectors so far (filesystem and GitHub); a database, Notion, Slack or Salesforce each need their own module meeting the same contract",
|
|
38
|
+
"Checks and command routes (need-now, time-to-ready, validation score) still read the venture folder, so they do not yet see a record kept in another source",
|
|
39
|
+
"A merged pull request is not logged as an accept in provenance; the read after the merge is the only sign"
|
|
40
|
+
],
|
|
41
|
+
"name": "knowledge"
|
|
42
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: find-reference
|
|
3
|
+
description: "Find, confirm and record the source behind a reference in a layer's references/references.json: fill a missing URL from title, authors and year, re-check URLs that may have rotted, and add new references with a stance. Triggers: add a reference, cite this, where does this term come from, find the source for, check the references, a reference has no url. Do not trigger for general web research that will not be recorded as a reference."
|
|
4
|
+
type: skill
|
|
5
|
+
source: hybrid
|
|
6
|
+
created: 2026-10-27T04:16:38Z
|
|
7
|
+
ai-model: claude-opus-5.5
|
|
8
|
+
tags: [skill, everything-ecosystem, knowledge, references]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# find-reference
|
|
12
|
+
|
|
13
|
+
The system is opinionated: each layer names one default for each choice, and its references say where the default came from and what the alternatives were (EE-014). This skill keeps those references findable.
|
|
14
|
+
|
|
15
|
+
## Where references live
|
|
16
|
+
|
|
17
|
+
One file per layer: `<layer>/references/references.json`, checked by `schema/reference.schema.json`. Each record has an id, title, authors, year, kind, summary, what it informs (`phase:validation`, `noun:wedge`, `field:venture.industry`), and a stance (adopted, adapted, alternative or rejected, with why). A url and the date it was last checked are recorded when a page exists.
|
|
18
|
+
|
|
19
|
+
## Fill a missing URL
|
|
20
|
+
|
|
21
|
+
1. Search with the exact title, the first author's surname and the year.
|
|
22
|
+
2. Prefer, in order: the author's or publisher's own page, a standards body, a library or DOI record, an archive copy (for example web.archive.org or a maintained mirror), then a reputable summary. Never a page that only quotes a snippet.
|
|
23
|
+
3. Open the page and confirm the title, author and year match. If they differ, fix the record or say which part could not be confirmed.
|
|
24
|
+
4. Write `url` and `checked` (today, from `date -u +%F`). If nothing confirms it, leave the url out and add one line to the summary saying what was searched.
|
|
25
|
+
|
|
26
|
+
## Re-check URLs
|
|
27
|
+
|
|
28
|
+
Re-check any url whose `checked` date is older than 180 days, or when a reader reports it broken. If it no longer resolves, look for the same work on an archive or the publisher's new site, and update the url. Never delete the record: the title, authors and year still identify the work.
|
|
29
|
+
|
|
30
|
+
## Add a reference
|
|
31
|
+
|
|
32
|
+
Add one when a default, a noun or a gate is chosen because of a source, or when an alternative was weighed and set aside. Write the summary in your own words (one or two sentences), set `informs` to the nouns, phases, gates or fields it backs, and give the stance with a one-line why. A source that is a conversation (for example an AI chat a founder shared) gets kind `conversation` and no url.
|
|
33
|
+
|
|
34
|
+
## Rules
|
|
35
|
+
|
|
36
|
+
- Standards first: when a published standard exists, cite it and use its term with its meaning (EE-014).
|
|
37
|
+
- A reference informs a decision; it never makes one. The decision log records the choice.
|
|
38
|
+
- Keep each layer's file to the sources that layer's defaults rest on.
|