fuli-context 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/LICENSE +201 -0
- package/README.md +178 -0
- package/compose.graphiti.yml +86 -0
- package/dist/web/assets/ConnectionsPage-CY6H_mJJ.js +1 -0
- package/dist/web/assets/KnowledgeInspector-BSpz5Sfm.js +1 -0
- package/dist/web/assets/KnowledgeInspector-CHbB_0rC.css +1 -0
- package/dist/web/assets/KnowledgeOrganizerPage-BlEvhPrv.css +1 -0
- package/dist/web/assets/KnowledgeOrganizerPage-CvjGPlUc.js +1 -0
- package/dist/web/assets/KnowledgePage-Khuo3cNs.js +1 -0
- package/dist/web/assets/KnowledgeWorkspace-DVZusvem.js +4 -0
- package/dist/web/assets/OverviewPage-DC4C4Fhn.js +1 -0
- package/dist/web/assets/PersonalProfilePage-CSV9Mtgz.js +1 -0
- package/dist/web/assets/PersonalProfilePage-CVJ3TcRi.css +1 -0
- package/dist/web/assets/PersonalProjectsPage-A50EaseQ.js +1 -0
- package/dist/web/assets/PublicProjectsPage-BAdO_bae.js +1 -0
- package/dist/web/assets/ReviewPage-Dztk2jDG.js +1 -0
- package/dist/web/assets/console-tbvTUi6p.js +1 -0
- package/dist/web/assets/fuli-logo-DGuyqchQ.png +0 -0
- package/dist/web/assets/identity-B3s5CXhv.js +1 -0
- package/dist/web/assets/index-Devf7glZ.css +1 -0
- package/dist/web/assets/index-DwUDhQKc.js +6 -0
- package/dist/web/assets/model-DVT8sjy9.js +1 -0
- package/dist/web/assets/paths-B790iniO.js +1 -0
- package/dist/web/assets/runtime-dom.esm-bundler-DttsK21F.js +1 -0
- package/dist/web/assets/vue-router-BYTAoWT3.js +1 -0
- package/dist/web/index.html +22 -0
- package/graph-provider/Dockerfile +16 -0
- package/graph-provider/fuli_graph/__init__.py +5 -0
- package/graph-provider/fuli_graph/app.py +547 -0
- package/graph-provider/fuli_graph/auth.py +17 -0
- package/graph-provider/fuli_graph/collaboration_context.py +290 -0
- package/graph-provider/fuli_graph/config.py +34 -0
- package/graph-provider/fuli_graph/graph_models.py +123 -0
- package/graph-provider/fuli_graph/graph_projection.py +405 -0
- package/graph-provider/fuli_graph/graph_query.py +561 -0
- package/graph-provider/fuli_graph/knowledge_audit.py +765 -0
- package/graph-provider/fuli_graph/knowledge_batch_confirmation.py +246 -0
- package/graph-provider/fuli_graph/knowledge_management.py +816 -0
- package/graph-provider/fuli_graph/knowledge_records.py +65 -0
- package/graph-provider/fuli_graph/knowledge_search.py +723 -0
- package/graph-provider/fuli_graph/knowledge_usage_models.py +52 -0
- package/graph-provider/fuli_graph/model_validation.py +58 -0
- package/graph-provider/fuli_graph/models.py +1179 -0
- package/graph-provider/fuli_graph/personal_project_access.py +29 -0
- package/graph-provider/fuli_graph/preference_conflicts.py +420 -0
- package/graph-provider/fuli_graph/project_action_models.py +142 -0
- package/graph-provider/fuli_graph/project_knowledge.py +707 -0
- package/graph-provider/fuli_graph/project_management.py +251 -0
- package/graph-provider/fuli_graph/provider_values.py +40 -0
- package/graph-provider/fuli_graph/runtime.py +350 -0
- package/graph-provider/fuli_graph/search_projection.py +156 -0
- package/graph-provider/fuli_graph/store.py +24 -0
- package/graph-provider/fuli_graph/store_identity.py +237 -0
- package/graph-provider/fuli_graph/store_knowledge.py +447 -0
- package/graph-provider/fuli_graph/store_projects.py +242 -0
- package/graph-provider/fuli_graph/store_publication.py +370 -0
- package/graph-provider/fuli_graph/store_records.py +134 -0
- package/graph-provider/pyproject.toml +35 -0
- package/npm-shrinkwrap.json +6045 -0
- package/package.json +99 -0
- package/skills/capturing-session-knowledge/SKILL.md +226 -0
- package/skills/capturing-session-knowledge/agents/openai.yaml +13 -0
- package/skills/grilling-project/SKILL.md +129 -0
- package/skills/grilling-project/agents/openai.yaml +4 -0
- package/skills/grilling-project/references/project-profile.md +105 -0
- package/src/agent/candidate-read-service.js +53 -0
- package/src/agent/context-pack-service.js +83 -0
- package/src/agent/public-read-policy.js +39 -0
- package/src/agent/public-read-service.js +69 -0
- package/src/agent/read-projection.js +107 -0
- package/src/agent/search-service.js +61 -0
- package/src/agent/space-boundary.js +33 -0
- package/src/agent-tools/graph-definitions.js +479 -0
- package/src/agent-tools/graph-handlers.js +96 -0
- package/src/agent-tools/schema.js +37 -0
- package/src/agent-tools.js +16 -0
- package/src/app/application-error.js +13 -0
- package/src/app/bootstrap.js +8 -0
- package/src/app/create-application.js +143 -0
- package/src/app/state-service.js +38 -0
- package/src/candidates.js +78 -0
- package/src/classifier.js +63 -0
- package/src/cli/command-arguments.js +14 -0
- package/src/cli/command-registry.js +78 -0
- package/src/cli/commands/candidates.js +17 -0
- package/src/cli/commands/ingestion.js +32 -0
- package/src/cli/commands/reads.js +50 -0
- package/src/cli/commands/spaces.js +20 -0
- package/src/cli/invocation.js +47 -0
- package/src/cli/local-runtime-command.js +94 -0
- package/src/cli/local-runtime-options.js +64 -0
- package/src/cli/migrate-command.js +71 -0
- package/src/cli/migration-destination.js +117 -0
- package/src/cli/setup-agent-selection.js +195 -0
- package/src/cli/setup-command.js +85 -0
- package/src/cli/uninstall-command.js +67 -0
- package/src/cli.js +90 -0
- package/src/context-pack.js +206 -0
- package/src/defaults.js +1 -0
- package/src/extractor.js +77 -0
- package/src/fact-history.js +39 -0
- package/src/facts/fact-service.js +89 -0
- package/src/graphiti/agent-access-policy.js +88 -0
- package/src/graphiti/capture-policy.js +84 -0
- package/src/graphiti/federated-application.js +1292 -0
- package/src/graphiti/personal-context.js +29 -0
- package/src/graphiti/project-path-context.js +159 -0
- package/src/graphiti/provider-client.js +288 -0
- package/src/graphiti/runtime-config.js +85 -0
- package/src/graphiti/setup.js +43 -0
- package/src/graphiti/source-marker.js +142 -0
- package/src/http/api-router.js +133 -0
- package/src/http/bounded-json-array.js +19 -0
- package/src/http/error-mapping.js +36 -0
- package/src/http/graph-api-router.js +257 -0
- package/src/http/lens-route.js +50 -0
- package/src/http/request-policy.js +41 -0
- package/src/http/response.js +29 -0
- package/src/http/static-handler.js +55 -0
- package/src/ingestion.js +161 -0
- package/src/lens/lens-correction-service.js +81 -0
- package/src/lens/lens-fact-writer.js +85 -0
- package/src/lens/lens-input.js +62 -0
- package/src/lens/lens-query-projection.js +87 -0
- package/src/lens/lens-query-ranking.js +62 -0
- package/src/lens/lens-query.js +143 -0
- package/src/lens/lens-resource-projection.js +93 -0
- package/src/lens/lens-resource-selection.js +45 -0
- package/src/lens/lens-resource-service.js +103 -0
- package/src/lens/lens-search-query.js +122 -0
- package/src/lens/lens-service.js +183 -0
- package/src/local-runtime/lifecycle.js +254 -0
- package/src/mcp/create-mcp-server.js +85 -0
- package/src/mcp/instructions.js +10 -0
- package/src/mcp/project-action-preview-tokens.js +72 -0
- package/src/mcp/runtime.js +71 -0
- package/src/mcp/tool-annotations.js +63 -0
- package/src/mcp/tool-result.js +167 -0
- package/src/mcp/tool-schema.js +60 -0
- package/src/mcp-server.js +76 -0
- package/src/models.js +44 -0
- package/src/observer.js +83 -0
- package/src/package-metadata.js +6 -0
- package/src/project-rules.js +33 -0
- package/src/publication/canonical-json.js +39 -0
- package/src/publication/outbox-service.js +46 -0
- package/src/publication/publication-envelope-schema.js +75 -0
- package/src/publication/publication-envelope.js +37 -0
- package/src/publication/publication-policy.js +82 -0
- package/src/publication/publication-service.js +48 -0
- package/src/router.js +58 -0
- package/src/runtime-options.js +139 -0
- package/src/security/episode-visibility.js +14 -0
- package/src/security/fact-visibility.js +15 -0
- package/src/security/sensitive-content.js +18 -0
- package/src/security/source-metadata-policy.js +8 -0
- package/src/server/application-lifecycle.js +34 -0
- package/src/server/listen.js +24 -0
- package/src/server.js +135 -0
- package/src/setup/agent-installation-status.js +97 -0
- package/src/setup/agents.js +123 -0
- package/src/setup/codex-bootstrap.js +118 -0
- package/src/setup/codex-config.js +122 -0
- package/src/setup/config-backup.js +22 -0
- package/src/setup/container-runtime.js +388 -0
- package/src/setup/cursor-config.js +61 -0
- package/src/setup/graph-runtime.js +360 -0
- package/src/setup/node-runtime.js +24 -0
- package/src/setup/options.js +91 -0
- package/src/setup/paths.js +47 -0
- package/src/setup/session-skill.js +91 -0
- package/src/setup/setup.js +85 -0
- package/src/setup/uninstall.js +90 -0
- package/src/storage/episode-evidence-preview.js +100 -0
- package/src/storage/fact-search-order.js +18 -0
- package/src/storage/file/episode-evidence.js +37 -0
- package/src/storage/file/episode-index.js +59 -0
- package/src/storage/file/fact-search.js +60 -0
- package/src/storage/file-store.js +437 -0
- package/src/storage/import-json.js +70 -0
- package/src/storage/json-file.js +41 -0
- package/src/storage/legacy-record-validation.js +152 -0
- package/src/storage/legacy-snapshot-validation.js +32 -0
- package/src/storage/migrate.js +128 -0
- package/src/storage/migrations/001-initial.sql +83 -0
- package/src/storage/migrations/002-storage-integrity.sql +113 -0
- package/src/storage/record-validation.js +46 -0
- package/src/storage/snapshot-defaults.js +54 -0
- package/src/storage/sqlite/candidates-repository.js +84 -0
- package/src/storage/sqlite/episode-evidence-repository.js +154 -0
- package/src/storage/sqlite/episode-privacy-sql.js +33 -0
- package/src/storage/sqlite/episodes-repository.js +52 -0
- package/src/storage/sqlite/fact-search-repository.js +162 -0
- package/src/storage/sqlite/facts-repository.js +146 -0
- package/src/storage/sqlite/imports-repository.js +39 -0
- package/src/storage/sqlite/mapper.js +84 -0
- package/src/storage/sqlite/open-database.js +15 -0
- package/src/storage/sqlite/outbox-repository.js +103 -0
- package/src/storage/sqlite/snapshot-repository.js +69 -0
- package/src/storage/sqlite/spaces-repository.js +52 -0
- package/src/storage/sqlite/subscriptions-repository.js +54 -0
- package/src/storage/sqlite-store.js +159 -0
- package/src/storage/stable-json.js +24 -0
- package/src/storage/store-port.js +20 -0
- package/src/store.js +2 -0
- package/src/workspace-protocol/array-validation.js +19 -0
- package/src/workspace-protocol/base64url-contract.js +27 -0
- package/src/workspace-protocol/constants.js +37 -0
- package/src/workspace-protocol/error-contract.js +24 -0
- package/src/workspace-protocol/fact-contract.js +110 -0
- package/src/workspace-protocol/governance-contract.js +47 -0
- package/src/workspace-protocol/index.js +53 -0
- package/src/workspace-protocol/json-budget.js +19 -0
- package/src/workspace-protocol/manifest-contract.js +186 -0
- package/src/workspace-protocol/publication-contract.js +212 -0
- package/src/workspace-protocol/query-contract.js +149 -0
- package/src/workspace-protocol/scalar-contract.js +192 -0
- package/src/workspace-protocol/sync-contract.js +184 -0
- package/src/workspace-protocol/text-contract.js +39 -0
- package/src/workspace-protocol/validation.js +66 -0
package/package.json
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fuli-context",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Local-first context graph for AI agents.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"npm-shrinkwrap.json",
|
|
8
|
+
"src/",
|
|
9
|
+
"dist/web/",
|
|
10
|
+
"graph-provider/Dockerfile",
|
|
11
|
+
"graph-provider/pyproject.toml",
|
|
12
|
+
"graph-provider/fuli_graph/*.py",
|
|
13
|
+
"graph-provider/fuli_graph/**/*.py",
|
|
14
|
+
"skills/",
|
|
15
|
+
"compose.graphiti.yml"
|
|
16
|
+
],
|
|
17
|
+
"bin": {
|
|
18
|
+
"fl": "./src/cli.js",
|
|
19
|
+
"fuli": "./src/cli.js"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"ai-agent",
|
|
23
|
+
"mcp",
|
|
24
|
+
"context",
|
|
25
|
+
"knowledge-graph",
|
|
26
|
+
"local-first",
|
|
27
|
+
"codex",
|
|
28
|
+
"claude-code"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"mcp": "node src/mcp-server.js",
|
|
32
|
+
"dev": "run-p dev:server dev:web",
|
|
33
|
+
"dev:server": "node src/server.js",
|
|
34
|
+
"dev:web": "vite",
|
|
35
|
+
"build": "run-s typecheck:web build:web",
|
|
36
|
+
"build:web": "vite build",
|
|
37
|
+
"typecheck:web": "vue-tsc --noEmit -p tsconfig.app.json",
|
|
38
|
+
"test:node": "node --test",
|
|
39
|
+
"test:web": "vitest run --config vitest.config.ts",
|
|
40
|
+
"test:package": "node scripts/package-smoke.js",
|
|
41
|
+
"test:knowledge:live": "node acceptance/knowledge-live.js",
|
|
42
|
+
"start": "node src/server.js",
|
|
43
|
+
"graph:setup": "node src/graphiti/setup.js",
|
|
44
|
+
"graph:up": "docker compose -f compose.graphiti.yml up -d --build",
|
|
45
|
+
"graph:down": "docker compose -f compose.graphiti.yml down",
|
|
46
|
+
"test:structure": "node --test test/source-structure.test.js",
|
|
47
|
+
"pretest": "npm run build:web",
|
|
48
|
+
"test": "run-s typecheck:web test:node test:web",
|
|
49
|
+
"prepack": "npm run build",
|
|
50
|
+
"prepublishOnly": "npm test"
|
|
51
|
+
},
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">=24.12"
|
|
54
|
+
},
|
|
55
|
+
"repository": {
|
|
56
|
+
"type": "git",
|
|
57
|
+
"url": "git+https://github.com/JevonsCode/fuli.git"
|
|
58
|
+
},
|
|
59
|
+
"homepage": "https://github.com/JevonsCode/fuli#readme",
|
|
60
|
+
"bugs": {
|
|
61
|
+
"url": "https://github.com/JevonsCode/fuli/issues"
|
|
62
|
+
},
|
|
63
|
+
"publishConfig": {
|
|
64
|
+
"access": "public"
|
|
65
|
+
},
|
|
66
|
+
"license": "Apache-2.0",
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"@hono/node-server": "2.0.12",
|
|
69
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
70
|
+
"better-sqlite3": "^12.11.1",
|
|
71
|
+
"zod": "^4.4.3"
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@types/d3": "^7.4.3",
|
|
75
|
+
"@types/node": "^24.13.3",
|
|
76
|
+
"@vitejs/plugin-vue": "^6.0.8",
|
|
77
|
+
"@vue/test-utils": "^2.4.11",
|
|
78
|
+
"brace-expansion": "5.0.8",
|
|
79
|
+
"d3": "^7.9.0",
|
|
80
|
+
"gsap": "^3.15.0",
|
|
81
|
+
"jsdom": "^29.1.1",
|
|
82
|
+
"linkedom": "^0.18.12",
|
|
83
|
+
"npm-run-all2": "^9.0.2",
|
|
84
|
+
"pinia": "^4.0.2",
|
|
85
|
+
"typescript": "~6.0.0",
|
|
86
|
+
"vite": "^8.1.5",
|
|
87
|
+
"vitest": "^4.1.10",
|
|
88
|
+
"vue": "^3.5.40",
|
|
89
|
+
"vue-router": "^5.2.0",
|
|
90
|
+
"vue-tsc": "^3.3.8"
|
|
91
|
+
},
|
|
92
|
+
"overrides": {
|
|
93
|
+
"@modelcontextprotocol/sdk": {
|
|
94
|
+
"@hono/node-server": "2.0.12"
|
|
95
|
+
},
|
|
96
|
+
"brace-expansion": "$brace-expansion",
|
|
97
|
+
"fast-uri": "3.1.4"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: capturing-session-knowledge
|
|
3
|
+
description: Use when Fuli tools are available and a task may depend on remembered personal preferences or durable project facts such as URLs, routes, requirements, architecture, prior decisions, runbooks, or rationale, or when ordinary work produces reusable knowledge worth retaining.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Capturing Session Knowledge
|
|
7
|
+
|
|
8
|
+
Accumulate reusable knowledge without interrupting the user's normal work. Keep an internal session buffer and flush focused batches at a natural task boundary or before the session ends.
|
|
9
|
+
|
|
10
|
+
## Load Collaboration Preferences
|
|
11
|
+
|
|
12
|
+
At the start of every user task, before any other tool or answer, call
|
|
13
|
+
`get_collaboration_preferences`. Pass `projectPath` as the current working directory. Fuli uses
|
|
14
|
+
that path only for this local MCP call, never stores or returns it, and resolves the exact local
|
|
15
|
+
personal project itself. Do not infer or guess `personalProjectId` in the Agent.
|
|
16
|
+
|
|
17
|
+
Apply only `effective_preferences`. Personal-global preferences apply in every user task;
|
|
18
|
+
project-scoped preferences layer on only for the exact selected project. Do not apply items
|
|
19
|
+
listed as conflicts, and do not borrow preferences from a related, similarly named, or guessed
|
|
20
|
+
project. Human or authoritative-source confirmation outranks explicitly marked
|
|
21
|
+
`agent_confirmed` preferences. Pending preferences remain search-only; invalid and
|
|
22
|
+
unrelated-project preferences are intentionally excluded. Automatic preference injection is
|
|
23
|
+
not usage evidence.
|
|
24
|
+
When `get_collaboration_preferences` returns a `deferred_conflict`, leave it untouched unless
|
|
25
|
+
the current task would use either side. Before using a relevant deferred conflict, compare both
|
|
26
|
+
sides and call `resolve_deferred_preference_conflict`; apply only the successfully resolved
|
|
27
|
+
result. The resolution record must remain marked as previously conflicted and AI-resolved.
|
|
28
|
+
Before any write tool call, enforce every applicable preference in the actual payload.
|
|
29
|
+
Mentioning a preference only in the final answer is not compliance.
|
|
30
|
+
|
|
31
|
+
## Retrieve Context
|
|
32
|
+
|
|
33
|
+
Call `search_knowledge_graph` when prior durable context can materially improve the task.
|
|
34
|
+
Before saying that a stable fact is unknown or asking the user to provide it again, search
|
|
35
|
+
Fuli if it may have been learned earlier. Strong triggers include URLs, deployment routes,
|
|
36
|
+
requirements, terminology, architecture, prior decisions, runbooks, rationale, and remembered
|
|
37
|
+
personal preferences. Do not search for a fully self-contained task or use Fuli as proof of live
|
|
38
|
+
external state.
|
|
39
|
+
|
|
40
|
+
Pending knowledge is eligible for on-demand retrieval and must remain visibly marked.
|
|
41
|
+
`agent_confirmed` knowledge is usable but ranks below user or authoritative-source
|
|
42
|
+
confirmation.
|
|
43
|
+
|
|
44
|
+
Treat an obvious content-location request specially: examples include asking for a named page,
|
|
45
|
+
URL, route, deployment, document, file, or where a durable artifact is located.
|
|
46
|
+
|
|
47
|
+
1. Run one bounded search that preserves distinctive names, identifiers, and quoted phrases from
|
|
48
|
+
the user's wording. Do not dilute them with generic expansion. An unrelated result is no
|
|
49
|
+
evidence even if the tool labels it matched.
|
|
50
|
+
2. If there is no supporting result, ask whether to widen this one read-only lookup to all
|
|
51
|
+
registered local personal projects and, if still unresolved, the current repository or
|
|
52
|
+
workspace files. Explain that it applies only to this lookup, excludes public projects and
|
|
53
|
+
paths outside the current workspace, then stop and wait for the user's answer.
|
|
54
|
+
3. Only after explicit confirmation, call `search_knowledge_graph` again with
|
|
55
|
+
`personalProjectScope: all_local_confirmed`. Never infer consent from the lookup intent itself.
|
|
56
|
+
4. This expanded scope does not expand any public project or subscription and must not become a
|
|
57
|
+
persistent default. If it still has no supporting result, continue with a local file fallback:
|
|
58
|
+
- When the current directory is inside one repository, search only that repository.
|
|
59
|
+
- When it is an intentional multi-repository workspace root, search only that workspace.
|
|
60
|
+
- When it is the user home, filesystem root, or otherwise too broad or ambiguous, ask for an
|
|
61
|
+
exact safe repository/workspace root and stop. Never recursively scan a home or system root.
|
|
62
|
+
- Within the safe root, use read-only `Grep`/`Glob`/`Read` or `rg`. Preserve the exact quoted
|
|
63
|
+
name first, respect ignore rules, and inspect only relevant matches and routing/deployment
|
|
64
|
+
context. Do not inspect credential stores, browser data, secrets, or paths outside the root.
|
|
65
|
+
- A route string alone is not a live URL. Require deployment-domain or equivalent evidence.
|
|
66
|
+
If local files still provide no supporting evidence, ask for a project, document, or source
|
|
67
|
+
clue.
|
|
68
|
+
|
|
69
|
+
Personal retrieval always includes the bounded personal-global profile. For a local personal
|
|
70
|
+
project, pass its exact `personalProjectId`; if the user explicitly names another personal
|
|
71
|
+
project, resolve it with `list_personal_projects` and add only that exact ID through
|
|
72
|
+
`contextPersonalProjectIds`. Without an active local project, search only the personal-global
|
|
73
|
+
profile. For public context, pass only the active or explicitly named subscribed public project
|
|
74
|
+
IDs; never search every personal project, every subscription, or the whole graph by default.
|
|
75
|
+
Use the current repository, the user's wording, and `list_knowledge_spaces` to resolve scope.
|
|
76
|
+
Ask if the active project remains ambiguous.
|
|
77
|
+
|
|
78
|
+
The active project may also retrieve only knowledge explicitly marked inheritable from projects
|
|
79
|
+
reached through outgoing `PART_OF` or `USES_KNOWLEDGE_FROM` relations. Never inherit
|
|
80
|
+
project-scoped personal preferences, never traverse `RELATED_TO`, stop after two hops, and retain
|
|
81
|
+
the returned scope path. Exact active-project knowledge with the same stable key overrides an
|
|
82
|
+
inherited item.
|
|
83
|
+
|
|
84
|
+
After a retrieved personal item materially affects the final answer or a completed action, call
|
|
85
|
+
`record_knowledge_usage` once for that task and item with `cited` or `applied`. Do not record
|
|
86
|
+
retrieval, inspection, automatic preference injection, or unused context. Usage evidence can
|
|
87
|
+
promote only to `agent_confirmed`; it never substitutes for human confirmation or makes an item
|
|
88
|
+
eligible for public publication. Use the current user task's caller-stable identifier as
|
|
89
|
+
`taskId` and reuse it on retries; never generate another ID to recount the same task.
|
|
90
|
+
|
|
91
|
+
The current `agent-usage-v1` policy requires at least five idempotent material-use events across
|
|
92
|
+
at least three distinct tasks in the current content generation, with no open knowledge or
|
|
93
|
+
preference conflict. It maintains utility and confidence as separate scores and caps
|
|
94
|
+
Agent-confirmed confidence below human/source confirmation. Agents report qualifying use; they
|
|
95
|
+
do not calculate, override, or claim the promotion themselves.
|
|
96
|
+
|
|
97
|
+
For “why was this code written?” questions, use stored evidence relationships and a separately configured Git MCP together. Never invent a commit, PRD link, or missing history. For “what errors happened today?” questions, obtain current data from a monitoring/log MCP; use Fuli only for runbooks, architecture, prior causes, and other durable context.
|
|
98
|
+
|
|
99
|
+
Every `search_knowledge_graph` response provides two terminal-safe Markdown choices:
|
|
100
|
+
`sourceMarker` for returned items that support the answer, and `noMatchSourceMarker`
|
|
101
|
+
for a search with no supporting result. A tool-labelled match that is irrelevant to
|
|
102
|
+
the answer still requires `noMatchSourceMarker`.
|
|
103
|
+
|
|
104
|
+
For the chosen marker, the final answer must begin with its `leadMarkdown` unchanged,
|
|
105
|
+
before any heading or prose, and append its `markdown` unchanged after the answer. If
|
|
106
|
+
any search supports the answer, choose `sourceMarker` from one supporting search. If
|
|
107
|
+
none do, choose `noMatchSourceMarker`. Never show either marker when no search was
|
|
108
|
+
called. Never fabricate, rewrite, omit, or wrap markers in HTML. A capture or write
|
|
109
|
+
result is not a read citation.
|
|
110
|
+
|
|
111
|
+
## Decide What Persists
|
|
112
|
+
|
|
113
|
+
Capture confirmed, stable information:
|
|
114
|
+
|
|
115
|
+
- Personal: the user's enduring preferences, boundaries, habits, and working methods. Project-specific personal rules must explicitly link to that project instead of becoming global defaults.
|
|
116
|
+
- Project: PRD facts, requirements, terminology, decisions, constraints, architecture, routes, APIs, metrics, and document-derived knowledge.
|
|
117
|
+
|
|
118
|
+
Do not capture credentials, tokens, cookies, private keys, raw transcripts, temporary logs, command output, speculative conclusions, or disposable implementation details. Treat a correction as a replacement, not an additional conflicting fact.
|
|
119
|
+
|
|
120
|
+
## Classify Knowledge State
|
|
121
|
+
|
|
122
|
+
Every entity and relationship needs an `originQuadrant`, `confirmationBasis`, and
|
|
123
|
+
`confirmationStatus`. These fields answer three separate questions:
|
|
124
|
+
|
|
125
|
+
1. `originQuadrant` records how the item was discovered. It is not a truth score and does
|
|
126
|
+
not change merely because the item is later confirmed.
|
|
127
|
+
2. `confirmationBasis` explains why the item exists, why it belongs to that quadrant,
|
|
128
|
+
who proposed it, and—when confirmed—who confirmed it and when.
|
|
129
|
+
3. `confirmationStatus` is `pending`, `agent_confirmed`, or `confirmed`.
|
|
130
|
+
|
|
131
|
+
Keep the canonical quadrant names:
|
|
132
|
+
|
|
133
|
+
- `known_known`: knowledge or a conclusion that was explicitly expressed when captured.
|
|
134
|
+
- `known_unknown`: an unresolved question or tradeoff that was explicitly recognized.
|
|
135
|
+
- `unknown_known`: tacit knowledge inferred from behaviour, examples, prototypes, or
|
|
136
|
+
reactions.
|
|
137
|
+
- `unknown_unknown`: a potential blind spot surfaced during open exploration. A truly
|
|
138
|
+
unknown item cannot be stored; this label describes how the recorded candidate arose.
|
|
139
|
+
|
|
140
|
+
Every `confirmationBasis` must contain:
|
|
141
|
+
|
|
142
|
+
- `existenceReason`: why this item was created;
|
|
143
|
+
- `quadrantReason`: why it was assigned to this quadrant;
|
|
144
|
+
- `proposedBy`: `{ kind, label }`, where kind is `user`, `agent`,
|
|
145
|
+
`authoritative_source`, or `import`;
|
|
146
|
+
- `confirmedBy` and `confirmedAt` together when confirmed.
|
|
147
|
+
|
|
148
|
+
An Agent may propose and explain knowledge. A user or authoritative source creates
|
|
149
|
+
`confirmed`; a deterministic Fuli usage policy may create only `agent_confirmed`, with an Agent
|
|
150
|
+
confirmer, timestamp, and policy version. Agent confirmation is lower-authority, never
|
|
151
|
+
public-eligible, and must not be produced by retrieval alone. Confirmation covers the content
|
|
152
|
+
and its classification. If either changes, return the item to `pending` and start a new usage
|
|
153
|
+
generation unless the same revision explicitly records a new valid human/source confirmer and
|
|
154
|
+
confirmation time. Legacy items without that audit record are `pending`, even if an old
|
|
155
|
+
`epistemicStatus` said `confirmed`.
|
|
156
|
+
|
|
157
|
+
`currentQuadrant` and `epistemicStatus` are legacy compatibility fields. Do not use them
|
|
158
|
+
for new product logic and do not treat them as confirmation evidence.
|
|
159
|
+
|
|
160
|
+
Agent retrieval includes pending items on demand and returns their status so the caller can
|
|
161
|
+
calibrate claims. Only user or authoritative-source `confirmed` project knowledge may enter
|
|
162
|
+
public review, regardless of how it was originally discovered; normal personal preview and
|
|
163
|
+
Maintainer review gates still apply.
|
|
164
|
+
|
|
165
|
+
## Grow The Personal Profile Separately
|
|
166
|
+
|
|
167
|
+
Durable facts about the person's collaboration style use `profileAspect`. They default to
|
|
168
|
+
the personal-global graph without `personalProjectId`:
|
|
169
|
+
|
|
170
|
+
- `taste`: aesthetic, writing, product, architecture, or engineering outcomes the user
|
|
171
|
+
likes or rejects.
|
|
172
|
+
- `personality`: stable self-described collaboration or working traits. Agent-inferred
|
|
173
|
+
personality stays `pending` and must never be silently promoted to confirmed.
|
|
174
|
+
- `judgment_preference`: repeated decision criteria, tradeoff priorities, risk posture,
|
|
175
|
+
and conditions that change how the user chooses.
|
|
176
|
+
|
|
177
|
+
When the user explicitly limits one preference to a project, keep `profileAspect` and capture
|
|
178
|
+
it with that exact `personalProjectId`; this makes the preference project-scoped without
|
|
179
|
+
turning it into public project knowledge. Use `set_personal_preference_scope` when the user
|
|
180
|
+
later changes the scope. Never put any personal-profile item into a public proposal.
|
|
181
|
+
For a preference that may have both global and project-specific forms, store a stable
|
|
182
|
+
`attributes.preferenceKey` on each form so the project value can explicitly override the same
|
|
183
|
+
global decision without hiding unrelated preferences.
|
|
184
|
+
|
|
185
|
+
## Route by Ownership
|
|
186
|
+
|
|
187
|
+
- Route global personal knowledge to `targetKind: personal` without `personalProjectId`; it is written directly to the local personal graph.
|
|
188
|
+
- Route knowledge for a local personal project, including an explicitly project-scoped personal preference, to `targetKind: personal` with that project's exact `personalProjectId`. This is private local knowledge, not a public submission.
|
|
189
|
+
- Route knowledge to `targetKind: project` only when the target is an explicitly selected subscribed public project. It becomes a team-shared Provider Proposal and must remain pending until a Maintainer reviews it.
|
|
190
|
+
- Never treat a project as public merely because the current repository or conversation has a project name. Only an active subscription makes it eligible for public project routing.
|
|
191
|
+
- Never omit `personalProjectId` when the current repository or conversation has already resolved one local personal project; doing so would leak project-specific facts into the personal-global scope.
|
|
192
|
+
- Never add another personal project to `contextPersonalProjectIds` merely because it is related, similarly named, or referenced by the active project. Automatic borrowing is limited to item-level inheritable knowledge reached through `PART_OF` or `USES_KNOWLEDGE_FROM`; all other cross-project borrowing requires an explicit user request or selection and applies only to the current search context.
|
|
193
|
+
- Never route project facts through the personal graph to bypass review.
|
|
194
|
+
- Never auto-approve a project Proposal.
|
|
195
|
+
- If ownership is genuinely ambiguous and changes who can see the knowledge, ask one concise question instead of guessing.
|
|
196
|
+
|
|
197
|
+
## Resolve Or Create The Local Project
|
|
198
|
+
|
|
199
|
+
Before the first project-scoped capture in a repository:
|
|
200
|
+
|
|
201
|
+
1. Call `list_knowledge_spaces`, then `list_personal_projects` for the active personal space.
|
|
202
|
+
2. Resolve the repository root from the current working directory and repo-local manifests. Use a stable, human-readable project ID derived from the repository or manifest name. Never store an absolute path, local username, hostname, credential, or private remote URL as the project ID or public profile evidence.
|
|
203
|
+
3. Match an existing personal project by exact project ID, publication mapping, or confirmed repository identity. Do not merge projects from similar names.
|
|
204
|
+
4. When one previously unseen repository has an unambiguous identity, immediately create a minimal private personal project with `upsert_personal_project`. Use lifecycle `active`, a private repository source with no URI, and an evidence-coverage summary containing only facts visible in the current repository. Do not generate a generic list of information the project supposedly lacks.
|
|
205
|
+
5. Ask one project-identity question only when the working directory contains multiple plausible projects or the repository identity conflicts with an existing project.
|
|
206
|
+
|
|
207
|
+
Creating a personal project is local classification, not public publication. Never create or subscribe to a public project automatically.
|
|
208
|
+
|
|
209
|
+
## Structure and Flush
|
|
210
|
+
|
|
211
|
+
Use `capture_session_knowledge` with a small, coherent batch:
|
|
212
|
+
|
|
213
|
+
1. List spaces when the target IDs are not already known.
|
|
214
|
+
2. Summarize the durable facts; do not submit the entire source document or conversation.
|
|
215
|
+
3. Create stable entity keys, typed entities, and explicit uppercase relationships. When relevant, model `GitCommit`, `CodeSymbol`, `PRDSection`, `Runbook`, and `Incident` entities and connect them with relationships such as `IMPLEMENTED_IN`, `DEFINED_BY`, `MOTIVATED_BY`, `APPLIES_TO`, and `INVESTIGATED_WITH`.
|
|
216
|
+
4. Include source kind, source application, a non-sensitive source description, reference time, session ID, and a retry-safe idempotency key. When available, include a stable source turn ID and only the smallest relevant excerpt needed to understand the evidence; never include a full transcript.
|
|
217
|
+
5. Use `supersedes` when replacing a known relationship and set confidence below `1` only when the source itself expresses uncertainty.
|
|
218
|
+
6. Flush silently at the boundary. Continue the user's task without narrating routine capture.
|
|
219
|
+
|
|
220
|
+
If `capture_session_knowledge` or automatic project creation returns `capture_disabled`, the
|
|
221
|
+
user has disabled automatic capture. Do not retry, do not create a fallback record elsewhere,
|
|
222
|
+
and do not describe the skipped batch as stored. Existing knowledge may still be queried.
|
|
223
|
+
|
|
224
|
+
Before sending the final response, perform one checkpoint: either flush the durable batch or determine that this turn produced no reusable knowledge. Do not finish a reusable project decision with an unflushed batch.
|
|
225
|
+
|
|
226
|
+
Only notify the user when capture fails, conflicts with existing knowledge, or requires an ownership decision. If project knowledge was proposed successfully, do not interrupt merely to announce the pending review item.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "Capturing Session Knowledge"
|
|
3
|
+
short_description: "Recall and retain durable personal and project context"
|
|
4
|
+
default_prompt: "Use $capturing-session-knowledge to load effective collaboration preferences, retrieve relevant durable context, and retain reusable knowledge in Fuli."
|
|
5
|
+
|
|
6
|
+
dependencies:
|
|
7
|
+
tools:
|
|
8
|
+
- type: "mcp"
|
|
9
|
+
value: "fuli"
|
|
10
|
+
description: "Local Fuli Graphiti knowledge tools"
|
|
11
|
+
|
|
12
|
+
policy:
|
|
13
|
+
allow_implicit_invocation: true
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: grilling-project
|
|
3
|
+
description: Use when creating, clarifying, updating, assessing, or publishing a Fuli project profile, especially when the user has only a partial project description or asks to add PRDs, technical documents, frontend/backend repositories, runbooks, monitoring, scope, or public-project metadata. Interview one question at a time, discover repository facts first, record confirmed personal project information progressively, and never publish before a final public-boundary preview is confirmed.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Grilling Project
|
|
7
|
+
|
|
8
|
+
Turn incomplete project knowledge into an evidence-backed Fuli personal project profile, then optionally publish it. Keep the interview light: discover what can be discovered, ask one useful question, recommend an answer, and wait.
|
|
9
|
+
|
|
10
|
+
Read [project-profile.md](references/project-profile.md) before assessing evidence coverage or constructing a project profile.
|
|
11
|
+
|
|
12
|
+
## Non-negotiable behavior
|
|
13
|
+
|
|
14
|
+
- During the interview, ask exactly one question in each question-bearing message. Pure status or failure notifications do not need a synthetic question.
|
|
15
|
+
- Before asking, use read-only repository inspection to discover relevant facts that are already available.
|
|
16
|
+
- State the current inference separately from confirmed facts.
|
|
17
|
+
- Include a recommended answer and explain its consequence briefly.
|
|
18
|
+
- Do not publish a public project until the user confirms a final publication preview.
|
|
19
|
+
- Evidence coverage is display-only. Never block publication because the score is low.
|
|
20
|
+
- Record confirmed information in the personal graph as the interview progresses. Personal recording is not public publication.
|
|
21
|
+
- Do not silently turn a related project into a subscription. Subscription is always explicit.
|
|
22
|
+
|
|
23
|
+
## Start with Fuli state
|
|
24
|
+
|
|
25
|
+
1. Call `list_knowledge_spaces` to learn the active personal space, public Provider state, subscriptions, and public projects.
|
|
26
|
+
2. Call `list_personal_projects` for the active personal space.
|
|
27
|
+
3. Match by stable project ID or an existing publication mapping first. Use repository evidence second. Never merge projects from name similarity alone; ask one identity question when the match is ambiguous.
|
|
28
|
+
4. If a public project already corresponds to it, treat publication as a profile sync, not a second project.
|
|
29
|
+
|
|
30
|
+
Use a stable, human-readable `projectId` derived from the repository/project name. Do not derive it from a local absolute path, username, hostname, or confidential identifier.
|
|
31
|
+
|
|
32
|
+
## Discover before asking
|
|
33
|
+
|
|
34
|
+
Inspect only the current project and directly relevant files. Typical evidence includes:
|
|
35
|
+
|
|
36
|
+
- README and project documentation indexes
|
|
37
|
+
- package or build manifests
|
|
38
|
+
- architecture and deployment documents
|
|
39
|
+
- repository-local Git remotes
|
|
40
|
+
- frontend/backend directory layout
|
|
41
|
+
- run, test, deployment, rollback, monitoring, and incident instructions
|
|
42
|
+
|
|
43
|
+
Do not read global Git configuration, credential helpers, SSH configuration, tokens, unrelated repositories, browser data, or secret stores. Treat internal URLs and repository remotes as private evidence until the user explicitly approves public inclusion.
|
|
44
|
+
|
|
45
|
+
Label every proposed fact as one of:
|
|
46
|
+
|
|
47
|
+
- **confirmed** — directly stated by the user or supported by inspected evidence
|
|
48
|
+
- **inferred** — plausible but not yet confirmed
|
|
49
|
+
|
|
50
|
+
Summarize only information and evidence that currently exist. Do not present a generated
|
|
51
|
+
list of “missing items”; absence from a generic checklist is not evidence that the project
|
|
52
|
+
actually needs that item.
|
|
53
|
+
|
|
54
|
+
Do not ask the user for a fact that can be verified safely from the current repository.
|
|
55
|
+
|
|
56
|
+
## Interview loop
|
|
57
|
+
|
|
58
|
+
Choose the highest-impact clarification that follows from the user's goal or current
|
|
59
|
+
evidence. Do not manufacture questions solely to fill a generic checklist. In each turn:
|
|
60
|
+
|
|
61
|
+
1. Summarize newly confirmed facts in one or two sentences.
|
|
62
|
+
2. State any relevant inference and its evidence.
|
|
63
|
+
3. Ask one question only.
|
|
64
|
+
4. Put the recommended answer first and explain the tradeoff.
|
|
65
|
+
5. Wait for the answer.
|
|
66
|
+
|
|
67
|
+
Prefer project identity, purpose, scope, and privacy boundary before lower-impact metadata. Skip resolved categories. If the user rejects a recommendation, record their choice without repeatedly arguing.
|
|
68
|
+
|
|
69
|
+
After a meaningful confirmed update, call `upsert_personal_project` with the complete current profile, not a partial patch. Preserve earlier confirmed fields and sources. Routine successful updates stay quiet.
|
|
70
|
+
|
|
71
|
+
## Evidence coverage assessment
|
|
72
|
+
|
|
73
|
+
Recompute the assessment when evidence changes. Follow the dimensions and scoring guidance in the reference.
|
|
74
|
+
|
|
75
|
+
The assessment must contain:
|
|
76
|
+
|
|
77
|
+
- an overall score and label
|
|
78
|
+
- confirmed facts
|
|
79
|
+
- clearly marked inferences
|
|
80
|
+
- dimension-level evidence already present
|
|
81
|
+
- `analyzedAt` set to the current time
|
|
82
|
+
|
|
83
|
+
Never inflate the score from a filename alone. A discovered link confirms that a source exists, not that its content is current or complete. Never present inference as confirmed.
|
|
84
|
+
|
|
85
|
+
## Publication gate
|
|
86
|
+
|
|
87
|
+
When the profile is useful enough for the user to review—or the user asks to publish—show one final preview containing:
|
|
88
|
+
|
|
89
|
+
- project name, purpose, scope, and lifecycle
|
|
90
|
+
- public sources and links
|
|
91
|
+
- excluded private or restricted sources
|
|
92
|
+
- confirmed and inferred existing information
|
|
93
|
+
- evidence coverage score with the sentence “资料覆盖仅用于展示,不影响发布”
|
|
94
|
+
- the selected public Provider
|
|
95
|
+
- the consequences: publisher becomes Owner and Maintainer, and the personal space is automatically subscribed
|
|
96
|
+
|
|
97
|
+
Ask one final question: whether to publish this exact preview. Recommend publishing when the public boundary is clear; sparse evidence does not block publication.
|
|
98
|
+
|
|
99
|
+
If more than one public Provider is ready and no existing project mapping determines the target, ask one Provider-selection question before the final preview. Do not select the first Provider implicitly.
|
|
100
|
+
|
|
101
|
+
Confirmation approves only the public sources and links individually listed in that preview. Unlisted sources remain private or restricted.
|
|
102
|
+
|
|
103
|
+
Only after explicit confirmation, call `publish_personal_project` with `personalSpaceId`, `localProjectId`, and `providerUrl` from the preview.
|
|
104
|
+
|
|
105
|
+
If no public Provider is connected:
|
|
106
|
+
|
|
107
|
+
- continue building the personal project profile normally
|
|
108
|
+
- do not offer a fake or queued publication
|
|
109
|
+
- explain once, when relevant, that public publication is unavailable until a Provider is connected
|
|
110
|
+
- do not automatically replay publication later
|
|
111
|
+
|
|
112
|
+
## Project relationships
|
|
113
|
+
|
|
114
|
+
Use `create_project_relation` only after both public projects are identified and the user confirms the relationship type.
|
|
115
|
+
|
|
116
|
+
- `PART_OF` means a real hierarchy and requires confirmation by a Maintainer of the parent project.
|
|
117
|
+
- `DEPENDS_ON` means a runtime, delivery, or development dependency.
|
|
118
|
+
- `PROVIDES_TO` means one project supplies a capability to another.
|
|
119
|
+
- `SHARES_CAPABILITY_WITH` means reusable capability overlap without hierarchy.
|
|
120
|
+
- `SUCCESSOR_OF` means replacement or evolution.
|
|
121
|
+
- `RELATED_TO` is the fallback when no stronger semantics are confirmed.
|
|
122
|
+
|
|
123
|
+
Do not use `PART_OF` merely because two projects are in the same business domain. Do not subscribe to the related project unless the user separately asks.
|
|
124
|
+
|
|
125
|
+
## Safety
|
|
126
|
+
|
|
127
|
+
Never record or publish credentials, tokens, cookies, private keys, personal/personnel information, or unrelated machine details. Keep confidential material out of names, summaries, source titles, URIs, assessment evidence, and publication previews.
|
|
128
|
+
|
|
129
|
+
Sources marked `private` or `restricted` may remain in the personal profile but cannot be sent to the public Provider. If the public profile would reveal company-confidential information, stop and ask one boundary question before proceeding.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Fuli project profile reference
|
|
2
|
+
|
|
3
|
+
Use this reference to construct the complete payload for `upsert_personal_project`.
|
|
4
|
+
Optional fields may be absent. Publication is never blocked by this guidance.
|
|
5
|
+
|
|
6
|
+
## Profile fields
|
|
7
|
+
|
|
8
|
+
- `name`: confirmed user-facing project name
|
|
9
|
+
- `purpose`: problem solved, primary users, and intended outcome
|
|
10
|
+
- `scope`: included and excluded product or technical boundaries
|
|
11
|
+
- `technicalSummary`: architecture, important modules, runtimes, and constraints
|
|
12
|
+
- `lifecycle`: `planned`, `active`, `maintenance`, or `archived`
|
|
13
|
+
- `sources`: evidence records described below
|
|
14
|
+
- `boundaries`: durable development, ownership, privacy, and operational rules
|
|
15
|
+
- `assessment`: evidence-backed summary of information currently recorded
|
|
16
|
+
|
|
17
|
+
## Source records
|
|
18
|
+
|
|
19
|
+
Every source needs a stable `key`, `kind`, and `title`. Add `uri` and `summary` only when supported by evidence.
|
|
20
|
+
|
|
21
|
+
Supported kinds:
|
|
22
|
+
|
|
23
|
+
- `prd`
|
|
24
|
+
- `product_document`
|
|
25
|
+
- `technical_document`
|
|
26
|
+
- `frontend_repository`
|
|
27
|
+
- `backend_repository`
|
|
28
|
+
- `repository`
|
|
29
|
+
- `design`
|
|
30
|
+
- `runbook`
|
|
31
|
+
- `monitoring`
|
|
32
|
+
- `issue_tracker`
|
|
33
|
+
- `other`
|
|
34
|
+
|
|
35
|
+
Set sensitivity to:
|
|
36
|
+
|
|
37
|
+
- `normal` only when the source is approved for public inclusion
|
|
38
|
+
- `private` for personal or non-public project evidence
|
|
39
|
+
- `restricted` for highly controlled evidence that must never reach a public Provider
|
|
40
|
+
|
|
41
|
+
Do not store credentials at any sensitivity.
|
|
42
|
+
|
|
43
|
+
## Evidence coverage dimensions
|
|
44
|
+
|
|
45
|
+
Use these dimensions only to summarize evidence already present, not to declare what a
|
|
46
|
+
project is missing. Each dimension has a 0–100 coverage score. The overall score should
|
|
47
|
+
be a reasoned weighted average of supported evidence, not an unexamined count of links.
|
|
48
|
+
|
|
49
|
+
1. `identity` — purpose, users, lifecycle, scope, and exclusions
|
|
50
|
+
2. `product` — PRD or equivalent product evidence and current requirements
|
|
51
|
+
3. `technical` — architecture, key modules, interfaces, and constraints
|
|
52
|
+
4. `code` — confirmed frontend/backend repositories and ownership boundaries
|
|
53
|
+
5. `operations` — run, deploy, rollback, monitoring, and incident evidence
|
|
54
|
+
6. `governance` — privacy boundary, contribution rules, maintainership, and durable development rules
|
|
55
|
+
|
|
56
|
+
Suggested weighting:
|
|
57
|
+
|
|
58
|
+
- identity: 20%
|
|
59
|
+
- product: 20%
|
|
60
|
+
- technical: 20%
|
|
61
|
+
- code: 20%
|
|
62
|
+
- operations: 10%
|
|
63
|
+
- governance: 10%
|
|
64
|
+
|
|
65
|
+
Scoring evidence:
|
|
66
|
+
|
|
67
|
+
- 80–100: current, direct, and sufficiently detailed evidence
|
|
68
|
+
- 50–79: partial evidence with material gaps
|
|
69
|
+
- 20–49: mainly user statements or weak/inferred evidence
|
|
70
|
+
- 0–19: no usable evidence currently recorded or evidence is contradicted
|
|
71
|
+
|
|
72
|
+
Overall labels:
|
|
73
|
+
|
|
74
|
+
- `needs_clarification`: 0–39
|
|
75
|
+
- `partially_documented`: 40–74
|
|
76
|
+
- `well_documented`: 75–100
|
|
77
|
+
|
|
78
|
+
Each dimension contains:
|
|
79
|
+
|
|
80
|
+
- `key`
|
|
81
|
+
- `label`
|
|
82
|
+
- `score`
|
|
83
|
+
- `state`: `confirmed` or `inferred`
|
|
84
|
+
- `evidence`: short statements pointing to the evidence
|
|
85
|
+
|
|
86
|
+
The assessment contains `confirmed` and `inferred` summaries only. It does not contain a
|
|
87
|
+
generated `missing` list. A zero score means Fuli currently has no usable evidence for
|
|
88
|
+
that dimension; it does not claim the project must add a particular artifact.
|
|
89
|
+
|
|
90
|
+
## Publication checklist
|
|
91
|
+
|
|
92
|
+
Before asking for final confirmation, verify the preview explicitly covers:
|
|
93
|
+
|
|
94
|
+
- project purpose and scope
|
|
95
|
+
- PRD/product documentation
|
|
96
|
+
- technical documentation
|
|
97
|
+
- frontend and backend repository evidence
|
|
98
|
+
- runbook or local run/deployment instructions
|
|
99
|
+
- monitoring and error-diagnosis instructions
|
|
100
|
+
- privacy and public-sharing boundary
|
|
101
|
+
- durable project development rules
|
|
102
|
+
- confirmed and inferred existing information
|
|
103
|
+
- Owner/automatic-subscription consequence
|
|
104
|
+
|
|
105
|
+
Sparse evidence never prevents publication.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { SpaceKind } from '../models.js';
|
|
2
|
+
import { isSafeAgentText } from './public-read-policy.js';
|
|
3
|
+
import { requirePersonalSpace } from './space-boundary.js';
|
|
4
|
+
|
|
5
|
+
export class AgentCandidateReadService {
|
|
6
|
+
constructor(store) {
|
|
7
|
+
this.store = store;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
list(personalSpaceId) {
|
|
11
|
+
requirePersonalSpace(this.store, personalSpaceId);
|
|
12
|
+
return this.store.pendingCandidates(personalSpaceId)
|
|
13
|
+
.map((candidate) => this.#project(candidate, personalSpaceId));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
listForSpace(personalSpaceId, spaceId) {
|
|
17
|
+
return this.list(personalSpaceId)
|
|
18
|
+
.filter((candidate) => !candidate.targetSpaceId || candidate.targetSpaceId === spaceId);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#project(candidate, personalSpaceId) {
|
|
22
|
+
const resolvedTarget = candidate.targetSpaceId
|
|
23
|
+
? this.store.getSpace(candidate.targetSpaceId)
|
|
24
|
+
: null;
|
|
25
|
+
const target = resolvedTarget?.kind === SpaceKind.PUBLIC ? resolvedTarget : null;
|
|
26
|
+
return {
|
|
27
|
+
id: candidate.id,
|
|
28
|
+
reason: isSafeAgentText(candidate.reason) ? candidate.reason : null,
|
|
29
|
+
status: candidate.status,
|
|
30
|
+
createdAt: candidate.createdAt,
|
|
31
|
+
targetSpaceId: target?.id ?? null,
|
|
32
|
+
targetSpaceName: target?.name ?? null,
|
|
33
|
+
source: this.#source(candidate.episodeId, personalSpaceId)
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
#source(episodeId, personalSpaceId) {
|
|
38
|
+
const episode = this.store.getEpisode(episodeId);
|
|
39
|
+
if (!episode || episode.spaceId !== personalSpaceId) return null;
|
|
40
|
+
if (![
|
|
41
|
+
episode.sourceKind,
|
|
42
|
+
episode.sourceUri,
|
|
43
|
+
episode.body,
|
|
44
|
+
JSON.stringify(episode.metadata)
|
|
45
|
+
].every(isSafeAgentText)) return null;
|
|
46
|
+
return {
|
|
47
|
+
id: episode.id,
|
|
48
|
+
kind: episode.sourceKind,
|
|
49
|
+
uri: episode.sourceUri,
|
|
50
|
+
createdAt: episode.createdAt
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|