phasegate 0.161.0 → 0.162.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/CHANGELOG.md +16 -0
- package/docs/contracts/requirement-test-matrix.schema.json +1 -1
- package/package.json +6 -3
- package/scripts/harness/agent-integration/domain/services/bash-write-target-extractor.ts +91 -23
- package/scripts/harness/agent-integration/domain/value-objects/protected-file-list.ts +4 -0
- package/scripts/harness/agent-integration/infrastructure/adapters/ci-governance-baseline-grandfather-adapter.ts +25 -2
- package/scripts/harness/agent-integration/infrastructure/adapters/phase-gate-query-adapter.ts +17 -2
- package/scripts/harness/biome-ast-engine/domain/value-objects/import-graph.ts +28 -1
- package/scripts/harness/config-foundation/application/mappers/validator-system-config-mapper.ts +1 -0
- package/scripts/harness/config-foundation/domain/harness-config.ts +1 -0
- package/scripts/harness/config-foundation/domain/value-objects/l3-config.ts +4 -0
- package/scripts/harness/config-foundation/domain/value-objects/layers-config.ts +1 -1
- package/scripts/harness/config-foundation/infrastructure/presets/minimal.json +2 -1
- package/scripts/harness/config-foundation/infrastructure/presets/standard.json +2 -1
- package/scripts/harness/config-foundation/infrastructure/presets/strict.json +2 -1
- package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v2.schema.json +14 -9
- package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v3.schema.json +14 -9
- package/scripts/harness/harness-api/infrastructure/adapters/phase-dependency-model-query-adapter.ts +18 -4
- package/scripts/harness/harness-api/infrastructure/adapters/validator-system-execution-adapter.ts +27 -4
- package/scripts/harness/installation/application/ports/model-delegation-port.ts +10 -0
- package/scripts/harness/installation/application/usecases/run-install.ts +56 -7
- package/scripts/harness/installation/application/usecases/run-reconcile.ts +12 -7
- package/scripts/harness/installation/composition-root.ts +4 -2
- package/scripts/harness/installation/infrastructure/adapters/skill-deployer-model-delegation-adapter.ts +16 -0
- package/scripts/harness/installation/presentation/cli/install-handler.ts +2 -1
- package/scripts/harness/main.ts +68 -12
- package/scripts/harness/nyquist-validation/application/dto/generate-matrix-output.ts +9 -7
- package/scripts/harness/nyquist-validation/domain/services/matrix-validation-service.ts +27 -2
- package/scripts/harness/nyquist-validation/domain/services/requirement-intent-coverage-service.ts +4 -4
- package/scripts/harness/nyquist-validation/domain/value-objects/intent-coverage.ts +33 -0
- package/scripts/harness/nyquist-validation/infrastructure/adapters/markdown-requirement-source-adapter.ts +3 -1
- package/scripts/harness/quick-mode/application/usecases/classify-change-category-usecase.ts +8 -3
- package/scripts/harness/quick-mode/composition-root.ts +3 -0
- package/scripts/harness/quick-mode/infrastructure/adapters/validator-system-quick-mode-execution-adapter.ts +18 -0
- package/scripts/harness/quick-mode/presentation/handlers/ci-check-quick-mode-handler.ts +51 -5
- package/scripts/harness/skill-quality/infrastructure/adapters/l1-biome-validator-adapter.ts +12 -2
- package/scripts/harness/skill-quality/infrastructure/adapters/l2-validator-system-adapter.ts +12 -2
- package/scripts/harness/traceability-model/application/usecases/apply-work-item-status-usecase.ts +6 -1
- package/scripts/harness/traceability-model/infrastructure/parsers/story-catalog-parser.ts +28 -9
- package/scripts/harness/validator-system/application/use-cases/run-l3-validators-usecase.ts +65 -27
- package/scripts/harness/validator-system/application/use-cases/run-l4-validators-usecase.ts +6 -7
- package/scripts/harness/validator-system/composition-root.ts +8 -1
- package/scripts/harness/validator-system/infrastructure/adapters/file-system-security-pattern-scanner-adapter.ts +16 -6
- package/scripts/harness/validator-system/infrastructure/adapters/file-system-work-item-reflection-adapter.ts +10 -1
- package/scripts/harness/validator-system/infrastructure/adapters/import-graph-source-analysis-adapter.ts +35 -3
- package/scripts/harness/validator-system/infrastructure/adapters/nyquist-ac-coverage-policy-adapter.ts +86 -14
- package/scripts/harness/validator-system/infrastructure/adapters/phase-dependency-phase-gate-policy-adapter.ts +29 -3
- package/templates/.claude/scripts/deny-check.sh +73 -12
|
@@ -51,9 +51,35 @@ export class PhaseDependencyPhaseGatePolicyAdapter implements PhaseGatePolicyPor
|
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return {
|
|
54
|
+
// Fail-closed: an unexpected exit code means prerequisites could not be confirmed.
|
|
55
|
+
console.error(`[validator-system] phase gate check returned unexpected exit code ${result.exitCode}`);
|
|
56
|
+
return {
|
|
57
|
+
satisfied: false,
|
|
58
|
+
violations: [
|
|
59
|
+
{
|
|
60
|
+
code: { value: 'L2-002', toString: () => 'L2-002' },
|
|
61
|
+
severity: { value: 'error', toString: () => 'error' },
|
|
62
|
+
message: `phase gate check returned unexpected exit code ${result.exitCode}; prerequisites cannot be confirmed`,
|
|
63
|
+
suggestion: 'phase gate prerequisites could not be evaluated; treating as NOT satisfied (fail-closed)',
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
} catch (err) {
|
|
68
|
+
// Fail-closed: if the phase-dependency-model could not be loaded/executed we cannot
|
|
69
|
+
// confirm prerequisites are met, so treat them as NOT satisfied rather than opening the gate.
|
|
70
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
71
|
+
console.error(`[validator-system] phase gate prerequisite check failed to run: ${message}`);
|
|
72
|
+
return {
|
|
73
|
+
satisfied: false,
|
|
74
|
+
violations: [
|
|
75
|
+
{
|
|
76
|
+
code: { value: 'L2-002', toString: () => 'L2-002' },
|
|
77
|
+
severity: { value: 'error', toString: () => 'error' },
|
|
78
|
+
message: `phase gate prerequisite check could not be evaluated: ${message}`,
|
|
79
|
+
suggestion: 'phase gate prerequisites could not be evaluated; treating as NOT satisfied (fail-closed)',
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
};
|
|
57
83
|
}
|
|
58
84
|
}
|
|
59
85
|
}
|
|
@@ -4,14 +4,33 @@
|
|
|
4
4
|
# Reads JSON from stdin, exits with code 2 to block dangerous commands.
|
|
5
5
|
# Deny patterns are read from .claude/settings.json permissions.deny.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
# Debug logging is OFF by default to avoid leaking command contents to a
|
|
8
|
+
# world-readable file. Set CLAUDE_DENY_CHECK_DEBUG=1 to enable. When enabled,
|
|
9
|
+
# the log is created with restrictive (owner-only) permissions.
|
|
10
|
+
DEBUG_LOG="${CLAUDE_DENY_CHECK_DEBUG_LOG:-$HOME/.cache/claude/deny-check-debug.log}"
|
|
11
|
+
|
|
12
|
+
debug_log() {
|
|
13
|
+
if [[ "$CLAUDE_DENY_CHECK_DEBUG" == "1" ]]; then
|
|
14
|
+
local dir
|
|
15
|
+
dir=$(dirname "$DEBUG_LOG")
|
|
16
|
+
mkdir -p "$dir" 2>/dev/null || return 0
|
|
17
|
+
# Restrict permissions before writing anything sensitive.
|
|
18
|
+
( umask 077; touch "$DEBUG_LOG" 2>/dev/null ) || return 0
|
|
19
|
+
chmod 600 "$DEBUG_LOG" 2>/dev/null || true
|
|
20
|
+
printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$1" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
21
|
+
fi
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
debug_log "deny-check.sh started"
|
|
9
25
|
|
|
10
26
|
INPUT_JSON=$(cat)
|
|
11
|
-
|
|
27
|
+
debug_log "input received (${#INPUT_JSON} bytes)"
|
|
12
28
|
|
|
29
|
+
# Fail CLOSED: without jq we cannot parse the deny policy, so deny the command
|
|
30
|
+
# rather than silently allowing it.
|
|
13
31
|
if ! command -v jq &> /dev/null; then
|
|
14
|
-
|
|
32
|
+
echo "Security policy: jq is required to evaluate the deny policy but was not found; command blocked." >&2
|
|
33
|
+
exit 2
|
|
15
34
|
fi
|
|
16
35
|
|
|
17
36
|
TOOL_NAME=$(echo "$INPUT_JSON" | jq -r '.tool_name // empty')
|
|
@@ -43,13 +62,55 @@ if [[ ${#DENY_PATTERNS[@]} -eq 0 ]]; then
|
|
|
43
62
|
exit 0
|
|
44
63
|
fi
|
|
45
64
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
65
|
+
# Split a shell command line into individual command segments so that denied
|
|
66
|
+
# commands smuggled behind chaining/grouping/substitution operators are still
|
|
67
|
+
# inspected. Operators handled: ; && || | & newline $( ) ` { } ( )
|
|
68
|
+
# We replace each operator with a newline, then treat each line as a segment.
|
|
69
|
+
split_command_segments() {
|
|
70
|
+
local cmd="$1"
|
|
71
|
+
# Order matters: multi-char operators first.
|
|
72
|
+
cmd=${cmd//&&/$'\n'}
|
|
73
|
+
cmd=${cmd//||/$'\n'}
|
|
74
|
+
cmd=${cmd//|/$'\n'}
|
|
75
|
+
cmd=${cmd//;/$'\n'}
|
|
76
|
+
cmd=${cmd//&/$'\n'}
|
|
77
|
+
cmd=${cmd//\$(/$'\n'}
|
|
78
|
+
cmd=${cmd//\`/$'\n'}
|
|
79
|
+
cmd=${cmd//(/$'\n'}
|
|
80
|
+
cmd=${cmd//)/$'\n'}
|
|
81
|
+
cmd=${cmd//\{/$'\n'}
|
|
82
|
+
cmd=${cmd//\}/$'\n'}
|
|
83
|
+
# Trailing newline ensures the final segment is emitted as a complete line
|
|
84
|
+
# so that `while read` does not drop an unterminated last segment.
|
|
85
|
+
printf '%s\n' "$cmd"
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# Convert a settings glob pattern to an anchored regex. ALL '*' become '.*'.
|
|
89
|
+
glob_to_regex() {
|
|
90
|
+
printf '%s' "$1" | sed 's/\*/.*/g'
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
check_segment() {
|
|
94
|
+
local segment="$1"
|
|
95
|
+
# Strip leading whitespace so "^pattern" anchors match after operators.
|
|
96
|
+
segment="${segment#"${segment%%[![:space:]]*}"}"
|
|
97
|
+
[[ -z "$segment" ]] && return 0
|
|
98
|
+
for pattern in "${DENY_PATTERNS[@]}"; do
|
|
99
|
+
local regex_pattern
|
|
100
|
+
regex_pattern=$(glob_to_regex "$pattern")
|
|
101
|
+
if printf '%s' "$segment" | grep -E "^$regex_pattern" &>/dev/null; then
|
|
102
|
+
debug_log "BLOCKED segment '$segment' matches '$pattern'"
|
|
103
|
+
echo "Security policy violation: command segment '$segment' is denied by pattern '$pattern'" >&2
|
|
104
|
+
exit 2
|
|
105
|
+
fi
|
|
106
|
+
done
|
|
107
|
+
return 0
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
# Inspect the whole command AND each chained/substituted segment.
|
|
111
|
+
check_segment "$COMMAND"
|
|
112
|
+
while IFS= read -r segment; do
|
|
113
|
+
check_segment "$segment"
|
|
114
|
+
done < <(split_command_segments "$COMMAND")
|
|
54
115
|
|
|
55
116
|
exit 0
|