alp-code 0.9.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 +770 -0
- package/LICENSE +21 -0
- package/README.md +295 -0
- package/alp.config.yaml +5 -0
- package/dist/src/agents/agent-definition.js +28 -0
- package/dist/src/agents/capability-catalog.js +33 -0
- package/dist/src/agents/compaction.js +36 -0
- package/dist/src/agents/errors.js +12 -0
- package/dist/src/agents/librarian.js +38 -0
- package/dist/src/agents/main.js +37 -0
- package/dist/src/agents/memory-grant.js +29 -0
- package/dist/src/agents/model-context.js +70 -0
- package/dist/src/agents/modes.js +134 -0
- package/dist/src/agents/oracle.js +36 -0
- package/dist/src/agents/read-thread.js +38 -0
- package/dist/src/agents/registry.js +238 -0
- package/dist/src/agents/render-identity.js +38 -0
- package/dist/src/agents/review.js +37 -0
- package/dist/src/agents/search.js +37 -0
- package/dist/src/agents/shared/house-rules.js +33 -0
- package/dist/src/agents/shared/principal.js +18 -0
- package/dist/src/agents/shared/voice.js +29 -0
- package/dist/src/agents/titling.js +32 -0
- package/dist/src/agents/types.js +15 -0
- package/dist/src/backend/execution-backend.js +2 -0
- package/dist/src/backend/local-execution-store.js +144 -0
- package/dist/src/backend/local-process-backend.js +533 -0
- package/dist/src/backend/local-supervisor.js +104 -0
- package/dist/src/cli/alp.js +380 -0
- package/dist/src/cli/commands/context.js +203 -0
- package/dist/src/cli/commands/delegate.js +136 -0
- package/dist/src/cli/commands/identity-sync.js +31 -0
- package/dist/src/cli/commands/init.js +184 -0
- package/dist/src/cli/commands/mode.js +22 -0
- package/dist/src/cli/commands/principal.js +114 -0
- package/dist/src/cli/commands/run-main.js +90 -0
- package/dist/src/cli/commands/runtime.js +21 -0
- package/dist/src/cli/mode-preference-store.js +62 -0
- package/dist/src/cli/mode-selector.js +178 -0
- package/dist/src/cli/update-check.js +77 -0
- package/dist/src/context/checkpoint.js +134 -0
- package/dist/src/context/compact-journal.js +153 -0
- package/dist/src/context/compact-payload.js +121 -0
- package/dist/src/context/continuity.js +70 -0
- package/dist/src/context/types.js +2 -0
- package/dist/src/delegation/backend-registry.js +40 -0
- package/dist/src/delegation/delegation-service.js +300 -0
- package/dist/src/delegation/types.js +12 -0
- package/dist/src/execution/execution-policy.js +96 -0
- package/dist/src/execution/execution-service.js +115 -0
- package/dist/src/execution/execution-store.js +78 -0
- package/dist/src/execution/identity-capsule.js +65 -0
- package/dist/src/execution/types.js +12 -0
- package/dist/src/hooks/execution-bridge.js +84 -0
- package/dist/src/index.js +4 -0
- package/dist/src/memory/adapters/markdown-file-store.js +257 -0
- package/dist/src/memory/adapters/memory-api-client.js +2 -0
- package/dist/src/memory/adapters/memory-path-mapper.js +76 -0
- package/dist/src/memory/adapters/remote-api-store.js +25 -0
- package/dist/src/memory/context-ranker.js +21 -0
- package/dist/src/memory/errors.js +58 -0
- package/dist/src/memory/memory-service.js +149 -0
- package/dist/src/memory/memory-store.js +2 -0
- package/dist/src/memory/types.js +2 -0
- package/dist/src/policy/capability-policy.js +29 -0
- package/dist/src/policy/delegation-policy.js +25 -0
- package/dist/src/policy/errors.js +10 -0
- package/dist/src/policy/invariants.js +31 -0
- package/dist/src/policy/memory-policy.js +22 -0
- package/dist/src/policy/policy-engine.js +85 -0
- package/dist/src/policy/types.js +8 -0
- package/dist/src/policy/workspace-policy.js +77 -0
- package/dist/src/principal/principal-profile-store.js +89 -0
- package/dist/src/runtime/adapter-files.js +147 -0
- package/dist/src/runtime/claude-adapter.js +177 -0
- package/dist/src/runtime/codex-adapter.js +169 -0
- package/dist/src/runtime/permission-rules.js +156 -0
- package/dist/src/runtime/render-session-context.js +124 -0
- package/dist/src/runtime/render-task-input.js +33 -0
- package/dist/src/runtime/runtime-adapter.js +2 -0
- package/dist/src/runtime/runtime-preference-store.js +66 -0
- package/dist/src/runtime/runtime-selector.js +178 -0
- package/dist/src/runtime/types.js +2 -0
- package/dist/src/runtime/windows-shim.js +57 -0
- package/dist/src/state-paths.js +49 -0
- package/dist/src/workflow/output-validator.js +27 -0
- package/dist/src/workflow/repair-policy.js +8 -0
- package/dist/src/workflow/types.js +22 -0
- package/dist/src/workflow/workflow-runner.js +81 -0
- package/hooks/compact-record.cjs +109 -0
- package/hooks/session-boot.cjs +112 -0
- package/hooks/session-end.cjs +34 -0
- package/package.json +48 -0
- package/scaffold/memory/INDEX.md +27 -0
- package/scaffold/memory/README.md +76 -0
- package/scaffold/memory/projects/INDEX.md +22 -0
- package/scaffold/memory/projects/PROTOCOL.md +128 -0
- package/scaffold/memory/projects/_template/PROJECT.md +45 -0
- package/scripts/alp.cjs +126 -0
- package/scripts/alp.ps1 +4 -0
- package/scripts/alp.sh +3 -0
- package/scripts/bootstrap.cjs +144 -0
- package/scripts/checkout-release.cjs +30 -0
- package/scripts/delegate.cjs +19 -0
- package/scripts/doctor.cjs +158 -0
- package/scripts/doctor.sh +3 -0
- package/scripts/ensure-state.cjs +22 -0
- package/scripts/lib/cli-link.cjs +375 -0
- package/scripts/lib/codex-role.cjs +18 -0
- package/scripts/lib/delegation/command-runner.cjs +108 -0
- package/scripts/lib/delegation/config.cjs +81 -0
- package/scripts/lib/install-paths.cjs +154 -0
- package/scripts/lib/release-manifest.cjs +42 -0
- package/scripts/lib/semver-lite.cjs +20 -0
- package/scripts/lib/state.cjs +274 -0
- package/scripts/lib/uninstall.cjs +252 -0
- package/scripts/lib/update-check-worker.cjs +21 -0
- package/scripts/lib/update.cjs +395 -0
- package/scripts/run-role.cjs +42 -0
- package/scripts/run-role.ps1 +4 -0
- package/scripts/run-role.sh +3 -0
- package/scripts/sync-project-index.sh +167 -0
- package/skills/agent-memory/SKILL.md +109 -0
- package/skills/alp-debug/SKILL.md +90 -0
- package/skills/alp-debug/references/defense-in-depth.md +118 -0
- package/skills/alp-debug/references/investigation-methodology.md +106 -0
- package/skills/alp-debug/references/log-and-ci-analysis.md +96 -0
- package/skills/alp-debug/references/performance-diagnostics.md +112 -0
- package/skills/alp-debug/references/reporting-standards.md +120 -0
- package/skills/alp-debug/references/root-cause-tracing.md +134 -0
- package/skills/alp-debug/references/systematic-debugging.md +93 -0
- package/skills/alp-debug/references/verification.md +86 -0
- package/skills/alp-debug/scripts/find-polluter.sh +63 -0
- package/skills/alp-debug/scripts/find-polluter.test.md +102 -0
- package/skills/alp-plan/SKILL.md +128 -0
- package/skills/alp-plan/references/archive-workflow.md +77 -0
- package/skills/alp-plan/references/codebase-understanding.md +55 -0
- package/skills/alp-plan/references/output-standards.md +96 -0
- package/skills/alp-plan/references/plan-organization.md +129 -0
- package/skills/alp-plan/references/red-team-personas.md +76 -0
- package/skills/alp-plan/references/red-team-workflow.md +81 -0
- package/skills/alp-plan/references/research-phase.md +57 -0
- package/skills/alp-plan/references/scope-challenge.md +82 -0
- package/skills/alp-plan/references/solution-design.md +76 -0
- package/skills/alp-plan/references/validate-question-framework.md +89 -0
- package/skills/alp-plan/references/validate-workflow.md +83 -0
- package/skills/alp-predict/SKILL.md +98 -0
- package/skills/alp-scenario/SKILL.md +86 -0
- package/skills/code-review/SKILL.md +111 -0
- package/skills/code-review/references/code-review-reception.md +114 -0
- package/skills/code-review/references/edge-case-scouting.md +78 -0
- package/skills/code-review/references/verification-before-completion.md +117 -0
- package/skills/delegation/SKILL.md +46 -0
- package/skills/docs-seeker/.env.example +15 -0
- package/skills/docs-seeker/SKILL.md +87 -0
- package/skills/docs-seeker/package.json +25 -0
- package/skills/docs-seeker/references/advanced.md +82 -0
- package/skills/docs-seeker/references/context7-patterns.md +68 -0
- package/skills/docs-seeker/references/errors.md +72 -0
- package/skills/docs-seeker/scripts/analyze-llms-txt.js +211 -0
- package/skills/docs-seeker/scripts/detect-topic.js +172 -0
- package/skills/docs-seeker/scripts/fetch-docs.js +213 -0
- package/skills/docs-seeker/scripts/tests/run-tests.js +72 -0
- package/skills/docs-seeker/scripts/tests/test-analyze-llms.js +119 -0
- package/skills/docs-seeker/scripts/tests/test-detect-topic.js +112 -0
- package/skills/docs-seeker/scripts/tests/test-fetch-docs.js +84 -0
- package/skills/docs-seeker/scripts/utils/env-loader.js +94 -0
- package/skills/docs-seeker/workflows/library-search.md +73 -0
- package/skills/docs-seeker/workflows/repo-analysis.md +90 -0
- package/skills/docs-seeker/workflows/topic-search.md +69 -0
- package/skills/git/SKILL.md +121 -0
- package/skills/git/references/branch-management.md +90 -0
- package/skills/git/references/commit-standards.md +82 -0
- package/skills/git/references/gh-cli-guide.md +132 -0
- package/skills/git/references/safety-protocols.md +86 -0
- package/skills/git/references/workflow-commit.md +89 -0
- package/skills/git/references/workflow-merge.md +63 -0
- package/skills/git/references/workflow-pr.md +70 -0
- package/skills/git/references/workflow-push.md +62 -0
- package/skills/gkg/SKILL.md +87 -0
- package/skills/gkg/references/cli-commands.md +92 -0
- package/skills/gkg/references/http-api.md +99 -0
- package/skills/gkg/references/language-support.md +54 -0
- package/skills/problem-solving/SKILL.md +86 -0
- package/skills/problem-solving/references/attribution.md +48 -0
- package/skills/problem-solving/references/collision-zone-thinking.md +71 -0
- package/skills/problem-solving/references/inversion-exercise.md +88 -0
- package/skills/problem-solving/references/meta-pattern-recognition.md +80 -0
- package/skills/problem-solving/references/scale-game.md +82 -0
- package/skills/problem-solving/references/simplification-cascades.md +83 -0
- package/skills/problem-solving/references/when-stuck.md +76 -0
- package/skills/repomix/SKILL.md +94 -0
- package/skills/repomix/references/configuration.md +134 -0
- package/skills/repomix/references/usage-patterns.md +106 -0
- package/skills/repomix/scripts/.coverage +0 -0
- package/skills/repomix/scripts/README.md +179 -0
- package/skills/repomix/scripts/repomix_batch.py +455 -0
- package/skills/repomix/scripts/repos.example.json +15 -0
- package/skills/repomix/scripts/requirements.txt +15 -0
- package/skills/repomix/scripts/tests/test_repomix_batch.py +531 -0
- package/skills/research/SKILL.md +107 -0
- package/skills/security-scan/SKILL.md +101 -0
- package/skills/security-scan/references/secret-patterns.md +75 -0
- package/skills/security-scan/references/vulnerability-patterns.md +136 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Deprecated compatibility wrapper. Identity-aware raw runtime launch is no longer
|
|
3
|
+
// supported; accepted legacy flags are translated into `alp delegate` arguments.
|
|
4
|
+
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const { spawnSyncCommand } = require("./lib/delegation/command-runner.cjs");
|
|
8
|
+
const repoRoot = path.resolve(__dirname, "..");
|
|
9
|
+
const entry = path.join(repoRoot, "dist", "src", "cli", "alp.js");
|
|
10
|
+
if (!fs.existsSync(entry)) {
|
|
11
|
+
const built = spawnSyncCommand("npm", ["run", "build"], { cwd: repoRoot, stdio: "inherit" });
|
|
12
|
+
if (built.error || built.status !== 0) process.exit(built.status || 2);
|
|
13
|
+
}
|
|
14
|
+
const input = process.argv.slice(2);
|
|
15
|
+
const role = input.shift();
|
|
16
|
+
if (!role) {
|
|
17
|
+
console.error("ERROR run-role requires a role");
|
|
18
|
+
process.exit(2);
|
|
19
|
+
}
|
|
20
|
+
if (input.includes("--dry-run") || input.includes("--anchor")) {
|
|
21
|
+
console.error("ERROR identity-aware raw-runtime shortcuts are unsupported; use `alp delegate`");
|
|
22
|
+
process.exit(2);
|
|
23
|
+
}
|
|
24
|
+
const output = ["delegate", role];
|
|
25
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
26
|
+
const value = input[index];
|
|
27
|
+
if (value === "--kind") {
|
|
28
|
+
console.error("ERROR `--kind` chọn runtime, mà runtime giờ là hệ quả của nấc; dùng `alp mode set <nấc>` hoặc ALP_MODE");
|
|
29
|
+
process.exit(2);
|
|
30
|
+
}
|
|
31
|
+
else if (value === "--pane") output.push("--background");
|
|
32
|
+
else if (value === "--exec") continue;
|
|
33
|
+
else if (value === "--release") {
|
|
34
|
+
output.splice(0, output.length, "delegation", "cleanup", input[++index]);
|
|
35
|
+
break;
|
|
36
|
+
} else output.push(value);
|
|
37
|
+
}
|
|
38
|
+
process.env.ALP_REPO_ROOT = repoRoot;
|
|
39
|
+
require(entry).main(output).then(
|
|
40
|
+
(code) => { process.exitCode = code; },
|
|
41
|
+
(error) => { console.error(`ERROR ${error && error.message ? error.message : String(error)}`); process.exitCode = 2; },
|
|
42
|
+
);
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# sync-project-index.sh — kiểm soát Project Layer bằng `modified`.
|
|
4
|
+
#
|
|
5
|
+
# Quét frontmatter của mọi L1 card (memory/projects/<slug>/PROJECT.md), so sánh với L0
|
|
6
|
+
# (memory/projects/INDEX.md) và với mtime của filesystem, rồi báo ba tín hiệu:
|
|
7
|
+
#
|
|
8
|
+
# DRIFT mtime > updated → file bị sửa mà chưa đóng dấu `updated`
|
|
9
|
+
# STALE ACTIVE, quá N ngày → khai đang chạy nhưng không ai đụng tới
|
|
10
|
+
# ORPHAN L1 ⟷ L0 lệch nhau → card không có dòng index, hoặc ngược lại
|
|
11
|
+
#
|
|
12
|
+
# Dùng:
|
|
13
|
+
# sync-project-index.sh # chỉ báo cáo (mặc định, không ghi gì)
|
|
14
|
+
# sync-project-index.sh --write # sinh lại bảng L0 từ frontmatter L1
|
|
15
|
+
# STALE_DAYS=30 sync-project-index.sh
|
|
16
|
+
#
|
|
17
|
+
# Exit: 0 mọi thứ khớp · 1 có tín hiệu cần xử lý · 2 lỗi cấu hình
|
|
18
|
+
#
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
22
|
+
PROJECTS_DIR="$ROOT/memory/projects"
|
|
23
|
+
INDEX_FILE="$PROJECTS_DIR/INDEX.md"
|
|
24
|
+
STALE_DAYS="${STALE_DAYS:-14}"
|
|
25
|
+
WRITE=0
|
|
26
|
+
|
|
27
|
+
[[ "${1:-}" == "--write" ]] && WRITE=1
|
|
28
|
+
[[ -f "$INDEX_FILE" ]] || { echo "Không thấy $INDEX_FILE" >&2; exit 2; }
|
|
29
|
+
|
|
30
|
+
TODAY_EPOCH=$(date +%s)
|
|
31
|
+
|
|
32
|
+
# Đọc một khoá từ YAML frontmatter (khối --- đầu tiên của file).
|
|
33
|
+
read_fm() {
|
|
34
|
+
awk -v key="$2" '
|
|
35
|
+
/^---[[:space:]]*$/ { if (seen) exit; seen = 1; next }
|
|
36
|
+
seen && $0 ~ "^" key ":" {
|
|
37
|
+
sub("^" key ":[[:space:]]*", "")
|
|
38
|
+
gsub(/^["'"'"']|["'"'"']$/, "")
|
|
39
|
+
sub(/[[:space:]]+$/, "")
|
|
40
|
+
print
|
|
41
|
+
exit
|
|
42
|
+
}
|
|
43
|
+
' "$1"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# YYYY-MM-DD → epoch. BSD date (macOS).
|
|
47
|
+
date_to_epoch() { date -j -f "%Y-%m-%d" "$1" "+%s" 2>/dev/null || echo 0; }
|
|
48
|
+
|
|
49
|
+
issues=0
|
|
50
|
+
active_rows=""
|
|
51
|
+
done_rows=""
|
|
52
|
+
all_slugs=()
|
|
53
|
+
|
|
54
|
+
shopt -s nullglob
|
|
55
|
+
for card in "$PROJECTS_DIR"/*/PROJECT.md; do
|
|
56
|
+
dir="$(dirname "$card")"
|
|
57
|
+
dirname_slug="$(basename "$dir")"
|
|
58
|
+
[[ "$dirname_slug" == _* ]] && continue # bỏ qua _template
|
|
59
|
+
|
|
60
|
+
slug="$(read_fm "$card" slug)"
|
|
61
|
+
status="$(read_fm "$card" status)"
|
|
62
|
+
priority="$(read_fm "$card" priority)"
|
|
63
|
+
summary="$(read_fm "$card" summary)"
|
|
64
|
+
updated="$(read_fm "$card" updated)"
|
|
65
|
+
|
|
66
|
+
# --- frontmatter thiếu hoặc sai ---
|
|
67
|
+
for field in slug status priority summary updated; do
|
|
68
|
+
if [[ -z "${!field}" ]]; then
|
|
69
|
+
echo "MISSING $dirname_slug — thiếu \`$field:\` trong frontmatter"
|
|
70
|
+
issues=$((issues + 1))
|
|
71
|
+
fi
|
|
72
|
+
done
|
|
73
|
+
[[ -z "$slug" || -z "$updated" ]] && continue
|
|
74
|
+
|
|
75
|
+
if [[ "$slug" != "$dirname_slug" ]]; then
|
|
76
|
+
echo "MISMATCH $dirname_slug — slug frontmatter là '$slug', không khớp tên thư mục"
|
|
77
|
+
issues=$((issues + 1))
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# --- DRIFT: file bị chạm sau lần đóng dấu cuối ---
|
|
81
|
+
mtime_date="$(date -r "$card" "+%Y-%m-%d")"
|
|
82
|
+
updated_epoch="$(date_to_epoch "$updated")"
|
|
83
|
+
mtime_epoch="$(date_to_epoch "$mtime_date")"
|
|
84
|
+
if (( mtime_epoch > updated_epoch )); then
|
|
85
|
+
echo "DRIFT $slug — sửa $mtime_date nhưng updated: $updated → đọc lại rồi đóng dấu"
|
|
86
|
+
issues=$((issues + 1))
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
# --- STALE: khai ACTIVE mà lâu không đụng ---
|
|
90
|
+
if [[ "$status" == "ACTIVE" ]]; then
|
|
91
|
+
age_days=$(( (TODAY_EPOCH - updated_epoch) / 86400 ))
|
|
92
|
+
if (( age_days > STALE_DAYS )); then
|
|
93
|
+
echo "STALE $slug — ACTIVE nhưng $age_days ngày không cập nhật (ngưỡng $STALE_DAYS)"
|
|
94
|
+
issues=$((issues + 1))
|
|
95
|
+
fi
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
all_slugs+=("$slug")
|
|
99
|
+
if [[ "$status" == "DONE" ]]; then
|
|
100
|
+
done_rows+="| $slug | $priority | $summary | $updated |"$'\n'
|
|
101
|
+
else
|
|
102
|
+
active_rows+="$priority $slug | $slug | $priority | $status | $summary | $updated |"$'\n'
|
|
103
|
+
fi
|
|
104
|
+
done
|
|
105
|
+
shopt -u nullglob
|
|
106
|
+
|
|
107
|
+
# --- sinh lại bảng L0 (làm trước, để ORPHAN kiểm tra trên bản mới nhất) ---
|
|
108
|
+
if (( WRITE )); then
|
|
109
|
+
# sắp xếp cố định: priority rồi slug — để L0 ổn định byte giữa các lần chạy
|
|
110
|
+
active_tbl="$(mktemp)"; done_tbl="$(mktemp)"
|
|
111
|
+
trap 'rm -f "$active_tbl" "$done_tbl"' EXIT
|
|
112
|
+
|
|
113
|
+
{
|
|
114
|
+
echo "| Slug | P | Trạng thái | Tóm tắt | Cập nhật |"
|
|
115
|
+
echo "|---|---|---|---|---|"
|
|
116
|
+
if [[ -n "$active_rows" ]]; then
|
|
117
|
+
printf '%s' "$active_rows" | sort -t' ' -k1,1 -k2,2 | cut -f3-
|
|
118
|
+
else
|
|
119
|
+
echo "| _(chưa có)_ | | | | |"
|
|
120
|
+
fi
|
|
121
|
+
} > "$active_tbl"
|
|
122
|
+
|
|
123
|
+
if [[ -n "$done_rows" ]]; then
|
|
124
|
+
{ echo "| Slug | P | Tóm tắt | Đóng ngày |"
|
|
125
|
+
echo "|---|---|---|---|"
|
|
126
|
+
printf '%s' "$done_rows" | sort
|
|
127
|
+
} > "$done_tbl"
|
|
128
|
+
else
|
|
129
|
+
echo "_(chưa có)_" > "$done_tbl"
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
tmp="$(mktemp)"
|
|
133
|
+
awk -v active_f="$active_tbl" -v done_f="$done_tbl" '
|
|
134
|
+
function emit(f, line) { while ((getline line < f) > 0) print line; close(f) }
|
|
135
|
+
/<!-- BEGIN:INDEX -->/ { print; emit(active_f); skip = 1; next }
|
|
136
|
+
/<!-- END:INDEX -->/ { skip = 0 }
|
|
137
|
+
/<!-- BEGIN:DONE -->/ { print; emit(done_f); skip = 1; next }
|
|
138
|
+
/<!-- END:DONE -->/ { skip = 0 }
|
|
139
|
+
!skip
|
|
140
|
+
' "$INDEX_FILE" > "$tmp"
|
|
141
|
+
mv "$tmp" "$INDEX_FILE"
|
|
142
|
+
echo "WROTE INDEX.md — bảng L0 đã sinh lại từ frontmatter L1"
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
# --- ORPHAN: card ⟷ dòng index, hai chiều ---
|
|
146
|
+
for slug in ${all_slugs+"${all_slugs[@]}"}; do
|
|
147
|
+
if ! grep -q "^| $slug |" "$INDEX_FILE"; then
|
|
148
|
+
echo "ORPHAN $slug — có PROJECT.md nhưng chưa có dòng trong INDEX.md (chạy --write)"
|
|
149
|
+
issues=$((issues + 1))
|
|
150
|
+
fi
|
|
151
|
+
done
|
|
152
|
+
|
|
153
|
+
while IFS= read -r indexed_slug; do
|
|
154
|
+
[[ -z "$indexed_slug" ]] && continue
|
|
155
|
+
if [[ ! -f "$PROJECTS_DIR/$indexed_slug/PROJECT.md" ]]; then
|
|
156
|
+
echo "ORPHAN $indexed_slug — có dòng trong INDEX.md nhưng không có PROJECT.md"
|
|
157
|
+
issues=$((issues + 1))
|
|
158
|
+
fi
|
|
159
|
+
done < <(awk -F'|' '/^\| [a-z0-9][a-z0-9-]* \|/ { gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2 }' "$INDEX_FILE")
|
|
160
|
+
|
|
161
|
+
if (( issues == 0 )); then
|
|
162
|
+
echo "OK Project Layer khớp — không có DRIFT / STALE / ORPHAN"
|
|
163
|
+
exit 0
|
|
164
|
+
fi
|
|
165
|
+
echo "---"
|
|
166
|
+
echo "$issues tín hiệu cần xử lý."
|
|
167
|
+
exit 1
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-memory
|
|
3
|
+
description: Luật ghi trí nhớ dùng chung cho mọi vai trong repo alp-code — khi nào ghi, ghi vào đâu, định dạng gì. Kích hoạt khi biết được fact mới về principal/project/thế giới, khi kết phiên, khi phân vân giữa shared/ và private/, hoặc khi cần tạo file trong memory/.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# agent-memory — ghi cái gì, vào đâu
|
|
7
|
+
|
|
8
|
+
Trí nhớ là **thói quen**, không phải tính năng. Agent mất hết giữa các phiên trừ những gì
|
|
9
|
+
được ghi lại. Nhưng ghi bừa còn tệ hơn không ghi: fact sai, fact trùng, fact lệch nhau
|
|
10
|
+
giữa các vai đều tốn tiền hơn là quên.
|
|
11
|
+
|
|
12
|
+
Quyền ghi của bạn nằm trong immutable execution policy → `memory.write`. Bảng dưới nói
|
|
13
|
+
*nên* ghi vào đâu; compiled policy nói *được* ghi vào đâu. Không có quyền → **báo cho vai
|
|
14
|
+
có quyền**, đừng ghi chỗ khác cho tiện.
|
|
15
|
+
|
|
16
|
+
## Bảng định tuyến
|
|
17
|
+
|
|
18
|
+
| Tình huống | Đích | Ai thấy |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| Sở thích / ràng buộc lặp lại của principal | `memory/shared/people/principal.md` | mọi vai |
|
|
21
|
+
| Quyết định chung, không thuộc project nào | `memory/shared/decisions/YYMMDD-slug.md` | mọi vai |
|
|
22
|
+
| Người / tổ chức | `memory/shared/people/<ten>.md` | mọi vai |
|
|
23
|
+
| Link / dashboard / ticket / tài liệu ngoài | `memory/shared/reference/<slug>.md` | mọi vai |
|
|
24
|
+
| Bối cảnh một project (mục tiêu, việc kế, cạm bẫy) | `memory/projects/<slug>/PROJECT.md` (L1) | mọi vai |
|
|
25
|
+
| Quyết định của một project | `memory/projects/<slug>/decisions/YYMMDD-slug.md` (L2) | mọi vai |
|
|
26
|
+
| Diễn biến một phiên | `memory/projects/<slug>/log/YYYY-MM.md` (L2) | mọi vai |
|
|
27
|
+
| Tài liệu tra cứu cho một project | `memory/projects/<slug>/refs/<slug>.md` (L2) | mọi vai |
|
|
28
|
+
| Nháp, giả thuyết **chưa kiểm chứng** | `memory/private/<role>/` | chỉ bạn |
|
|
29
|
+
| Bài học về **chính agent này** | `memory/private/<role>/journal/YYYY-MM.md` | chỉ bạn |
|
|
30
|
+
|
|
31
|
+
Giao thức Project Layer 3 tầng: `memory/projects/PROTOCOL.md`.
|
|
32
|
+
|
|
33
|
+
## Bảy luật cứng
|
|
34
|
+
|
|
35
|
+
1. **Fact về principal / project / thế giới → LUÔN `shared/` hoặc `projects/`.
|
|
36
|
+
KHÔNG BAO GIỜ `private/`.**
|
|
37
|
+
`private/` chỉ chứa nháp và self-log. Vi phạm = fact bị nhân bản giữa các vai rồi
|
|
38
|
+
lệch nhau, và không vai nào biết bản nào đúng. Đây là lỗi tốn kém nhất của hệ này.
|
|
39
|
+
|
|
40
|
+
*Kiểm nhanh:* "vai khác mà biết điều này thì có làm việc tốt hơn không?" → có = `shared/`.
|
|
41
|
+
|
|
42
|
+
2. **Một fact = một file.** Đừng dồn. Ngày luôn tuyệt đối (`2026-08-21`), không "tuần sau".
|
|
43
|
+
Trùng thì gộp, sai thì **xoá** — trí nhớ sai nguy hiểm hơn không có trí nhớ.
|
|
44
|
+
|
|
45
|
+
3. **Không ghi thứ repo đã ghi** — cấu trúc code, lịch sử git, compiled agent definitions.
|
|
46
|
+
Nếu `grep` ra được trong 5 giây thì đừng chép vào `memory/`.
|
|
47
|
+
|
|
48
|
+
4. **File mới trong `memory/shared/` → thêm một dòng vào `memory/INDEX.md`.**
|
|
49
|
+
Định dạng: `- [Tiêu đề](shared/<thư-mục>/<file>.md) — móc câu một dòng`.
|
|
50
|
+
File không có dòng index = file không tồn tại với các phiên sau.
|
|
51
|
+
|
|
52
|
+
5. **Sửa L1 (`PROJECT.md`) → đóng dấu `updated:` ngay.** Quên là sinh `DRIFT`, doctor sẽ kêu.
|
|
53
|
+
|
|
54
|
+
6. **Không sửa tay bảng trong `projects/INDEX.md`.** Sửa frontmatter L1 rồi chạy
|
|
55
|
+
`scripts/sync-project-index.sh --write`.
|
|
56
|
+
|
|
57
|
+
7. **Journal:** một file mỗi tháng, mỗi entry ≤5 dòng, >200 dòng thì nén lại.
|
|
58
|
+
Journal **không** nằm trong boot set — nó là chỗ nghĩ, không phải chỗ tra.
|
|
59
|
+
|
|
60
|
+
## Frontmatter chuẩn
|
|
61
|
+
|
|
62
|
+
```yaml
|
|
63
|
+
---
|
|
64
|
+
id: <slug ổn định, kebab-case>
|
|
65
|
+
type: decision | person | reference | log | project
|
|
66
|
+
layer: L1 | L2 | L3
|
|
67
|
+
visibility: private | team
|
|
68
|
+
owner: <role>
|
|
69
|
+
created: YYYY-MM-DD
|
|
70
|
+
updated: YYYY-MM-DD
|
|
71
|
+
tags: []
|
|
72
|
+
source: <link | phiên>
|
|
73
|
+
---
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Thân file:
|
|
77
|
+
|
|
78
|
+
```markdown
|
|
79
|
+
# <Tiêu đề>
|
|
80
|
+
|
|
81
|
+
<Một fact chính. Cụ thể, kiểm chứng được.>
|
|
82
|
+
|
|
83
|
+
**Vì sao quan trọng:** <một dòng>
|
|
84
|
+
**Áp dụng thế nào:** <một dòng>
|
|
85
|
+
|
|
86
|
+
Liên quan: [[slug-khac]]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`[[slug]]` trỏ tới file chưa tồn tại là **bình thường** — đó là ghi chú cho việc cần viết
|
|
90
|
+
sau, không phải lỗi.
|
|
91
|
+
|
|
92
|
+
## Khi nào ghi
|
|
93
|
+
|
|
94
|
+
**Ghi ngay** khi: principal nói ra một ràng buộc sẽ còn đúng tuần sau · một quyết định
|
|
95
|
+
kiến trúc được chốt · phát hiện một hành vi hệ thống mà lần sau sẽ lại phải tra · một
|
|
96
|
+
project đổi trạng thái.
|
|
97
|
+
|
|
98
|
+
**Đừng ghi** khi: chỉ đúng trong phiên này · repo/git đã ghi · bạn chưa kiểm chứng
|
|
99
|
+
(→ `private/` nếu vẫn muốn giữ) · trùng file đã có (→ sửa file đó).
|
|
100
|
+
|
|
101
|
+
## Kết phiên
|
|
102
|
+
|
|
103
|
+
1. Diễn biến → `memory/projects/<slug>/log/YYYY-MM.md`
|
|
104
|
+
2. L1 `PROJECT.md` cập nhật + đóng dấu `updated:`
|
|
105
|
+
3. Fact mới theo bảng trên; file mới trong `shared/` → thêm dòng vào `memory/INDEX.md`
|
|
106
|
+
4. `scripts/sync-project-index.sh --write`
|
|
107
|
+
|
|
108
|
+
Hook `Stop` nhắc nếu quên. Nó chỉ **nhắc** — không ghi thay bạn. Trích fact là việc ngữ
|
|
109
|
+
nghĩa, hook không gọi LLM.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: alp-debug
|
|
3
|
+
description: Điều tra sự cố có hệ thống — truy nguyên nhân gốc trước khi bàn cách sửa, phân tích log và CI/CD, chẩn đoán hiệu năng, kiểm chứng bằng bằng chứng. Kích hoạt khi bế tắc với một bug, test fail, hành vi lạ, pipeline hỏng, hoặc hệ chậm bất thường.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# alp-debug — điều tra trước, kết luận sau
|
|
7
|
+
|
|
8
|
+
Dùng khi **đã có giả thuyết và bằng chứng mà vẫn bế tắc** — nên đừng bắt đầu lại từ đầu,
|
|
9
|
+
hãy hỏi đã thử những gì rồi.
|
|
10
|
+
|
|
11
|
+
## Luật cứng
|
|
12
|
+
|
|
13
|
+
**KHÔNG KẾT LUẬN KHI CHƯA TRUY RA NGUYÊN NHÂN GỐC.**
|
|
14
|
+
|
|
15
|
+
Đoán rồi sửa là cách tạo bug mới trong lúc giấu bug cũ. Và nếu loadout không cấp `Edit` thì luật
|
|
16
|
+
này còn dễ giữ hơn: bạn **không sửa được gì**, chỉ giao nguyên nhân gốc cho người sửa.
|
|
17
|
+
|
|
18
|
+
Hệ quả: sản phẩm của bạn là **chuỗi bằng chứng**, không phải bản vá. Một chuỗi bằng chứng
|
|
19
|
+
tốt phải để người đọc tự đi lại được và tới cùng kết luận.
|
|
20
|
+
|
|
21
|
+
## Chọn kỹ thuật
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Bug trong code → systematic-debugging.md (4 pha, không nhảy pha)
|
|
25
|
+
sâu trong stack → root-cause-tracing.md (lần ngược tới chỗ phát sinh)
|
|
26
|
+
đã ra nguyên nhân → defense-in-depth.md (khuyến nghị chốt chặn từng lớp)
|
|
27
|
+
sắp kết luận → verification.md (bằng chứng mới, không dùng lại cũ)
|
|
28
|
+
|
|
29
|
+
Sự cố mức hệ → investigation-methodology.md (5 bước)
|
|
30
|
+
CI/CD hỏng → log-and-ci-analysis.md (`gh` CLI)
|
|
31
|
+
chậm bất thường → performance-diagnostics.md
|
|
32
|
+
cần viết báo cáo → reporting-standards.md
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
| # | Kỹ thuật | Đọc khi |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| 1 | **Gỡ lỗi có hệ thống** | mọi bug cần điều tra — 4 pha: truy nguyên nhân → phân tích mẫu → thử giả thuyết → kết luận. Xong pha này mới sang pha kia |
|
|
38
|
+
| 2 | **Lần ngược nguyên nhân** | lỗi nổ sâu trong call stack, chưa rõ dữ liệu hỏng sinh ra từ đâu. Có `scripts/find-polluter.sh` để bisect test bị nhiễm |
|
|
39
|
+
| 3 | **Phòng thủ nhiều lớp** | đã ra nguyên nhân, cần chỉ ra nên chốt ở những lớp nào: chặn ở cửa vào → nghiệp vụ → guard môi trường → chỗ đặt log |
|
|
40
|
+
| 4 | **Kiểm chứng** | sắp nói "đã tìm ra" hoặc "đã hết" |
|
|
41
|
+
| 5 | **Phương pháp điều tra** | sự cố nhiều thành phần: đánh giá ban đầu → thu thập dữ liệu → phân tích → xác định gốc → phương án |
|
|
42
|
+
| 6 | **Phân tích log và CI/CD** | pipeline hỏng, lỗi phía server, sự cố deploy |
|
|
43
|
+
| 7 | **Chẩn đoán hiệu năng** | truy vấn chậm, độ trễ cao, cạn tài nguyên |
|
|
44
|
+
| 8 | **Chuẩn báo cáo** | cần xuất báo cáo chẩn đoán có cấu trúc |
|
|
45
|
+
|
|
46
|
+
## Công cụ có sẵn
|
|
47
|
+
|
|
48
|
+
- **Database:** `psql` cho PostgreSQL.
|
|
49
|
+
- **CI/CD:** `gh` CLI cho log GitHub Actions.
|
|
50
|
+
- **Bế tắc thật sự:** skill `problem-solving` — đổi kiểu nghĩ, không nghĩ chăm hơn.
|
|
51
|
+
|
|
52
|
+
Cần thứ bạn không lấy được (tìm code diện rộng, tra tài liệu ngoài) → **nói rõ cần gì và
|
|
53
|
+
báo lại**. Loadout không cho giao việc thì đừng tự đi tìm đường vòng.
|
|
54
|
+
|
|
55
|
+
## Cờ đỏ — dừng lại nếu bắt gặp mình đang nghĩ
|
|
56
|
+
|
|
57
|
+
- "sửa tạm đã, điều tra sau"
|
|
58
|
+
- "cứ thử đổi X xem sao"
|
|
59
|
+
- "chắc là do X, sửa chỗ đó"
|
|
60
|
+
- "chắc hết rồi" · "nhìn có vẻ ổn"
|
|
61
|
+
- "test xanh rồi, xong"
|
|
62
|
+
|
|
63
|
+
Tất cả đều nghĩa là: quay lại quy trình. Và còn một cờ đỏ nữa — **"để tôi sửa luôn"**:
|
|
64
|
+
nếu loadout không cấp `Edit` thì viết đề xuất ra, đừng tìm đường vòng qua `Bash`
|
|
65
|
+
(HOUSE-RULES §1.9).
|
|
66
|
+
|
|
67
|
+
## Bàn giao
|
|
68
|
+
|
|
69
|
+
Báo cáo gồm đúng bốn phần:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
## Điều tra: <triệu chứng>
|
|
73
|
+
|
|
74
|
+
### Nguyên nhân gốc
|
|
75
|
+
<một câu. Chưa ra thì ghi "chưa xác định được" — không thay bằng nguyên nhân gần nhất>
|
|
76
|
+
|
|
77
|
+
### Chuỗi bằng chứng
|
|
78
|
+
1. <quan sát> — `path:line` hoặc output lệnh
|
|
79
|
+
2. <suy ra> — vì sao bước 1 dẫn tới đây
|
|
80
|
+
...
|
|
81
|
+
|
|
82
|
+
### Đã loại trừ
|
|
83
|
+
<giả thuyết nào đã thử và bị bác, bằng gì — để người đọc không đi lại đường cũ>
|
|
84
|
+
|
|
85
|
+
### Đề xuất sửa
|
|
86
|
+
<sửa ở đâu, vì sao ở đó chứ không phải chỗ triệu chứng nổ ra>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Nháp và giả thuyết chưa kiểm chứng → kho riêng của bạn trong `memory/private/`. Chỉ kết
|
|
90
|
+
luận đã có bằng chứng mới đi vào báo cáo.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Phòng thủ nhiều lớp
|
|
2
|
+
|
|
3
|
+
Chốt chặn ở **mọi tầng** dữ liệu đi qua, để bug trở thành không thể xảy ra.
|
|
4
|
+
|
|
5
|
+
Nếu loadout không cấp `Edit` thì bạn không tự thêm được chốt. File này dùng để **viết
|
|
6
|
+
khuyến nghị**: chỉ ra nên chặn ở đâu, mỗi chỗ chặn cái gì, và vì sao một chỗ là không đủ.
|
|
7
|
+
|
|
8
|
+
## Nguyên lý
|
|
9
|
+
|
|
10
|
+
Sửa một bug do dữ liệu sai, thêm một chỗ kiểm là thấy đủ. Nhưng một chỗ kiểm bị vượt qua
|
|
11
|
+
bởi: đường code khác, refactor sau này, hoặc mock trong test.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
Một chỗ kiểm → "đã sửa bug"
|
|
15
|
+
Nhiều tầng chốt → "bug không thể xảy ra"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Mỗi tầng bắt được loại khác nhau — đó là lý do cần nhiều tầng, không phải vì thừa.
|
|
19
|
+
|
|
20
|
+
## Bốn tầng
|
|
21
|
+
|
|
22
|
+
### Tầng 1 — chặn ở cửa vào
|
|
23
|
+
|
|
24
|
+
Từ chối input sai rõ ràng, ngay ở ranh giới API.
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
function createProject(name, workingDirectory) {
|
|
28
|
+
if (!workingDirectory || workingDirectory.trim() === '')
|
|
29
|
+
throw new Error('workingDirectory không được rỗng');
|
|
30
|
+
if (!existsSync(workingDirectory))
|
|
31
|
+
throw new Error(`workingDirectory không tồn tại: ${workingDirectory}`);
|
|
32
|
+
if (!statSync(workingDirectory).isDirectory())
|
|
33
|
+
throw new Error(`workingDirectory không phải thư mục: ${workingDirectory}`);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Tầng 2 — chặn ở nghiệp vụ
|
|
38
|
+
|
|
39
|
+
Dữ liệu có hợp lý **với thao tác này** không.
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
function initializeWorkspace(projectDir, sessionId) {
|
|
43
|
+
if (!projectDir) throw new Error('initializeWorkspace cần projectDir');
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Tầng 3 — guard môi trường
|
|
48
|
+
|
|
49
|
+
Chặn thao tác nguy hiểm trong ngữ cảnh cụ thể.
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
async function gitInit(directory) {
|
|
53
|
+
if (process.env.NODE_ENV === 'test') {
|
|
54
|
+
const normalized = normalize(resolve(directory));
|
|
55
|
+
const tmp = normalize(resolve(tmpdir()));
|
|
56
|
+
if (!normalized.startsWith(tmp))
|
|
57
|
+
throw new Error(`Từ chối git init ngoài thư mục tạm khi chạy test: ${directory}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Tầng 4 — chỗ đặt log
|
|
63
|
+
|
|
64
|
+
Bắt bối cảnh để lần sau còn điều tra được.
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
logger.debug('sắp git init', { directory, cwd: process.cwd(), stack: new Error().stack });
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Cách áp dụng
|
|
71
|
+
|
|
72
|
+
1. **Lần dòng dữ liệu** — giá trị sai sinh ra ở đâu, được dùng ở đâu.
|
|
73
|
+
2. **Liệt kê mọi trạm** dữ liệu đi qua.
|
|
74
|
+
3. **Đề xuất chốt ở từng tầng** — cửa vào, nghiệp vụ, môi trường, log.
|
|
75
|
+
4. **Đề xuất cách kiểm từng tầng** — thử vượt tầng 1, xác nhận tầng 2 bắt được.
|
|
76
|
+
|
|
77
|
+
Bước 4 hay bị bỏ. Chốt chưa từng được kiểm là chốt chưa biết có hoạt động không.
|
|
78
|
+
|
|
79
|
+
## Ví dụ thật
|
|
80
|
+
|
|
81
|
+
**Bug:** `projectDir` rỗng làm `git init` chạy trong thư mục source.
|
|
82
|
+
|
|
83
|
+
**Dòng dữ liệu:** test setup → chuỗi rỗng → `Project.create(name, '')` →
|
|
84
|
+
`WorkspaceManager.createWorkspace('')` → `git init` chạy ở `process.cwd()`.
|
|
85
|
+
|
|
86
|
+
| Tầng | Chốt |
|
|
87
|
+
|---|---|
|
|
88
|
+
| 1 | `Project.create()` kiểm không rỗng / tồn tại / ghi được |
|
|
89
|
+
| 2 | `WorkspaceManager` từ chối `projectDir` rỗng |
|
|
90
|
+
| 3 | `WorktreeManager` từ chối `git init` ngoài thư mục tạm khi chạy test |
|
|
91
|
+
| 4 | log stack trace trước `git init` |
|
|
92
|
+
|
|
93
|
+
**Kết quả:** 1847 test pass, bug không tái hiện được nữa.
|
|
94
|
+
|
|
95
|
+
**Cả bốn tầng đều cần.** Trong lúc kiểm, mỗi tầng bắt được thứ tầng khác bỏ lọt: đường code
|
|
96
|
+
khác vượt qua tầng 1 · mock vượt qua tầng 2 · ca biên trên nền tảng khác cần tầng 3 · log
|
|
97
|
+
tầng 4 lộ ra chỗ dùng sai về mặt cấu trúc.
|
|
98
|
+
|
|
99
|
+
## Với alp-code
|
|
100
|
+
|
|
101
|
+
Repo này chọn **fail đóng** làm mặc định — hỏng thì hỏng to và thấy ngay. Vài chỗ đã theo
|
|
102
|
+
đúng mẫu bốn tầng, dùng làm ví dụ khi viết khuyến nghị:
|
|
103
|
+
|
|
104
|
+
| Tầng | Trong alp-code |
|
|
105
|
+
|---|---|
|
|
106
|
+
| 1 | `L.validate()` — loadout sai thì `npm run build` ném lỗi, không sinh settings hỏng |
|
|
107
|
+
| 2 | `denyRules()` — deny của mọi vai anh em, enumerate từng cái |
|
|
108
|
+
| 3 | `hooks/acl-guard.cjs` — chặn lúc chạy, kể cả khi settings hỏng |
|
|
109
|
+
| 4 | `doctor.cjs` — tín hiệu `ACL-DRIFT`, `SKILL-DRIFT` khi hai bên lệch nhau |
|
|
110
|
+
|
|
111
|
+
compiled policy invariants nói thẳng giới hạn: `acl-guard` là **guardrail, không phải sandbox**. Nhiều tầng
|
|
112
|
+
chặn nhầm lẫn và vượt quyền tình cờ — không chặn được kẻ cố tình lách. Khuyến nghị phòng
|
|
113
|
+
thủ nhiều lớp thì đừng hứa nhiều hơn mức nó làm được.
|
|
114
|
+
|
|
115
|
+
## Chốt
|
|
116
|
+
|
|
117
|
+
Đừng dừng ở một chỗ kiểm. Và khi viết khuyến nghị, nói rõ **mỗi tầng bắt được gì
|
|
118
|
+
mà tầng khác bỏ lọt** — không có phần đó thì nó chỉ giống như bảo đi thêm việc.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Phương pháp điều tra mức hệ
|
|
2
|
+
|
|
3
|
+
Năm bước cho sự cố nhiều thành phần — khác với gỡ một bug trong code, ở đây bạn phải dựng
|
|
4
|
+
lại **chuyện gì đã xảy ra** trước khi bàn tới sửa gì.
|
|
5
|
+
|
|
6
|
+
## Khi nào dùng
|
|
7
|
+
|
|
8
|
+
- Server trả 500 hoặc phản hồi lạ.
|
|
9
|
+
- Hành vi hệ đổi mà không thấy code đổi.
|
|
10
|
+
- Sự cố trải qua nhiều dịch vụ / database / hạ tầng.
|
|
11
|
+
- Cần biết "đã xảy ra chuyện gì" trước khi bàn cách sửa.
|
|
12
|
+
|
|
13
|
+
## Bước 1 — Đánh giá ban đầu
|
|
14
|
+
|
|
15
|
+
Nắm phạm vi và mức ảnh hưởng **trước khi** lao vào chi tiết.
|
|
16
|
+
|
|
17
|
+
1. **Gom triệu chứng** — thông báo lỗi, endpoint bị ảnh hưởng, mô tả của principal.
|
|
18
|
+
2. **Xác định thành phần liên quan** — dịch vụ nào, database nào, hàng đợi nào.
|
|
19
|
+
3. **Khoanh mốc thời gian** — bắt đầu từ khi nào? Trùng với deploy hay thay đổi nào?
|
|
20
|
+
4. **Đánh giá mức nghiêm trọng** — ảnh hưởng ai, dữ liệu có rủi ro không.
|
|
21
|
+
5. **Xem gì vừa đổi.**
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
gh run list --limit 10
|
|
25
|
+
git log --oneline -20 --since="2 days ago"
|
|
26
|
+
git diff HEAD~5 -- '*.env*' '*.config*' '*.yml' '*.yaml' '*.json'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Bước 5 giải quyết một tỷ lệ lớn sự cố ngay tại chỗ. Làm trước khi làm gì phức tạp hơn.
|
|
30
|
+
|
|
31
|
+
## Bước 2 — Thu thập dữ liệu
|
|
32
|
+
|
|
33
|
+
Gom bằng chứng **có hệ thống**, trước khi phân tích. Vừa gom vừa suy diễn dẫn tới việc chỉ
|
|
34
|
+
gom thứ khớp với giả thuyết đầu tiên.
|
|
35
|
+
|
|
36
|
+
1. **Log ứng dụng / server** — lọc theo mốc thời gian và thành phần.
|
|
37
|
+
2. **Log CI/CD** — xem `log-and-ci-analysis.md`.
|
|
38
|
+
3. **Trạng thái database** — truy vấn bảng liên quan, kiểm migration gần đây.
|
|
39
|
+
4. **Số đo hệ thống** — CPU, bộ nhớ, đĩa, mạng.
|
|
40
|
+
5. **Phụ thuộc bên ngoài** — API bên thứ ba, DNS, CDN.
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
gh run list --workflow=<workflow> --limit 5
|
|
44
|
+
gh run view <run-id> --log-failed
|
|
45
|
+
gh run view <run-id> --log > /tmp/ci-logs.txt
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Cần hiểu codebase lạ:** báo lại để nhờ một lượt truy xuất code hoặc tra tài liệu ngoài.
|
|
49
|
+
Loadout không cho giao việc thì đừng tự đi làm phần đó.
|
|
50
|
+
|
|
51
|
+
## Bước 3 — Phân tích
|
|
52
|
+
|
|
53
|
+
Đối chiếu chéo giữa các nguồn.
|
|
54
|
+
|
|
55
|
+
1. **Dựng lại mốc thời gian** — xếp sự kiện theo thứ tự, gộp mọi nguồn log.
|
|
56
|
+
2. **Nhận mẫu** — lỗi lặp lại, mẫu theo thời điểm, nhóm người dùng bị ảnh hưởng.
|
|
57
|
+
3. **Lần đường thực thi** — request đi qua những thành phần nào.
|
|
58
|
+
4. **Phân tích database** — hiệu năng truy vấn, quan hệ bảng, toàn vẹn dữ liệu.
|
|
59
|
+
5. **Vẽ phụ thuộc** — thành phần nào phụ thuộc thành phần đang hỏng.
|
|
60
|
+
|
|
61
|
+
Bốn câu hỏi then chốt:
|
|
62
|
+
|
|
63
|
+
- Có trùng với một lần deploy hay một khung giờ cụ thể không?
|
|
64
|
+
- Xảy ra lúc có lúc không, hay luôn luôn?
|
|
65
|
+
- Ảnh hưởng mọi người dùng hay một nhóm?
|
|
66
|
+
- Dịch vụ phía trước / phía sau có lỗi liên quan không?
|
|
67
|
+
|
|
68
|
+
## Bước 4 — Xác định nguyên nhân gốc
|
|
69
|
+
|
|
70
|
+
Loại trừ có hệ thống, bằng bằng chứng.
|
|
71
|
+
|
|
72
|
+
1. **Liệt kê giả thuyết**, xếp theo độ mạnh của bằng chứng.
|
|
73
|
+
2. **Thử từng cái** — thí nghiệm nhỏ nhất đủ để xác nhận hoặc loại bỏ.
|
|
74
|
+
3. **Xác nhận bằng bằng chứng** — log, số đo, bước tái hiện.
|
|
75
|
+
4. **Xét yếu tố môi trường** — race condition, giới hạn tài nguyên, config trôi lệch.
|
|
76
|
+
5. **Ghi lại cả chuỗi** — từ chỗ kích hoạt tới triệu chứng.
|
|
77
|
+
|
|
78
|
+
**Tránh:** sửa theo giả thuyết đầu tiên mà chưa thử các giả thuyết khác. Nhiều nguyên nhân
|
|
79
|
+
đều hợp lý thì phải loại trừ, không phải chọn cái tiện nhất.
|
|
80
|
+
|
|
81
|
+
Ghi rõ giả thuyết nào **đã bị bác và bằng gì** — không có phần đó, người đọc sẽ đi lại đúng con
|
|
82
|
+
đường bạn vừa đi.
|
|
83
|
+
|
|
84
|
+
## Bước 5 — Đề xuất phương án
|
|
85
|
+
|
|
86
|
+
Bạn đề xuất, người khác thực hiện. Tách rõ ba loại:
|
|
87
|
+
|
|
88
|
+
| Loại | Nội dung |
|
|
89
|
+
|---|---|
|
|
90
|
+
| **Ngay** | thay đổi nhỏ nhất để khôi phục — hotfix, rollback, đổi config |
|
|
91
|
+
| **Gốc** | xử lý dứt điểm nguyên nhân gốc |
|
|
92
|
+
| **Phòng ngừa** | giám sát, cảnh báo, chốt chặn để lần sau phát hiện sớm |
|
|
93
|
+
|
|
94
|
+
Thứ tự ưu tiên: **ảnh hưởng × mức khẩn**. Khôi phục trước, sửa gốc sau, phòng ngừa sau nữa.
|
|
95
|
+
|
|
96
|
+
Đánh dấu rõ phương án nào là thao tác **khó đảo ngược** (rollback production, migration,
|
|
97
|
+
xoá dữ liệu) — phải xin principal duyệt trước khi chạy (HOUSE-RULES §1.2).
|
|
98
|
+
|
|
99
|
+
## Khi thu hẹp được về code cụ thể
|
|
100
|
+
|
|
101
|
+
| Chuyển sang | Khi |
|
|
102
|
+
|---|---|
|
|
103
|
+
| `systematic-debugging.md` | đã khoanh về một vùng code |
|
|
104
|
+
| `root-cause-tracing.md` | lỗi nổ sâu trong call stack |
|
|
105
|
+
| `defense-in-depth.md` | đã ra nguyên nhân, cần khuyến nghị chốt chặn |
|
|
106
|
+
| `verification.md` | trước khi phát biểu kết luận |
|