psyclaw 0.25.1 → 0.26.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/README.md +111 -60
- package/{apps → dist/apps}/panel/index.html +50 -28
- package/dist/src/adapters/pi/extension.d.ts +19 -0
- package/dist/src/adapters/pi/extension.js +735 -0
- package/dist/src/adapters/pi/extension.js.map +1 -0
- package/dist/src/adapters/pi/model.d.ts +72 -0
- package/dist/src/adapters/pi/model.js +152 -0
- package/dist/src/adapters/pi/model.js.map +1 -0
- package/dist/src/adapters/pi/resources.d.ts +23 -0
- package/dist/src/adapters/pi/resources.js +54 -0
- package/dist/src/adapters/pi/resources.js.map +1 -0
- package/dist/src/adapters/pi/rpc.d.ts +58 -0
- package/dist/src/adapters/pi/rpc.js +253 -0
- package/dist/src/adapters/pi/rpc.js.map +1 -0
- package/dist/src/adapters/pi/session.d.ts +30 -0
- package/dist/src/adapters/pi/session.js +64 -0
- package/dist/src/adapters/pi/session.js.map +1 -0
- package/dist/src/agents/catalog.d.ts +30 -0
- package/dist/src/agents/catalog.js +118 -0
- package/dist/src/agents/catalog.js.map +1 -0
- package/dist/src/agents/discover.d.ts +28 -0
- package/dist/src/agents/discover.js +127 -0
- package/dist/src/agents/discover.js.map +1 -0
- package/dist/src/agents/import.d.ts +67 -0
- package/dist/src/agents/import.js +789 -0
- package/dist/src/agents/import.js.map +1 -0
- package/dist/src/analysis/hooks.d.ts +81 -0
- package/dist/src/analysis/hooks.js +139 -0
- package/dist/src/analysis/hooks.js.map +1 -0
- package/dist/src/analysis/pre-registration.d.ts +18 -0
- package/dist/src/analysis/pre-registration.js +86 -0
- package/dist/src/analysis/pre-registration.js.map +1 -0
- package/dist/src/branding.d.ts +44 -0
- package/dist/src/branding.js +128 -0
- package/dist/src/branding.js.map +1 -0
- package/dist/src/chat.d.ts +16 -0
- package/dist/src/chat.js +95 -0
- package/dist/src/chat.js.map +1 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +316 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/core/citations.d.ts +44 -0
- package/dist/src/core/citations.js +48 -0
- package/dist/src/core/citations.js.map +1 -0
- package/dist/src/core/contracts.d.ts +119 -0
- package/dist/src/core/contracts.js +2 -0
- package/dist/src/core/contracts.js.map +1 -0
- package/dist/src/core/docx.d.ts +11 -0
- package/dist/src/core/docx.js +46 -0
- package/dist/src/core/docx.js.map +1 -0
- package/dist/src/core/doi.d.ts +41 -0
- package/dist/src/core/doi.js +82 -0
- package/dist/src/core/doi.js.map +1 -0
- package/dist/src/core/evidence-policy.d.ts +24 -0
- package/dist/src/core/evidence-policy.js +308 -0
- package/dist/src/core/evidence-policy.js.map +1 -0
- package/dist/src/core/filekind.d.ts +15 -0
- package/dist/src/core/filekind.js +82 -0
- package/dist/src/core/filekind.js.map +1 -0
- package/dist/src/core/hash.d.ts +2 -0
- package/dist/src/core/hash.js +17 -0
- package/dist/src/core/hash.js.map +1 -0
- package/dist/src/core/pricing.d.ts +38 -0
- package/dist/src/core/pricing.js +110 -0
- package/dist/src/core/pricing.js.map +1 -0
- package/dist/src/core/redact.d.ts +12 -0
- package/dist/src/core/redact.js +48 -0
- package/dist/src/core/redact.js.map +1 -0
- package/dist/src/core/references.d.ts +55 -0
- package/dist/src/core/references.js +102 -0
- package/dist/src/core/references.js.map +1 -0
- package/dist/src/core/schemas.d.ts +162 -0
- package/dist/src/core/schemas.js +160 -0
- package/dist/src/core/schemas.js.map +1 -0
- package/dist/src/extension.d.ts +1 -0
- package/dist/src/extension.js +2 -0
- package/dist/src/extension.js.map +1 -0
- package/dist/src/index.d.ts +72 -0
- package/dist/src/index.js +73 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/install/installer.d.ts +147 -0
- package/dist/src/install/installer.js +721 -0
- package/dist/src/install/installer.js.map +1 -0
- package/dist/src/integrations/contracts.d.ts +35 -0
- package/dist/src/integrations/contracts.js +27 -0
- package/dist/src/integrations/contracts.js.map +1 -0
- package/dist/src/integrations/mcp.d.ts +155 -0
- package/dist/src/integrations/mcp.js +826 -0
- package/dist/src/integrations/mcp.js.map +1 -0
- package/dist/src/knowledge-map/contracts.d.ts +20 -0
- package/dist/src/knowledge-map/contracts.js +2 -0
- package/dist/src/knowledge-map/contracts.js.map +1 -0
- package/dist/src/knowledge-map/index.d.ts +4 -0
- package/dist/src/knowledge-map/index.js +39 -0
- package/dist/src/knowledge-map/index.js.map +1 -0
- package/dist/src/literature/contracts.d.ts +106 -0
- package/dist/src/literature/contracts.js +2 -0
- package/dist/src/literature/contracts.js.map +1 -0
- package/dist/src/literature/fulltext.d.ts +7 -0
- package/dist/src/literature/fulltext.js +24 -0
- package/dist/src/literature/fulltext.js.map +1 -0
- package/dist/src/literature/knowledge-map.d.ts +2 -0
- package/dist/src/literature/knowledge-map.js +20 -0
- package/dist/src/literature/knowledge-map.js.map +1 -0
- package/dist/src/literature/ledger.d.ts +3 -0
- package/dist/src/literature/ledger.js +17 -0
- package/dist/src/literature/ledger.js.map +1 -0
- package/dist/src/literature/metadata.d.ts +6 -0
- package/dist/src/literature/metadata.js +32 -0
- package/dist/src/literature/metadata.js.map +1 -0
- package/dist/src/memory/store.d.ts +22 -0
- package/dist/src/memory/store.js +73 -0
- package/dist/src/memory/store.js.map +1 -0
- package/dist/src/orchestration/contracts.d.ts +61 -0
- package/dist/src/orchestration/contracts.js +2 -0
- package/dist/src/orchestration/contracts.js.map +1 -0
- package/dist/src/orchestration/pi-executor.d.ts +28 -0
- package/dist/src/orchestration/pi-executor.js +169 -0
- package/dist/src/orchestration/pi-executor.js.map +1 -0
- package/dist/src/orchestration/runner.d.ts +196 -0
- package/dist/src/orchestration/runner.js +991 -0
- package/dist/src/orchestration/runner.js.map +1 -0
- package/dist/src/orchestration/scheduler.d.ts +8 -0
- package/dist/src/orchestration/scheduler.js +335 -0
- package/dist/src/orchestration/scheduler.js.map +1 -0
- package/dist/src/panel/events.d.ts +20 -0
- package/dist/src/panel/events.js +93 -0
- package/dist/src/panel/events.js.map +1 -0
- package/dist/src/panel/extension.d.ts +8 -0
- package/dist/src/panel/extension.js +115 -0
- package/dist/src/panel/extension.js.map +1 -0
- package/dist/src/panel/literature-map.d.ts +26 -0
- package/dist/src/panel/literature-map.js +34 -0
- package/dist/src/panel/literature-map.js.map +1 -0
- package/dist/src/panel/projection.d.ts +51 -0
- package/dist/src/panel/projection.js +288 -0
- package/dist/src/panel/projection.js.map +1 -0
- package/dist/src/panel/server.d.ts +46 -0
- package/dist/src/panel/server.js +1610 -0
- package/dist/src/panel/server.js.map +1 -0
- package/dist/src/panel/usage.d.ts +53 -0
- package/dist/src/panel/usage.js +150 -0
- package/dist/src/panel/usage.js.map +1 -0
- package/dist/src/project/bootstrap.d.ts +10 -0
- package/dist/src/project/bootstrap.js +83 -0
- package/dist/src/project/bootstrap.js.map +1 -0
- package/dist/src/project/hitl.d.ts +12 -0
- package/dist/src/project/hitl.js +43 -0
- package/dist/src/project/hitl.js.map +1 -0
- package/dist/src/project/jsonl.d.ts +16 -0
- package/dist/src/project/jsonl.js +93 -0
- package/dist/src/project/jsonl.js.map +1 -0
- package/dist/src/project/manuscript.d.ts +21 -0
- package/dist/src/project/manuscript.js +74 -0
- package/dist/src/project/manuscript.js.map +1 -0
- package/dist/src/project/paths.d.ts +38 -0
- package/dist/src/project/paths.js +166 -0
- package/dist/src/project/paths.js.map +1 -0
- package/dist/src/project/versions.d.ts +10 -0
- package/dist/src/project/versions.js +14 -0
- package/dist/src/project/versions.js.map +1 -0
- package/dist/src/psyclaw-theme.d.ts +88 -0
- package/dist/src/psyclaw-theme.js +89 -0
- package/dist/src/psyclaw-theme.js.map +1 -0
- package/dist/src/research/brief.d.ts +11 -0
- package/dist/src/research/brief.js +81 -0
- package/dist/src/research/brief.js.map +1 -0
- package/dist/src/research/ledger.d.ts +12 -0
- package/dist/src/research/ledger.js +43 -0
- package/dist/src/research/ledger.js.map +1 -0
- package/dist/src/run.d.ts +20 -0
- package/dist/src/run.js +34 -0
- package/dist/src/run.js.map +1 -0
- package/dist/src/setup.d.ts +54 -0
- package/dist/src/setup.js +221 -0
- package/dist/src/setup.js.map +1 -0
- package/dist/src/skills/contracts.d.ts +105 -0
- package/dist/src/skills/contracts.js +3 -0
- package/dist/src/skills/contracts.js.map +1 -0
- package/dist/src/skills/preflight.d.ts +10 -0
- package/dist/src/skills/preflight.js +39 -0
- package/dist/src/skills/preflight.js.map +1 -0
- package/dist/src/skills/registry.d.ts +28 -0
- package/dist/src/skills/registry.js +540 -0
- package/dist/src/skills/registry.js.map +1 -0
- package/dist/src/style/artifact.d.ts +6 -0
- package/dist/src/style/artifact.js +61 -0
- package/dist/src/style/artifact.js.map +1 -0
- package/dist/src/style/cli-ui.d.ts +41 -0
- package/dist/src/style/cli-ui.js +119 -0
- package/dist/src/style/cli-ui.js.map +1 -0
- package/dist/src/style/contracts.d.ts +34 -0
- package/dist/src/style/contracts.js +2 -0
- package/dist/src/style/contracts.js.map +1 -0
- package/dist/src/style/registry.d.ts +16 -0
- package/dist/src/style/registry.js +50 -0
- package/dist/src/style/registry.js.map +1 -0
- package/dist/src/trust/manifest.d.ts +42 -0
- package/dist/src/trust/manifest.js +53 -0
- package/dist/src/trust/manifest.js.map +1 -0
- package/dist/src/trust/sbom.d.ts +54 -0
- package/dist/src/trust/sbom.js +77 -0
- package/dist/src/trust/sbom.js.map +1 -0
- package/dist/src/tui/app.d.ts +3 -0
- package/dist/src/tui/app.js +103 -0
- package/dist/src/tui/app.js.map +1 -0
- package/dist/src/tui/model.d.ts +13 -0
- package/dist/src/tui/model.js +25 -0
- package/dist/src/tui/model.js.map +1 -0
- package/dist/src/updates/check.d.ts +43 -0
- package/dist/src/updates/check.js +68 -0
- package/dist/src/updates/check.js.map +1 -0
- package/dist/src/updates/manifest.d.ts +19 -0
- package/dist/src/updates/manifest.js +58 -0
- package/dist/src/updates/manifest.js.map +1 -0
- package/dist/src/updates/registry.d.ts +21 -0
- package/dist/src/updates/registry.js +82 -0
- package/dist/src/updates/registry.js.map +1 -0
- package/dist/src/updates/skills.d.ts +15 -0
- package/dist/src/updates/skills.js +39 -0
- package/dist/src/updates/skills.js.map +1 -0
- package/dist/src/updates/status.d.ts +7 -0
- package/dist/src/updates/status.js +37 -0
- package/dist/src/updates/status.js.map +1 -0
- package/dist/src/updates/update.d.ts +43 -0
- package/dist/src/updates/update.js +128 -0
- package/dist/src/updates/update.js.map +1 -0
- package/dist/src/wizard.d.ts +7 -0
- package/dist/src/wizard.js +90 -0
- package/dist/src/wizard.js.map +1 -0
- package/dist/src/workflows/analysis-delegation.d.ts +3 -0
- package/dist/src/workflows/analysis-delegation.js +96 -0
- package/dist/src/workflows/analysis-delegation.js.map +1 -0
- package/dist/src/workflows/expert-review-runner.d.ts +29 -0
- package/dist/src/workflows/expert-review-runner.js +35 -0
- package/dist/src/workflows/expert-review-runner.js.map +1 -0
- package/dist/src/workflows/expert-review.d.ts +140 -0
- package/dist/src/workflows/expert-review.js +111 -0
- package/dist/src/workflows/expert-review.js.map +1 -0
- package/dist/src/workflows/institutional-fulltext.d.ts +16 -0
- package/dist/src/workflows/institutional-fulltext.js +110 -0
- package/dist/src/workflows/institutional-fulltext.js.map +1 -0
- package/dist/src/workflows/literature-review.d.ts +3 -0
- package/dist/src/workflows/literature-review.js +76 -0
- package/dist/src/workflows/literature-review.js.map +1 -0
- package/dist/src/workflows/meta-analysis.d.ts +38 -0
- package/dist/src/workflows/meta-analysis.js +185 -0
- package/dist/src/workflows/meta-analysis.js.map +1 -0
- package/dist/src/workflows/publish.d.ts +51 -0
- package/dist/src/workflows/publish.js +153 -0
- package/dist/src/workflows/publish.js.map +1 -0
- package/dist/src/workflows/spec.d.ts +51 -0
- package/dist/src/workflows/spec.js +157 -0
- package/dist/src/workflows/spec.js.map +1 -0
- package/dist/src/workflows/style-contract.d.ts +24 -0
- package/dist/src/workflows/style-contract.js +23 -0
- package/dist/src/workflows/style-contract.js.map +1 -0
- package/dist/src/workflows/writing-review.d.ts +15 -0
- package/dist/src/workflows/writing-review.js +82 -0
- package/dist/src/workflows/writing-review.js.map +1 -0
- package/package.json +20 -8
- package/scripts/rebrand-pi.mjs +6 -5
- package/scripts/__pycache__/build_dist.cpython-314.pyc +0 -0
- package/scripts/__pycache__/build_whitepaper_docx.cpython-314.pyc +0 -0
- package/scripts/build_preprint_docx.py +0 -729
- package/scripts/build_preprint_figures.py +0 -238
- package/scripts/build_three_line_table_fixture.py +0 -56
- package/scripts/build_whitepaper_docx.py +0 -768
- package/scripts/check-branding.mjs +0 -159
- package/scripts/copy-panel.mjs +0 -11
- package/scripts/verify_docx.py +0 -41
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
import { Compile } from "typebox/compile";
|
|
3
|
+
const Role = Type.Union([
|
|
4
|
+
Type.Literal("methodologist"),
|
|
5
|
+
Type.Literal("evidence-critic"),
|
|
6
|
+
Type.Literal("writing-editor"),
|
|
7
|
+
Type.Literal("devil-advocate"),
|
|
8
|
+
Type.Literal("ethics-reviewer"),
|
|
9
|
+
Type.Literal("reproducibility-reviewer"),
|
|
10
|
+
]);
|
|
11
|
+
const Finding = Type.Object({
|
|
12
|
+
id: Type.String({ minLength: 1 }),
|
|
13
|
+
severity: Type.Union([Type.Literal("block"), Type.Literal("major"), Type.Literal("minor"), Type.Literal("note")]),
|
|
14
|
+
rule: Type.String({ minLength: 1 }),
|
|
15
|
+
message: Type.String({ minLength: 1 }),
|
|
16
|
+
refs: Type.Array(Type.String()),
|
|
17
|
+
disposition: Type.Union([Type.Literal("accept"), Type.Literal("revise"), Type.Literal("reject"), Type.Literal("uncertain")]),
|
|
18
|
+
}, { additionalProperties: false });
|
|
19
|
+
export const ExpertReviewOpinionSchema = Type.Object({
|
|
20
|
+
schemaVersion: Type.Literal("psyclaw/expert-review-opinion/v1"),
|
|
21
|
+
runId: Type.String({ minLength: 1 }), taskId: Type.String({ minLength: 1 }), dispatchId: Type.String({ minLength: 1 }),
|
|
22
|
+
expertId: Type.String({ minLength: 1 }), role: Role,
|
|
23
|
+
outcome: Type.Union([Type.Literal("complete"), Type.Literal("blocked"), Type.Literal("uncertain")]),
|
|
24
|
+
summary: Type.String({ minLength: 1 }), findings: Type.Array(Finding), evidenceRefs: Type.Array(Type.String()),
|
|
25
|
+
}, { additionalProperties: false });
|
|
26
|
+
export const ExpertReviewContractSchema = Type.Object({
|
|
27
|
+
schemaVersion: Type.Literal("psyclaw/expert-review/v1"), runId: Type.String({ minLength: 1 }),
|
|
28
|
+
subject: Type.Object({ kind: Type.Union([Type.Literal("manuscript"), Type.Literal("artifact"), Type.Literal("workflow")]), ref: Type.String({ minLength: 1 }) }, { additionalProperties: false }),
|
|
29
|
+
inputRefs: Type.Array(Type.String()),
|
|
30
|
+
experts: Type.Array(Type.Object({ expertId: Type.String({ minLength: 1 }), role: Role, taskId: Type.String({ minLength: 1 }) }, { additionalProperties: false }), { minItems: 1 }),
|
|
31
|
+
requiredRoles: Type.Array(Role, { minItems: 1 }), minOpinions: Type.Integer({ minimum: 1 }), independent: Type.Literal(true),
|
|
32
|
+
output: Type.Object({ artifactPath: Type.String({ minLength: 1 }), verdictPath: Type.String({ minLength: 1 }) }, { additionalProperties: false }),
|
|
33
|
+
}, { additionalProperties: false });
|
|
34
|
+
export const ExpertReviewResultSchema = Type.Object({
|
|
35
|
+
schemaVersion: Type.Literal("psyclaw/expert-review-result/v1"), runId: Type.String({ minLength: 1 }),
|
|
36
|
+
verdict: Type.Union([Type.Literal("pass"), Type.Literal("blocked"), Type.Literal("uncertain")]),
|
|
37
|
+
opinions: Type.Array(ExpertReviewOpinionSchema), findings: Type.Array(Finding), unresolvedRoles: Type.Array(Role), blockReasons: Type.Array(Type.String()),
|
|
38
|
+
}, { additionalProperties: false });
|
|
39
|
+
const contractValidator = Compile(ExpertReviewContractSchema);
|
|
40
|
+
const opinionValidator = Compile(ExpertReviewOpinionSchema);
|
|
41
|
+
const resultValidator = Compile(ExpertReviewResultSchema);
|
|
42
|
+
export function validateExpertReviewContract(value) {
|
|
43
|
+
if (!contractValidator.Check(value))
|
|
44
|
+
throw new Error("invalid psyclaw/expert-review/v1 contract");
|
|
45
|
+
const contract = value;
|
|
46
|
+
const expertRoles = new Set(contract.experts.map((expert) => expert.role));
|
|
47
|
+
if (contract.minOpinions > contract.experts.length)
|
|
48
|
+
throw new Error("minOpinions exceeds configured experts");
|
|
49
|
+
if (contract.requiredRoles.some((role) => !expertRoles.has(role)))
|
|
50
|
+
throw new Error("required role has no configured expert");
|
|
51
|
+
if (new Set(contract.requiredRoles).size !== contract.requiredRoles.length)
|
|
52
|
+
throw new Error("duplicate required role");
|
|
53
|
+
if (new Set(contract.experts.map((expert) => expert.expertId)).size !== contract.experts.length)
|
|
54
|
+
throw new Error("duplicate expertId");
|
|
55
|
+
return contract;
|
|
56
|
+
}
|
|
57
|
+
export function validateExpertReviewOpinion(value) {
|
|
58
|
+
if (!opinionValidator.Check(value))
|
|
59
|
+
throw new Error("invalid psyclaw/expert-review-opinion/v1 opinion");
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
62
|
+
export function validateExpertReviewResult(value) {
|
|
63
|
+
if (!resultValidator.Check(value))
|
|
64
|
+
throw new Error("invalid psyclaw/expert-review-result/v1 result");
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Deterministically combines independent opinions. It does not infer a
|
|
69
|
+
* finding from a vote and never upgrades an uncertain or blocked opinion.
|
|
70
|
+
*/
|
|
71
|
+
export function aggregateExpertReview(contractValue, opinionValues) {
|
|
72
|
+
const contract = validateExpertReviewContract(contractValue);
|
|
73
|
+
const opinions = opinionValues.map(validateExpertReviewOpinion);
|
|
74
|
+
const blockReasons = [];
|
|
75
|
+
const configured = new Map(contract.experts.map((expert) => [expert.expertId, expert]));
|
|
76
|
+
const seen = new Set();
|
|
77
|
+
for (const opinion of opinions) {
|
|
78
|
+
if (opinion.runId !== contract.runId)
|
|
79
|
+
blockReasons.push(`opinion ${opinion.expertId} belongs to another run`);
|
|
80
|
+
const expert = configured.get(opinion.expertId);
|
|
81
|
+
if (!expert)
|
|
82
|
+
blockReasons.push(`unconfigured expert: ${opinion.expertId}`);
|
|
83
|
+
else if (expert.role !== opinion.role || expert.taskId !== opinion.taskId)
|
|
84
|
+
blockReasons.push(`opinion identity mismatch: ${opinion.expertId}`);
|
|
85
|
+
if (seen.has(opinion.expertId))
|
|
86
|
+
blockReasons.push(`duplicate opinion: ${opinion.expertId}`);
|
|
87
|
+
seen.add(opinion.expertId);
|
|
88
|
+
if (opinion.outcome === "blocked")
|
|
89
|
+
blockReasons.push(`expert blocked: ${opinion.expertId}`);
|
|
90
|
+
}
|
|
91
|
+
const roles = new Set(opinions.map((opinion) => opinion.role));
|
|
92
|
+
const unresolvedRoles = contract.requiredRoles.filter((role) => !roles.has(role));
|
|
93
|
+
if (opinions.length < contract.minOpinions)
|
|
94
|
+
blockReasons.push("minimum opinion count not met");
|
|
95
|
+
if (unresolvedRoles.length > 0)
|
|
96
|
+
blockReasons.push(`missing required roles: ${unresolvedRoles.join(", ")}`);
|
|
97
|
+
const findings = opinions.flatMap((opinion) => opinion.findings);
|
|
98
|
+
if (findings.some((finding) => finding.severity === "block"))
|
|
99
|
+
blockReasons.push("blocking finding reported");
|
|
100
|
+
const uncertain = opinions.some((opinion) => opinion.outcome === "uncertain") || findings.some((finding) => finding.disposition === "uncertain");
|
|
101
|
+
return {
|
|
102
|
+
schemaVersion: "psyclaw/expert-review-result/v1",
|
|
103
|
+
runId: contract.runId,
|
|
104
|
+
verdict: blockReasons.length > 0 ? "blocked" : uncertain ? "uncertain" : "pass",
|
|
105
|
+
opinions,
|
|
106
|
+
findings,
|
|
107
|
+
unresolvedRoles,
|
|
108
|
+
blockReasons,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=expert-review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expert-review.js","sourceRoot":"","sources":["../../../src/workflows/expert-review.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { InstitutionalRequestPlan, LiteratureRequestMode, MetadataCandidate, VerifiedFulltextRecord } from "../literature/contracts.js";
|
|
2
|
+
import { type WorkflowResult, type WorkflowSpec } from "./spec.js";
|
|
3
|
+
export declare const institutionalFulltextSpec: WorkflowSpec;
|
|
4
|
+
export declare function runInstitutionalFulltext(root: string, identifier?: string): Promise<WorkflowResult>;
|
|
5
|
+
export declare function recordVerifiedInstitutionalFulltext(root: string, options: {
|
|
6
|
+
path: string;
|
|
7
|
+
expected: MetadataCandidate;
|
|
8
|
+
observed: MetadataCandidate;
|
|
9
|
+
approved: boolean;
|
|
10
|
+
retrievedAt?: string;
|
|
11
|
+
}): Promise<VerifiedFulltextRecord>;
|
|
12
|
+
export declare function makeInstitutionalRequestPlan(target: string, options?: {
|
|
13
|
+
mode?: LiteratureRequestMode;
|
|
14
|
+
apiUrl?: string;
|
|
15
|
+
allowedDomains?: string[];
|
|
16
|
+
}): InstitutionalRequestPlan;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { basename, resolve } from "node:path";
|
|
3
|
+
import { appendEvidence, readProject } from "../research/ledger.js";
|
|
4
|
+
import { assertSafeProjectPath } from "../project/paths.js";
|
|
5
|
+
import { crossCheckMetadata, detectFulltext, sha256Bytes } from "../literature/metadata.js";
|
|
6
|
+
import { allParadigms, finalizeWorkflow } from "./spec.js";
|
|
7
|
+
export const institutionalFulltextSpec = {
|
|
8
|
+
id: "institutional-fulltext",
|
|
9
|
+
version: "1.0.0",
|
|
10
|
+
description: "Prepare an auditable, human-approved browser workflow for retrieving institutionally authorized full text.",
|
|
11
|
+
paradigms: allParadigms,
|
|
12
|
+
steps: [
|
|
13
|
+
{ id: "identify", role: "researcher", effect: "read", description: "normalize the DOI, publisher URL, or title supplied by the researcher" },
|
|
14
|
+
{ id: "browse", role: "researcher", effect: "read", description: "use the user's already authenticated browser session" },
|
|
15
|
+
{ id: "approve-download", role: "verifier", effect: "write", description: "ask for confirmation before downloading a licensed full text" },
|
|
16
|
+
{ id: "validate", role: "verifier", effect: "read", description: "verify PDF signature, title/DOI, size, and SHA-256" },
|
|
17
|
+
{ id: "ledger", role: "writer", effect: "write", description: "import the verified local PDF as evidence" },
|
|
18
|
+
],
|
|
19
|
+
requiredArtifacts: ["institutional-fulltext-plan.json", "institutional-fulltext-plan.md"],
|
|
20
|
+
};
|
|
21
|
+
export async function runInstitutionalFulltext(root, identifier = "") {
|
|
22
|
+
const project = await readProject(root);
|
|
23
|
+
const target = identifier.trim() || project.goal;
|
|
24
|
+
const isUrl = /^https?:\/\//i.test(target);
|
|
25
|
+
const isDoi = /^10\.\d{4,9}\//i.test(target);
|
|
26
|
+
const plan = {
|
|
27
|
+
schemaVersion: "psyclaw/institutional-fulltext-plan/v1",
|
|
28
|
+
documentVersion: "1.0.0",
|
|
29
|
+
target: { value: target, kind: isUrl ? "publisher-url" : isDoi ? "doi" : "title-or-query" },
|
|
30
|
+
bridge: {
|
|
31
|
+
adapter: "playwright-mcp",
|
|
32
|
+
mode: "existing-chrome-tab",
|
|
33
|
+
credentialPolicy: "user-authenticated-session-only",
|
|
34
|
+
network: "publisher-domain-only",
|
|
35
|
+
},
|
|
36
|
+
steps: [
|
|
37
|
+
{ id: "identify", action: "resolve DOI/title and verify publisher page" },
|
|
38
|
+
{ id: "authenticate", action: "user completes institutional login, VPN, or proxy in the visible browser" },
|
|
39
|
+
{ id: "confirm", action: "human confirms the exact article and download action" },
|
|
40
|
+
{ id: "download", action: "save PDF under data/clean or an approved evidence staging path" },
|
|
41
|
+
{ id: "validate", action: "check PDF magic bytes, non-HTML content, title/DOI match, size, and SHA-256" },
|
|
42
|
+
{ id: "record", action: "import verified file with psyclaw evidence add and retain source receipt" },
|
|
43
|
+
],
|
|
44
|
+
stopConditions: [
|
|
45
|
+
"login page, CAPTCHA, or access denied",
|
|
46
|
+
"publisher page does not match the requested work",
|
|
47
|
+
"download is HTML, truncated, or hash changes",
|
|
48
|
+
"the action would bypass access controls or violate the user's authorization",
|
|
49
|
+
],
|
|
50
|
+
approval: { requiredBefore: ["download", "record"], actor: "human", status: "pending" },
|
|
51
|
+
};
|
|
52
|
+
const markdown = [
|
|
53
|
+
"# Institutional Full Text Plan",
|
|
54
|
+
"",
|
|
55
|
+
`Target: ${target}`,
|
|
56
|
+
`Bridge: ${plan.bridge.adapter} (${plan.bridge.mode})`,
|
|
57
|
+
"",
|
|
58
|
+
"## Human Gate",
|
|
59
|
+
"",
|
|
60
|
+
"The user must complete institutional authentication in the visible browser and confirm the exact article before download.",
|
|
61
|
+
"",
|
|
62
|
+
"## Steps",
|
|
63
|
+
"",
|
|
64
|
+
...plan.steps.map((step, index) => `${index + 1}. **${step.id}** — ${step.action}`),
|
|
65
|
+
"",
|
|
66
|
+
"## Stop Conditions",
|
|
67
|
+
"",
|
|
68
|
+
...plan.stopConditions.map((item) => `- ${item}`),
|
|
69
|
+
"",
|
|
70
|
+
"## Next Action",
|
|
71
|
+
"",
|
|
72
|
+
"Open the plan in the workbench, connect the approved browser bridge, and request human confirmation before the download step.",
|
|
73
|
+
"",
|
|
74
|
+
].join("\n");
|
|
75
|
+
return finalizeWorkflow(root, institutionalFulltextSpec, {
|
|
76
|
+
gates: [{ gateId: "institutional-fulltext:human-approval", ok: false, severity: "block", reason: "human must confirm the authenticated article and download" }],
|
|
77
|
+
outputs: [
|
|
78
|
+
{ path: "institutional-fulltext-plan.json", contents: `${JSON.stringify(plan, null, 2)}\n` },
|
|
79
|
+
{ path: "institutional-fulltext-plan.md", contents: markdown },
|
|
80
|
+
],
|
|
81
|
+
completed: ["target normalized", "browser bridge and validation plan prepared"],
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
export async function recordVerifiedInstitutionalFulltext(root, options) {
|
|
85
|
+
if (!options.approved)
|
|
86
|
+
throw new Error("human approval is required before ledger record");
|
|
87
|
+
const safe = await assertSafeProjectPath(root, options.path);
|
|
88
|
+
const bytes = await readFile(safe);
|
|
89
|
+
const contentType = detectFulltext(bytes);
|
|
90
|
+
if (contentType === "unknown")
|
|
91
|
+
throw new Error("full text is neither PDF nor HTML");
|
|
92
|
+
const crossCheck = crossCheckMetadata(options.expected, options.observed);
|
|
93
|
+
if (!crossCheck.match)
|
|
94
|
+
throw new Error(`metadata cross-check failed: ${crossCheck.reasons.join("; ")}`);
|
|
95
|
+
const hash = sha256Bytes(bytes);
|
|
96
|
+
const evidence = { id: `institutional:${hash.slice(0, 16)}`, source: { kind: "file", locator: resolve(root, options.path), title: options.observed.title ?? basename(options.path) }, level: "fulltext", retrievedAt: options.retrievedAt ?? new Date().toISOString(), sha256: hash, accessStatus: "verified", locators: [{ kind: "file", value: options.path }, ...(crossCheck.normalizedDoi ? [{ kind: "doi", value: crossCheck.normalizedDoi }] : [])] };
|
|
97
|
+
await appendEvidence(root, evidence);
|
|
98
|
+
return { evidence, crossCheck, contentType, sha256: hash, approval: "approved" };
|
|
99
|
+
}
|
|
100
|
+
export function makeInstitutionalRequestPlan(target, options = {}) {
|
|
101
|
+
const value = target.trim();
|
|
102
|
+
const doi = /^10\.\d{4,9}\//i.test(value);
|
|
103
|
+
const url = /^https?:\/\//i.test(value);
|
|
104
|
+
const mode = options.mode ?? "browser";
|
|
105
|
+
const plan = { schemaVersion: "psyclaw/institutional-request-plan/v1", mode, target: { value, kind: url ? "publisher-url" : doi ? "doi" : "title-or-query" }, allowedDomains: options.allowedDomains ?? [], approval: { required: true, before: ["network", "download", "ledger-record"], status: "pending" }, stopConditions: ["authentication, CAPTCHA, or access denied", "domain is not allowlisted", "request would bypass access controls", "response is HTML login page or metadata does not match"] };
|
|
106
|
+
if (mode === "api")
|
|
107
|
+
plan.api = { method: "GET", url: options.apiUrl ?? value, headers: { Accept: "application/pdf, text/html, application/json" }, response: "pdf-or-html" };
|
|
108
|
+
return plan;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=institutional-fulltext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"institutional-fulltext.js","sourceRoot":"","sources":["../../../src/workflows/institutional-fulltext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE5F,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAA0C,MAAM,WAAW,CAAC;AAEnG,MAAM,CAAC,MAAM,yBAAyB,GAAiB;IACrD,EAAE,EAAE,wBAAwB;IAC5B,OAAO,EAAE,OAAO;IAChB,WAAW,EAAE,4GAA4G;IACzH,SAAS,EAAE,YAAY;IACvB,KAAK,EAAE;QACL,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,uEAAuE,EAAE;QAC5I,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,sDAAsD,EAAE;QACzH,EAAE,EAAE,EAAE,kBAAkB,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,8DAA8D,EAAE;QAC1I,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,oDAAoD,EAAE;QACvH,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,2CAA2C,EAAE;KAC5G;IACD,iBAAiB,EAAE,CAAC,kCAAkC,EAAE,gCAAgC,CAAC;CAC1F,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,IAAY,EAAE,UAAU,GAAG,EAAE;IAC1E,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC;IACjD,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG;QACX,aAAa,EAAE,wCAAwC;QACvD,eAAe,EAAE,OAAO;QACxB,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,EAAE;QAC3F,MAAM,EAAE;YACN,OAAO,EAAE,gBAAgB;YACzB,IAAI,EAAE,qBAAqB;YAC3B,gBAAgB,EAAE,iCAAiC;YACnD,OAAO,EAAE,uBAAuB;SACjC;QACD,KAAK,EAAE;YACL,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,6CAA6C,EAAE;YACzE,EAAE,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,0EAA0E,EAAE;YAC1G,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,sDAAsD,EAAE;YACjF,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,gEAAgE,EAAE;YAC5F,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,6EAA6E,EAAE;YACzG,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,0EAA0E,EAAE;SACrG;QACD,cAAc,EAAE;YACd,uCAAuC;YACvC,kDAAkD;YAClD,8CAA8C;YAC9C,6EAA6E;SAC9E;QACD,QAAQ,EAAE,EAAE,cAAc,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE;KACxF,CAAC;IACF,MAAM,QAAQ,GAAG;QACf,gCAAgC;QAChC,EAAE;QACF,WAAW,MAAM,EAAE;QACnB,WAAW,IAAI,CAAC,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG;QACtD,EAAE;QACF,eAAe;QACf,EAAE;QACF,2HAA2H;QAC3H,EAAE;QACF,UAAU;QACV,EAAE;QACF,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,GAAG,CAAC,OAAO,IAAI,CAAC,EAAE,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;QACnF,EAAE;QACF,oBAAoB;QACpB,EAAE;QACF,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;QACjD,EAAE;QACF,gBAAgB;QAChB,EAAE;QACF,+HAA+H;QAC/H,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,gBAAgB,CAAC,IAAI,EAAE,yBAAyB,EAAE;QACvD,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,uCAAuC,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,2DAA2D,EAAE,CAAC;QAC/J,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,kCAAkC,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;YAC5F,EAAE,IAAI,EAAE,gCAAgC,EAAE,QAAQ,EAAE,QAAQ,EAAE;SAC/D;QACD,SAAS,EAAE,CAAC,mBAAmB,EAAE,6CAA6C,CAAC;KAChF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mCAAmC,CAAC,IAAY,EAAE,OAA4H;IAClM,IAAI,CAAC,OAAO,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAC1F,MAAM,IAAI,GAAG,MAAM,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IAAC,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAC9E,IAAI,WAAW,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACpF,MAAM,UAAU,GAAG,kBAAkB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1E,IAAI,CAAC,UAAU,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxG,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,QAAQ,GAAG,EAAE,EAAE,EAAE,iBAAiB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAe,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,UAAmB,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,UAAmB,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAc,EAAE,KAAK,EAAE,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACze,MAAM,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACrC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,MAAc,EAAE,UAAwF,EAAE;IACrJ,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAAC,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAAC,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC;IACxJ,MAAM,IAAI,GAA6B,EAAE,aAAa,EAAE,uCAAuC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,eAAe,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,cAAc,EAAE,CAAC,2CAA2C,EAAE,2BAA2B,EAAE,sCAAsC,EAAE,wDAAwD,CAAC,EAAE,CAAC;IACxgB,IAAI,IAAI,KAAK,KAAK;QAAE,IAAI,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,8CAA8C,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC7K,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { checkEvidenceSufficiency } from "../core/evidence-policy.js";
|
|
2
|
+
import { loadLedger, readProject } from "../research/ledger.js";
|
|
3
|
+
import { buildKnowledgeMap } from "../knowledge-map/index.js";
|
|
4
|
+
import { allParadigms, finalizeWorkflow } from "./spec.js";
|
|
5
|
+
export const literatureReviewSpec = {
|
|
6
|
+
id: "literature-review",
|
|
7
|
+
version: "1.0.0",
|
|
8
|
+
description: "Aggregate the evidence ledger into a review matrix with conflicts and gaps.",
|
|
9
|
+
paradigms: allParadigms,
|
|
10
|
+
steps: [
|
|
11
|
+
{ id: "capture", role: "researcher", effect: "read", description: "load sources and claims" },
|
|
12
|
+
{ id: "audit", role: "critic", effect: "read", description: "evidence sufficiency and conflict disclosure" },
|
|
13
|
+
{ id: "write", role: "writer", effect: "write", description: "write review matrix and markdown" },
|
|
14
|
+
],
|
|
15
|
+
requiredArtifacts: ["literature-review.md", "review-matrix.json", "knowledge-map.json"],
|
|
16
|
+
};
|
|
17
|
+
export async function runLiteratureReview(root) {
|
|
18
|
+
const project = await readProject(root);
|
|
19
|
+
const ledger = await loadLedger(root);
|
|
20
|
+
const gates = checkEvidenceSufficiency({ ...ledger, paradigm: project.paradigm });
|
|
21
|
+
if (ledger.evidence.length === 0) {
|
|
22
|
+
gates.push({ gateId: "review:sources", ok: false, severity: "block", reason: "no sources recorded" });
|
|
23
|
+
}
|
|
24
|
+
const matrix = {
|
|
25
|
+
schemaVersion: "psyclaw/review-matrix/v1",
|
|
26
|
+
sources: ledger.evidence.map((item) => ({
|
|
27
|
+
id: item.id,
|
|
28
|
+
locator: item.source.locator,
|
|
29
|
+
level: item.level,
|
|
30
|
+
accessStatus: item.accessStatus,
|
|
31
|
+
})),
|
|
32
|
+
claims: ledger.claims.map((item) => ({
|
|
33
|
+
id: item.id,
|
|
34
|
+
kind: item.kind,
|
|
35
|
+
status: item.status,
|
|
36
|
+
evidenceIds: item.evidenceIds,
|
|
37
|
+
})),
|
|
38
|
+
conflicts: ledger.links
|
|
39
|
+
.filter((link) => link.relation === "contradicts")
|
|
40
|
+
.map((link) => ({ claimId: link.claimId, evidenceId: link.evidenceId })),
|
|
41
|
+
gaps: gates.filter((gate) => !gate.ok).map((gate) => gate.reason),
|
|
42
|
+
};
|
|
43
|
+
const knowledgeMap = buildKnowledgeMap(ledger.evidence, ledger.claims);
|
|
44
|
+
const markdown = [
|
|
45
|
+
"# Literature Review",
|
|
46
|
+
"",
|
|
47
|
+
`Research goal: ${project.goal}`,
|
|
48
|
+
"",
|
|
49
|
+
"## Sources",
|
|
50
|
+
"",
|
|
51
|
+
...(matrix.sources.length ? matrix.sources.map((item) => `- [${item.level}] ${item.locator}`) : ["- None"]),
|
|
52
|
+
"",
|
|
53
|
+
"## Claims",
|
|
54
|
+
"",
|
|
55
|
+
...(matrix.claims.length ? matrix.claims.map((item) => `- (${item.kind}) ${item.status}: ${item.id}`) : ["- None"]),
|
|
56
|
+
"",
|
|
57
|
+
"## Conflicts",
|
|
58
|
+
"",
|
|
59
|
+
...(matrix.conflicts.length ? matrix.conflicts.map((item) => `- ${item.claimId} vs ${item.evidenceId}`) : ["- None"]),
|
|
60
|
+
"",
|
|
61
|
+
"## Gaps",
|
|
62
|
+
"",
|
|
63
|
+
...(matrix.gaps.length ? matrix.gaps.map((item) => `- ${item}`) : ["- None"]),
|
|
64
|
+
"",
|
|
65
|
+
].join("\n");
|
|
66
|
+
return finalizeWorkflow(root, literatureReviewSpec, {
|
|
67
|
+
gates,
|
|
68
|
+
outputs: [
|
|
69
|
+
{ path: "literature-review.md", contents: markdown },
|
|
70
|
+
{ path: "review-matrix.json", contents: `${JSON.stringify(matrix, null, 2)}\n` },
|
|
71
|
+
{ path: "knowledge-map.json", contents: `${JSON.stringify(knowledgeMap, null, 2)}\n` },
|
|
72
|
+
],
|
|
73
|
+
completed: ["sources loaded", "claims aggregated", "conflicts and gaps disclosed"],
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=literature-review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"literature-review.js","sourceRoot":"","sources":["../../../src/workflows/literature-review.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type StageRunner } from "../run.js";
|
|
2
|
+
import { type WorkflowResult, type WorkflowSpec } from "./spec.js";
|
|
3
|
+
export declare const metaAnalysisSpec: WorkflowSpec;
|
|
4
|
+
export interface MetaStudy {
|
|
5
|
+
id: string;
|
|
6
|
+
title: string;
|
|
7
|
+
authors: string[];
|
|
8
|
+
year?: number;
|
|
9
|
+
venue?: string;
|
|
10
|
+
doi?: string;
|
|
11
|
+
citations?: number;
|
|
12
|
+
}
|
|
13
|
+
/** Search OpenAlex for studies matching the target (real network; injectable for tests). */
|
|
14
|
+
export declare function searchOpenAlex(target: string, nStudies: number, fetchFn?: typeof fetch): Promise<MetaStudy[]>;
|
|
15
|
+
export interface EffectRow {
|
|
16
|
+
studyId: string;
|
|
17
|
+
effectSize: number;
|
|
18
|
+
standardError: number;
|
|
19
|
+
n?: number;
|
|
20
|
+
}
|
|
21
|
+
/** Parse a CSV with at least `study_id,effect_size,standard_error`. */
|
|
22
|
+
export declare function parseEffectCsv(text: string): EffectRow[];
|
|
23
|
+
export declare function loadEffectDataset(root: string): Promise<EffectRow[] | undefined>;
|
|
24
|
+
/** R metafor script that computes the random-effects model, I², Egger's test, and the forest plot. */
|
|
25
|
+
export declare function metaforScript(datasetPath: string): string;
|
|
26
|
+
export interface MetaAnalysisOptions {
|
|
27
|
+
target: string;
|
|
28
|
+
nStudies: number;
|
|
29
|
+
fetchFn?: typeof fetch;
|
|
30
|
+
runner?: StageRunner;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Real meta-analysis pipeline. Statistics are never computed in core: the
|
|
34
|
+
* audit stage writes an R (metafor) script and the brief records what was
|
|
35
|
+
* found and what must run externally. Effect sizes come from the project's
|
|
36
|
+
* dataset; without one the workflow blocks honestly instead of faking numbers.
|
|
37
|
+
*/
|
|
38
|
+
export declare function runMetaAnalysis(root: string, options: MetaAnalysisOptions): Promise<WorkflowResult>;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { sha256Text } from "../core/hash.js";
|
|
4
|
+
import { appendJsonlIfMissing, atomicWriteFile } from "../project/jsonl.js";
|
|
5
|
+
import { projectPaths } from "../project/paths.js";
|
|
6
|
+
import { readProject } from "../research/ledger.js";
|
|
7
|
+
import { createStageRunner } from "../run.js";
|
|
8
|
+
import { finalizeWorkflow } from "./spec.js";
|
|
9
|
+
export const metaAnalysisSpec = {
|
|
10
|
+
id: "meta-analysis",
|
|
11
|
+
version: "1.0.0",
|
|
12
|
+
description: "Systematic meta-analysis: literature intake, effect-size dataset contract, R metafor audit, brief.",
|
|
13
|
+
paradigms: ["meta-analysis"],
|
|
14
|
+
steps: [
|
|
15
|
+
{ id: "intake", role: "researcher", effect: "read", description: "search OpenAlex for studies" },
|
|
16
|
+
{ id: "capture", role: "analyst", effect: "read", description: "bind the effect-size dataset contract" },
|
|
17
|
+
{ id: "audit", role: "analyst", effect: "write", description: "delegate metafor audit (I², Egger funnel)" },
|
|
18
|
+
{ id: "brief", role: "writer", effect: "write", description: "write the report and ledger entry" },
|
|
19
|
+
],
|
|
20
|
+
requiredArtifacts: ["meta-analysis.json", "meta-analysis.md"],
|
|
21
|
+
};
|
|
22
|
+
/** Search OpenAlex for studies matching the target (real network; injectable for tests). */
|
|
23
|
+
export async function searchOpenAlex(target, nStudies, fetchFn = fetch) {
|
|
24
|
+
const perPage = Math.min(50, Math.max(1, nStudies));
|
|
25
|
+
const url = `https://api.openalex.org/works?search=${encodeURIComponent(target)}&per-page=${perPage}&mailto=psyclaw@example.org`;
|
|
26
|
+
const response = await fetchFn(url, { signal: AbortSignal.timeout(15_000) });
|
|
27
|
+
if (!response.ok)
|
|
28
|
+
throw new Error(`OpenAlex 检索失败 (${response.status})`);
|
|
29
|
+
const body = await response.json();
|
|
30
|
+
return (body.results ?? []).slice(0, nStudies).map((item, index) => ({
|
|
31
|
+
id: `study_${index + 1}`,
|
|
32
|
+
title: item.title ?? "untitled",
|
|
33
|
+
authors: (item.authorships ?? []).map((entry) => entry.author?.display_name ?? "?").slice(0, 10),
|
|
34
|
+
...(item.publication_year === undefined ? {} : { year: item.publication_year }),
|
|
35
|
+
...(item.host_venue?.display_name ? { venue: item.host_venue.display_name } : {}),
|
|
36
|
+
...(item.doi ? { doi: item.doi } : {}),
|
|
37
|
+
...(item.cited_by_count === undefined ? {} : { citations: item.cited_by_count }),
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
/** Parse a CSV with at least `study_id,effect_size,standard_error`. */
|
|
41
|
+
export function parseEffectCsv(text) {
|
|
42
|
+
const rows = [];
|
|
43
|
+
const lines = text.split(/\r?\n/).filter((line) => line.trim());
|
|
44
|
+
if (lines.length === 0)
|
|
45
|
+
return rows;
|
|
46
|
+
const header = lines[0].split(",").map((cell) => cell.trim().toLowerCase());
|
|
47
|
+
// Accept the canonical names plus common shorthand (study, effect, se/g/d).
|
|
48
|
+
const ALIASES = {
|
|
49
|
+
study_id: ["study_id", "study", "id"],
|
|
50
|
+
effect_size: ["effect_size", "effect", "es", "g", "d"],
|
|
51
|
+
standard_error: ["standard_error", "se", "std_error", "std_err"],
|
|
52
|
+
};
|
|
53
|
+
const indexOf = (name) => {
|
|
54
|
+
const aliases = ALIASES[name] ?? [name];
|
|
55
|
+
return header.findIndex((cell) => aliases.includes(cell) || cell.endsWith(name));
|
|
56
|
+
};
|
|
57
|
+
const studyIdx = indexOf("study_id");
|
|
58
|
+
const effectIdx = indexOf("effect_size");
|
|
59
|
+
const seIdx = indexOf("standard_error");
|
|
60
|
+
if (studyIdx < 0 || effectIdx < 0 || seIdx < 0)
|
|
61
|
+
return rows;
|
|
62
|
+
for (const line of lines.slice(1)) {
|
|
63
|
+
const cells = line.split(",").map((cell) => cell.trim());
|
|
64
|
+
const effectSize = Number(cells[effectIdx]);
|
|
65
|
+
const standardError = Number(cells[seIdx]);
|
|
66
|
+
if (!Number.isFinite(effectSize) || !Number.isFinite(standardError) || standardError <= 0)
|
|
67
|
+
continue;
|
|
68
|
+
const n = Number(cells[header.indexOf("n")]);
|
|
69
|
+
rows.push({
|
|
70
|
+
studyId: cells[studyIdx] ?? `study_${rows.length + 1}`,
|
|
71
|
+
effectSize,
|
|
72
|
+
standardError,
|
|
73
|
+
...(Number.isFinite(n) && n > 0 ? { n } : {}),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return rows;
|
|
77
|
+
}
|
|
78
|
+
export async function loadEffectDataset(root) {
|
|
79
|
+
const candidates = ["data/clean/effects.csv", "analysis/outputs/effects.csv", "outputs/effects.csv"];
|
|
80
|
+
for (const candidate of candidates) {
|
|
81
|
+
try {
|
|
82
|
+
const rows = parseEffectCsv(await readFile(join(root, candidate), "utf8"));
|
|
83
|
+
if (rows.length > 0)
|
|
84
|
+
return rows;
|
|
85
|
+
}
|
|
86
|
+
catch { /* try next */ }
|
|
87
|
+
}
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
/** R metafor script that computes the random-effects model, I², Egger's test, and the forest plot. */
|
|
91
|
+
export function metaforScript(datasetPath) {
|
|
92
|
+
return [
|
|
93
|
+
"# metafor.R — 随机效应元分析(委托 R 执行;psyclaw 不在核心计算统计量)",
|
|
94
|
+
"suppressMessages(library(metafor))",
|
|
95
|
+
`d <- read.csv("${datasetPath.replaceAll("\\", "/")}", stringsAsFactors = FALSE)`,
|
|
96
|
+
"fit <- rma(yi = d$effect_size, vi = d$standard_error^2, method = \"REML\")",
|
|
97
|
+
'cat(sprintf("I2=%.1f%%\\n", fit$I2))',
|
|
98
|
+
'cat(sprintf("k=%d\\n", fit$k))',
|
|
99
|
+
'res <- regtest(fit, predictor = "sei")',
|
|
100
|
+
'cat(sprintf("egger_p=%.3f\\n", res$pval))',
|
|
101
|
+
'dir.create("outputs/figures", recursive = TRUE, showWarnings = FALSE)',
|
|
102
|
+
'png("outputs/figures/forest.png", width = 800, height = 480, res = 110)',
|
|
103
|
+
"forest(fit)",
|
|
104
|
+
"dev.off()",
|
|
105
|
+
'dir.create("analysis/outputs", recursive = TRUE, showWarnings = FALSE)',
|
|
106
|
+
'saveRDS(fit, "analysis/outputs/meta_fit.rds")',
|
|
107
|
+
"",
|
|
108
|
+
].join("\n");
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Real meta-analysis pipeline. Statistics are never computed in core: the
|
|
112
|
+
* audit stage writes an R (metafor) script and the brief records what was
|
|
113
|
+
* found and what must run externally. Effect sizes come from the project's
|
|
114
|
+
* dataset; without one the workflow blocks honestly instead of faking numbers.
|
|
115
|
+
*/
|
|
116
|
+
export async function runMetaAnalysis(root, options) {
|
|
117
|
+
const runner = options.runner ?? createStageRunner();
|
|
118
|
+
const project = await readProject(root);
|
|
119
|
+
const gates = [];
|
|
120
|
+
const studies = await runner.stage("intake", `检索 OpenAlex 数据库并提取 "${options.target}" 的实证研究`, async () => searchOpenAlex(options.target, options.nStudies, options.fetchFn ?? fetch), (found) => `命中 ${found.length} 项研究,登记为证据账本条目`);
|
|
121
|
+
if (studies.length < 2) {
|
|
122
|
+
gates.push({ gateId: "meta:insufficient-studies", ok: false, severity: "block", reason: `需要至少 2 项研究,实际 ${studies.length}` });
|
|
123
|
+
}
|
|
124
|
+
const dataset = await runner.stage("capture", "绑定效应量数据集(Hedges' g / SE)", async () => loadEffectDataset(root), (rows) => rows === undefined ? "未找到数据集,进入数据契约状态" : `解析 ${rows.length} 条效应量记录`);
|
|
125
|
+
if (dataset === undefined) {
|
|
126
|
+
gates.push({ gateId: "meta:effect-data-missing", ok: false, severity: "block", reason: "缺少效应量数据集(data/clean/effects.csv:study_id,effect_size,standard_error)" });
|
|
127
|
+
}
|
|
128
|
+
const datasetPath = dataset === undefined ? null : `data/clean/effects.csv`;
|
|
129
|
+
await runner.stage("audit", "委托 R (metafor) 生成随机效应模型、I² 与 Egger 检验", async () => {
|
|
130
|
+
const scriptPath = join(root, "analysis", "scripts", "metafor.R");
|
|
131
|
+
await atomicWriteFile(scriptPath, metaforScript(datasetPath ?? "data/clean/effects.csv"));
|
|
132
|
+
return scriptPath;
|
|
133
|
+
}, (path) => `已写入 ${path};统计由 R 执行,psyclaw 不伪造 I²/Egger 数值`);
|
|
134
|
+
const auditNote = dataset === undefined
|
|
135
|
+
? "数据集缺失:I² 与 Egger 检验待 R 在有数据后执行"
|
|
136
|
+
: `数据集就绪(${dataset.length} 条):运行 analysis/scripts/metafor.R 得到 I² 与 Egger p 值`;
|
|
137
|
+
await runner.stage("brief", "生成元分析报告与账本条目", async () => {
|
|
138
|
+
for (const study of studies) {
|
|
139
|
+
await appendJsonlIfMissing(projectPaths(root).evidence, {
|
|
140
|
+
id: `meta:${sha256Text(study.title).slice(0, 16)}`,
|
|
141
|
+
source: { kind: "url", locator: study.doi ?? study.id, title: study.title },
|
|
142
|
+
level: "metadata",
|
|
143
|
+
retrievedAt: new Date().toISOString(),
|
|
144
|
+
accessStatus: "partial",
|
|
145
|
+
locators: [{ kind: "url", value: study.doi ?? "" }],
|
|
146
|
+
}, (item) => item.id);
|
|
147
|
+
}
|
|
148
|
+
const summary = {
|
|
149
|
+
schemaVersion: "psyclaw/meta-analysis/v1",
|
|
150
|
+
target: options.target,
|
|
151
|
+
nStudiesRequested: options.nStudies,
|
|
152
|
+
studiesFound: studies.length,
|
|
153
|
+
effectRows: dataset?.length ?? 0,
|
|
154
|
+
audit: { delegatedTo: "R metafor", script: "analysis/scripts/metafor.R", note: auditNote },
|
|
155
|
+
generatedAt: new Date().toISOString(),
|
|
156
|
+
};
|
|
157
|
+
const markdown = [
|
|
158
|
+
`# Meta-Analysis: ${options.target}`,
|
|
159
|
+
"",
|
|
160
|
+
`- 检索:OpenAlex,目标 "${options.target}",${studies.length} 项研究`,
|
|
161
|
+
`- 效应量数据集:${dataset === undefined ? "缺失(需 data/clean/effects.csv)" : `${dataset.length} 条`}`,
|
|
162
|
+
`- 统计:委托 R metafor(REML 随机效应、I²、Egger 漏斗回归、森林图)`,
|
|
163
|
+
`- 审计:${auditNote}`,
|
|
164
|
+
"",
|
|
165
|
+
"## 研究清单",
|
|
166
|
+
"",
|
|
167
|
+
...studies.map((study) => `- ${study.title}${study.year ? ` (${study.year})` : ""}${study.doi ? ` · ${study.doi}` : ""}`),
|
|
168
|
+
"",
|
|
169
|
+
"> 统计数值由 R (metafor) 在数据集就绪后计算,本文件不伪造任何效应量或检验结果。",
|
|
170
|
+
"",
|
|
171
|
+
].join("\n");
|
|
172
|
+
await atomicWriteFile(join(root, "analysis", "outputs", "meta-analysis.json"), `${JSON.stringify(summary, null, 2)}\n`);
|
|
173
|
+
await atomicWriteFile(join(root, "analysis", "outputs", "meta-analysis.md"), markdown);
|
|
174
|
+
return { studies: studies.length, rows: dataset?.length ?? 0 };
|
|
175
|
+
}, (result) => `签发 ${result.studies} 条研究账本条目,报告落盘`);
|
|
176
|
+
return finalizeWorkflow(root, metaAnalysisSpec, {
|
|
177
|
+
gates,
|
|
178
|
+
outputs: [
|
|
179
|
+
{ path: "meta-analysis.md", contents: `# Meta-Analysis: ${options.target}\n\n见 analysis/outputs/meta-analysis.md\n` },
|
|
180
|
+
{ path: "meta-analysis.json", contents: `${JSON.stringify({ target: options.target, studies: studies.length, effectRows: dataset?.length ?? 0 }, null, 2)}\n` },
|
|
181
|
+
],
|
|
182
|
+
completed: ["literature intake", "effect-size contract", "metafor delegation", "report written"],
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=meta-analysis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta-analysis.js","sourceRoot":"","sources":["../../../src/workflows/meta-analysis.ts"],"names":[],"mappings":"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"}
|