yam-flow 2.7.0 → 2.8.1
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 +5 -0
- package/CHANGELOG.md +41 -0
- package/COMMANDS.md +52 -5
- package/README.md +40 -8
- package/ROADMAP.md +17 -6
- package/dist/bin/yam.js +462 -74
- package/dist/lib/external-updates.d.ts +9 -0
- package/dist/lib/external-updates.js +232 -4
- package/dist/lib/next-step.d.ts +61 -0
- package/dist/lib/next-step.js +340 -0
- package/dist/lib/release-auth-readiness.d.ts +81 -0
- package/dist/lib/release-auth-readiness.js +106 -0
- package/dist/lib/release-registry-status.d.ts +18 -0
- package/dist/lib/release-registry-status.js +37 -0
- package/dist/lib/scout-receipt.d.ts +89 -0
- package/dist/lib/scout-receipt.js +542 -0
- package/dist/lib/security-check.d.ts +98 -0
- package/dist/lib/security-check.js +262 -0
- package/dist/lib/security-integration.d.ts +8 -0
- package/dist/lib/security-integration.js +428 -0
- package/dist/lib/skill-installation.d.ts +30 -0
- package/dist/lib/skill-installation.js +470 -82
- package/dist/lib/trust-kernel.d.ts +2 -0
- package/dist/lib/trust-kernel.js +21 -2
- package/package.json +26 -4
- package/references/final-report.md +17 -1
- package/references/next-step.md +67 -0
- package/references/scout-wide-scan.md +16 -0
- package/references/security-check.md +131 -0
- package/references/study-note.md +10 -2
- package/references/tool-trust-layer.md +2 -0
- package/skills/deep/SKILL.md +6 -0
- package/skills/mission/SKILL.md +6 -0
- package/skills/quick/SKILL.md +5 -0
- package/skills/scout/SKILL.md +19 -9
- package/skills/ueye/SKILL.md +5 -0
- package/src/bin/yam.ts +465 -72
- package/src/lib/external-updates.ts +262 -4
- package/src/lib/next-step.ts +397 -0
- package/src/lib/release-auth-readiness.ts +148 -0
- package/src/lib/release-registry-status.ts +55 -0
- package/src/lib/scout-receipt.ts +593 -0
- package/src/lib/security-check.ts +184 -0
- package/src/lib/security-integration.ts +299 -0
- package/src/lib/skill-installation.ts +542 -87
- package/src/lib/trust-kernel.ts +25 -2
- package/templates/security-check-note.md +42 -0
- package/templates/security-gate.yml +44 -0
- package/yam.manifest.json +4 -3
package/src/lib/trust-kernel.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { verifyStrictGateResult } from './gate-result.js';
|
|
2
|
+
import { buildNextStep } from './next-step.js';
|
|
3
|
+
import type { NextStepInput, NextStepReceipt } from './next-step.js';
|
|
2
4
|
|
|
3
5
|
export const TRUTH_STATUSES = Object.freeze([
|
|
4
6
|
'verified',
|
|
@@ -273,6 +275,7 @@ export interface LoopReport {
|
|
|
273
275
|
side_effects: string[];
|
|
274
276
|
avoidance_note: string;
|
|
275
277
|
study_note: StudyNote;
|
|
278
|
+
next_step: NextStepReceipt | null;
|
|
276
279
|
}
|
|
277
280
|
|
|
278
281
|
export interface UeyeRunReport {
|
|
@@ -784,13 +787,32 @@ export function buildLoopReport(input: Partial<LoopReport> & Record<string, unkn
|
|
|
784
787
|
const uncoveredRequirements = asList(input.uncovered_requirements || input.uncovered_requirement);
|
|
785
788
|
const blockers = asList(input.blockers || input.blocked);
|
|
786
789
|
const blockedBy = asList(input.blocked_by);
|
|
787
|
-
const
|
|
790
|
+
const requestedBlockedKind = shortText(input.blocked_kind);
|
|
788
791
|
const failureCause = shortText(input.failure_cause);
|
|
789
792
|
const recoveryHint = shortText(input.recovery_hint);
|
|
790
793
|
const avoidanceNote = shortText(input.avoidance_note);
|
|
791
794
|
const evidenceStamp = shortText(input.evidence_stamp || input.source_digest, 320);
|
|
792
795
|
const sourceDigest = shortText(input.source_digest || input.evidence_stamp, 320);
|
|
793
796
|
const hasBlockedStage = stages.some((stage) => stage.status === 'blocked' || stage.status === 'failed');
|
|
797
|
+
const nextStepSupplied = input.next_step !== undefined && input.next_step !== null;
|
|
798
|
+
const nextStep = nextStepSupplied ? buildNextStep(input.next_step as unknown as NextStepInput) : null;
|
|
799
|
+
const nextStepRequired = touchedFiles.length > 0;
|
|
800
|
+
const nextStepBlocked = (nextStepRequired && !nextStep)
|
|
801
|
+
|| Boolean(nextStep && (!nextStep.contract_valid || nextStep.truth_status === 'blocked'));
|
|
802
|
+
if (nextStepBlocked) {
|
|
803
|
+
blockers.push(!nextStep
|
|
804
|
+
? 'next_step_missing_for_changed_artifacts'
|
|
805
|
+
: `next_step_contract_blocked: ${nextStep.contract_errors[0] || nextStep.truth_status}`);
|
|
806
|
+
}
|
|
807
|
+
const blockedKind = shortText(requestedBlockedKind || (
|
|
808
|
+
readinessState === 'blocked'
|
|
809
|
+
? 'readiness_blocked'
|
|
810
|
+
: uncoveredRequirements.length
|
|
811
|
+
? 'requirement_uncovered'
|
|
812
|
+
: blockers.length || blockedBy.length
|
|
813
|
+
? 'evidence_missing'
|
|
814
|
+
: ''
|
|
815
|
+
));
|
|
794
816
|
const hasBlockerSignal = Boolean(blockers.length || blockedBy.length || blockedKind || uncoveredRequirements.length || readinessState === 'blocked');
|
|
795
817
|
const requestedTruth = isTruthStatus(input.truth_status) ? input.truth_status : '';
|
|
796
818
|
const derivedTruth: TruthStatus = hasBlockerSignal || hasBlockedStage ? 'blocked'
|
|
@@ -844,7 +866,8 @@ export function buildLoopReport(input: Partial<LoopReport> & Record<string, unkn
|
|
|
844
866
|
scope_owner: normalizeOwnerRoute(input.scope_owner || input.owner),
|
|
845
867
|
side_effects: asList(input.side_effects || input.side_effect),
|
|
846
868
|
avoidance_note: avoidanceNote,
|
|
847
|
-
study_note: studyNote
|
|
869
|
+
study_note: studyNote,
|
|
870
|
+
next_step: nextStep
|
|
848
871
|
};
|
|
849
872
|
}
|
|
850
873
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Yam note security-check starter
|
|
2
|
+
|
|
3
|
+
Copy the block below into the project's Yam note for each run. Replace every placeholder with actual scope/evidence; do not infer a pass from the template. The authoritative status and gate rules are in [Security check contract v1](../references/security-check.md).
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
-- Security check --
|
|
7
|
+
|
|
8
|
+
Contract: security-check-v1
|
|
9
|
+
Run: <unique run ID>; Time: <ISO timestamp with timezone>
|
|
10
|
+
Stage: <commit | push | deploy>; Policy: <stage-policy version>
|
|
11
|
+
Environment: <target environment or explicit local/not-applicable reason>
|
|
12
|
+
Binding: <commit: staged tree and base revision | push: outgoing commit IDs and destination | deploy: artifact digest, source commit, environment and configuration revision>
|
|
13
|
+
Scope: <changed paths and connected security boundaries>
|
|
14
|
+
Checker: <tool/version or named reviewer>; Evidence: <sanitized evidence references>
|
|
15
|
+
|
|
16
|
+
1. SEC-01 : "사용자·관리자·외부 서비스·DB·파일 사이의 신뢰 경계와 보호할 데이터·작업을 식별한다." : 미검증
|
|
17
|
+
- Required at: <stages>; Target/evidence/result/time: <actual check details or missing evidence>
|
|
18
|
+
2. SEC-02 : "명시적으로 허용한 접근만 열고, 사용자·서비스 계정에 필요한 최소 권한만 부여한다." : 미검증
|
|
19
|
+
- Required at: <stages>; Target/evidence/result/time: <actual check details or missing evidence>
|
|
20
|
+
3. SEC-03 : "화면을 우회한 API·서버 함수·DB·파일·백그라운드 작업에서도 사용자·조직·대상별 권한을 확인한다." : 미검증
|
|
21
|
+
- Required at: <stages>; Target/evidence/result/time: <actual check details or missing evidence>
|
|
22
|
+
4. SEC-04 : "계정 정지·승인 철회·탈퇴·소속 변경 후 기존 세션·토큰·캐시에서도 권한 회수가 반영된다." : 미검증
|
|
23
|
+
- Required at: <stages>; Target/evidence/result/time: <actual check details or missing evidence>
|
|
24
|
+
5. SEC-05 : "코드의 보안 정책·migration·ACL·환경 설정이 대상 배포 환경의 실제 상태와 일치한다." : 미검증
|
|
25
|
+
- Required at: <stages>; Target/evidence/result/time: <actual check details or missing evidence>
|
|
26
|
+
6. SEC-06 : "로그인·관리자 인증·세션 만료·로그아웃·비밀번호 재설정·계정 복구가 계정 탈취를 막도록 동작한다." : 미검증
|
|
27
|
+
- Required at: <stages>; Target/evidence/result/time: <actual check details or missing evidence>
|
|
28
|
+
7. SEC-07 : "외부 입력·파일 업로드·출력의 형식·크기·경로를 검증하고 SQL 주입·XSS·SSRF·CSRF 등 해당 공격을 방어한다." : 미검증
|
|
29
|
+
- Required at: <stages>; Target/evidence/result/time: <actual check details or missing evidence>
|
|
30
|
+
8. SEC-08 : "API 키·토큰·개인키·개인정보가 코드·브라우저 번들·로그·점검 기록에 불필요하게 노출되지 않는다." : 미검증
|
|
31
|
+
- Required at: <stages>; Target/evidence/result/time: <actual check details or missing evidence>
|
|
32
|
+
9. SEC-09 : "의존성·CI/CD 권한·배포 자격증명·릴리스 산출물의 출처와 무결성을 확인해 공급망 위험을 통제한다." : 미검증
|
|
33
|
+
- Required at: <stages>; Target/evidence/result/time: <actual check details or missing evidence>
|
|
34
|
+
|
|
35
|
+
Result: BLOCKED
|
|
36
|
+
Blocking: <required-at-current-stage unresolved IDs/subchecks or invalid record fields>
|
|
37
|
+
Deferred: <later-stage missing evidence, required stage, owner and action; none if absent>
|
|
38
|
+
Retry of: <prior run ID or none>
|
|
39
|
+
-- End Security check --
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
For `점검 완료 - 보완 필요` or `점검 실패`, add a concrete finding, severity, owner, follow-up action/date and mitigation. For `해당 없음`, add a project/stage-specific reason. Keep missing evidence as `미검증`. All applicable conditional subchecks must appear in the details; one passing test cannot cover an untested requirement.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Copy to the target project after configuring trusted repository variables.
|
|
2
|
+
# Require this job in branch protection and make deployment jobs depend on it.
|
|
3
|
+
name: Security check
|
|
4
|
+
on:
|
|
5
|
+
pull_request:
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
jobs:
|
|
11
|
+
security:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
timeout-minutes: 10
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
|
|
16
|
+
with:
|
|
17
|
+
fetch-depth: 0
|
|
18
|
+
persist-credentials: false
|
|
19
|
+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
|
|
20
|
+
with:
|
|
21
|
+
node-version: 22.14.0
|
|
22
|
+
# The caller provisions reviewed yam code, policy and evidence before this step.
|
|
23
|
+
# Do not execute PR-supplied code with deployment credentials.
|
|
24
|
+
- name: Validate security evidence for exact revisions
|
|
25
|
+
env:
|
|
26
|
+
SECURITY_POLICY_DIGEST: ${{ vars.SECURITY_POLICY_DIGEST }}
|
|
27
|
+
SECURITY_SOURCE: ${{ github.event.pull_request.head.sha || github.sha }}
|
|
28
|
+
SECURITY_BASE: ${{ github.event.pull_request.base.sha || github.event.before }}
|
|
29
|
+
run: >-
|
|
30
|
+
node /opt/trusted-yam/dist/bin/yam.js security check
|
|
31
|
+
--stage ci --source "$SECURITY_SOURCE" --base "$SECURITY_BASE"
|
|
32
|
+
--policy security/policy.json --policy-digest "$SECURITY_POLICY_DIGEST"
|
|
33
|
+
--evidence security/check.json --json
|
|
34
|
+
- name: Preserve sanitized security notes on success and failure
|
|
35
|
+
if: always()
|
|
36
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
|
|
37
|
+
with:
|
|
38
|
+
name: security-check-note
|
|
39
|
+
include-hidden-files: true
|
|
40
|
+
path: |
|
|
41
|
+
.yam/security/notes.md
|
|
42
|
+
.yam/security/runs/
|
|
43
|
+
retention-days: 14
|
|
44
|
+
if-no-files-found: error
|
package/yam.manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yam",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.1",
|
|
4
4
|
"principles": [
|
|
5
5
|
"Direction before execution.",
|
|
6
6
|
"Start fast.",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"Explain what changed, what role it has, where it runs or is read, what was wrong or missing when relevant, before/after behavior, expected behavior, and one useful syntax or structure insight in short non-specialist language.",
|
|
18
18
|
"When relevant, include architecture hygiene: avoid dumping unrelated logic into page.tsx, one-off component CSS into global.css, or structured product data into broad DB jsonb blobs when better project boundaries exist.",
|
|
19
19
|
"Use handoff notes for fix-first items, remaining tasks, recommended next direction, requirement coverage, blocker kind, failure cause, recovery hint, safe retry, evidence level, and owner scope when useful.",
|
|
20
|
-
"Use bounded heavy verification for serious claims, with explicit stop conditions instead of endless proof loops."
|
|
20
|
+
"Use bounded heavy verification for serious claims, with explicit stop conditions instead of endless proof loops.",
|
|
21
|
+
"After changed artifacts, put an evidence-bound Next step immediately after Study Note with a whole-process scan, critical opinion, recommendations, and fix-first-before-planned ordering."
|
|
21
22
|
],
|
|
22
23
|
"defaultHooks": false,
|
|
23
24
|
"routes": [
|
|
@@ -39,7 +40,7 @@
|
|
|
39
40
|
{
|
|
40
41
|
"id": "scout",
|
|
41
42
|
"stage": "v0.2",
|
|
42
|
-
"purpose": "Investigation,
|
|
43
|
+
"purpose": "Investigation, canonical-entity resolution, four-clock freshness checks, evidence-led source mapping, blocked-source fallback, immutable source/claim receipts for repeated scans, opposition pass, and recommendation without code changes by default."
|
|
43
44
|
},
|
|
44
45
|
{
|
|
45
46
|
"id": "deep",
|