@geraldmaron/construct 1.0.5 → 1.0.6
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 +8 -4
- package/agents/prompts/cx-accessibility.md +3 -3
- package/agents/prompts/cx-ai-engineer.md +7 -7
- package/agents/prompts/cx-architect.md +6 -6
- package/agents/prompts/cx-business-strategist.md +6 -6
- package/agents/prompts/cx-data-analyst.md +7 -7
- package/agents/prompts/cx-data-engineer.md +3 -3
- package/agents/prompts/cx-debugger.md +6 -6
- package/agents/prompts/cx-designer.md +5 -5
- package/agents/prompts/cx-devil-advocate.md +4 -4
- package/agents/prompts/cx-docs-keeper.md +5 -5
- package/agents/prompts/cx-engineer.md +5 -5
- package/agents/prompts/cx-evaluator.md +2 -2
- package/agents/prompts/cx-explorer.md +8 -8
- package/agents/prompts/cx-legal-compliance.md +2 -2
- package/agents/prompts/cx-operations.md +5 -5
- package/agents/prompts/cx-orchestrator.md +10 -10
- package/agents/prompts/cx-platform-engineer.md +5 -5
- package/agents/prompts/cx-product-manager.md +4 -4
- package/agents/prompts/cx-qa.md +8 -8
- package/agents/prompts/cx-rd-lead.md +9 -9
- package/agents/prompts/cx-release-manager.md +5 -5
- package/agents/prompts/cx-researcher.md +22 -22
- package/agents/prompts/cx-reviewer.md +7 -7
- package/agents/prompts/cx-security.md +10 -10
- package/agents/prompts/cx-sre.md +7 -7
- package/agents/prompts/cx-test-automation.md +3 -3
- package/agents/prompts/cx-trace-reviewer.md +8 -8
- package/agents/prompts/cx-ux-researcher.md +3 -3
- package/bin/construct +235 -21
- package/commands/build/feature.md +4 -4
- package/commands/build/fix.md +8 -8
- package/commands/design/access.md +3 -3
- package/commands/design/flow.md +3 -3
- package/commands/design/ui.md +4 -4
- package/commands/measure/experiment.md +5 -5
- package/commands/measure/metrics.md +3 -3
- package/commands/measure/results.md +4 -4
- package/commands/plan/api.md +3 -3
- package/commands/plan/challenge.md +3 -3
- package/commands/plan/decide.md +3 -3
- package/commands/plan/feature.md +7 -7
- package/commands/plan/requirements.md +3 -3
- package/commands/remember/context.md +5 -5
- package/commands/remember/handoff.md +3 -3
- package/commands/remember/runbook.md +3 -3
- package/commands/review/code.md +8 -8
- package/commands/review/quality.md +4 -4
- package/commands/review/security.md +3 -3
- package/commands/ship/ready.md +3 -3
- package/commands/ship/release.md +3 -3
- package/commands/ship/status.md +4 -4
- package/commands/understand/docs.md +3 -3
- package/commands/understand/this.md +4 -4
- package/commands/understand/why.md +8 -8
- package/commands/work/clean.md +14 -14
- package/commands/work/drive.md +10 -10
- package/commands/work/optimize-prompts.md +9 -9
- package/commands/work/parallel-review.md +8 -8
- package/db/schema/006_graph.sql +24 -0
- package/examples/provider-plugin/README.md +7 -7
- package/examples/seed-observations/README.md +6 -6
- package/examples/seed-observations/anti-patterns.md +14 -14
- package/examples/seed-observations/decisions.md +4 -4
- package/examples/seed-observations/patterns.md +14 -14
- package/lib/auto-docs.mjs +8 -3
- package/lib/cli-commands.mjs +2 -2
- package/lib/flavors/loader.mjs +1 -1
- package/lib/knowledge/graph.mjs +213 -0
- package/lib/mcp/server.mjs +187 -1
- package/lib/mcp/tools/profile.mjs +270 -0
- package/package.json +1 -1
- package/platforms/claude/CLAUDE.md +6 -6
- package/rules/common/agents.md +2 -2
- package/rules/common/beads-hygiene.md +11 -11
- package/rules/common/code-review.md +1 -1
- package/rules/common/coding-style.md +1 -1
- package/rules/common/comments.md +8 -8
- package/rules/common/commit-approval.md +4 -4
- package/rules/common/cx-agent-routing.md +2 -2
- package/rules/common/cx-skill-routing.md +2 -2
- package/rules/common/development-workflow.md +1 -1
- package/rules/common/doc-ownership.md +2 -2
- package/rules/common/efficiency.md +3 -3
- package/rules/common/framing.md +1 -1
- package/rules/common/git-workflow.md +1 -1
- package/rules/common/patterns.md +1 -1
- package/rules/common/performance.md +1 -1
- package/rules/common/release-gates.md +7 -7
- package/rules/common/research.md +4 -4
- package/rules/common/security.md +1 -1
- package/rules/common/skill-composition.md +8 -8
- package/rules/common/testing.md +1 -1
- package/rules/golang/coding-style.md +2 -2
- package/rules/golang/hooks.md +1 -1
- package/rules/golang/patterns.md +1 -1
- package/rules/golang/security.md +1 -1
- package/rules/golang/testing.md +1 -1
- package/rules/python/coding-style.md +1 -1
- package/rules/python/hooks.md +1 -1
- package/rules/python/patterns.md +1 -1
- package/rules/python/security.md +1 -1
- package/rules/python/testing.md +1 -1
- package/rules/swift/coding-style.md +3 -3
- package/rules/swift/hooks.md +2 -2
- package/rules/swift/patterns.md +2 -2
- package/rules/swift/security.md +4 -4
- package/rules/swift/testing.md +2 -2
- package/rules/typescript/coding-style.md +1 -1
- package/rules/typescript/hooks.md +1 -1
- package/rules/typescript/patterns.md +1 -1
- package/rules/typescript/security.md +1 -1
- package/rules/typescript/testing.md +1 -1
- package/rules/web/coding-style.md +1 -1
- package/rules/web/design-quality.md +1 -1
- package/rules/web/hooks.md +1 -1
- package/rules/web/patterns.md +1 -1
- package/rules/web/performance.md +1 -1
- package/rules/web/security.md +1 -1
- package/rules/web/testing.md +1 -1
- package/skills/ai/agent-dev.md +1 -1
- package/skills/ai/llm-security.md +1 -1
- package/skills/ai/ml-ops.md +6 -6
- package/skills/ai/orchestration-workflow.md +1 -1
- package/skills/ai/prompt-and-eval.md +1 -1
- package/skills/ai/prompt-optimizer.md +13 -13
- package/skills/ai/rag-system.md +1 -1
- package/skills/architecture/api-design.md +1 -1
- package/skills/architecture/caching.md +1 -1
- package/skills/architecture/cloud-native.md +1 -1
- package/skills/architecture/message-queue.md +1 -1
- package/skills/architecture/security-arch.md +1 -1
- package/skills/compliance/ai-disclosure.md +1 -1
- package/skills/compliance/data-privacy.md +1 -1
- package/skills/compliance/license-audit.md +2 -2
- package/skills/compliance/regulatory-review.md +1 -1
- package/skills/development/cpp.md +1 -1
- package/skills/development/go.md +1 -1
- package/skills/development/java.md +1 -1
- package/skills/development/kotlin.md +9 -9
- package/skills/development/mobile-crossplatform.md +13 -13
- package/skills/development/python.md +1 -1
- package/skills/development/rust.md +1 -1
- package/skills/development/shell.md +1 -1
- package/skills/development/swift.md +6 -6
- package/skills/development/typescript.md +1 -1
- package/skills/devops/ci-cd.md +5 -5
- package/skills/devops/containerization.md +9 -9
- package/skills/devops/cost-optimization.md +1 -1
- package/skills/devops/data-engineering.md +2 -2
- package/skills/devops/database.md +1 -1
- package/skills/devops/dependency-management.md +3 -3
- package/skills/devops/devsecops.md +1 -1
- package/skills/devops/git-workflow.md +1 -1
- package/skills/devops/incident-response.md +18 -18
- package/skills/devops/monorepo.md +5 -5
- package/skills/devops/observability.md +1 -1
- package/skills/devops/performance.md +1 -1
- package/skills/devops/testing.md +1 -1
- package/skills/docs/adr-workflow.md +2 -2
- package/skills/docs/backlog-proposal-workflow.md +1 -1
- package/skills/docs/customer-profile-workflow.md +1 -1
- package/skills/docs/document-ingest-workflow.md +1 -1
- package/skills/docs/evidence-ingest-workflow.md +1 -1
- package/skills/docs/init-docs.md +15 -15
- package/skills/docs/init-project.md +1 -1
- package/skills/docs/prd-workflow.md +3 -3
- package/skills/docs/prfaq-workflow.md +1 -1
- package/skills/docs/product-intelligence-review.md +1 -1
- package/skills/docs/product-intelligence-workflow.md +1 -1
- package/skills/docs/product-signal-workflow.md +9 -9
- package/skills/docs/research-workflow.md +10 -10
- package/skills/docs/runbook-workflow.md +2 -2
- package/skills/docs/strategy-workflow.md +3 -3
- package/skills/exploration/repo-map.md +11 -11
- package/skills/frameworks/django.md +15 -15
- package/skills/frameworks/nextjs.md +16 -16
- package/skills/frameworks/react.md +12 -12
- package/skills/frameworks/spring-boot.md +12 -12
- package/skills/frontend-design/accessibility.md +6 -6
- package/skills/frontend-design/component-patterns.md +1 -1
- package/skills/frontend-design/engineering.md +1 -1
- package/skills/frontend-design/state-management.md +1 -1
- package/skills/frontend-design/ui-aesthetics.md +1 -1
- package/skills/frontend-design/ux-principles.md +1 -1
- package/skills/operating/orchestration-reference.md +27 -27
- package/skills/quality-gates/review-work.md +3 -3
- package/skills/quality-gates/verify-change.md +1 -1
- package/skills/quality-gates/verify-module.md +1 -1
- package/skills/quality-gates/verify-quality.md +1 -1
- package/skills/quality-gates/verify-security.md +1 -1
- package/skills/routing.md +14 -14
- package/skills/security/blue-team.md +1 -1
- package/skills/security/code-audit.md +1 -1
- package/skills/security/pentest.md +1 -1
- package/skills/security/red-team.md +1 -1
- package/skills/security/threat-intel.md +1 -1
- package/skills/security/vuln-research.md +1 -1
- package/skills/utility/clean-code.md +2 -2
- package/templates/docs/changelog-entry.md +1 -1
- package/templates/docs/construct_guide.md +13 -13
- package/templates/docs/meta-prd.md +16 -16
- package/templates/docs/one-pager.md +1 -1
- package/templates/docs/prd-business.md +1 -1
- package/templates/docs/prd-platform.md +1 -1
- package/templates/docs/prd.md +17 -17
- package/templates/docs/research-brief.md +8 -8
- package/templates/docs/rfc.md +1 -1
- package/templates/docs/strategy.md +1 -1
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/mcp/tools/profile.mjs — MCP wrappers for the org-profile + learning surfaces.
|
|
3
|
+
*
|
|
4
|
+
* Bridges PR #67 capabilities (profiles, outcomes, sandboxes, knowledge_add,
|
|
5
|
+
* learning status) so subagents talking through the construct-mcp server can
|
|
6
|
+
* read the same state the CLI exposes. Operator-only surfaces (optimize_apply,
|
|
7
|
+
* optimize_rollback) remain CLI-only and are not registered here.
|
|
8
|
+
*
|
|
9
|
+
* Pattern: each export is a thin schema-validated wrapper around the existing
|
|
10
|
+
* lib/* function the CLI already uses. Errors return `{ error: string }` so
|
|
11
|
+
* the MCP dispatcher hands a structured failure back instead of crashing.
|
|
12
|
+
* Destructive operations (profile_archive) require `confirm: true`, matching
|
|
13
|
+
* the storage_reset / delete_ingested_artifacts pattern in tools/storage.mjs.
|
|
14
|
+
*/
|
|
15
|
+
import { resolve } from 'node:path';
|
|
16
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
loadProfile,
|
|
21
|
+
listProfiles,
|
|
22
|
+
loadCustomProfile,
|
|
23
|
+
resolveActiveProfile,
|
|
24
|
+
} from '../../profiles/loader.mjs';
|
|
25
|
+
import {
|
|
26
|
+
createDraftProfile,
|
|
27
|
+
listDrafts,
|
|
28
|
+
archiveProfile,
|
|
29
|
+
profileHealth,
|
|
30
|
+
} from '../../profiles/lifecycle.mjs';
|
|
31
|
+
import { recordOutcome } from '../../outcomes/record.mjs';
|
|
32
|
+
import { aggregateOutcomes, readSummary } from '../../outcomes/aggregate.mjs';
|
|
33
|
+
import { addResearchFinding } from '../../knowledge/research-store.mjs';
|
|
34
|
+
import { askGlobal } from '../../knowledge/graph.mjs';
|
|
35
|
+
import { listSandboxes } from '../../sandbox.mjs';
|
|
36
|
+
|
|
37
|
+
function cwdOf(args) {
|
|
38
|
+
return args && args.cwd ? resolve(String(args.cwd)) : process.cwd();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Read-only: active profile.
|
|
42
|
+
|
|
43
|
+
export function profileShow(args = {}) {
|
|
44
|
+
const cwd = cwdOf(args);
|
|
45
|
+
const profile = resolveActiveProfile(cwd, args.id ? String(args.id) : null);
|
|
46
|
+
return {
|
|
47
|
+
id: profile.id,
|
|
48
|
+
displayName: profile.displayName ?? profile.id,
|
|
49
|
+
tagline: profile.tagline ?? null,
|
|
50
|
+
custom: profile.custom === true,
|
|
51
|
+
roles: Array.isArray(profile.roles) ? profile.roles : [],
|
|
52
|
+
departments: Array.isArray(profile.departments)
|
|
53
|
+
? profile.departments.map((d) => ({ id: d.id, displayName: d.displayName, roleCount: Array.isArray(d.roles) ? d.roles.length : 0 }))
|
|
54
|
+
: [],
|
|
55
|
+
intake: {
|
|
56
|
+
types: profile.intake?.types ?? [],
|
|
57
|
+
stages: profile.intake?.stages ?? [],
|
|
58
|
+
},
|
|
59
|
+
docTemplates: profile.docTemplates ?? [],
|
|
60
|
+
hooks: profile.hooks ?? null,
|
|
61
|
+
rebrand: profile.rebrand ?? null,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Read-only: catalog summary.
|
|
66
|
+
|
|
67
|
+
export function profileList() {
|
|
68
|
+
return {
|
|
69
|
+
profiles: listProfiles().map((id) => {
|
|
70
|
+
const p = loadProfile(id);
|
|
71
|
+
return p
|
|
72
|
+
? {
|
|
73
|
+
id: p.id,
|
|
74
|
+
displayName: p.displayName ?? p.id,
|
|
75
|
+
tagline: p.tagline ?? null,
|
|
76
|
+
roleCount: Array.isArray(p.roles) ? p.roles.length : 0,
|
|
77
|
+
departmentCount: Array.isArray(p.departments) ? p.departments.length : 0,
|
|
78
|
+
}
|
|
79
|
+
: { id, error: 'failed to parse' };
|
|
80
|
+
}),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Read-only: drafts + custom profile under .cx/.
|
|
85
|
+
|
|
86
|
+
export function profileDrafts(args = {}) {
|
|
87
|
+
const cwd = cwdOf(args);
|
|
88
|
+
const drafts = listDrafts(cwd).map((d) => ({
|
|
89
|
+
id: d.id,
|
|
90
|
+
dir: d.dir,
|
|
91
|
+
hasProfile: d.hasProfile,
|
|
92
|
+
hasBrief: d.hasBrief,
|
|
93
|
+
}));
|
|
94
|
+
const custom = loadCustomProfile(cwd);
|
|
95
|
+
return {
|
|
96
|
+
drafts,
|
|
97
|
+
custom: custom ? { id: custom.id, displayName: custom.displayName ?? custom.id } : null,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Read-only: per-profile health rollup.
|
|
102
|
+
|
|
103
|
+
export function profileHealthTool(args = {}) {
|
|
104
|
+
const cwd = cwdOf(args);
|
|
105
|
+
const id = args.id ? String(args.id) : resolveActiveProfile(cwd).id;
|
|
106
|
+
const windowDays = Number.isFinite(args.window_days) ? Number(args.window_days) : 30;
|
|
107
|
+
return { id, windowDays, ...profileHealth(cwd, id, { windowDays }) };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Read-only: outcomes rollup. Optional aggregate=true rebuilds _summary.json.
|
|
111
|
+
|
|
112
|
+
export function outcomesSummary(args = {}) {
|
|
113
|
+
const cwd = cwdOf(args);
|
|
114
|
+
if (args.aggregate === true) {
|
|
115
|
+
try { aggregateOutcomes(cwd); } catch (err) { return { error: `aggregate failed: ${err.message}` }; }
|
|
116
|
+
}
|
|
117
|
+
const summary = readSummary(cwd);
|
|
118
|
+
if (!summary) return { roles: {}, note: 'no outcomes recorded yet' };
|
|
119
|
+
return summary;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Mutating, gated: append an outcome line.
|
|
123
|
+
|
|
124
|
+
export function outcomesRecord(args = {}) {
|
|
125
|
+
if (args.confirm !== true) {
|
|
126
|
+
return { error: 'outcomes_record requires confirm=true to write durable state' };
|
|
127
|
+
}
|
|
128
|
+
const cwd = cwdOf(args);
|
|
129
|
+
if (!args.role || typeof args.success !== 'boolean') {
|
|
130
|
+
return { error: 'outcomes_record requires role:string and success:boolean' };
|
|
131
|
+
}
|
|
132
|
+
const profile = args.profile ? String(args.profile) : resolveActiveProfile(cwd)?.id;
|
|
133
|
+
const file = recordOutcome(cwd, {
|
|
134
|
+
role: String(args.role),
|
|
135
|
+
intakeId: args.intake_id ? String(args.intake_id) : null,
|
|
136
|
+
profile,
|
|
137
|
+
success: !!args.success,
|
|
138
|
+
escalated: !!args.escalated,
|
|
139
|
+
durationMs: Number.isFinite(args.duration_ms) ? Number(args.duration_ms) : null,
|
|
140
|
+
notes: args.notes ? String(args.notes) : null,
|
|
141
|
+
source: args.source ? String(args.source) : 'mcp',
|
|
142
|
+
});
|
|
143
|
+
if (!file) return { error: 'outcomes_record: write failed' };
|
|
144
|
+
return { ok: true, file };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Mutating, gated: persist a research finding.
|
|
148
|
+
|
|
149
|
+
export async function knowledgeAdd(args = {}) {
|
|
150
|
+
if (args.confirm !== true) {
|
|
151
|
+
return { error: 'knowledge_add requires confirm=true to write durable state' };
|
|
152
|
+
}
|
|
153
|
+
const cwd = cwdOf(args);
|
|
154
|
+
try {
|
|
155
|
+
const res = await addResearchFinding({
|
|
156
|
+
cwd,
|
|
157
|
+
slug: String(args.slug || ''),
|
|
158
|
+
topic: String(args.topic || ''),
|
|
159
|
+
body: String(args.body || ''),
|
|
160
|
+
confidence: args.confidence ? String(args.confidence) : 'inferred',
|
|
161
|
+
sources: Array.isArray(args.sources) ? args.sources : [],
|
|
162
|
+
ttlDays: Number.isFinite(args.ttl_days) ? Number(args.ttl_days) : undefined,
|
|
163
|
+
});
|
|
164
|
+
return { ok: true, path: res.path, bytes: res.bytes };
|
|
165
|
+
} catch (err) {
|
|
166
|
+
return { error: err.message ?? String(err) };
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Mutating, gated: scaffold a draft profile.
|
|
171
|
+
|
|
172
|
+
export function profileCreate(args = {}) {
|
|
173
|
+
if (args.confirm !== true) {
|
|
174
|
+
return { error: 'profile_create requires confirm=true to scaffold files' };
|
|
175
|
+
}
|
|
176
|
+
const cwd = cwdOf(args);
|
|
177
|
+
if (!args.id) return { error: 'profile_create requires id:string' };
|
|
178
|
+
try {
|
|
179
|
+
const res = createDraftProfile({
|
|
180
|
+
cwd,
|
|
181
|
+
id: String(args.id),
|
|
182
|
+
displayName: args.display_name ? String(args.display_name) : undefined,
|
|
183
|
+
seedRoles: Array.isArray(args.seed_roles) ? args.seed_roles.map(String) : [],
|
|
184
|
+
seedDepartments: Array.isArray(args.seed_departments) ? args.seed_departments : [],
|
|
185
|
+
});
|
|
186
|
+
return {
|
|
187
|
+
ok: true,
|
|
188
|
+
dir: res.dir,
|
|
189
|
+
briefPath: res.briefPath,
|
|
190
|
+
draftPath: res.draftPath,
|
|
191
|
+
personaPaths: res.personaPaths,
|
|
192
|
+
departmentPaths: res.departmentPaths,
|
|
193
|
+
};
|
|
194
|
+
} catch (err) {
|
|
195
|
+
return { error: err.message ?? String(err) };
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Mutating, gated, destructive: archive a curated profile.
|
|
200
|
+
|
|
201
|
+
export function profileArchive(args = {}) {
|
|
202
|
+
if (args.confirm !== true) {
|
|
203
|
+
return { error: 'profile_archive requires confirm=true (destructive: moves files into archive/profiles/)' };
|
|
204
|
+
}
|
|
205
|
+
if (!args.id || !args.reason || String(args.reason).trim().length < 8) {
|
|
206
|
+
return { error: 'profile_archive requires id:string and reason:string (>=8 chars)' };
|
|
207
|
+
}
|
|
208
|
+
try {
|
|
209
|
+
return { ok: true, ...archiveProfile({ id: String(args.id), reason: String(args.reason) }) };
|
|
210
|
+
} catch (err) {
|
|
211
|
+
return { error: err.message ?? String(err) };
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Read-only: sandbox roster.
|
|
216
|
+
|
|
217
|
+
export function sandboxList() {
|
|
218
|
+
return { sandboxes: listSandboxes() };
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Read-only: GraphRAG global query over the entity graph.
|
|
222
|
+
|
|
223
|
+
export function knowledgeGraphAsk(args = {}) {
|
|
224
|
+
const cwd = cwdOf(args);
|
|
225
|
+
if (!args.query || typeof args.query !== 'string') {
|
|
226
|
+
return { error: 'knowledge_graph_ask requires query:string' };
|
|
227
|
+
}
|
|
228
|
+
const topK = Number.isFinite(args.top_k) ? Number(args.top_k) : 5;
|
|
229
|
+
const minSize = Number.isFinite(args.min_size) ? Number(args.min_size) : undefined;
|
|
230
|
+
return askGlobal({ query: String(args.query), rootDir: cwd, topK, ...(minSize !== undefined ? { minSize } : {}) });
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Read-only: learning dashboard mirror.
|
|
234
|
+
|
|
235
|
+
export function learningStatus(args = {}) {
|
|
236
|
+
const cwd = cwdOf(args);
|
|
237
|
+
|
|
238
|
+
let observations = { total: 0, last24h: 0 };
|
|
239
|
+
try {
|
|
240
|
+
const idxPath = join(cwd, '.cx', 'observations', 'index.json');
|
|
241
|
+
if (existsSync(idxPath)) {
|
|
242
|
+
const idx = JSON.parse(readFileSync(idxPath, 'utf8'));
|
|
243
|
+
if (Array.isArray(idx)) {
|
|
244
|
+
const since = Date.now() - 24 * 60 * 60 * 1000;
|
|
245
|
+
observations = {
|
|
246
|
+
total: idx.length,
|
|
247
|
+
last24h: idx.filter((e) => Date.parse(e?.createdAt) >= since).length,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
} catch { /* best effort */ }
|
|
252
|
+
|
|
253
|
+
let researchCount = 0;
|
|
254
|
+
try {
|
|
255
|
+
const dir = join(cwd, '.cx', 'knowledge', 'external', 'research');
|
|
256
|
+
if (existsSync(dir)) {
|
|
257
|
+
researchCount = readdirSync(dir).filter((f) => f.endsWith('.md')).length;
|
|
258
|
+
}
|
|
259
|
+
} catch { /* best effort */ }
|
|
260
|
+
|
|
261
|
+
const profile = resolveActiveProfile(cwd);
|
|
262
|
+
const outcomes = readSummary(cwd) || { roles: {} };
|
|
263
|
+
|
|
264
|
+
return {
|
|
265
|
+
profile: { id: profile.id, displayName: profile.displayName ?? profile.id, custom: profile.custom === true },
|
|
266
|
+
observations,
|
|
267
|
+
research: { count: researchCount },
|
|
268
|
+
outcomes,
|
|
269
|
+
};
|
|
270
|
+
}
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Construct
|
|
1
|
+
# Construct: Claude Code Integration
|
|
2
2
|
|
|
3
3
|
This project uses Construct. Personas and specialists are defined in `agents/registry.json` and synced to Claude Code via `construct sync`.
|
|
4
4
|
|
|
@@ -6,11 +6,11 @@ This project uses Construct. Personas and specialists are defined in `agents/reg
|
|
|
6
6
|
|
|
7
7
|
Construct is the only intended user-facing surface.
|
|
8
8
|
|
|
9
|
-
- **Planning
|
|
10
|
-
- **Implementation
|
|
11
|
-
- **Validation
|
|
12
|
-
- **Research
|
|
13
|
-
- **Operations
|
|
9
|
+
- **Planning**: requirements, strategy, architecture
|
|
10
|
+
- **Implementation**: builds features and fixes bugs
|
|
11
|
+
- **Validation**: quality gates, security, accessibility
|
|
12
|
+
- **Research**: docs, debugging, codebase exploration
|
|
13
|
+
- **Operations**: releases, dev servers, health checks
|
|
14
14
|
|
|
15
15
|
## Usage
|
|
16
16
|
|
package/rules/common/agents.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/agents.md
|
|
2
|
+
rules/common/agents.md: platform-agnostic agent orchestration guidance.
|
|
3
3
|
|
|
4
4
|
Defines when to route to specialist agents, parallel execution rules,
|
|
5
5
|
and multi-perspective analysis patterns. Does not reference specific
|
|
@@ -9,7 +9,7 @@ platform agent types or config paths.
|
|
|
9
9
|
|
|
10
10
|
## Immediate Agent Usage
|
|
11
11
|
|
|
12
|
-
No user prompt needed
|
|
12
|
+
No user prompt needed: match the task to the right specialist:
|
|
13
13
|
1. Complex feature requests - planning specialist
|
|
14
14
|
2. Code just written/modified - code review specialist
|
|
15
15
|
3. Bug fix or new feature - TDD specialist
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/beads-hygiene.md
|
|
2
|
+
rules/common/beads-hygiene.md: Beads issue tracker hygiene contract.
|
|
3
3
|
|
|
4
4
|
Beads is the system of record for durable work in this project. Status drifts
|
|
5
5
|
when issues are not updated alongside the code, so every agent and persona
|
|
@@ -7,16 +7,16 @@ operating in Construct treats hygiene as part of the work, not as cleanup.
|
|
|
7
7
|
Loaded by AGENTS.md, CLAUDE.md, the construct persona, and the engineer /
|
|
8
8
|
operator / planner role overlays.
|
|
9
9
|
-->
|
|
10
|
-
# Beads Hygiene
|
|
10
|
+
# Beads Hygiene: Project Contract
|
|
11
11
|
|
|
12
|
-
Beads (`bd`) is the canonical durable tracker for Construct. Beads only earn their keep when their state matches the world. Stale "open" issues pollute `bd ready`, hide real work, and let agents propose work that already shipped. Every agent
|
|
12
|
+
Beads (`bd`) is the canonical durable tracker for Construct. Beads only earn their keep when their state matches the world. Stale "open" issues pollute `bd ready`, hide real work, and let agents propose work that already shipped. Every agent (human or AI, on any platform) is responsible for keeping the tracker honest.
|
|
13
13
|
|
|
14
14
|
## When to update beads
|
|
15
15
|
|
|
16
16
|
| Event | Required action |
|
|
17
17
|
|---|---|
|
|
18
18
|
| About to start non-trivial work | A Beads issue exists. `bd ready` to find or `bd create` if missing. `bd update <id> --claim` before edits. |
|
|
19
|
-
| Work lands on `main` | `bd close <id> --reason="Landed in PR #N
|
|
19
|
+
| Work lands on `main` | `bd close <id> --reason="Landed in PR #N. Verified: <file:line evidence>"`. Do not wait for someone else to notice. |
|
|
20
20
|
| Direction reverses mid-work | `bd supersede <old-id> --with=<new-id>`. Do not edit the old description in place. |
|
|
21
21
|
| Issue scope expands | Update the description and acceptance criteria in the same change that broadens scope. |
|
|
22
22
|
| A blocker is discovered | Add the dependency with `bd dep add <id> <depends-on>` so the readiness queue reflects reality. |
|
|
@@ -27,10 +27,10 @@ Beads (`bd`) is the canonical durable tracker for Construct. Beads only earn the
|
|
|
27
27
|
|
|
28
28
|
Run before planning, before claiming work, before proposing changes:
|
|
29
29
|
|
|
30
|
-
1. `bd ready
|
|
31
|
-
2. `bd list --status=in_progress
|
|
32
|
-
3. `bd stale
|
|
33
|
-
4. Cross-check the open list against `git log --oneline -20 origin/main
|
|
30
|
+
1. `bd ready`: surface unblocked work.
|
|
31
|
+
2. `bd list --status=in_progress`: verify nothing has been left mid-flight by an earlier session.
|
|
32
|
+
3. `bd stale`: surface anything untouched past the staleness window.
|
|
33
|
+
4. Cross-check the open list against `git log --oneline -20 origin/main`: close anything whose work actually landed.
|
|
34
34
|
|
|
35
35
|
If any of these surface drift, fix it before starting new work. Drift you observe and ignore becomes drift the next agent inherits.
|
|
36
36
|
|
|
@@ -40,14 +40,14 @@ After the code changes land in main:
|
|
|
40
40
|
|
|
41
41
|
1. The bead the work was claimed against is closed with evidence in the reason.
|
|
42
42
|
2. Any beads superseded by the change are marked superseded, not left open.
|
|
43
|
-
3. New beads exist for follow-up work that was discovered but not done
|
|
43
|
+
3. New beads exist for follow-up work that was discovered but not done: file them in the same session, not "later".
|
|
44
44
|
4. `bd doctor` and `bd preflight` should run before push and report clean.
|
|
45
45
|
|
|
46
46
|
## What goes in a bead
|
|
47
47
|
|
|
48
48
|
| Field | Standard |
|
|
49
49
|
|---|---|
|
|
50
|
-
| Title | Imperative, scoped, parseable. "PR 3
|
|
50
|
+
| Title | Imperative, scoped, parseable. "PR 3: `construct intake` CLI" beats "intake CLI". |
|
|
51
51
|
| Description | Why the bead exists + what success looks like. State the new shape directly. Do not preserve a "current behavior must keep working" goal unless the user explicitly asked for migration. |
|
|
52
52
|
| Acceptance criteria | Numbered, binary checks. A reviewer can answer pass/fail without re-reading the description. |
|
|
53
53
|
| Dependencies | Wire `bd dep add` whenever order matters. Implicit ordering rots into parallel work that breaks each other. |
|
|
@@ -72,4 +72,4 @@ There is no authorized bypass. Beads hygiene is a release gate. If the tooling i
|
|
|
72
72
|
|
|
73
73
|
## Automation
|
|
74
74
|
|
|
75
|
-
Project-level automation is tracked in the beads queue
|
|
75
|
+
Project-level automation is tracked in the beads queue: auto-close on merge, pre-push `bd preflight` gate, weekly drift report, memory-contradiction detection. Until that ships, hygiene is a per-session discipline.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/code-review.md
|
|
2
|
+
rules/common/code-review.md: when and how to conduct code reviews.
|
|
3
3
|
|
|
4
4
|
Defines mandatory review triggers, severity levels, approval criteria,
|
|
5
5
|
and references coding-style.md and security.md for checklists.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/coding-style.md
|
|
2
|
+
rules/common/coding-style.md: language-agnostic coding standards.
|
|
3
3
|
|
|
4
4
|
Covers immutability, core principles (KISS/DRY/YAGNI), file organization,
|
|
5
5
|
error handling, input validation, naming conventions, and quality checklist.
|
package/rules/common/comments.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/comments.md
|
|
2
|
+
rules/common/comments.md: Construct comment convention for JS/TS/MJS source files.
|
|
3
3
|
|
|
4
4
|
Defines the two allowed comment forms (file header, section context block) and
|
|
5
5
|
what is never allowed (inline narration, trailing comments, mid-function notes).
|
|
@@ -37,12 +37,12 @@ The blank line between the comment and the code is required. It signals "this co
|
|
|
37
37
|
|
|
38
38
|
## What is never allowed
|
|
39
39
|
|
|
40
|
-
- **Inline trailing comments**
|
|
41
|
-
- **Mid-function narration**
|
|
42
|
-
- **Between-group labels**
|
|
43
|
-
- **Narrative voice**
|
|
44
|
-
- **Point-in-time notes**
|
|
45
|
-
- **Noise sentinels**
|
|
40
|
+
- **Inline trailing comments** (`const x = 1; // increment`) delete them
|
|
41
|
+
- **Mid-function narration** (a comment in the middle of a function body that describes what the next line does) delete it; rename the variable or extract a function instead
|
|
42
|
+
- **Between-group labels** (`// Language patterns`, `// Dashboard`, `// Step 1:`) delete them
|
|
43
|
+
- **Narrative voice** (`// We weight BM25`, `// Now test the keys`, `// This correctly scores`) delete them
|
|
44
|
+
- **Point-in-time notes** (`// X removed`, `// previously`, `// no longer`) belongs in git log
|
|
45
|
+
- **Noise sentinels** (`// ok`, `// best effort`, `// skip`) delete them; use `/* non-critical */` inline only when the catch clause would otherwise look like a bug
|
|
46
46
|
|
|
47
47
|
## SLA annotations (hooks only)
|
|
48
48
|
|
|
@@ -54,5 +54,5 @@ The blank line between the comment and the code is required. It signals "this co
|
|
|
54
54
|
|
|
55
55
|
## Rule of thumb
|
|
56
56
|
|
|
57
|
-
Delete the comment. If the section becomes harder to understand, the comment earns its place
|
|
57
|
+
Delete the comment. If the section becomes harder to understand, the comment earns its place: as a block before it, with a blank line after. If it reads just as clearly without, it stays deleted.
|
|
58
58
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/commit-approval.md
|
|
2
|
+
rules/common/commit-approval.md: conversational approval rule for mutating git operations.
|
|
3
3
|
|
|
4
4
|
Behavioral rule, not a hook. The agent asks and waits for a yes; the user
|
|
5
5
|
replies in chat. Infrastructure stays out of the way.
|
|
@@ -19,7 +19,7 @@ Before running any of these Bash tool calls:
|
|
|
19
19
|
The agent must:
|
|
20
20
|
|
|
21
21
|
1. **State the working branch** so the user sees the scope.
|
|
22
|
-
2. **Show the proposed action verbatim
|
|
22
|
+
2. **Show the proposed action verbatim**: for a commit, the full proposed message (subject and body) formatted exactly as it will appear in `git log`. For a push, the target refspec. For a merge, the PR number and merge mode (`--squash`, `--rebase`, etc.).
|
|
23
23
|
3. **Ask for confirmation** and wait for a yes before executing.
|
|
24
24
|
|
|
25
25
|
A yes from the user in chat is the approval. No marker file, no CLI command, no special syntax.
|
|
@@ -41,13 +41,13 @@ Then stop and wait.
|
|
|
41
41
|
|
|
42
42
|
## Exceptions
|
|
43
43
|
|
|
44
|
-
- **The user explicitly tells the agent to run a defined sequence** ("commit, push, and merge when ready"). That single yes covers the named batch
|
|
44
|
+
- **The user explicitly tells the agent to run a defined sequence** ("commit, push, and merge when ready"). That single yes covers the named batch: but only the actions named, in the order named. A new commit triggered later (e.g. by a CI fix or follow-up edit) is its own approval gate.
|
|
45
45
|
- **Read-only git operations** (`git status`, `git log`, `git diff`, `git fetch`, `git branch`, `git show`) don't need approval.
|
|
46
46
|
|
|
47
47
|
A "yes" from earlier in the session does NOT carry forward to subsequent commits. Each new commit message must be shown and approved.
|
|
48
48
|
|
|
49
49
|
## Why this is a rule, not a hook
|
|
50
50
|
|
|
51
|
-
A hook that blocked every commit turned out to be over-restrictive
|
|
51
|
+
A hook that blocked every commit turned out to be over-restrictive: it required a separate command invocation to write a marker file each time, which added friction without much safety beyond the agent just following the rule. The agent is the one producing commit messages; asking in chat is the right interface.
|
|
52
52
|
|
|
53
53
|
If the agent ever commits without asking, that's a correctness bug. Surface it in the session and raise a follow-up to catch the regression.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/cx-agent-routing.md
|
|
2
|
+
rules/common/cx-agent-routing.md: auto-trigger routing rules for cx-* specialist agents.
|
|
3
3
|
|
|
4
4
|
Defines when to route directly to a cx-* specialist vs through Construct orchestration.
|
|
5
5
|
Covers intent-based routing table, complexity gate, and routing rules.
|
|
6
6
|
Loaded by rule-loading systems that look for cx-agent-routing in the rules hierarchy.
|
|
7
7
|
-->
|
|
8
|
-
# cx-* Agent Routing
|
|
8
|
+
# cx-* Agent Routing: Auto-trigger Rules
|
|
9
9
|
|
|
10
10
|
When a request matches the trigger patterns below, automatically route to the corresponding cx-* specialist or persona before responding.
|
|
11
11
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/cx-skill-routing.md
|
|
2
|
+
rules/common/cx-skill-routing.md: Redirect to canonical skill routing table.
|
|
3
3
|
-->
|
|
4
4
|
# cx-* Skill Routing
|
|
5
5
|
|
|
@@ -7,5 +7,5 @@ rules/common/cx-skill-routing.md — Redirect to canonical skill routing table.
|
|
|
7
7
|
>
|
|
8
8
|
> All skill routing keywords, domain tables, and routing rules live there.
|
|
9
9
|
> This file exists only as a named entry point for rule-loading systems that
|
|
10
|
-
> look for `cx-skill-routing.md`. Do not add routing entries here
|
|
10
|
+
> look for `cx-skill-routing.md`. Do not add routing entries here: update
|
|
11
11
|
> `skills/routing.md` instead.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/development-workflow.md
|
|
2
|
+
rules/common/development-workflow.md: feature implementation pipeline.
|
|
3
3
|
|
|
4
4
|
Defines the research-plan-TDD-review-commit workflow that runs before
|
|
5
5
|
git operations. References testing.md, code-review.md, git-workflow.md.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/doc-ownership.md
|
|
2
|
+
rules/common/doc-ownership.md: which specialist owns which document type.
|
|
3
3
|
|
|
4
4
|
Prevents the orchestrator (or any general persona) from authoring specialist
|
|
5
5
|
documents directly. Routing authorship to the owning role is how research,
|
|
6
|
-
framing, and domain scrutiny actually fire
|
|
6
|
+
framing, and domain scrutiny actually fire: writing a PRD without the
|
|
7
7
|
product manager bypasses those checks entirely.
|
|
8
8
|
-->
|
|
9
9
|
# Document Ownership
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/efficiency.md
|
|
2
|
+
rules/common/efficiency.md: session context and tool-use efficiency standards.
|
|
3
3
|
|
|
4
4
|
Applies to all agents operating in a Construct session. Violations compound context
|
|
5
5
|
cost and reduce throughput. These rules are enforced by read-tracker.mjs and surfaced
|
|
@@ -19,7 +19,7 @@ Signals that a re-read is warranted:
|
|
|
19
19
|
- An external process (Bash, a subagent) may have modified it.
|
|
20
20
|
- The last read was in a prior session (context was compacted).
|
|
21
21
|
|
|
22
|
-
Do not re-read to verify
|
|
22
|
+
Do not re-read to verify: trust the in-context state. If staleness is a concern,
|
|
23
23
|
check the file hash via `read-tracker.mjs` state rather than re-reading the full file.
|
|
24
24
|
|
|
25
25
|
**Threshold:** more than 3 reads of the same file within a session without an intervening
|
|
@@ -54,4 +54,4 @@ re-running the command.
|
|
|
54
54
|
Each Task dispatch creates a subagent context. Dispatch a specialist when the task
|
|
55
55
|
benefits from a structurally different view (architecture suspicion, security scan,
|
|
56
56
|
coverage gap analysis). Do not dispatch for tasks that fit within a single focused
|
|
57
|
-
pass
|
|
57
|
+
pass: the round-trip cost exceeds the benefit.
|
package/rules/common/framing.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/framing.md
|
|
2
|
+
rules/common/framing.md: how to frame a problem before acting on it.
|
|
3
3
|
|
|
4
4
|
Establishes the hard separation between execution artifacts (tickets, chat
|
|
5
5
|
transcripts, existing docs) and sources of truth (the underlying problem).
|
package/rules/common/patterns.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/performance.md
|
|
2
|
+
rules/common/performance.md: model-agnostic performance and context management rules.
|
|
3
3
|
|
|
4
4
|
Defines model selection tiers, context window management heuristics,
|
|
5
5
|
and build troubleshooting steps. No platform-specific tool names or config paths.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/release-gates.md
|
|
2
|
+
rules/common/release-gates.md: Hard release gates for Construct work.
|
|
3
3
|
|
|
4
4
|
Defines the blocking contracts every agent and persona must satisfy locally
|
|
5
5
|
before any commit, push, or "done" claim. Loaded by the construct persona,
|
|
6
6
|
AGENTS.md, and the engineer/reviewer/operator role overlays. Enforcement is at
|
|
7
|
-
the prompt level
|
|
7
|
+
the prompt level: CI is a backstop, not the primary gate.
|
|
8
8
|
-->
|
|
9
|
-
# Release Gates
|
|
9
|
+
# Release Gates: Hard Contracts
|
|
10
10
|
|
|
11
11
|
These are blocking gates. Every agent, persona, and harness session working in or shipping Construct must satisfy them locally **before** any commit, push, or "done" claim. CI is a backstop, not the primary check.
|
|
12
12
|
|
|
@@ -20,7 +20,7 @@ Run these before declaring work done. Pasting the output into the PR body or `bd
|
|
|
20
20
|
|---|---|---|
|
|
21
21
|
| Tests | `npm test` | 0 failed, 0 unexpected skips |
|
|
22
22
|
| Comment policy | `node bin/construct lint:comments` | 0 errors AND 0 warnings |
|
|
23
|
-
| Doc verification | `node bin/construct docs:verify` | "All documentation checks passed"
|
|
23
|
+
| Doc verification | `node bin/construct docs:verify` | "All documentation checks passed": no warnings either |
|
|
24
24
|
| AUTO doc drift | `node bin/construct docs:update --check` | "Docs are up to date" |
|
|
25
25
|
| Template policy | `npm run lint:templates` | "Template policy: clean." |
|
|
26
26
|
|
|
@@ -34,9 +34,9 @@ npm run release:check
|
|
|
34
34
|
|
|
35
35
|
The repo enforces `.gitmessage` and `.github/pull_request_template.md`. Both are validated by `scripts/lint-commits-pr.mjs` (the `lint-templates` CI job) and fail the build on any deviation.
|
|
36
36
|
|
|
37
|
-
Commit subjects must match `type(scope): subject
|
|
37
|
+
Commit subjects must match `type(scope): subject`: type from {feat, fix, refactor, perf, docs, test, chore, ci, build, style}, imperative mood, ≤72 chars, no trailing period, lowercase after the colon. Run `git config commit.template .gitmessage` once per clone to load the template into your editor.
|
|
38
38
|
|
|
39
|
-
PR descriptions must keep all six headings
|
|
39
|
+
PR descriptions must keep all six headings (Summary, Beads issue, Doc updates included, Local gates, Test plan, Risks / rollback) with at least one checked box in both the "Doc updates" and "Local gates" sections. Empty templates fail.
|
|
40
40
|
|
|
41
41
|
Forbidden in commit messages: `Co-Authored-By: Claude*` trailers (unless the user explicitly asks), `--no-verify`, `--no-gpg-sign`. Forbidden in PR bodies: deleting the required headings, leaving every gate box unchecked.
|
|
42
42
|
|
|
@@ -47,7 +47,7 @@ For every non-trivial change:
|
|
|
47
47
|
1. **A Beads issue exists.** `bd ready` to find or create one. `bd show <id>` to read context. `bd update <id> --claim` to claim before editing files.
|
|
48
48
|
2. **`plan.md` reflects the work.** Even though `plan.md` is local-only and gitignored, it stays the human-readable working plan. Mark items `done` when they ship; add new rows for work that wasn't previously tracked.
|
|
49
49
|
3. **Doc updates land in the same change as code.** If runtime shape, contracts, boundaries, or major dependencies changed, update `docs/concepts/architecture.md` in the same commit. If the docs surface or maintenance contract changed, update `docs/README.md`. If active work, decisions, or assumptions changed, update `.cx/context.md` and `.cx/context.json`. Always add a `CHANGELOG.md` entry.
|
|
50
|
-
4. **Beads close on green.** `bd close <id>` happens after CI is green and the work is verified
|
|
50
|
+
4. **Beads close on green.** `bd close <id>` happens after CI is green and the work is verified: not before.
|
|
51
51
|
|
|
52
52
|
## Hard rules
|
|
53
53
|
|
package/rules/common/research.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
rules/common/research.md
|
|
2
|
+
rules/common/research.md: canonical research and evidence policy for Construct.
|
|
3
3
|
|
|
4
4
|
Defines how research starts, which sources to prefer, how claims are verified,
|
|
5
5
|
and what must be recorded so findings are reproducible. Applies to research,
|
|
@@ -14,9 +14,9 @@ Construct treats research as a reproducible evidence-gathering process, not free
|
|
|
14
14
|
|
|
15
15
|
Research always starts from the most recent available evidence.
|
|
16
16
|
|
|
17
|
-
- Default to sources from the current year before earlier years
|
|
17
|
+
- Default to sources from the current year before earlier years: always search most-recent-first.
|
|
18
18
|
- For fast-moving topics (AI tools, LLM behavior, cloud APIs, security advisories, market data), treat anything older than 12 months as presumptively stale unless a newer source confirms it is still accurate.
|
|
19
|
-
- When using a search engine or index, always filter or sort by date
|
|
19
|
+
- When using a search engine or index, always filter or sort by date: do not rely on relevance ranking alone.
|
|
20
20
|
- State the publication or access date for every external source. If a source has no date, treat its confidence as `low` until recency is established another way.
|
|
21
21
|
|
|
22
22
|
## 2. Domain-specific starting points
|
|
@@ -67,7 +67,7 @@ Record:
|
|
|
67
67
|
Every URL cited in a committed document must be verified before the document is published.
|
|
68
68
|
|
|
69
69
|
- Fetch the URL. Confirm it resolves and the content matches the cited claim.
|
|
70
|
-
- Do not cite aggregate or index pages (e.g., arxiv.org search results, Google Scholar listings) for quantitative claims
|
|
70
|
+
- Do not cite aggregate or index pages (e.g., arxiv.org search results, Google Scholar listings) for quantitative claims: cite the specific paper or article URL.
|
|
71
71
|
- If a URL returns a 404, paywall, or redirect loop, find the canonical source or replace the citation.
|
|
72
72
|
- Unverified URLs must be marked `[unverified]` until confirmed.
|
|
73
73
|
|