@metasession.co/devaudit-cli 0.1.74 → 0.1.75
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/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/sdlc/ai-rules/INSTRUCTIONS-SDLC.md +14 -4
- package/sdlc/ai-rules/SDLC_RULES.md +7 -3
- package/sdlc/ai-rules/claude/CLAUDE.md +7 -3
- package/sdlc/ai-rules/windsurf/.windsurfrules +7 -3
- package/sdlc/files/_common/1-plan-requirement.md +12 -0
- package/sdlc/files/_common/2-implement-and-test.md +12 -0
- package/sdlc/files/_common/3-compile-evidence.md +12 -0
- package/sdlc/files/_common/4-submit-for-review.md +12 -0
- package/sdlc/files/_common/5-deploy-main.md +12 -0
- package/sdlc/files/_common/implementing-an-sdlc-issue.md +10 -0
- package/sdlc/files/stacks/node/hooks/commit-msg +36 -3
package/package.json
CHANGED
|
@@ -29,8 +29,10 @@ When the user requests implementation of an issue (e.g. "implement issue #N", "f
|
|
|
29
29
|
|
|
30
30
|
Wait for the user's yes/no response. Do NOT begin implementation until they answer.
|
|
31
31
|
|
|
32
|
-
- **YES** →
|
|
33
|
-
- **
|
|
32
|
+
- **YES** → route to your platform's orchestration path:
|
|
33
|
+
- **Claude Code:** invoke the `sdlc-implementer` skill immediately via `Skill(name: "sdlc-implementer", …)`. The skill drives Phase 0 (triage) through Phase 4 (PR + UAT review).
|
|
34
|
+
- **Other agents (Cursor, Windsurf, Gemini, etc.):** proceed with the SDLC workflow manually, following the stage docs in `SDLC/`. **You MUST first create the commit sentinel:** `touch .sdlc-implementer-invoked` — without this file, the `commit-msg` and `pre-push` hooks will reject `feat`/`fix`/`refactor`/`perf` commits.
|
|
35
|
+
- **NO** → proceed with manual implementation outside the SDLC workflow. The user has explicitly opted out; respect their choice and do not ask again for the same issue.
|
|
34
36
|
|
|
35
37
|
This prompt is **mandatory and structural** — it is not advisory. The `sdlc-implementer` is the default entry point; manual implementation is the explicit opt-out. Skipping the prompt and jumping straight into code is the same class of inertia-trap bug as #132 (e2e delegation bypass).
|
|
36
38
|
|
|
@@ -46,9 +48,17 @@ The most common failure mode for this rule is **not skipping the prompt entirely
|
|
|
46
48
|
- Walking through Stage 1 → Stage 2 → Stage 3 sequentially by reading each workflow file
|
|
47
49
|
- Saying "let me read the SDLC workflow files" or "let me follow the SDLC process" without invoking the skill
|
|
48
50
|
|
|
49
|
-
**When you catch yourself:** Stop immediately
|
|
51
|
+
**When you catch yourself:** Stop immediately and route to your platform's orchestration path:
|
|
52
|
+
- **Claude Code:** Invoke the skill with `Skill(name: "sdlc-implementer", …)`. The skill will re-read state and resume correctly.
|
|
53
|
+
- **Other agents (Cursor, Windsurf, Gemini, etc.):** Ensure you have operator authorization and have created the commit sentinel (`touch .sdlc-implementer-invoked`). Then follow the stage docs step by step, pausing at each gate for operator confirmation.
|
|
50
54
|
|
|
51
|
-
|
|
55
|
+
**Structural enforcement (not just advisory):**
|
|
56
|
+
- Every SDLC stage doc (`SDLC/1-plan-requirement.md` through `SDLC/5-deploy-main.md`) and `SDLC/implementing-an-sdlc-issue.md` now opens with a **SYSTEM OVERRIDE banner** naming this anti-pattern and providing agent-agnostic routing instructions. If you read one of those files manually, the first thing you see is the warning. Heed it.
|
|
57
|
+
- The `commit-msg` hook checks for the `.sdlc-implementer-invoked` sentinel on `feat`/`fix`/`refactor`/`perf` commits. If the skill was not invoked (or the sentinel was not manually created by a non-Claude agent with operator authorization), **the commit is refused** — not just the push, the commit itself.
|
|
58
|
+
- The `pre-push` hook provides a second sentinel check (defence in depth).
|
|
59
|
+
- CI's `validate-commits.sh` checks RTM provenance — the unskippable safety net.
|
|
60
|
+
|
|
61
|
+
This anti-pattern is the same class of bug as #132 (e2e delegation bypass): the agent has a purpose-built tool and defaults to hand-rolling the procedure it automates. Use the tool — or, for non-Claude agents, follow the authorized manual path with the sentinel in place.
|
|
52
62
|
|
|
53
63
|
### Driver clarity — always state who is driving (devaudit-installer#199)
|
|
54
64
|
|
|
@@ -25,8 +25,10 @@ When the user requests implementation of an issue (e.g. "implement issue #N", "f
|
|
|
25
25
|
|
|
26
26
|
Wait for the user's yes/no response. Do NOT begin implementation until they answer.
|
|
27
27
|
|
|
28
|
-
- **YES** →
|
|
29
|
-
- **
|
|
28
|
+
- **YES** → route to your platform's orchestration path:
|
|
29
|
+
- **Claude Code:** invoke the `sdlc-implementer` skill immediately via `Skill(name: "sdlc-implementer", …)`. The skill drives Phase 0 (triage) through Phase 4 (PR + UAT review).
|
|
30
|
+
- **Other agents (Cursor, Windsurf, Gemini, etc.):** proceed with the SDLC workflow manually, following the stage docs in `SDLC/`. **You MUST first create the commit sentinel:** `touch .sdlc-implementer-invoked` — without this file, the `commit-msg` and `pre-push` hooks will reject `feat`/`fix`/`refactor`/`perf` commits.
|
|
31
|
+
- **NO** → proceed with manual implementation outside the SDLC workflow. The user has explicitly opted out; respect their choice and do not ask again for the same issue.
|
|
30
32
|
|
|
31
33
|
This prompt is **mandatory and structural** — it is not advisory. Skipping the prompt and jumping straight into code is the same class of inertia-trap bug as #132 (e2e delegation bypass).
|
|
32
34
|
|
|
@@ -42,7 +44,9 @@ The most common failure mode is **prompting (or being told to use the skill) and
|
|
|
42
44
|
- Walking through Stage 1 → Stage 2 → Stage 3 sequentially by reading each workflow file
|
|
43
45
|
- Saying "let me read the SDLC workflow files" or "let me follow the SDLC process" without invoking the skill
|
|
44
46
|
|
|
45
|
-
**When you catch yourself:** Stop immediately
|
|
47
|
+
**When you catch yourself:** Stop immediately and route to your platform's orchestration path:
|
|
48
|
+
- **Claude Code:** Invoke the skill with `Skill(name: "sdlc-implementer", …)`. The skill will re-read state and resume correctly.
|
|
49
|
+
- **Other agents (Cursor, Windsurf, Gemini, etc.):** Ensure you have operator authorization and have created the commit sentinel (`touch .sdlc-implementer-invoked`). Then follow the stage docs step by step, pausing at each gate for operator confirmation.
|
|
46
50
|
|
|
47
51
|
## Driver clarity — always state who is driving (devaudit-installer#199)
|
|
48
52
|
|
|
@@ -29,8 +29,10 @@ When the user requests implementation of an issue (e.g. "implement issue #N", "f
|
|
|
29
29
|
|
|
30
30
|
Wait for the user's yes/no response. Do NOT begin implementation until they answer.
|
|
31
31
|
|
|
32
|
-
- **YES** →
|
|
33
|
-
- **
|
|
32
|
+
- **YES** → route to your platform's orchestration path:
|
|
33
|
+
- **Claude Code:** invoke the `sdlc-implementer` skill immediately via `Skill(name: "sdlc-implementer", …)`. The skill drives Phase 0 (triage) through Phase 4 (PR + UAT review).
|
|
34
|
+
- **Other agents (Cursor, Windsurf, Gemini, etc.):** proceed with the SDLC workflow manually, following the stage docs in `SDLC/`. **You MUST first create the commit sentinel:** `touch .sdlc-implementer-invoked` — without this file, the `commit-msg` and `pre-push` hooks will reject `feat`/`fix`/`refactor`/`perf` commits.
|
|
35
|
+
- **NO** → proceed with manual implementation outside the SDLC workflow. The user has explicitly opted out; respect their choice and do not ask again for the same issue.
|
|
34
36
|
|
|
35
37
|
This prompt is **mandatory and structural** — it is not advisory. Skipping the prompt and jumping straight into code is the same class of inertia-trap bug as #132 (e2e delegation bypass).
|
|
36
38
|
|
|
@@ -46,7 +48,9 @@ The most common failure mode is **prompting (or being told to use the skill) and
|
|
|
46
48
|
- Walking through Stage 1 → Stage 2 → Stage 3 sequentially by reading each workflow file
|
|
47
49
|
- Saying "let me read the SDLC workflow files" or "let me follow the SDLC process" without invoking the skill
|
|
48
50
|
|
|
49
|
-
**When you catch yourself:** Stop immediately
|
|
51
|
+
**When you catch yourself:** Stop immediately and route to your platform's orchestration path:
|
|
52
|
+
- **Claude Code:** Invoke the skill with `Skill(name: "sdlc-implementer", …)`. The skill will re-read state and resume correctly.
|
|
53
|
+
- **Other agents (Cursor, Windsurf, Gemini, etc.):** Ensure you have operator authorization and have created the commit sentinel (`touch .sdlc-implementer-invoked`). Then follow the stage docs step by step, pausing at each gate for operator confirmation.
|
|
50
54
|
|
|
51
55
|
### Driver clarity — always state who is driving (devaudit-installer#199)
|
|
52
56
|
|
|
@@ -23,8 +23,10 @@ When the user requests implementation of an issue (e.g. "implement issue #N", "f
|
|
|
23
23
|
|
|
24
24
|
Wait for the user's yes/no response. Do NOT begin implementation until they answer.
|
|
25
25
|
|
|
26
|
-
- **YES** →
|
|
27
|
-
- **
|
|
26
|
+
- **YES** → route to your platform's orchestration path:
|
|
27
|
+
- **Claude Code:** invoke the `sdlc-implementer` skill immediately via `Skill(name: "sdlc-implementer", …)`. The skill drives Phase 0 (triage) through Phase 4 (PR + UAT review).
|
|
28
|
+
- **Other agents (Cursor, Windsurf, Gemini, etc.):** proceed with the SDLC workflow manually, following the stage docs in `SDLC/`. **You MUST first create the commit sentinel:** `touch .sdlc-implementer-invoked` — without this file, the `commit-msg` and `pre-push` hooks will reject `feat`/`fix`/`refactor`/`perf` commits.
|
|
29
|
+
- **NO** → proceed with manual implementation outside the SDLC workflow. The user has explicitly opted out; respect their choice and do not ask again for the same issue.
|
|
28
30
|
|
|
29
31
|
This prompt is **mandatory and structural** — it is not advisory. Skipping the prompt and jumping straight into code is the same class of inertia-trap bug as #132 (e2e delegation bypass).
|
|
30
32
|
|
|
@@ -40,7 +42,9 @@ The most common failure mode is **prompting (or being told to use the skill) and
|
|
|
40
42
|
- Walking through Stage 1 → Stage 2 → Stage 3 sequentially by reading each workflow file
|
|
41
43
|
- Saying "let me read the SDLC workflow files" or "let me follow the SDLC process" without invoking the skill
|
|
42
44
|
|
|
43
|
-
**When you catch yourself:** Stop immediately
|
|
45
|
+
**When you catch yourself:** Stop immediately and route to your platform's orchestration path:
|
|
46
|
+
- **Claude Code:** Invoke the skill with `Skill(name: "sdlc-implementer", …)`. The skill will re-read state and resume correctly.
|
|
47
|
+
- **Other agents (Cursor, Windsurf, Gemini, etc.):** Ensure you have operator authorization and have created the commit sentinel (`touch .sdlc-implementer-invoked`). Then follow the stage docs step by step, pausing at each gate for operator confirmation.
|
|
44
48
|
|
|
45
49
|
### Driver clarity — always state who is driving (devaudit-installer#199)
|
|
46
50
|
|
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
description: Define a new requirement in the RTM, classify risk, create implementation plan, generate test scope, and prepare for implementation
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
### 🛑 SYSTEM OVERRIDE: AUTOMATED SDLC ENFORCEMENT
|
|
6
|
+
|
|
7
|
+
If you are an AI agent reading this file, you are strictly prohibited from manually executing this workflow step-by-step unless explicitly authorized. Route immediately to your platform's orchestration path:
|
|
8
|
+
|
|
9
|
+
- **CLAUDE CODE:** Halt manual tracking immediately. Invoke the orchestrator skill via: `Skill(name: "sdlc-implementer", …)`
|
|
10
|
+
- **OTHER AGENTS (Cursor, Windsurf, Gemini, etc.):** Halt and output this exact message to the user:
|
|
11
|
+
"I am pausing to request authorization for the SDLC workflow on this issue. Please confirm if I should proceed."
|
|
12
|
+
|
|
13
|
+
CRITICAL: Once the operator grants permission, you MUST execute `touch .sdlc-implementer-invoked` to generate the required commit sentinel BEFORE making any file modifications. Failure to create this sentinel file will result in local git commits being automatically rejected by the pre-commit hooks.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
5
17
|
# Plan Requirement
|
|
6
18
|
|
|
7
19
|
**Pipeline Stage:** 1 of 5
|
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
description: Implement changes on develop, run scoped local gates, and let CI/UAT provide authoritative full E2E verification when local prerequisites are unavailable
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
### 🛑 SYSTEM OVERRIDE: AUTOMATED SDLC ENFORCEMENT
|
|
6
|
+
|
|
7
|
+
If you are an AI agent reading this file, you are strictly prohibited from manually executing this workflow step-by-step unless explicitly authorized. Route immediately to your platform's orchestration path:
|
|
8
|
+
|
|
9
|
+
- **CLAUDE CODE:** Halt manual tracking immediately. Invoke the orchestrator skill via: `Skill(name: "sdlc-implementer", …)`
|
|
10
|
+
- **OTHER AGENTS (Cursor, Windsurf, Gemini, etc.):** Halt and output this exact message to the user:
|
|
11
|
+
"I am pausing to request authorization for the SDLC workflow on this issue. Please confirm if I should proceed."
|
|
12
|
+
|
|
13
|
+
CRITICAL: Once the operator grants permission, you MUST execute `touch .sdlc-implementer-invoked` to generate the required commit sentinel BEFORE making any file modifications. Failure to create this sentinel file will result in local git commits being automatically rejected by the pre-commit hooks.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
5
17
|
# Implement & Test
|
|
6
18
|
|
|
7
19
|
**Pipeline Stage:** 2 of 5
|
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
description: Compile test, security, and AI evidence, update RTM, create release ticket for review
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
### 🛑 SYSTEM OVERRIDE: AUTOMATED SDLC ENFORCEMENT
|
|
6
|
+
|
|
7
|
+
If you are an AI agent reading this file, you are strictly prohibited from manually executing this workflow step-by-step unless explicitly authorized. Route immediately to your platform's orchestration path:
|
|
8
|
+
|
|
9
|
+
- **CLAUDE CODE:** Halt manual tracking immediately. Invoke the orchestrator skill via: `Skill(name: "sdlc-implementer", …)`
|
|
10
|
+
- **OTHER AGENTS (Cursor, Windsurf, Gemini, etc.):** Halt and output this exact message to the user:
|
|
11
|
+
"I am pausing to request authorization for the SDLC workflow on this issue. Please confirm if I should proceed."
|
|
12
|
+
|
|
13
|
+
CRITICAL: Once the operator grants permission, you MUST execute `touch .sdlc-implementer-invoked` to generate the required commit sentinel BEFORE making any file modifications. Failure to create this sentinel file will result in local git commits being automatically rejected by the pre-commit hooks.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
5
17
|
# Compile Evidence
|
|
6
18
|
|
|
7
19
|
**Pipeline Stage:** 3 of 5
|
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
description: Create a PR from develop to main — triggers CI independent verification and human review
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
### 🛑 SYSTEM OVERRIDE: AUTOMATED SDLC ENFORCEMENT
|
|
6
|
+
|
|
7
|
+
If you are an AI agent reading this file, you are strictly prohibited from manually executing this workflow step-by-step unless explicitly authorized. Route immediately to your platform's orchestration path:
|
|
8
|
+
|
|
9
|
+
- **CLAUDE CODE:** Halt manual tracking immediately. Invoke the orchestrator skill via: `Skill(name: "sdlc-implementer", …)`
|
|
10
|
+
- **OTHER AGENTS (Cursor, Windsurf, Gemini, etc.):** Halt and output this exact message to the user:
|
|
11
|
+
"I am pausing to request authorization for the SDLC workflow on this issue. Please confirm if I should proceed."
|
|
12
|
+
|
|
13
|
+
CRITICAL: Once the operator grants permission, you MUST execute `touch .sdlc-implementer-invoked` to generate the required commit sentinel BEFORE making any file modifications. Failure to create this sentinel file will result in local git commits being automatically rejected by the pre-commit hooks.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
5
17
|
# Submit for Review
|
|
6
18
|
|
|
7
19
|
**Pipeline Stage:** 4 of 5
|
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
description: Merge approved PR, verify deployment including security checks, sync branches, finalize compliance
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
### 🛑 SYSTEM OVERRIDE: AUTOMATED SDLC ENFORCEMENT
|
|
6
|
+
|
|
7
|
+
If you are an AI agent reading this file, you are strictly prohibited from manually executing this workflow step-by-step unless explicitly authorized. Route immediately to your platform's orchestration path:
|
|
8
|
+
|
|
9
|
+
- **CLAUDE CODE:** Halt manual tracking immediately. Invoke the orchestrator skill via: `Skill(name: "sdlc-implementer", …)`
|
|
10
|
+
- **OTHER AGENTS (Cursor, Windsurf, Gemini, etc.):** Halt and output this exact message to the user:
|
|
11
|
+
"I am pausing to request authorization for the SDLC workflow on this issue. Please confirm if I should proceed."
|
|
12
|
+
|
|
13
|
+
CRITICAL: Once the operator grants permission, you MUST execute `touch .sdlc-implementer-invoked` to generate the required commit sentinel BEFORE making any file modifications. Failure to create this sentinel file will result in local git commits being automatically rejected by the pre-commit hooks.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
5
17
|
# Deploy to Production
|
|
6
18
|
|
|
7
19
|
**Pipeline Stage:** 5 of 5
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Implementing a GitHub issue under the Metasession SDLC
|
|
2
2
|
|
|
3
|
+
### 🛑 SYSTEM OVERRIDE: AUTOMATED SDLC ENFORCEMENT
|
|
4
|
+
|
|
5
|
+
If you are an AI agent reading this file, you are strictly prohibited from manually executing this workflow step-by-step unless explicitly authorized. Route immediately to your platform's orchestration path:
|
|
6
|
+
|
|
7
|
+
- **CLAUDE CODE:** Halt manual tracking immediately. Invoke the orchestrator skill via: `Skill(name: "sdlc-implementer", …)`
|
|
8
|
+
- **OTHER AGENTS (Cursor, Windsurf, Gemini, etc.):** Halt and output this exact message to the user:
|
|
9
|
+
"I am pausing to request authorization for the SDLC workflow on this issue. Please confirm if I should proceed."
|
|
10
|
+
|
|
11
|
+
CRITICAL: Once the operator grants permission, you MUST execute `touch .sdlc-implementer-invoked` to generate the required commit sentinel BEFORE making any file modifications. Failure to create this sentinel file will result in local git commits being automatically rejected by the pre-commit hooks.
|
|
12
|
+
|
|
3
13
|
End-to-end walkthrough for taking a GitHub issue from triage to merged-and-deployed under the Metasession SDLC. Audience: this project's developers and AI coding agents.
|
|
4
14
|
|
|
5
15
|
> This document is **synced into your repo from DevAudit-Installer** via `devaudit update`. Do not edit this file in place — your edits will be overwritten on the next sync. To propose a change, open a Task issue against [`metasession-dev/DevAudit-Installer`](https://github.com/metasession-dev/DevAudit-Installer) referencing `sdlc/files/_common/implementing-an-sdlc-issue.md`.
|
|
@@ -1,7 +1,40 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Husky commit-msg hook — runs commitlint
|
|
3
|
-
#
|
|
2
|
+
# Husky commit-msg hook — runs commitlint + skill-invocation sentinel check.
|
|
3
|
+
#
|
|
4
|
+
# 1. Runs commitlint to validate commit message format (Conventional Commits,
|
|
5
|
+
# SDLC trailers).
|
|
6
|
+
# 2. If the commit is feat/fix/refactor/perf, checks for the
|
|
7
|
+
# .sdlc-implementer-invoked sentinel. If missing, blocks the commit —
|
|
8
|
+
# the sdlc-implementer skill was not invoked (devaudit-installer#199/#226).
|
|
9
|
+
# Housekeeping types (docs/chore/ci/build/test/revert) are exempt.
|
|
10
|
+
#
|
|
11
|
+
# Bypass with --no-verify (last resort — pre-push hook and CI also check).
|
|
4
12
|
#
|
|
5
13
|
# Install: cp this file to .husky/commit-msg && chmod +x .husky/commit-msg
|
|
6
14
|
|
|
7
|
-
|
|
15
|
+
COMMIT_MSG_FILE="$1"
|
|
16
|
+
|
|
17
|
+
# ── 1. Commitlint ────────────────────────────────────────────────────
|
|
18
|
+
npx commitlint --edit "$COMMIT_MSG_FILE"
|
|
19
|
+
|
|
20
|
+
# ── 2. Skill-invocation sentinel (devaudit-installer#199/#226) ──────
|
|
21
|
+
# If the commit type is feat/fix/refactor/perf, verify the
|
|
22
|
+
# sdlc-implementer skill was invoked (writes .sdlc-implementer-invoked).
|
|
23
|
+
# Housekeeping types are exempt. This fires at commit time — earlier
|
|
24
|
+
# than the pre-push hook — so the agent hits the gate before it can
|
|
25
|
+
# even create the commit.
|
|
26
|
+
TRACKED_TYPES='^(feat|fix|refactor|perf)(\(.+\))?!?:'
|
|
27
|
+
COMMIT_SUBJECT=$(head -1 "$COMMIT_MSG_FILE")
|
|
28
|
+
|
|
29
|
+
if echo "$COMMIT_SUBJECT" | grep -qE "$TRACKED_TYPES"; then
|
|
30
|
+
if [ ! -f .sdlc-implementer-invoked ]; then
|
|
31
|
+
echo ""
|
|
32
|
+
echo "ERROR: sdlc-implementer skill was not invoked (devaudit-installer#199)."
|
|
33
|
+
echo " This commit uses a tracked type ($COMMIT_SUBJECT) which requires"
|
|
34
|
+
echo " the SDLC skill flow. The .sdlc-implementer-invoked sentinel is missing."
|
|
35
|
+
echo ""
|
|
36
|
+
echo " Invoke sdlc-implementer to drive the process, or use --no-verify"
|
|
37
|
+
echo " to bypass (not recommended — pre-push hook and CI will also check)."
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
40
|
+
fi
|