intentdna 1.7.4 → 1.8.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/LICENSE +201 -0
- package/README.md +143 -194
- package/dist/assets/candidates.d.ts +124 -0
- package/dist/assets/candidates.js +1249 -0
- package/dist/assets/catalog.d.ts +101 -0
- package/dist/assets/catalog.js +311 -0
- package/dist/assets/evidence.d.ts +93 -0
- package/dist/assets/evidence.js +391 -0
- package/dist/assets/index.d.ts +4 -0
- package/dist/assets/index.js +4 -0
- package/dist/assets/metadata.d.ts +19 -0
- package/dist/assets/metadata.js +227 -0
- package/dist/cli/commands/assets.d.ts +65 -0
- package/dist/cli/commands/assets.js +2871 -0
- package/dist/cli/commands/auth.d.ts +322 -0
- package/dist/cli/commands/auth.js +1592 -0
- package/dist/cli/commands/cloud-auth-guidance.d.ts +2 -0
- package/dist/cli/commands/cloud-auth-guidance.js +4 -0
- package/dist/cli/commands/cloud.d.ts +1359 -0
- package/dist/cli/commands/cloud.js +8364 -0
- package/dist/cli/commands/evolve.js +18 -2
- package/dist/cli/commands/generate.js +25 -2
- package/dist/cli/commands/guard.d.ts +1 -1
- package/dist/cli/commands/guard.js +1 -1
- package/dist/cli/commands/guide.d.ts +15 -0
- package/dist/cli/commands/guide.js +1747 -0
- package/dist/cli/commands/init.d.ts +12 -0
- package/dist/cli/commands/init.js +95 -60
- package/dist/cli/commands/org.d.ts +16 -0
- package/dist/cli/commands/org.js +2393 -0
- package/dist/cli/commands/release.d.ts +59 -0
- package/dist/cli/commands/release.js +716 -0
- package/dist/cli/commands/report.d.ts +82 -0
- package/dist/cli/commands/report.js +1516 -0
- package/dist/cli/commands/run.d.ts +6 -1
- package/dist/cli/commands/run.js +95 -26
- package/dist/cli/commands/sync.d.ts +8 -1
- package/dist/cli/commands/sync.js +436 -141
- package/dist/cli/commands/templates.d.ts +64 -0
- package/dist/cli/commands/templates.js +2151 -1
- package/dist/cli/commands/workflow.d.ts +26 -0
- package/dist/cli/commands/workflow.js +3053 -0
- package/dist/cli/index.js +719 -42
- package/dist/compiler/cascade.js +4 -9
- package/dist/compiler/compile.js +1 -0
- package/dist/governance/evidence-capture-attribution.d.ts +12 -0
- package/dist/governance/evidence-capture-attribution.js +46 -0
- package/dist/governance/index.d.ts +2 -0
- package/dist/governance/index.js +1 -0
- package/dist/hooks/cli.d.ts +6 -0
- package/dist/hooks/cli.js +168 -12
- package/dist/hooks/enforce.d.ts +1 -0
- package/dist/hooks/protocol.d.ts +1 -1
- package/dist/hooks/protocol.js +1 -1
- package/dist/hooks/state.d.ts +41 -0
- package/dist/hooks/state.js +126 -2
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/mcp/tools-state.js +2 -0
- package/dist/organization/index.d.ts +121 -0
- package/dist/organization/index.js +413 -0
- package/dist/runtime/claude-sync-target.d.ts +49 -0
- package/dist/runtime/claude-sync-target.js +280 -0
- package/dist/runtime/codex-adapter.d.ts +254 -0
- package/dist/runtime/codex-adapter.js +1204 -0
- package/dist/runtime/codex-sync-target.d.ts +33 -0
- package/dist/runtime/codex-sync-target.js +241 -0
- package/dist/runtime/index.d.ts +8 -0
- package/dist/runtime/index.js +4 -0
- package/dist/runtime/output-artifact-registry.d.ts +1 -1
- package/dist/runtime/output-artifact-registry.js +2 -0
- package/dist/runtime/settings-adapter.d.ts +1 -1
- package/dist/runtime/settings-adapter.js +1 -1
- package/dist/runtime/skill-adapter.d.ts +5 -1
- package/dist/runtime/skill-adapter.js +120 -34
- package/dist/runtime/sync-artifact-registry.d.ts +99 -0
- package/dist/runtime/sync-artifact-registry.js +194 -0
- package/dist/runtime/sync-target-plan.d.ts +45 -0
- package/dist/runtime/sync-target-plan.js +19 -0
- package/dist/schema/controller-registry.d.ts +8 -1
- package/dist/schema/controller-registry.js +8 -0
- package/dist/schema/types.d.ts +35 -23
- package/dist/schema/types.js +10 -1
- package/dist/schema/validate.js +22 -22
- package/dist/schema/validators/controllers.js +38 -20
- package/dist/schema/workflow-authoring-contract.d.ts +29 -0
- package/dist/schema/workflow-authoring-contract.js +109 -0
- package/dist/schema/yaml-parser.js +18 -0
- package/dist/templates/api-backend.dna.yaml +19 -0
- package/dist/templates/brainstorming-first.dna.yaml +19 -0
- package/dist/templates/code-cleanup.dna.yaml +19 -0
- package/dist/templates/code-review-pipeline.dna.yaml +18 -0
- package/dist/templates/documentation-writer.dna.yaml +19 -0
- package/dist/templates/flutter-behavior-lock.dna.yaml +19 -0
- package/dist/templates/flutter-refactoring-rescue.dna.yaml +19 -0
- package/dist/templates/flutter-rewrite-diagnosis-review.dna.yaml +210 -0
- package/dist/templates/flutter-rewrite-fix-review-loop.dna.yaml +260 -0
- package/dist/templates/flutter-rewrite-new.dna.yaml +506 -0
- package/dist/templates/flutter-rewrite.dna.yaml +20 -0
- package/dist/templates/frontend-quality.dna.yaml +19 -0
- package/dist/templates/full-pipeline.dna.yaml +20 -0
- package/dist/templates/marketplace.d.ts +92 -0
- package/dist/templates/marketplace.js +502 -0
- package/dist/templates/metadata.d.ts +25 -0
- package/dist/templates/metadata.js +136 -3
- package/dist/templates/mobile-dev.dna.yaml +19 -0
- package/dist/templates/multi-agent-handoff-coordination.dna.yaml +156 -0
- package/dist/templates/multi-perspective-review.dna.yaml +19 -0
- package/dist/templates/persistent-executor.dna.yaml +19 -0
- package/dist/templates/qa-loop.dna.yaml +18 -0
- package/dist/templates/release-evidence-gate.dna.yaml +131 -0
- package/dist/templates/requirements-gate.dna.yaml +19 -0
- package/dist/templates/research-orchestration.dna.yaml +19 -0
- package/dist/templates/root-cause-analysis.dna.yaml +19 -0
- package/dist/templates/safe-refactoring.dna.yaml +321 -0
- package/dist/templates/secure-dev.dna.yaml +19 -0
- package/dist/templates/subagent-parallel.dna.yaml +19 -0
- package/dist/templates/systematic-debugging.dna.yaml +19 -0
- package/dist/templates/tdd-strict.dna.yaml +19 -0
- package/dist/templates/ui-visual-regression-qa.dna.yaml +133 -0
- package/dist/templates/workflow-author.dna.yaml +302 -0
- package/dist/templates/workflow-blocked-scope-triage.dna.yaml +242 -0
- package/dist/templates/workflow-completion-audit.dna.yaml +254 -0
- package/dist/templates/workflow-cross-boundary-resource-approval.dna.yaml +249 -0
- package/dist/templates/workflow-evidence-review.dna.yaml +198 -0
- package/dist/templates/workflow-module-inventory.dna.yaml +257 -0
- package/dist/templates/workflow-runtime-smoke-review.dna.yaml +252 -0
- package/dist/templates/workflow-verification-command-routing.dna.yaml +278 -0
- package/dist/workflow/authoring-packet.d.ts +67 -0
- package/dist/workflow/authoring-packet.js +218 -0
- package/dist/workflow/draft.d.ts +159 -0
- package/dist/workflow/draft.js +800 -0
- package/dist/workflow/index.d.ts +3 -0
- package/dist/workflow/index.js +3 -0
- package/dist/workflow/suggestion-review.d.ts +65 -0
- package/dist/workflow/suggestion-review.js +245 -0
- package/package.json +1 -1
- package/spec/README.md +15 -48
- package/spec/codex-adapter-contract.md +176 -0
- package/spec/sync-target-plan.md +158 -0
- package/spec/workflow-capability-ir.md +153 -0
- package/spec/agent-dispatch-fix.md +0 -116
- package/spec/control-plane-convergence-handoff-2026-04-24.md +0 -432
- package/spec/flutter-rewrite-template-optimization.md +0 -301
- package/spec/foundation-hardening.md +0 -178
- package/spec/hooks-infra-harness-hardening.md +0 -741
- package/spec/multi-config.md +0 -172
- package/spec/parallel-isolation.md +0 -268
- package/spec/template-version-namespace-fix.md +0 -653
- package/spec/workflow-pipeline.md +0 -101
package/dist/compiler/cascade.js
CHANGED
|
@@ -109,15 +109,10 @@ function prefixRecordKeys(record, ns) {
|
|
|
109
109
|
function prefixController(controller, ns) {
|
|
110
110
|
return {
|
|
111
111
|
...controller,
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
analysis_reviewer: `${ns}_${controller.roles.analysis_reviewer}`,
|
|
117
|
-
surgeon: `${ns}_${controller.roles.surgeon}`,
|
|
118
|
-
fix_reviewer: `${ns}_${controller.roles.fix_reviewer}`,
|
|
119
|
-
test_runner: `${ns}_${controller.roles.test_runner}`,
|
|
120
|
-
},
|
|
112
|
+
workflow: controller.workflow ? `${ns}_${controller.workflow}` : undefined,
|
|
113
|
+
diagnosis_workflow: controller.diagnosis_workflow ? `${ns}_${controller.diagnosis_workflow}` : undefined,
|
|
114
|
+
fix_workflow: controller.fix_workflow ? `${ns}_${controller.fix_workflow}` : undefined,
|
|
115
|
+
roles: Object.fromEntries(Object.entries(controller.roles).map(([roleKey, roleName]) => [roleKey, `${ns}_${roleName}`])),
|
|
121
116
|
};
|
|
122
117
|
}
|
|
123
118
|
function prefixLegibilityAssets(map, ns) {
|
package/dist/compiler/compile.js
CHANGED
|
@@ -384,6 +384,7 @@ export function compileDNA(activated, cascaded) {
|
|
|
384
384
|
workflowsIR.push({
|
|
385
385
|
workflow_name: wfKey,
|
|
386
386
|
namespace,
|
|
387
|
+
step_ids: (wf.steps ?? []).map((step) => step.id),
|
|
387
388
|
step_checkpoints: wfStepCheckpoints,
|
|
388
389
|
active_roles: activeRoles,
|
|
389
390
|
handoff_chain: handoffChain,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ConstraintIR } from "../schema/types.js";
|
|
2
|
+
export interface EvidenceCaptureAttributionHint {
|
|
3
|
+
workflowAsset?: string;
|
|
4
|
+
workflowId?: string;
|
|
5
|
+
stepId?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface TrustedEvidenceCaptureAttribution {
|
|
8
|
+
workflowAsset: string;
|
|
9
|
+
workflowId: string;
|
|
10
|
+
stepId: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function trustedEvidenceCaptureAttribution(ir: ConstraintIR, hint: EvidenceCaptureAttributionHint): TrustedEvidenceCaptureAttribution;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const UNKNOWN_ATTRIBUTION = "unknown";
|
|
2
|
+
function canonicalWorkflowAsset(ir) {
|
|
3
|
+
const sourceIds = [...new Set(ir.source_dna_ids)]
|
|
4
|
+
.filter((sourceId) => sourceId.length > 0)
|
|
5
|
+
.filter((sourceId) => !sourceId.startsWith("species:"))
|
|
6
|
+
.filter((sourceId) => !sourceId.startsWith("enterprise:"));
|
|
7
|
+
return sourceIds.length === 1 ? sourceIds[0] : undefined;
|
|
8
|
+
}
|
|
9
|
+
function attributedWorkflow(ir, workflowId) {
|
|
10
|
+
if (workflowId) {
|
|
11
|
+
return ir.workflows_ir?.find((workflow) => workflow.workflow_name === workflowId);
|
|
12
|
+
}
|
|
13
|
+
return ir.workflows_ir?.length === 1 ? ir.workflows_ir[0] : undefined;
|
|
14
|
+
}
|
|
15
|
+
function workflowStepIds(ir, workflow) {
|
|
16
|
+
return new Set([
|
|
17
|
+
...(workflow.step_ids ?? []),
|
|
18
|
+
...workflow.step_checkpoints.map((checkpoint) => checkpoint.step_id),
|
|
19
|
+
...workflow.handoff_chain.map((handoff) => handoff.step_id),
|
|
20
|
+
...(workflow.step_enforce_rules ?? []).map((rule) => rule.step_id),
|
|
21
|
+
...(ir.verifier_specs ?? [])
|
|
22
|
+
.filter((spec) => spec.workflow_name === workflow.workflow_name)
|
|
23
|
+
.map((spec) => spec.step_id)
|
|
24
|
+
.filter((stepId) => typeof stepId === "string"),
|
|
25
|
+
]);
|
|
26
|
+
}
|
|
27
|
+
export function trustedEvidenceCaptureAttribution(ir, hint) {
|
|
28
|
+
const workflow = attributedWorkflow(ir, hint.workflowId);
|
|
29
|
+
const invalidExplicitWorkflow = Boolean(hint.workflowId && !workflow);
|
|
30
|
+
if (invalidExplicitWorkflow) {
|
|
31
|
+
return {
|
|
32
|
+
workflowAsset: UNKNOWN_ATTRIBUTION,
|
|
33
|
+
workflowId: UNKNOWN_ATTRIBUTION,
|
|
34
|
+
stepId: UNKNOWN_ATTRIBUTION,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const canonicalAsset = canonicalWorkflowAsset(ir);
|
|
38
|
+
const workflowAsset = canonicalAsset
|
|
39
|
+
? hint.workflowAsset === canonicalAsset ? hint.workflowAsset : canonicalAsset
|
|
40
|
+
: UNKNOWN_ATTRIBUTION;
|
|
41
|
+
const workflowId = workflow?.workflow_name ?? UNKNOWN_ATTRIBUTION;
|
|
42
|
+
const stepId = workflow && hint.stepId && workflowStepIds(ir, workflow).has(hint.stepId)
|
|
43
|
+
? hint.stepId
|
|
44
|
+
: UNKNOWN_ATTRIBUTION;
|
|
45
|
+
return { workflowAsset, workflowId, stepId };
|
|
46
|
+
}
|
|
@@ -5,4 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export type { AuditReport, RemoteDNAPolicy, PolicyContent, PolicyScope, PolicyUpdate, GovernanceConfig, GovernanceClient, GovernanceResponse, GovernanceSubscription, } from "./types.js";
|
|
7
7
|
export { CASCADE_LAYER_NAMES, RUNTIME_DECISION_EVENT_SCHEMA_VERSION, validateRuntimeDecisionEvent, } from "./runtime-decision-event.js";
|
|
8
|
+
export { trustedEvidenceCaptureAttribution } from "./evidence-capture-attribution.js";
|
|
9
|
+
export type { EvidenceCaptureAttributionHint, TrustedEvidenceCaptureAttribution, } from "./evidence-capture-attribution.js";
|
|
8
10
|
export type { CascadeDecisionTrace, CascadeLayerFingerprint, CascadeLayerName, CascadeLayers, EnforcementPoint, ExplicitPlaceholder, HarnessRuntimeContext, PolicyBundle, RuntimeDecision, RuntimeDecisionEvent, RuntimeDecisionEventValidationResult, RuntimeEvidenceRef, WinningConstraint, } from "./runtime-decision-event.js";
|
package/dist/governance/index.js
CHANGED
|
@@ -4,3 +4,4 @@
|
|
|
4
4
|
* Exports the v1.7.1 enterprise evidence contract plus reserved remote governance interfaces.
|
|
5
5
|
*/
|
|
6
6
|
export { CASCADE_LAYER_NAMES, RUNTIME_DECISION_EVENT_SCHEMA_VERSION, validateRuntimeDecisionEvent, } from "./runtime-decision-event.js";
|
|
7
|
+
export { trustedEvidenceCaptureAttribution } from "./evidence-capture-attribution.js";
|
package/dist/hooks/cli.d.ts
CHANGED
|
@@ -47,7 +47,11 @@ export interface RunHookEventOptions {
|
|
|
47
47
|
sessionId?: string;
|
|
48
48
|
roles?: Record<string, RoleDef>;
|
|
49
49
|
}
|
|
50
|
+
export declare function normalizeHookOutputForEvent(output: HookOutput, event: HookEvent): HookOutput;
|
|
50
51
|
export declare function runHookEvent(options: RunHookEventOptions): Promise<HookOutput>;
|
|
52
|
+
export declare function codexHookEventForInput(rawInput: Record<string, unknown>, args: string[]): unknown;
|
|
53
|
+
declare function inferWorkflowAssetFromIr(ir: ConstraintIR, workflowId?: string): string | undefined;
|
|
54
|
+
declare function runCodexHookWithLoadedIr(rawInput: Record<string, unknown>, projectDir: string, args: string[], ir: ConstraintIR): Promise<import("../runtime/codex-adapter.js").CodexHookRunnerResult>;
|
|
51
55
|
declare function recordProducedArtifacts(projectDir: string, ir: ConstraintIR, wfState: {
|
|
52
56
|
workflow: string;
|
|
53
57
|
current_step: string;
|
|
@@ -86,6 +90,8 @@ declare function finalizeAndResolveArtifactsForHook(projectDir: string, ir: Cons
|
|
|
86
90
|
export declare const recordProducedArtifactsForTest: typeof recordProducedArtifacts;
|
|
87
91
|
export declare const resolveWorkflowArtifactFactsForTest: typeof resolveWorkflowArtifactFacts;
|
|
88
92
|
export declare const readWorkflowStateForHookTest: typeof readWorkflowStateForHook;
|
|
93
|
+
export declare const runCodexHookWithLoadedIrForTest: typeof runCodexHookWithLoadedIr;
|
|
94
|
+
export declare const inferWorkflowAssetFromIrForTest: typeof inferWorkflowAssetFromIr;
|
|
89
95
|
export declare const resolveWorkflowArtifactFactsForHookTest: typeof resolveWorkflowArtifactFactsForHook;
|
|
90
96
|
export declare const finalizeAndResolveArtifactsForHookTest: typeof finalizeAndResolveArtifactsForHook;
|
|
91
97
|
export declare function appendStopVerifierWarnings(output: HookOutput, verifierResults: VerifierResultEntry[], currentStep?: string): HookOutput;
|
package/dist/hooks/cli.js
CHANGED
|
@@ -23,10 +23,11 @@ import { fileURLToPath } from "node:url";
|
|
|
23
23
|
import { readStdin, writeOutput, silentOutput, allowOutput, blockOutput, stopOutput } from "./protocol.js";
|
|
24
24
|
import { validateHookInput } from "./schema.js";
|
|
25
25
|
import { enforcePreToolUse, enforcePostToolUse, enforceUserPromptSubmit, enforceSubagentStop, enforcePreCompact, enforceNotification, enforceSessionStart, enforceStop, extractBashWritePaths, checkReflectionLimit, checkContextReadiness, checkWorkflowBoundary, } from "./enforce.js";
|
|
26
|
-
import { appendAudit, readWorkflowState, appendTrace, appendRuntimeDecisionEvent, rotateTraces, readTraces, cleanStaleState, readSurgeonAttempts, writeSurgeonAttempts, appendSessionRead, readSessionReads, appendVerifierResult, appendCompletedArtifact, artifactIdentity, buildArtifactKey, readArtifactManifest, resolveArtifactTemplate, safePathComponent, writeArtifactManifest } from "./state.js";
|
|
26
|
+
import { appendAudit, readWorkflowState, appendTrace, appendRuntimeDecisionEvent, appendEvidenceCaptureEvent, rotateTraces, readTraces, cleanStaleState, readSurgeonAttempts, writeSurgeonAttempts, appendSessionRead, readSessionReads, appendVerifierResult, appendCompletedArtifact, artifactIdentity, buildArtifactKey, readArtifactManifest, resolveArtifactTemplate, safePathComponent, writeArtifactManifest, EVIDENCE_CAPTURE_SCHEMA_VERSION } from "./state.js";
|
|
27
27
|
import { hookEventsForSurface } from "./event-registry.js";
|
|
28
28
|
import { writeAuditEvent } from "../audit/index.js";
|
|
29
|
-
import { RUNTIME_DECISION_EVENT_SCHEMA_VERSION } from "../governance/index.js";
|
|
29
|
+
import { RUNTIME_DECISION_EVENT_SCHEMA_VERSION, trustedEvidenceCaptureAttribution } from "../governance/index.js";
|
|
30
|
+
import { runCodexHook } from "../runtime/codex-adapter.js";
|
|
30
31
|
// ── Constants ──────────────────────────────────────────────
|
|
31
32
|
const DEFAULT_IR_PATH = ".dna/compiled/ir.json";
|
|
32
33
|
const VALID_EVENTS = new Set(hookEventsForSurface("cli"));
|
|
@@ -150,6 +151,74 @@ function buildRuntimeDecisionEvent(params) {
|
|
|
150
151
|
evidence_refs: [{ type: "trace", ref: params.traceId }],
|
|
151
152
|
};
|
|
152
153
|
}
|
|
154
|
+
function captureResultForHook(rawInput, decision) {
|
|
155
|
+
if (decision === "block")
|
|
156
|
+
return "blocked";
|
|
157
|
+
if (typeof rawInput.result === "string" && ["success", "failure", "blocked", "skipped", "unknown", "unsupported"].includes(rawInput.result)) {
|
|
158
|
+
return rawInput.result;
|
|
159
|
+
}
|
|
160
|
+
if (typeof rawInput.exit_code === "number")
|
|
161
|
+
return rawInput.exit_code === 0 ? "success" : "failure";
|
|
162
|
+
return "unknown";
|
|
163
|
+
}
|
|
164
|
+
function captureFactForHook(rawInput, decision, event) {
|
|
165
|
+
if (decision === "block")
|
|
166
|
+
return "blocker";
|
|
167
|
+
if (event === "PostToolUse" || event === "Stop" || rawInput.result || rawInput.exit_code !== undefined)
|
|
168
|
+
return "result";
|
|
169
|
+
const toolInput = typeof rawInput.tool_input === "object" && rawInput.tool_input !== null
|
|
170
|
+
? rawInput.tool_input
|
|
171
|
+
: {};
|
|
172
|
+
if (typeof rawInput.command === "string" || typeof toolInput.command === "string")
|
|
173
|
+
return "command";
|
|
174
|
+
return "result";
|
|
175
|
+
}
|
|
176
|
+
function commandForHook(rawInput) {
|
|
177
|
+
const toolInput = typeof rawInput.tool_input === "object" && rawInput.tool_input !== null
|
|
178
|
+
? rawInput.tool_input
|
|
179
|
+
: {};
|
|
180
|
+
const command = rawInput.command ?? toolInput.command;
|
|
181
|
+
return typeof command === "string" && command.trim().length > 0 ? command : undefined;
|
|
182
|
+
}
|
|
183
|
+
function buildClaudeEvidenceCaptureEvent(params) {
|
|
184
|
+
const fact = captureFactForHook(params.rawInput, params.decision, params.event);
|
|
185
|
+
const result = captureResultForHook(params.rawInput, params.decision);
|
|
186
|
+
const command = commandForHook(params.rawInput);
|
|
187
|
+
const toolName = typeof params.rawInput.tool_name === "string" ? params.rawInput.tool_name : "unknown tool";
|
|
188
|
+
const subject = command ?? `${toolName} ${params.event}`;
|
|
189
|
+
const attribution = trustedEvidenceCaptureAttribution(params.ir, {
|
|
190
|
+
workflowAsset: params.wfState?.workflow_asset,
|
|
191
|
+
workflowId: params.wfState?.workflow,
|
|
192
|
+
stepId: params.wfState?.current_step ?? params.runtimeEvent.step_id,
|
|
193
|
+
});
|
|
194
|
+
return {
|
|
195
|
+
schema_version: EVIDENCE_CAPTURE_SCHEMA_VERSION,
|
|
196
|
+
event_id: `c5:${params.runtimeEvent.event_id}`,
|
|
197
|
+
captured_at: params.runtimeEvent.timestamp,
|
|
198
|
+
project_root: params.projectDir,
|
|
199
|
+
source: "claude_code",
|
|
200
|
+
workflow_asset: attribution.workflowAsset,
|
|
201
|
+
workflow_id: attribution.workflowId,
|
|
202
|
+
run_id: params.runtimeEvent.run_id || params.runtimeEvent.session_id || "unknown",
|
|
203
|
+
step_id: attribution.stepId === "unknown" && !params.wfState
|
|
204
|
+
? `${params.event}:direct`
|
|
205
|
+
: attribution.stepId,
|
|
206
|
+
fact,
|
|
207
|
+
summary: `Claude hook observed ${fact} for ${subject}: ${result}`,
|
|
208
|
+
command,
|
|
209
|
+
result,
|
|
210
|
+
exit_code: typeof params.rawInput.exit_code === "number" ? params.rawInput.exit_code : undefined,
|
|
211
|
+
duration_ms: typeof params.rawInput.duration_ms === "number" ? params.rawInput.duration_ms : undefined,
|
|
212
|
+
manual_intervention: fact === "manual_intervention"
|
|
213
|
+
? { required: true, reason: params.reason, actor: "human" }
|
|
214
|
+
: undefined,
|
|
215
|
+
evidence_refs: [
|
|
216
|
+
{ type: "runtime_decision_event", ref: params.runtimeEvent.event_id },
|
|
217
|
+
...params.runtimeEvent.evidence_refs.map((ref) => ({ type: ref.type, ref: ref.ref })),
|
|
218
|
+
],
|
|
219
|
+
redaction: "intentdna.c5.claude_hook_secret_redaction.v1",
|
|
220
|
+
};
|
|
221
|
+
}
|
|
153
222
|
export function computeSummary(traces) {
|
|
154
223
|
let blocks = 0, warns = 0;
|
|
155
224
|
const toolCounts = new Map();
|
|
@@ -193,7 +262,12 @@ export function formatSummary(s) {
|
|
|
193
262
|
async function main() {
|
|
194
263
|
// Parse args
|
|
195
264
|
const args = process.argv.slice(2);
|
|
196
|
-
const
|
|
265
|
+
const eventArg = args[0];
|
|
266
|
+
if (eventArg === "CodexHook") {
|
|
267
|
+
await runCodexHookCli(args);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
const event = eventArg;
|
|
197
271
|
if (!event || !VALID_EVENTS.has(event)) {
|
|
198
272
|
writeOutput(silentOutput());
|
|
199
273
|
return;
|
|
@@ -227,13 +301,25 @@ async function main() {
|
|
|
227
301
|
const output = await runHookEvent({ event, ir, rawInput, projectDir, sessionId });
|
|
228
302
|
writeOutput(output);
|
|
229
303
|
}
|
|
304
|
+
export function normalizeHookOutputForEvent(output, event) {
|
|
305
|
+
if (!output.hookSpecificOutput)
|
|
306
|
+
return output;
|
|
307
|
+
return {
|
|
308
|
+
...output,
|
|
309
|
+
hookSpecificOutput: {
|
|
310
|
+
...output.hookSpecificOutput,
|
|
311
|
+
hookEventName: output.hookSpecificOutput.hookEventName ?? event,
|
|
312
|
+
},
|
|
313
|
+
};
|
|
314
|
+
}
|
|
230
315
|
export async function runHookEvent(options) {
|
|
231
316
|
const { event, ir, rawInput, projectDir, sessionId, roles } = options;
|
|
317
|
+
const finish = (output) => normalizeHookOutputForEvent(output, event);
|
|
232
318
|
const state = {};
|
|
233
319
|
const writeRuntimeDecision = async (output, result, wfState, traceId = randomUUID()) => {
|
|
234
320
|
const decision = normalizeDecision(output);
|
|
235
321
|
const reason = decision !== "allow" ? (output.reason ?? output.hookSpecificOutput?.additionalContext ?? "unknown") : "allowed by active policy";
|
|
236
|
-
|
|
322
|
+
const runtimeEvent = buildRuntimeDecisionEvent({
|
|
237
323
|
ir,
|
|
238
324
|
rawInput,
|
|
239
325
|
output,
|
|
@@ -245,7 +331,18 @@ export async function runHookEvent(options) {
|
|
|
245
331
|
decision,
|
|
246
332
|
reason,
|
|
247
333
|
wfState,
|
|
248
|
-
})
|
|
334
|
+
});
|
|
335
|
+
await appendRuntimeDecisionEvent(projectDir, runtimeEvent, sessionId);
|
|
336
|
+
await appendEvidenceCaptureEvent(projectDir, buildClaudeEvidenceCaptureEvent({
|
|
337
|
+
ir,
|
|
338
|
+
rawInput,
|
|
339
|
+
event,
|
|
340
|
+
projectDir,
|
|
341
|
+
decision,
|
|
342
|
+
reason,
|
|
343
|
+
runtimeEvent,
|
|
344
|
+
wfState,
|
|
345
|
+
}));
|
|
249
346
|
};
|
|
250
347
|
let wfStateRaw = null;
|
|
251
348
|
// Load workflow state for events that need it (handoff context + PreCompact preservation)
|
|
@@ -253,13 +350,14 @@ export async function runHookEvent(options) {
|
|
|
253
350
|
const workflowState = await readWorkflowStateForHook(projectDir, event, sessionId);
|
|
254
351
|
if ("output" in workflowState) {
|
|
255
352
|
await writeRuntimeDecision(workflowState.output, { output: workflowState.output, trace: { matched_rule: "workflow_boundary" } }, null);
|
|
256
|
-
return workflowState.output;
|
|
353
|
+
return finish(workflowState.output);
|
|
257
354
|
}
|
|
258
355
|
wfStateRaw = workflowState.state;
|
|
259
356
|
if (wfStateRaw && wfStateRaw.active) {
|
|
260
357
|
state.workflowState = {
|
|
261
358
|
current_step: wfStateRaw.current_step,
|
|
262
359
|
workflow: wfStateRaw.workflow,
|
|
360
|
+
workflow_asset: wfStateRaw.workflow_asset,
|
|
263
361
|
current_role: wfStateRaw.current_role,
|
|
264
362
|
completed_artifacts: wfStateRaw.completed_artifacts,
|
|
265
363
|
iteration: wfStateRaw.iteration, // G4: pass iteration for state-driven rules
|
|
@@ -268,7 +366,7 @@ export async function runHookEvent(options) {
|
|
|
268
366
|
if ("output" in artifactFacts) {
|
|
269
367
|
appendArtifactResolverTrace(projectDir, event, wfStateRaw, artifactFacts.output, sessionId);
|
|
270
368
|
await writeRuntimeDecision(artifactFacts.output, { output: artifactFacts.output, trace: { matched_rule: "handoff", step_id: wfStateRaw.current_step } }, wfStateRaw);
|
|
271
|
-
return artifactFacts.output;
|
|
369
|
+
return finish(artifactFacts.output);
|
|
272
370
|
}
|
|
273
371
|
state.artifactFacts = artifactFacts.facts;
|
|
274
372
|
}
|
|
@@ -298,7 +396,7 @@ export async function runHookEvent(options) {
|
|
|
298
396
|
timestamp: new Date().toISOString(),
|
|
299
397
|
}, sessionId).catch(() => { });
|
|
300
398
|
await writeRuntimeDecision(gateResult.output, { output: gateResult.output, trace: { matched_rule: gateResult.matched_rule, step_id: wfStateRaw?.current_step } }, wfStateRaw, traceId);
|
|
301
|
-
return gateResult.output;
|
|
399
|
+
return finish(gateResult.output);
|
|
302
400
|
}
|
|
303
401
|
}
|
|
304
402
|
// Special handling for Stop — needs async workflow state read + session summary
|
|
@@ -306,7 +404,7 @@ export async function runHookEvent(options) {
|
|
|
306
404
|
const workflowState = await readWorkflowStateForHook(projectDir, event, sessionId);
|
|
307
405
|
if ("output" in workflowState) {
|
|
308
406
|
await writeRuntimeDecision(workflowState.output, { output: workflowState.output, trace: { matched_rule: "workflow_boundary" } }, null);
|
|
309
|
-
return workflowState.output;
|
|
407
|
+
return finish(workflowState.output);
|
|
310
408
|
}
|
|
311
409
|
const wfState = workflowState.state;
|
|
312
410
|
let stopArtifactFacts = [];
|
|
@@ -315,7 +413,7 @@ export async function runHookEvent(options) {
|
|
|
315
413
|
if ("output" in artifactFacts) {
|
|
316
414
|
appendArtifactResolverTrace(projectDir, event, wfState, artifactFacts.output, sessionId);
|
|
317
415
|
await writeRuntimeDecision(artifactFacts.output, { output: artifactFacts.output, trace: { matched_rule: "handoff", step_id: wfState.current_step } }, wfState);
|
|
318
|
-
return artifactFacts.output;
|
|
416
|
+
return finish(artifactFacts.output);
|
|
319
417
|
}
|
|
320
418
|
stopArtifactFacts = artifactFacts.facts;
|
|
321
419
|
}
|
|
@@ -375,7 +473,7 @@ export async function runHookEvent(options) {
|
|
|
375
473
|
timestamp: new Date().toISOString(),
|
|
376
474
|
}, sessionId).catch(() => { });
|
|
377
475
|
await writeRuntimeDecision(stopOutput, { output: stopOutput, trace: { matched_rule: "validator", step_id: wfState?.current_step } }, wfState, traceId);
|
|
378
|
-
return stopOutput;
|
|
476
|
+
return finish(stopOutput);
|
|
379
477
|
}
|
|
380
478
|
// Dispatch to enforcement engine with timing
|
|
381
479
|
const start = Date.now();
|
|
@@ -488,7 +586,7 @@ export async function runHookEvent(options) {
|
|
|
488
586
|
session_id: sessionId,
|
|
489
587
|
}).catch(() => { }); // Fail-open
|
|
490
588
|
}
|
|
491
|
-
return output;
|
|
589
|
+
return finish(output);
|
|
492
590
|
}
|
|
493
591
|
// ── Dispatch ───────────────────────────────────────────────
|
|
494
592
|
function dispatch(event, ir, input, state, roles) {
|
|
@@ -542,6 +640,62 @@ function dispatch(event, ir, input, state, roles) {
|
|
|
542
640
|
return null;
|
|
543
641
|
}
|
|
544
642
|
}
|
|
643
|
+
// ── Codex Hook Entry ───────────────────────────────────────
|
|
644
|
+
function argValue(args, flag) {
|
|
645
|
+
const index = args.indexOf(flag);
|
|
646
|
+
return index >= 0 ? args[index + 1] : undefined;
|
|
647
|
+
}
|
|
648
|
+
function codexInstallMode(value) {
|
|
649
|
+
return value === "plugin_scoped" || value === "managed" || value === "none" ? value : "project_fallback";
|
|
650
|
+
}
|
|
651
|
+
export function codexHookEventForInput(rawInput, args) {
|
|
652
|
+
return argValue(args, "--codex-event") ?? rawInput.event;
|
|
653
|
+
}
|
|
654
|
+
function inferWorkflowAssetFromIr(ir, workflowId) {
|
|
655
|
+
const attribution = trustedEvidenceCaptureAttribution(ir, { workflowId });
|
|
656
|
+
return attribution.workflowAsset === "unknown" ? undefined : attribution.workflowAsset;
|
|
657
|
+
}
|
|
658
|
+
async function runCodexHookWithLoadedIr(rawInput, projectDir, args, ir) {
|
|
659
|
+
const sessionId = typeof rawInput.session_id === "string"
|
|
660
|
+
? rawInput.session_id
|
|
661
|
+
: typeof rawInput.sessionId === "string"
|
|
662
|
+
? rawInput.sessionId
|
|
663
|
+
: undefined;
|
|
664
|
+
const sessionWorkflowState = sessionId
|
|
665
|
+
? await readWorkflowState(projectDir, sessionId)
|
|
666
|
+
: null;
|
|
667
|
+
const workflowState = sessionWorkflowState ?? await readWorkflowState(projectDir);
|
|
668
|
+
const workflowAsset = inferWorkflowAssetFromIr(ir, workflowState?.workflow);
|
|
669
|
+
return runCodexHook({ ...rawInput, event: codexHookEventForInput(rawInput, args) }, {
|
|
670
|
+
ir,
|
|
671
|
+
projectDir,
|
|
672
|
+
hookInstallMode: codexInstallMode(argValue(args, "--codex-install-mode")),
|
|
673
|
+
hookTrusted: true,
|
|
674
|
+
codexVersion: process.env.CODEX_VERSION,
|
|
675
|
+
workflowAsset,
|
|
676
|
+
workflowId: workflowState?.workflow,
|
|
677
|
+
stepId: workflowState?.current_step,
|
|
678
|
+
appendEvent: true,
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
async function runCodexHookCli(args) {
|
|
682
|
+
try {
|
|
683
|
+
const rawInput = await readStdin(5000);
|
|
684
|
+
const projectDir = typeof rawInput.cwd === "string" ? rawInput.cwd : process.cwd();
|
|
685
|
+
const irPath = argValue(args, "--ir") ?? DEFAULT_IR_PATH;
|
|
686
|
+
const ir = await loadIR(resolve(projectDir, irPath));
|
|
687
|
+
if (!ir) {
|
|
688
|
+
writeOutput(silentOutput());
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
const result = await runCodexHookWithLoadedIr(rawInput, projectDir, args, ir);
|
|
692
|
+
writeOutput(result.output);
|
|
693
|
+
}
|
|
694
|
+
catch (err) {
|
|
695
|
+
process.stderr.write(`\n Intent DNA: CodexHook failed open — ${err instanceof Error ? err.message : String(err)}\n`);
|
|
696
|
+
writeOutput(silentOutput());
|
|
697
|
+
}
|
|
698
|
+
}
|
|
545
699
|
// ── IR Loading ─────────────────────────────────────────────
|
|
546
700
|
/** Expected IR schema version — must match plugin-adapter.ts */
|
|
547
701
|
const EXPECTED_IR_VERSION = 1;
|
|
@@ -765,6 +919,8 @@ function appendArtifactResolverTrace(projectDir, event, wfState, output, session
|
|
|
765
919
|
export const recordProducedArtifactsForTest = recordProducedArtifacts;
|
|
766
920
|
export const resolveWorkflowArtifactFactsForTest = resolveWorkflowArtifactFacts;
|
|
767
921
|
export const readWorkflowStateForHookTest = readWorkflowStateForHook;
|
|
922
|
+
export const runCodexHookWithLoadedIrForTest = runCodexHookWithLoadedIr;
|
|
923
|
+
export const inferWorkflowAssetFromIrForTest = inferWorkflowAssetFromIr;
|
|
768
924
|
export const resolveWorkflowArtifactFactsForHookTest = resolveWorkflowArtifactFactsForHook;
|
|
769
925
|
export const finalizeAndResolveArtifactsForHookTest = finalizeAndResolveArtifactsForHook;
|
|
770
926
|
function clearBlockingVerifierCheckpoints(ir, workflowState) {
|
package/dist/hooks/enforce.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export interface EnforceState {
|
|
|
26
26
|
workflowState?: {
|
|
27
27
|
current_step: string;
|
|
28
28
|
workflow: string;
|
|
29
|
+
workflow_asset?: string;
|
|
29
30
|
current_role?: string;
|
|
30
31
|
completed_artifacts?: CompletedArtifactEntry[];
|
|
31
32
|
/** G4: current workflow iteration (for relax_after_iteration rules) */
|
package/dist/hooks/protocol.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* TypeScript types for Claude Code hook I/O and stdin/stdout utilities.
|
|
5
5
|
* All hooks read JSON from stdin and write JSON to stdout.
|
|
6
6
|
*
|
|
7
|
-
* Protocol reference: docs/references/cc-source-analysis.md §2
|
|
7
|
+
* Protocol reference: docs/archive/2026H1/references/cc-source-analysis.md §2
|
|
8
8
|
*/
|
|
9
9
|
export type { HookEvent } from "./event-registry.js";
|
|
10
10
|
/** Base fields present in all hook inputs */
|
package/dist/hooks/protocol.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* TypeScript types for Claude Code hook I/O and stdin/stdout utilities.
|
|
5
5
|
* All hooks read JSON from stdin and write JSON to stdout.
|
|
6
6
|
*
|
|
7
|
-
* Protocol reference: docs/references/cc-source-analysis.md §2
|
|
7
|
+
* Protocol reference: docs/archive/2026H1/references/cc-source-analysis.md §2
|
|
8
8
|
*/
|
|
9
9
|
// ── Output Helpers ─────────────────────────────────────────
|
|
10
10
|
/** Create an allow output, optionally injecting text into the conversation. */
|
package/dist/hooks/state.d.ts
CHANGED
|
@@ -11,9 +11,11 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import type { ArtifactFact, ArtifactKey, ArtifactManifest, CompletedArtifactEntry, HandoffArtifact, HandoffType, VerifierKind, VerifierSeverity, VerifierWhen } from "../schema/types.js";
|
|
13
13
|
import { type RuntimeDecisionEvent } from "../governance/index.js";
|
|
14
|
+
export declare const EVIDENCE_CAPTURE_SCHEMA_VERSION = "intentdna.evidence_capture.v1";
|
|
14
15
|
/** Workflow state written by runtime and read by hooks */
|
|
15
16
|
export interface DNAWorkflowState {
|
|
16
17
|
active: boolean;
|
|
18
|
+
workflow_asset?: string;
|
|
17
19
|
workflow: string;
|
|
18
20
|
current_step: string;
|
|
19
21
|
current_role: string;
|
|
@@ -51,6 +53,44 @@ export interface SurgeonAttemptState {
|
|
|
51
53
|
lesson: string;
|
|
52
54
|
}>;
|
|
53
55
|
}
|
|
56
|
+
export type EvidenceCaptureSource = "dna_hook" | "codex_cli" | "claude_code" | "dna_cli" | "manual";
|
|
57
|
+
export type EvidenceCaptureFact = "command" | "result" | "retry" | "manual_intervention" | "blocker" | "handoff";
|
|
58
|
+
export type EvidenceCaptureResult = "success" | "failure" | "blocked" | "skipped" | "unknown" | "unsupported";
|
|
59
|
+
export interface EvidenceCaptureRetry {
|
|
60
|
+
attempt: number;
|
|
61
|
+
max_attempts: number;
|
|
62
|
+
reason: string;
|
|
63
|
+
}
|
|
64
|
+
export interface EvidenceCaptureManualIntervention {
|
|
65
|
+
required: boolean;
|
|
66
|
+
reason: string;
|
|
67
|
+
actor: string;
|
|
68
|
+
}
|
|
69
|
+
export interface EvidenceCaptureRef {
|
|
70
|
+
type: string;
|
|
71
|
+
ref: string;
|
|
72
|
+
}
|
|
73
|
+
export interface EvidenceCaptureEvent {
|
|
74
|
+
schema_version: typeof EVIDENCE_CAPTURE_SCHEMA_VERSION;
|
|
75
|
+
event_id: string;
|
|
76
|
+
captured_at: string;
|
|
77
|
+
project_root: string;
|
|
78
|
+
source: EvidenceCaptureSource;
|
|
79
|
+
workflow_asset: string;
|
|
80
|
+
workflow_id: string;
|
|
81
|
+
run_id: string;
|
|
82
|
+
step_id: string;
|
|
83
|
+
fact: EvidenceCaptureFact;
|
|
84
|
+
summary: string;
|
|
85
|
+
command?: string;
|
|
86
|
+
result?: EvidenceCaptureResult;
|
|
87
|
+
exit_code?: number;
|
|
88
|
+
duration_ms?: number;
|
|
89
|
+
retry?: EvidenceCaptureRetry;
|
|
90
|
+
manual_intervention?: EvidenceCaptureManualIntervention;
|
|
91
|
+
evidence_refs?: EvidenceCaptureRef[];
|
|
92
|
+
redaction?: string;
|
|
93
|
+
}
|
|
54
94
|
export declare function safePathComponent(value: string, label: string): string;
|
|
55
95
|
/**
|
|
56
96
|
* Resolve state directory path.
|
|
@@ -181,6 +221,7 @@ export interface TraceEntry {
|
|
|
181
221
|
* Fail-open: never throws.
|
|
182
222
|
*/
|
|
183
223
|
export declare function appendTrace(projectDir: string, entry: TraceEntry, sessionId?: string): Promise<void>;
|
|
224
|
+
export declare function appendEvidenceCaptureEvent(projectDir: string, event: EvidenceCaptureEvent): Promise<void>;
|
|
184
225
|
export declare function appendRuntimeDecisionEvent(projectDir: string, event: RuntimeDecisionEvent, sessionId?: string): Promise<void>;
|
|
185
226
|
export declare function readRuntimeDecisionEvents(projectDir: string, days?: number, sessionId?: string): Promise<RuntimeDecisionEvent[]>;
|
|
186
227
|
export declare function readTraces(projectDir: string, days?: number, sessionId?: string): Promise<TraceEntry[]>;
|