@donghyeonlee/jjamppong-harness 0.1.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/AGENTS.md +77 -0
- package/CONTEXT.md +51 -0
- package/README.md +85 -0
- package/bin/jjamppong.js +123 -0
- package/handoff.md +13 -0
- package/harness/contracts/capability-catalog.yaml +128 -0
- package/harness/contracts/gate-contract-matrix.yaml +188 -0
- package/harness/contracts/installer-contract.yaml +79 -0
- package/harness/contracts/ledger-event.schema.yaml +79 -0
- package/harness/contracts/path-policy.schema.yaml +51 -0
- package/harness/contracts/permission-decision.schema.yaml +95 -0
- package/harness/contracts/task.schema.yaml +88 -0
- package/harness/docs/adr/.gitkeep +1 -0
- package/harness/docs/adr/2026-06-02-jjamppong-planning-gate.md +33 -0
- package/harness/docs/agents/domain.md +14 -0
- package/harness/docs/agents/issue-tracker.md +9 -0
- package/harness/docs/agents/matt-pocock-skills.md +60 -0
- package/harness/docs/agents/triage-labels.md +11 -0
- package/harness/docs/solutions/.gitkeep +1 -0
- package/harness/docs/tasks/active/.gitkeep +1 -0
- package/harness/docs/tasks/archive/.gitkeep +1 -0
- package/harness/docs/tasks/archive/index.md +5 -0
- package/harness/docs/tasks/index.md +13 -0
- package/harness/doctor/doctor.js +114 -0
- package/harness/installer/install.js +235 -0
- package/harness/lifecycle/lifecycle.js +133 -0
- package/harness/permission/permission-decision.js +377 -0
- package/harness/release/CHECKSUMS.sha256 +84 -0
- package/harness/release/RELEASE-NOTES.md +33 -0
- package/harness/release/SOURCE-MANIFEST.md +31 -0
- package/harness/rules/module-types.md +98 -0
- package/harness/rules/rules.md +220 -0
- package/harness/rules/workflow.md +252 -0
- package/harness/state/compound.md +7 -0
- package/harness/state/intake.md +11 -0
- package/harness/state/module-structure.md +13 -0
- package/harness/state/planning.md +21 -0
- package/harness/templates/module/module-state.md +13 -0
- package/harness/templates/task/archive-summary.md +19 -0
- package/harness/templates/task/events.jsonl.template +1 -0
- package/harness/templates/task/gate-ledger.md +21 -0
- package/harness/templates/task/implementation-approval.md +11 -0
- package/harness/templates/task/planning/00-current-planning-context.md +3 -0
- package/harness/templates/task/planning/01-grill-summary.md +3 -0
- package/harness/templates/task/planning/02-research-summary.md +3 -0
- package/harness/templates/task/planning/02b-compound-lookup.md +3 -0
- package/harness/templates/task/planning/02c-architecture-orientation.md +3 -0
- package/harness/templates/task/planning/03-prd.md +3 -0
- package/harness/templates/task/planning/04-issues.md +3 -0
- package/harness/templates/task/planning/05-module-structure.md +3 -0
- package/harness/templates/task/planning/06-writing-plan.md +3 -0
- package/harness/templates/task/planning/07-plan-review.md +3 -0
- package/harness/templates/task/planning-pack.md +23 -0
- package/harness/templates/task/task.yaml +10 -0
- package/harness/templates/task/verification.md +12 -0
- package/harness/verify/verify.js +271 -0
- package/module-template/MODULE.md +25 -0
- package/module-template/README.md +9 -0
- package/modules/.gitkeep +0 -0
- package/package.json +40 -0
- package/proposals/README.md +16 -0
- package/scripts/install-jjamppong-harness.ps1 +62 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
This repository uses Jjamppong Harness, an AI work safety harness.
|
|
6
|
+
|
|
7
|
+
The directory containing this file is the harness root.
|
|
8
|
+
|
|
9
|
+
## Required Reads
|
|
10
|
+
|
|
11
|
+
For any substantive task, read these first:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
harness/contracts/gate-contract-matrix.yaml
|
|
15
|
+
harness/contracts/capability-catalog.yaml
|
|
16
|
+
harness/contracts/task.schema.yaml
|
|
17
|
+
harness/contracts/permission-decision.schema.yaml
|
|
18
|
+
harness/rules/workflow.md
|
|
19
|
+
harness/rules/rules.md
|
|
20
|
+
harness/state/planning.md
|
|
21
|
+
active task events.jsonl, if one exists
|
|
22
|
+
active task task.yaml, if one exists
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
If required files are missing, stale, or contradictory, stop and run verify/doctor.
|
|
26
|
+
|
|
27
|
+
## Permission Source Of Truth
|
|
28
|
+
|
|
29
|
+
Permission is granted only by:
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
harness/contracts/*.yaml
|
|
33
|
+
active task events.jsonl
|
|
34
|
+
PermissionDecision result
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`gate-ledger.md` is a human-readable projection.
|
|
38
|
+
|
|
39
|
+
`task.yaml` is a derived cache.
|
|
40
|
+
|
|
41
|
+
This file may restrict behavior further, but it must not grant permission beyond contracts and canonical events.
|
|
42
|
+
|
|
43
|
+
## Hard Rules
|
|
44
|
+
|
|
45
|
+
- Use `vowline` for substantive work, including subagents.
|
|
46
|
+
- Do not start with README or AGENTS rewrites before contracts/tests/verify are in place.
|
|
47
|
+
- Install requests stop after install and verify. Do not continue into planning.
|
|
48
|
+
- Product planning starts with `grill` before project file reads.
|
|
49
|
+
- `research` comes after `grill`; web research is not live target access.
|
|
50
|
+
- `plan_review completed` never unlocks implementation.
|
|
51
|
+
- `module_structure` never creates folders.
|
|
52
|
+
- `folder_skeleton` never creates code, tests, fixtures, runtime config, package files, live access, commit, or push.
|
|
53
|
+
- Short approvals approve only the immediately preceding explicit gate question and named scope.
|
|
54
|
+
- Missing or ambiguous capabilities are denied.
|
|
55
|
+
- Product code belongs under `modules/` unless exact `file.write.outside_modules` approval exists.
|
|
56
|
+
- Secrets are deny-by-default.
|
|
57
|
+
- Package install, live target access, commit, and push each need separate explicit capability approval.
|
|
58
|
+
- Harness-core changes in product tasks must become proposals, not live edits.
|
|
59
|
+
- Doctor/update/repair are proposal-only by default for modified managed files.
|
|
60
|
+
- Root `handoff.md` changes only when the user asks for handoff.
|
|
61
|
+
|
|
62
|
+
## User Language
|
|
63
|
+
|
|
64
|
+
Ask user-facing gate questions in the user's language.
|
|
65
|
+
|
|
66
|
+
If the user writes Korean, ask in Korean and explain technical labels briefly in plain language.
|
|
67
|
+
|
|
68
|
+
- Human-facing artifacts use the user's language.
|
|
69
|
+
- Machine-readable artifacts keep stable schema keys.
|
|
70
|
+
- Static templates may use Korean starter copy; agents write live human-facing artifacts in the current user's language when presenting or updating them.
|
|
71
|
+
- This phase does not add lifecycle-level localization.
|
|
72
|
+
|
|
73
|
+
## Git
|
|
74
|
+
|
|
75
|
+
Do not run `git commit`, `git push`, PR, merge, tag, or release commands unless the user explicitly approves that exact action in the current chat.
|
|
76
|
+
|
|
77
|
+
Before asking for git approval, show changed files and the exact operation.
|
package/CONTEXT.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# 짬뽕하네스 Context
|
|
2
|
+
|
|
3
|
+
## Language
|
|
4
|
+
|
|
5
|
+
**짬뽕하네스**:
|
|
6
|
+
A private agent workflow harness that combines Matt Pocock planning skills, Superpowers execution planning, gstack review lenses, Compound Engineering learning, and vowline discipline.
|
|
7
|
+
Avoid: calling the whole harness Matt Planning Harness or OuroSuper Harness.
|
|
8
|
+
|
|
9
|
+
**Planning gate**:
|
|
10
|
+
The mandatory pre-implementation sequence that every task must pass before execution.
|
|
11
|
+
|
|
12
|
+
**Task artifact**:
|
|
13
|
+
A file created under `harness/docs/tasks/active/<slug>/` while planning, reviewing, implementing, or verifying a task.
|
|
14
|
+
|
|
15
|
+
**Event log**:
|
|
16
|
+
The append-only canonical task record at `harness/docs/tasks/active/<slug>/events.jsonl`.
|
|
17
|
+
This is the source of truth for gate questions, user answers, approval decisions, permission decisions, verification results, and archive events.
|
|
18
|
+
|
|
19
|
+
**Gate ledger**:
|
|
20
|
+
The human-readable projection at `harness/docs/tasks/active/<slug>/gate-ledger.md`.
|
|
21
|
+
It helps people review decisions, but it does not grant permission by itself.
|
|
22
|
+
|
|
23
|
+
**Task cache**:
|
|
24
|
+
The compact derived state at `harness/docs/tasks/active/<slug>/task.yaml`.
|
|
25
|
+
If it disagrees with `events.jsonl`, verification fails and `events.jsonl` wins.
|
|
26
|
+
|
|
27
|
+
**Brief**:
|
|
28
|
+
The task-specific summary at `harness/docs/tasks/active/<slug>/brief.md`. This is not the same as root `handoff.md`.
|
|
29
|
+
|
|
30
|
+
**Writing plan**:
|
|
31
|
+
A Superpowers implementation plan at `harness/docs/tasks/active/<slug>/writing-plan.md`.
|
|
32
|
+
|
|
33
|
+
**Module**:
|
|
34
|
+
Product or application code under `modules/`, created only after approved module structure exists.
|
|
35
|
+
|
|
36
|
+
**Proposal**:
|
|
37
|
+
A pending harness rule change under `proposals/`, used before changing live rules.
|
|
38
|
+
|
|
39
|
+
**Archive summary**:
|
|
40
|
+
The required cold-context summary at `archive-summary.md` before moving a task from `active/` to `archive/YYYY/MM/`.
|
|
41
|
+
|
|
42
|
+
## Relationships
|
|
43
|
+
|
|
44
|
+
- The event log records gate questions, user answers, approval decisions, and permission decisions.
|
|
45
|
+
- `gate-ledger.md`, `task.yaml`, and `planning-pack.md` are projections or manifests derived from approved state.
|
|
46
|
+
- The planning gate creates a PRD.
|
|
47
|
+
- A PRD is decomposed into one or more local task issues.
|
|
48
|
+
- The task issues inform the brief and writing plan.
|
|
49
|
+
- The writing plan controls implementation.
|
|
50
|
+
- Verification and Compound Engineering run after implementation.
|
|
51
|
+
- Finished task artifacts move from `harness/docs/tasks/active/` to `harness/docs/tasks/archive/YYYY/MM/` only after `archive-summary.md` exists.
|
package/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# 짬뽕하네스
|
|
2
|
+
|
|
3
|
+
AI가 바로 코드를 만들지 않고, **질문 -> 기획 -> 승인 -> 실행 -> 검증** 순서로 움직이게 하는 안전 하네스입니다.
|
|
4
|
+
|
|
5
|
+
프로젝트 폴더에 하네스를 설치하면 Codex가 `AGENTS.md`와 `harness/` 규칙을 읽고, 사용자가 승인하지 않은 코드 작성, 테스트 생성, 패키지 설치, live access, commit, push를 하지 못하게 막습니다.
|
|
6
|
+
|
|
7
|
+
## Codex에게 설치시키기
|
|
8
|
+
|
|
9
|
+
Codex에게 아래처럼 말하면 됩니다.
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
vibedong/jjamppong-harness.git 설치해줘.
|
|
13
|
+
설치할 위치는 내가 말한 프로젝트 폴더를 사용해줘.
|
|
14
|
+
설치 후 verify까지만 하고 멈춰.
|
|
15
|
+
기존 .git과 origin은 보존해줘.
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
설치할 폴더는 Codex에게 말할 때 같이 지정하면 됩니다.
|
|
19
|
+
|
|
20
|
+
## 설치 결과
|
|
21
|
+
|
|
22
|
+
정상 설치되면 대상 폴더 바로 아래에 하네스 파일이 생깁니다.
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
프로젝트 폴더/
|
|
26
|
+
AGENTS.md
|
|
27
|
+
README.md
|
|
28
|
+
CONTEXT.md
|
|
29
|
+
handoff.md
|
|
30
|
+
harness/
|
|
31
|
+
modules/
|
|
32
|
+
module-template/
|
|
33
|
+
proposals/
|
|
34
|
+
harness.lock.yaml
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
잘못된 설치입니다.
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
프로젝트 폴더/jjamppong-harness/AGENTS.md
|
|
41
|
+
프로젝트 폴더/ourosuper-harness/AGENTS.md
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
하네스는 하위 폴더에 들어가는 앱이 아니라, 프로젝트 루트에 펼쳐지는 작업 규칙입니다.
|
|
45
|
+
|
|
46
|
+
## 자주 보이는 문구와 파일
|
|
47
|
+
|
|
48
|
+
Gate id는 지금 어느 단계의 허락을 받는지 보여주는 이름표입니다.
|
|
49
|
+
|
|
50
|
+
예를 들어 `Gate id: implementation`이 보이면 "이제 구현을 시작해도 되는지 묻는 단계"라는 뜻입니다.
|
|
51
|
+
|
|
52
|
+
자주 보이는 예시는 `Gate id: planning`, `Gate id: implementation`, `Gate id: handoff`입니다.
|
|
53
|
+
|
|
54
|
+
events.jsonl은 실제 승인 기록 원본입니다. 작업이 진행되면 events.jsonl에 새 줄이 추가될 수 있습니다. 이 파일이 바뀌는 것은 정상입니다. 다만 기존 기록을 마음대로 고쳐 쓰면 안 됩니다.
|
|
55
|
+
|
|
56
|
+
gate-ledger.md는 사람이 읽기 쉽게 정리한 승인 기록입니다. AI가 상황 파악용으로 읽을 수는 있지만, 권한 판단의 원본은 `events.jsonl`입니다.
|
|
57
|
+
|
|
58
|
+
task.yaml은 현재 상태를 빠르게 읽는 요약 파일입니다. 이것도 권한 원본은 아닙니다.
|
|
59
|
+
|
|
60
|
+
handoff.md는 새 채팅으로 넘길 상태 요약입니다. handoff.md를 만든 뒤에는 다음 채팅에 붙여넣을 프롬프트를 채팅 응답으로 출력합니다.
|
|
61
|
+
|
|
62
|
+
## 하네스가 막는 것
|
|
63
|
+
|
|
64
|
+
- 설치만 했는데 PRD, issue, module, code를 바로 만드는 것
|
|
65
|
+
- 사용자 의도 질문 전에 기존 폴더부터 읽는 것
|
|
66
|
+
- plan review가 끝났다는 이유로 구현을 시작하는 것
|
|
67
|
+
- 폴더 구조 승인만 받고 코드, 테스트, fixture까지 만드는 것
|
|
68
|
+
- "좋아"를 넓은 승인으로 해석하는 것
|
|
69
|
+
- live target access, package install, commit, push를 묵시적으로 실행하는 것
|
|
70
|
+
|
|
71
|
+
## 실제 작업 흐름
|
|
72
|
+
|
|
73
|
+
설치 후 새 작업을 시작하면 Codex는 보통 이렇게 움직여야 합니다.
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
1. 사용자 의도 질문
|
|
77
|
+
2. 필요한 자료조사
|
|
78
|
+
3. PRD / issue / module structure / writing plan 작성
|
|
79
|
+
4. plan review
|
|
80
|
+
5. 실제 작업 범위와 권한을 다시 질문
|
|
81
|
+
6. 승인된 범위만 구현
|
|
82
|
+
7. verify 후 사용자 확인
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
좋은 문서가 아니라, AI가 통과해야 하는 문을 만든다.
|
package/bin/jjamppong.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { installHarness } = require('../harness/installer/install');
|
|
6
|
+
const { verifyRoot } = require('../harness/verify/verify');
|
|
7
|
+
const { diagnose } = require('../harness/doctor/doctor');
|
|
8
|
+
const { decide } = require('../harness/permission/permission-decision');
|
|
9
|
+
|
|
10
|
+
function parseArgs(argv) {
|
|
11
|
+
const positional = [];
|
|
12
|
+
const flags = {};
|
|
13
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
14
|
+
const token = argv[i];
|
|
15
|
+
if (!token.startsWith('--')) {
|
|
16
|
+
positional.push(token);
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
const key = token.slice(2);
|
|
20
|
+
const next = argv[i + 1];
|
|
21
|
+
if (!next || next.startsWith('--')) {
|
|
22
|
+
flags[key] = true;
|
|
23
|
+
} else {
|
|
24
|
+
flags[key] = next;
|
|
25
|
+
i += 1;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return { positional, flags };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function printHelp() {
|
|
32
|
+
process.stdout.write(`Usage:
|
|
33
|
+
jjamppong install --target <path> [--template <path>]
|
|
34
|
+
jjamppong verify --target <path> [--json]
|
|
35
|
+
jjamppong doctor --target <path> [--proposal] [--json]
|
|
36
|
+
jjamppong perm decide --repo-root <path> --capability <capability> [--path <path>]
|
|
37
|
+
|
|
38
|
+
Safety defaults:
|
|
39
|
+
install stops after install/verify;
|
|
40
|
+
no planning, package install, GitHub repo creation, commit, or push.
|
|
41
|
+
`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function main() {
|
|
45
|
+
const { positional, flags } = parseArgs(process.argv.slice(2));
|
|
46
|
+
const command = positional[0];
|
|
47
|
+
|
|
48
|
+
if (!command || flags.help || command === 'help') {
|
|
49
|
+
printHelp();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (command === 'install') {
|
|
54
|
+
const target = flags.target || positional[1];
|
|
55
|
+
if (!target) throw new Error('install requires --target <path>.');
|
|
56
|
+
const result = installHarness({
|
|
57
|
+
target,
|
|
58
|
+
templateRoot: flags.template ? path.resolve(flags.template) : path.resolve(__dirname, '..'),
|
|
59
|
+
version: require('../package.json').version,
|
|
60
|
+
});
|
|
61
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (command === 'verify') {
|
|
66
|
+
const target = flags.target || positional[1] || process.cwd();
|
|
67
|
+
const result = verifyRoot(target);
|
|
68
|
+
if (flags.json) {
|
|
69
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
70
|
+
} else if (result.ok) {
|
|
71
|
+
process.stdout.write(`verify passed for ${result.root}\n`);
|
|
72
|
+
} else {
|
|
73
|
+
process.stdout.write(`verify failed for ${result.root}\n`);
|
|
74
|
+
for (const failure of result.failures) {
|
|
75
|
+
process.stdout.write(`FAIL ${failure.id}: ${failure.message}\n`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
process.exitCode = result.ok ? 0 : 1;
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (command === 'doctor') {
|
|
83
|
+
const target = flags.target || positional[1] || process.cwd();
|
|
84
|
+
const result = diagnose(target, { proposal: Boolean(flags.proposal) });
|
|
85
|
+
if (flags.json) {
|
|
86
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
87
|
+
} else if (result.ok) {
|
|
88
|
+
process.stdout.write(`doctor found no P0 issues for ${result.root}\n`);
|
|
89
|
+
} else {
|
|
90
|
+
process.stdout.write(`doctor found ${result.failures.length} issue(s) for ${result.root}\n`);
|
|
91
|
+
for (const failure of result.failures) {
|
|
92
|
+
process.stdout.write(`- ${failure.id}: ${failure.next_action}\n`);
|
|
93
|
+
}
|
|
94
|
+
if (result.proposal_path) process.stdout.write(`proposal: ${result.proposal_path}\n`);
|
|
95
|
+
}
|
|
96
|
+
process.exitCode = result.ok ? 0 : 1;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (command === 'perm' && positional[1] === 'decide') {
|
|
101
|
+
const result = decide({
|
|
102
|
+
repoRoot: flags['repo-root'] || process.cwd(),
|
|
103
|
+
taskDir: flags.task,
|
|
104
|
+
eventsPath: flags.events,
|
|
105
|
+
taskYamlPath: flags['task-yaml'],
|
|
106
|
+
capability: flags.capability,
|
|
107
|
+
path: flags.path,
|
|
108
|
+
action: flags.action,
|
|
109
|
+
});
|
|
110
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
111
|
+
process.exitCode = result.decision === 'allow' ? 0 : 2;
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
throw new Error(`Unknown command: ${positional.join(' ')}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
main();
|
|
120
|
+
} catch (error) {
|
|
121
|
+
process.stderr.write(`ERROR ${error.message}\n`);
|
|
122
|
+
process.exitCode = 1;
|
|
123
|
+
}
|
package/handoff.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Global Handoff
|
|
2
|
+
|
|
3
|
+
Root `handoff.md` is the global next-chat/context-transfer file.
|
|
4
|
+
|
|
5
|
+
Write this file in the user's language when the user requests a handoff.
|
|
6
|
+
|
|
7
|
+
Include status summary, current decisions, remaining work, risks, and files the next agent should read.
|
|
8
|
+
|
|
9
|
+
Do not store the next-chat restart prompt here by default. Return that prompt in the chat response after creating the handoff.
|
|
10
|
+
|
|
11
|
+
Task-specific summaries belong under:
|
|
12
|
+
|
|
13
|
+
`harness/docs/tasks/active/<YYYY-MM-DD-short-topic>/brief.md`
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
version: 0.1.0
|
|
2
|
+
name: jjamppong-harness-capability-catalog
|
|
3
|
+
principle: >-
|
|
4
|
+
Permissions are capability-based. File writes are only one capability.
|
|
5
|
+
Reads, commands, network, package operations, git operations, secrets,
|
|
6
|
+
installer actions, harness-core changes, and parallel writes are all explicit capabilities.
|
|
7
|
+
|
|
8
|
+
defaults:
|
|
9
|
+
missing_capability: deny
|
|
10
|
+
ambiguous_scope: deny
|
|
11
|
+
short_approval_expansion: deny
|
|
12
|
+
|
|
13
|
+
capabilities:
|
|
14
|
+
file.read.project:
|
|
15
|
+
description: Read non-secret files inside the project root.
|
|
16
|
+
default: denied_before_grill
|
|
17
|
+
unlock: research_after_grill
|
|
18
|
+
file.read.archive:
|
|
19
|
+
description: Read archived task details.
|
|
20
|
+
default: index_only
|
|
21
|
+
rule: Read index and archive-summary first; raw archive logs require relevance justification.
|
|
22
|
+
file.read.raw_artifact:
|
|
23
|
+
description: Read large raw artifacts such as HTML dumps, crawl outputs, logs.
|
|
24
|
+
default: deny
|
|
25
|
+
file.read.secret:
|
|
26
|
+
description: Read credentials, tokens, cookies, private keys, .env files, service accounts.
|
|
27
|
+
default: deny
|
|
28
|
+
file.write.task_artifact:
|
|
29
|
+
description: Write current task artifacts under active task directory.
|
|
30
|
+
default: gated
|
|
31
|
+
file.write.module:
|
|
32
|
+
description: Write approved files under approved modules/<module> paths.
|
|
33
|
+
default: deny_until_implementation
|
|
34
|
+
file.write.folder_skeleton:
|
|
35
|
+
description: Create approved empty module folders and approved non-executable placeholder docs.
|
|
36
|
+
default: deny_until_folder_skeleton
|
|
37
|
+
file.write.outside_modules:
|
|
38
|
+
description: Write product integration files outside modules/.
|
|
39
|
+
default: deny
|
|
40
|
+
requires: outside_modules_write capability approval with exact paths
|
|
41
|
+
file.write.harness_core:
|
|
42
|
+
description: Write AGENTS.md, harness/rules/**, harness/contracts/**, installer, package, plugin rules.
|
|
43
|
+
default: deny_in_product_task
|
|
44
|
+
requires: template_maintenance or harness_update task
|
|
45
|
+
file.delete:
|
|
46
|
+
description: Delete files.
|
|
47
|
+
default: deny_unless_explicit
|
|
48
|
+
file.move:
|
|
49
|
+
description: Move or rename files.
|
|
50
|
+
default: deny_unless_explicit
|
|
51
|
+
file.symlink:
|
|
52
|
+
description: Create symlink, junction, hardlink, shortcut, mount-like indirection.
|
|
53
|
+
default: deny
|
|
54
|
+
|
|
55
|
+
exec.readonly_info:
|
|
56
|
+
description: Non-mutating commands such as git status, listing files, version checks.
|
|
57
|
+
default: allowed_after_relevant_gate
|
|
58
|
+
exec.test:
|
|
59
|
+
description: Run tests.
|
|
60
|
+
default: deny_until_verification_or_plan
|
|
61
|
+
exec.build:
|
|
62
|
+
description: Run build commands.
|
|
63
|
+
default: deny_until_approved
|
|
64
|
+
exec.mutating:
|
|
65
|
+
description: Commands that modify filesystem state.
|
|
66
|
+
default: deny
|
|
67
|
+
exec.destructive:
|
|
68
|
+
description: rm -rf, git clean, force reset, destructive DB operations.
|
|
69
|
+
default: deny
|
|
70
|
+
exec.networked:
|
|
71
|
+
description: Command that contacts network.
|
|
72
|
+
default: deny_unless_network_capability
|
|
73
|
+
|
|
74
|
+
network.web_research:
|
|
75
|
+
description: General web search or documentation lookup.
|
|
76
|
+
default: allowed_in_research_with_citation
|
|
77
|
+
network.live_target:
|
|
78
|
+
description: Actual target site/API access, including read-only requests, crawl, download, login page, API calls.
|
|
79
|
+
default: deny_until_live_access_approval
|
|
80
|
+
network.package_registry:
|
|
81
|
+
description: npm/pip/apt/other package registry access.
|
|
82
|
+
default: deny_until_package_install_approval
|
|
83
|
+
network.authenticated:
|
|
84
|
+
description: Authenticated network access using token, cookie, account, API key, login.
|
|
85
|
+
default: deny
|
|
86
|
+
|
|
87
|
+
package.install:
|
|
88
|
+
description: Install or change dependencies, lockfiles, package manager state, runtime packages.
|
|
89
|
+
default: deny
|
|
90
|
+
package.update:
|
|
91
|
+
description: Update dependency versions.
|
|
92
|
+
default: deny
|
|
93
|
+
|
|
94
|
+
git.commit:
|
|
95
|
+
description: Create a git commit.
|
|
96
|
+
default: deny_until_git_commit_approval
|
|
97
|
+
git.push:
|
|
98
|
+
description: Push to remote.
|
|
99
|
+
default: deny_until_git_push_approval
|
|
100
|
+
git.remote_change:
|
|
101
|
+
description: Add/change/remove git remote.
|
|
102
|
+
default: deny_unless_install_or_explicit
|
|
103
|
+
|
|
104
|
+
installer.install:
|
|
105
|
+
description: Install harness files.
|
|
106
|
+
default: allowed_only_in_install_task
|
|
107
|
+
installer.update:
|
|
108
|
+
description: Update installed harness files.
|
|
109
|
+
default: proposal_only_if_modified
|
|
110
|
+
installer.repair:
|
|
111
|
+
description: Repair installed harness files.
|
|
112
|
+
default: proposal_only_if_modified
|
|
113
|
+
installer.rollback:
|
|
114
|
+
description: Roll back installer changes using manifest.
|
|
115
|
+
default: explicit_only
|
|
116
|
+
|
|
117
|
+
harness.core_change:
|
|
118
|
+
description: Change harness core rules/contracts/installer/plugins.
|
|
119
|
+
default: deny_in_product_repo
|
|
120
|
+
requires: template_maintenance task and proposal approval
|
|
121
|
+
project.policy_change:
|
|
122
|
+
description: Change project-local harness overlay policy.
|
|
123
|
+
default: proposal_required
|
|
124
|
+
|
|
125
|
+
parallel.write:
|
|
126
|
+
description: Allow multiple active writers/tasks.
|
|
127
|
+
default: deny
|
|
128
|
+
requires: explicit_parallel_active_task_approval
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
version: 0.1.0
|
|
2
|
+
name: jjamppong-harness-gate-contract-matrix
|
|
3
|
+
notes:
|
|
4
|
+
- Workflow gates are not the same as capability approvals.
|
|
5
|
+
- Capability approvals may be embedded in implementation approval or separate exact-scope gates.
|
|
6
|
+
- Missing or ambiguous capabilities are denied.
|
|
7
|
+
|
|
8
|
+
gates:
|
|
9
|
+
install:
|
|
10
|
+
user_label: 설치만 하기
|
|
11
|
+
previous: []
|
|
12
|
+
reads: [file.read.project]
|
|
13
|
+
writes: [installer.install]
|
|
14
|
+
required_artifacts: [harness.lock.yaml, install-summary]
|
|
15
|
+
forbidden: [project_planning_start, prd, issues, module_creation, code, tests, fixtures, live_access, git.commit, git.push]
|
|
16
|
+
transition_to: [stop, intake]
|
|
17
|
+
verify_ids: [T001, T002, T003]
|
|
18
|
+
|
|
19
|
+
intake:
|
|
20
|
+
user_label: 요청 기록
|
|
21
|
+
previous: [install_or_existing_project]
|
|
22
|
+
reads: [user_prompt]
|
|
23
|
+
writes: [task_artifact]
|
|
24
|
+
required_artifacts: [task.yaml, events.jsonl]
|
|
25
|
+
forbidden: [project_file_read, prd, module_creation, code, tests, live_access]
|
|
26
|
+
transition_to: [grill]
|
|
27
|
+
verify_ids: [T004]
|
|
28
|
+
|
|
29
|
+
grill:
|
|
30
|
+
user_label: 압박 질문
|
|
31
|
+
previous: [intake]
|
|
32
|
+
reads: [user_prompt, prior_user_answers]
|
|
33
|
+
writes: [planning/01-grill-summary.md, events.jsonl]
|
|
34
|
+
required_artifacts: [grill-summary, gate_question_events, user_answer_events]
|
|
35
|
+
forbidden: [project_scan_before_approval, docs_first, prd, issues, folders, code, tests, live_access]
|
|
36
|
+
transition_to: [research]
|
|
37
|
+
verify_ids: [T005, T006, T007]
|
|
38
|
+
|
|
39
|
+
research:
|
|
40
|
+
aliases: [evidence_check]
|
|
41
|
+
user_label: 자료조사 / 근거 확인
|
|
42
|
+
previous: [grill]
|
|
43
|
+
reads: [file.read.project, network.web_research]
|
|
44
|
+
writes: [planning/02-research-summary.md, events.jsonl]
|
|
45
|
+
required_artifacts: [research-summary]
|
|
46
|
+
forbidden: [network.live_target, package.install, code, tests, folders, prd_approval_without_user]
|
|
47
|
+
transition_to: [grill, compound_lookup, prd]
|
|
48
|
+
verify_ids: [T008, T009, T022, T023]
|
|
49
|
+
|
|
50
|
+
compound_lookup:
|
|
51
|
+
user_label: 이전 배운 점 확인
|
|
52
|
+
previous: [research]
|
|
53
|
+
reads: [knowledge.index, archive.summary, selected_top_learnings]
|
|
54
|
+
writes: [planning/02b-compound-lookup.md]
|
|
55
|
+
required_artifacts: [compound-lookup-summary]
|
|
56
|
+
forbidden: [archive_raw_default_read, past_learning_over_current_intent, unapproved_proposal_as_rule]
|
|
57
|
+
transition_to: [prd]
|
|
58
|
+
verify_ids: [T040]
|
|
59
|
+
|
|
60
|
+
architecture_orientation:
|
|
61
|
+
user_label: 기술 구성 설명
|
|
62
|
+
previous: [grill]
|
|
63
|
+
reads: [planning_context]
|
|
64
|
+
writes: [planning/02c-architecture-orientation.md]
|
|
65
|
+
required_artifacts: [architecture-orientation]
|
|
66
|
+
forbidden: [technology_forcing_without_user, code]
|
|
67
|
+
transition_to: [prd]
|
|
68
|
+
|
|
69
|
+
prd:
|
|
70
|
+
user_label: PRD / 기획 확정
|
|
71
|
+
previous: [grill, research]
|
|
72
|
+
writes: [planning/03-prd.md, planning-pack.md]
|
|
73
|
+
required_artifacts: [approved_prd]
|
|
74
|
+
forbidden: [implementation, code, tests, folder_creation]
|
|
75
|
+
transition_to: [issues]
|
|
76
|
+
verify_ids: [T011]
|
|
77
|
+
|
|
78
|
+
issues:
|
|
79
|
+
user_label: 이슈 나누기
|
|
80
|
+
previous: [prd]
|
|
81
|
+
writes: [planning/04-issues.md, planning-pack.md]
|
|
82
|
+
required_artifacts: [approved_issues]
|
|
83
|
+
forbidden: [code, tests, live_access]
|
|
84
|
+
transition_to: [module_structure]
|
|
85
|
+
|
|
86
|
+
module_structure:
|
|
87
|
+
user_label: 구조 나누기
|
|
88
|
+
previous: [prd, issues]
|
|
89
|
+
writes: [planning/05-module-structure.md, module_structure_state_projection]
|
|
90
|
+
required_artifacts: [approved_module_structure]
|
|
91
|
+
forbidden: [folder_creation, code, tests, fixtures, live_access]
|
|
92
|
+
transition_to: [writing_plan, folder_skeleton]
|
|
93
|
+
verify_ids: [T016]
|
|
94
|
+
|
|
95
|
+
writing_plan:
|
|
96
|
+
user_label: 구현계획 쓰기
|
|
97
|
+
previous: [issues, module_structure]
|
|
98
|
+
reads: [planning/00-current-planning-context.md, prd, issues, module_structure]
|
|
99
|
+
writes: [planning/06-writing-plan.md]
|
|
100
|
+
required_artifacts: [writing_plan]
|
|
101
|
+
forbidden: [code, tests, fixtures, live_access]
|
|
102
|
+
transition_to: [plan_review]
|
|
103
|
+
verify_ids: [T010]
|
|
104
|
+
|
|
105
|
+
plan_review:
|
|
106
|
+
user_label: 계획 리뷰
|
|
107
|
+
previous: [writing_plan]
|
|
108
|
+
writes: [planning/07-plan-review.md]
|
|
109
|
+
required_artifacts: [plan_review]
|
|
110
|
+
forbidden: [implementation_unlock, code, tests, fixtures, live_access]
|
|
111
|
+
transition_to: [folder_skeleton, implementation]
|
|
112
|
+
verify_ids: [T010]
|
|
113
|
+
|
|
114
|
+
folder_skeleton:
|
|
115
|
+
user_label: 빈 폴더틀 승인
|
|
116
|
+
previous: [module_structure]
|
|
117
|
+
writes: [approved_empty_dirs, approved_gitkeep, approved_placeholder_docs]
|
|
118
|
+
required_artifacts: [folder_skeleton_approval, skeleton_log]
|
|
119
|
+
forbidden: [executable_source, tests, fixtures, runtime_config, package_files, live_access]
|
|
120
|
+
transition_to: [implementation, writing_plan]
|
|
121
|
+
verify_ids: [T017, T018]
|
|
122
|
+
|
|
123
|
+
implementation:
|
|
124
|
+
user_label: 진짜 작업 승인
|
|
125
|
+
previous: [plan_review]
|
|
126
|
+
writes: [implementation-approval.md, events.jsonl]
|
|
127
|
+
required_artifacts: [permission_decision_scope, artifact_hash_snapshot]
|
|
128
|
+
effect_capabilities: [file.write.module, exec.test, exec.build, package.install, network.live_target, git.commit, git.push]
|
|
129
|
+
forbidden: [implicit_capability, approval_scope_expansion]
|
|
130
|
+
transition_to: [work]
|
|
131
|
+
verify_ids: [T012, T013, T014, T015]
|
|
132
|
+
|
|
133
|
+
work:
|
|
134
|
+
user_label: 작업 실행
|
|
135
|
+
previous: [implementation]
|
|
136
|
+
writes: [approved_target_paths]
|
|
137
|
+
required_artifacts: [permission_decisions, implementation_log]
|
|
138
|
+
forbidden: [scope_creep, unapproved_outside_modules, unapproved_live_access, unapproved_git, unapproved_package_install]
|
|
139
|
+
transition_to: [verification]
|
|
140
|
+
verify_ids: [T020, T021, T022, T024, T025, T026, T027, T028]
|
|
141
|
+
|
|
142
|
+
verification:
|
|
143
|
+
user_label: 검증
|
|
144
|
+
previous: [work]
|
|
145
|
+
writes: [verification.md]
|
|
146
|
+
required_artifacts: [commands_run, expected_actual, exit_codes, risk_status]
|
|
147
|
+
forbidden: [new_feature_work]
|
|
148
|
+
transition_to: [acceptance, compound_capture]
|
|
149
|
+
|
|
150
|
+
acceptance:
|
|
151
|
+
user_label: 사용자 확인
|
|
152
|
+
previous: [verification]
|
|
153
|
+
writes: [acceptance.md]
|
|
154
|
+
required_artifacts: [accepted_or_deferred_or_blocked]
|
|
155
|
+
forbidden: [silent_archive_without_acceptance_status]
|
|
156
|
+
transition_to: [compound_capture, archive]
|
|
157
|
+
|
|
158
|
+
compound_capture:
|
|
159
|
+
user_label: 배운 점 정리
|
|
160
|
+
previous: [verification]
|
|
161
|
+
writes: [learning-capture.md, knowledge_draft]
|
|
162
|
+
required_artifacts: [learning_capture]
|
|
163
|
+
forbidden: [live_rule_edit]
|
|
164
|
+
transition_to: [compound_review, archive]
|
|
165
|
+
verify_ids: [T039]
|
|
166
|
+
|
|
167
|
+
proposal:
|
|
168
|
+
user_label: 개선 제안
|
|
169
|
+
previous: [compound_review_or_user_request]
|
|
170
|
+
writes: [proposals/active/*.md]
|
|
171
|
+
required_artifacts: [proposal_doc]
|
|
172
|
+
forbidden: [live_harness_core_change_without_approval]
|
|
173
|
+
transition_to: [template_maintenance, archive]
|
|
174
|
+
verify_ids: [T031, T032]
|
|
175
|
+
|
|
176
|
+
archive:
|
|
177
|
+
user_label: 완료 보관
|
|
178
|
+
previous: [verification]
|
|
179
|
+
writes: [archive-summary.md, tasks/index.md, archive_move]
|
|
180
|
+
required_artifacts: [archive_summary]
|
|
181
|
+
forbidden: [active_left_dirty, raw_archive_as_hot_context]
|
|
182
|
+
|
|
183
|
+
handoff:
|
|
184
|
+
user_label: 새 채팅 인계
|
|
185
|
+
previous: [user_requested]
|
|
186
|
+
writes: [handoff.md]
|
|
187
|
+
required_artifacts: [handoff_summary]
|
|
188
|
+
forbidden: [automatic_handoff_update]
|