kin: auto-commit after pipeline
This commit is contained in:
parent
c767c6157a
commit
348aa07fec
3 changed files with 74 additions and 2 deletions
|
|
@ -40,7 +40,27 @@ You receive:
|
|||
|
||||
## Output format
|
||||
|
||||
Return ONLY valid JSON (no markdown, no explanation):
|
||||
Return TWO sections in your response:
|
||||
|
||||
### Section 1 — `## Verdict` (human-readable, in Russian)
|
||||
|
||||
2-3 sentences in plain Russian for the project director: what was checked, whether everything is OK, are there any issues, can the task be closed. No JSON, no technical terms, no code snippets.
|
||||
|
||||
Example:
|
||||
```
|
||||
## Verdict
|
||||
Реализация проверена — логика корректна, безопасность соблюдена. Найдено одно незначительное замечание по документации, не блокирующее. Задачу можно закрывать.
|
||||
```
|
||||
|
||||
Another example (with issues):
|
||||
```
|
||||
## Verdict
|
||||
Проверка выявила критическую проблему: SQL-запрос уязвим к инъекциям. Также отсутствуют тесты для нового эндпоинта. Задачу нельзя закрывать до исправления.
|
||||
```
|
||||
|
||||
### Section 2 — `## Details` (JSON block for agents)
|
||||
|
||||
The full technical output in JSON, wrapped in a ```json code fence:
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -71,6 +91,25 @@ If verdict is "changes_requested", findings must be non-empty with actionable su
|
|||
If verdict is "revise", include `"target_role": "..."` and findings must be non-empty with actionable suggestions.
|
||||
If verdict is "blocked", include `"blocked_reason": "..."` (e.g. unable to read files).
|
||||
|
||||
**Full response example:**
|
||||
|
||||
```
|
||||
## Verdict
|
||||
Реализация проверена — логика корректна, безопасность соблюдена. Найдено одно незначительное замечание по документации, не блокирующее. Задачу можно закрывать.
|
||||
|
||||
## Details
|
||||
```json
|
||||
{
|
||||
"verdict": "approved",
|
||||
"findings": [...],
|
||||
"security_issues": [],
|
||||
"conventions_violations": [],
|
||||
"test_coverage": "adequate",
|
||||
"summary": "..."
|
||||
}
|
||||
` ` `
|
||||
```
|
||||
|
||||
## Verdict definitions
|
||||
|
||||
### verdict: "revise"
|
||||
|
|
|
|||
|
|
@ -516,6 +516,39 @@ class TestSSHBuildCmd:
|
|||
assert "cd" not in full_cmd_arg
|
||||
assert full_cmd_arg == "git pull"
|
||||
|
||||
def test_deploy_path_with_semicolon_injection_is_escaped(self):
|
||||
"""Path containing ';' must be quoted so it cannot inject a second shell command."""
|
||||
project = {
|
||||
"deploy_host": "myserver",
|
||||
"deploy_path": "/srv/api; rm -rf /",
|
||||
}
|
||||
cmd = _build_ssh_cmd(project, "git pull")
|
||||
full_cmd_arg = cmd[-1]
|
||||
# The dangerous path must appear only as a quoted argument, not as a bare shell fragment.
|
||||
assert "cd /srv/api; rm -rf /" not in full_cmd_arg
|
||||
# shlex.quote wraps it in single quotes — the semicolon is inside the quotes.
|
||||
assert shlex.quote("/srv/api; rm -rf /") in full_cmd_arg
|
||||
|
||||
def test_deploy_restart_cmd_is_not_shlex_quoted(self):
|
||||
"""deploy_restart_cmd must reach SSH as a plain shell command, not as a single quoted arg.
|
||||
|
||||
shlex.quote would turn 'docker compose restart worker' into a literal string
|
||||
which the remote shell would refuse to execute. Admin-controlled field — no quoting.
|
||||
"""
|
||||
project = {
|
||||
"deploy_host": "myserver",
|
||||
"deploy_path": "/srv/api",
|
||||
"deploy_runtime": "docker",
|
||||
"deploy_restart_cmd": "docker compose restart worker",
|
||||
}
|
||||
# Build steps manually and feed one step into _build_ssh_cmd.
|
||||
restart_cmd = "docker compose restart worker"
|
||||
cmd = _build_ssh_cmd(project, restart_cmd)
|
||||
full_cmd_arg = cmd[-1]
|
||||
# The command must appear verbatim (not as a single quoted token).
|
||||
assert "docker compose restart worker" in full_cmd_arg
|
||||
assert full_cmd_arg != shlex.quote("docker compose restart worker")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 9. deploy_with_dependents — cascade deploy unit tests
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ describe('api.projectLinks', () => {
|
|||
|
||||
it('возвращает массив ProjectLink', async () => {
|
||||
const links = [
|
||||
{ id: 1, from_project: 'KIN', to_project: 'BRS', link_type: 'depends_on', description: null, created_at: '2026-01-01' },
|
||||
{ id: 1, from_project: 'KIN', to_project: 'BRS', type: 'depends_on', description: null, created_at: '2026-01-01' },
|
||||
]
|
||||
mockFetch(links)
|
||||
const result = await api.projectLinks('KIN')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue