Skip to content

Commit 2014630

Browse files
chore(tooling): refresh managed config + source credentials from env (#511)
* chore(tooling): refresh managed config to current Vergil tooling/actions Items 1/3/6/7 of the fleet refresh (epic mq-rest-admin-project/.github#14): marketplace -> vergil-claude-plugin; embed canonical CLAUDE.md template (+ vrg-docker-run -> vrg-container-run); ignore .vergil/; cd.yml release uses secrets: inherit (fixes CD startup_failure). Hook guard (item 2) already landed via #509. audit COMPLIANT; vrg-validate passes. Refs #510. * fix(security): source test and example credentials from the environment Updated CodeQL/Semgrep rulesets flag hard-coded credentials. Remove all hard-coded password literals from test and example code: - tests/pymqrest/{test_auth,test_session,test_ensure,test_sync}.py: TEST_PASSWORD now reads MQ_TEST_PASSWORD from the env (defaults empty); mock transports ignore the value and assertions compare against the same constant. - examples/*.py __main__ blocks: require MQ_ADMIN_PASSWORD from the env instead of defaulting to a hard-coded "mqadmin". vrg-validate (incl. 100% coverage) passes. Refs #510. * fix(security): use verified SSL context in archived extraction scripts Semgrep python.lang.security.unverified-ssl-context flagged ssl._create_unverified_context() in the archived MQSC doc-extraction scripts. They fetch public IBM docs (https://www.ibm.com/docs, valid certs), so switch to ssl.create_default_context() — verification works and the insecure context is removed. Scripts are archived/not run in CI; change is static-clean for the scanner and more correct if re-run. Refs #510. --------- Co-authored-by: Phillip Moore <w.phillip.moore@gmail.com>
1 parent 99b2d72 commit 2014630

18 files changed

Lines changed: 63 additions & 36 deletions

.claude/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"vergil-marketplace": {
2222
"source": {
2323
"source": "github",
24-
"repo": "vergil-project/vergil-plugin"
24+
"repo": "vergil-project/vergil-claude-plugin"
2525
}
2626
}
2727
},

.github/workflows/cd.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,4 @@ jobs:
3131
language: python
3232
container-tag: "3.14"
3333
registry-publish: true
34-
secrets:
35-
APP_CLIENT_ID: ${{ secrets.APP_CLIENT_ID }}
36-
APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }}
34+
secrets: inherit

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,6 @@ marimo/_static/
207207
marimo/_lsp/
208208
__marimo__/
209209
.worktrees/
210+
211+
# Vergil tooling scratch (PR/session working dir)
212+
.vergil/

CLAUDE.md

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,27 +36,27 @@ on-ramp.
3636
### Structure
3737

3838
```text
39-
~/dev/github/mq-rest-admin-python/ ← sessions ALWAYS start here
39+
<project-root>/ ← sessions ALWAYS start here
4040
.git/
41-
CLAUDE.md, src/, tests/, … ← main worktree (usually `develop`)
42-
.worktrees/ ← container for parallel worktrees
43-
issue-454-adopt-worktree-convention/ ← worktree on feature/454-...
41+
CLAUDE.md, ← main worktree (usually `develop`)
42+
.worktrees/ ← container for parallel worktrees
43+
issue-<N>-<short-slug>/ ← worktree on feature/<N>-<short-slug>
4444
4545
```
4646

4747
### Rules
4848

4949
1. **Sessions always start at the project root.**
50-
`cd ~/dev/github/mq-rest-admin-python && claude` — never from inside
51-
`.worktrees/<name>/`. This keeps the memory-path slug stable and shared.
50+
Never start Claude from inside `.worktrees/<name>/`. This keeps the
51+
memory-path slug stable and shared.
5252
2. **Each parallel agent is assigned exactly one worktree.** The session
5353
prompt names the worktree (see Agent prompt contract below).
5454
- For Read / Edit / Write tools: use the worktree's absolute path.
5555
- For Bash commands that touch files: `cd` into the worktree first,
5656
or use absolute paths.
5757
3. **The main worktree is read-only.** All edits flow through a worktree
5858
on a feature branch — the logical endpoint of the standing
59-
"no direct commits to `develop`" policy.
59+
"no direct commits to develop" policy.
6060
4. **One worktree per issue.** Don't stack in-flight issues. When a
6161
branch lands, remove the worktree before starting the next.
6262
5. **Naming: `issue-<N>-<short-slug>`.** `<N>` is the GitHub issue
@@ -70,22 +70,44 @@ placeholders):
7070
```text
7171
You are working on issue #<N>: <issue title>.
7272
73-
Your worktree is: /Users/pmoore/dev/github/mq-rest-admin-python/.worktrees/issue-<N>-<slug>/
73+
Your worktree is: <project-root>/.worktrees/issue-<N>-<slug>/
7474
Your branch is: feature/<N>-<slug>
7575
7676
Rules for this session:
7777
- Do all git operations from inside your worktree:
78-
cd <absolute-worktree-path> && git <command>
78+
cd <absolute-worktree-path> && vrg-git <command>
7979
- For Read / Edit / Write tools, use the absolute worktree path.
8080
- For Bash commands that touch files, cd into the worktree first
8181
or use absolute paths.
8282
- Do not edit files at the project root. The main worktree is
8383
read-only — all changes flow through your worktree on your
8484
feature branch.
85+
- When you need to run validation, run it from inside your worktree
86+
(vrg-container-run mounts the current directory).
8587
```
8688

8789
All fields are required.
8890

91+
## Shell command policy
92+
93+
Use `vrg-git` instead of `git` for all git operations. Use `vrg-gh`
94+
instead of `gh` for all GitHub CLI operations. These wrappers enforce
95+
subcommand allowlists, flag deny lists, and credential selection.
96+
97+
Raw `git` and `gh` are denied by the permission model. If a command
98+
is not available through the wrappers, explain the situation to the
99+
human who can run it directly via `! <command>` in the prompt.
100+
101+
## Validation
102+
103+
```bash
104+
vrg-container-run -- vrg-validate
105+
```
106+
107+
This is the **only** validation command. Do not run individual linters,
108+
formatters, or other tools outside of `vrg-validate`. If a tool is not
109+
invoked by `vrg-validate`, it is not part of the validation pipeline.
110+
89111
## Project Overview
90112

91113
`pymqrest` is a Python wrapper for the IBM MQ administrative REST API. The project provides a Python mapping layer for MQ REST API attribute translations and command metadata experiments. The current focus is on attribute mapping and metadata modeling.
@@ -123,7 +145,7 @@ gates.
123145
### Validation
124146

125147
```bash
126-
vrg-docker-run -- vrg-validate # Full validation (runs in dev container)
148+
vrg-container-run -- vrg-validate # Full validation (runs in dev container)
127149
```
128150
- Lock file verification
129151
- Security audit (pip-audit)

docs/archive/extraction/scripts/build_mqsc_pcf_command_map.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ def read_group_entries() -> list[GroupEntry]:
248248

249249
def fetch_html(href: str) -> str:
250250
url = f"{IBM_DOCS_BASE}{href}"
251-
context = ssl._create_unverified_context() # noqa: S323, SLF001
251+
context = ssl.create_default_context()
252252
request = Request( # noqa: S310
253253
url,
254254
headers={"User-Agent": "pymqrest-pcf-map/1.0", "Accept": "text/html"},

docs/archive/extraction/scripts/extract_mqsc_command_metadata.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ def extract_command_name(html: str) -> str | None:
602602

603603
def fetch_html(href: str) -> str:
604604
url = f"{IBM_DOCS_BASE}{href}"
605-
context = ssl._create_unverified_context() # noqa: S323, SLF001
605+
context = ssl.create_default_context()
606606
request = urllib.request.Request( # noqa: S310
607607
url,
608608
headers={

docs/archive/extraction/scripts/extract_pcf_command_pages.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def handle_data(self, data: str) -> None:
6363

6464

6565
def fetch_index(url: str) -> str:
66-
context = ssl._create_unverified_context() # noqa: S323, SLF001
66+
context = ssl.create_default_context()
6767
request = Request( # noqa: S310
6868
url,
6969
headers={"User-Agent": "pymqrest-pcf-index/1.0", "Accept": "text/html"},

docs/archive/extraction/scripts/refresh_mqsc_output_parameters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ def fetch_html(href: str) -> str:
162162
if cache_path.exists():
163163
return cache_path.read_text(encoding="utf-8", errors="ignore")
164164
url = f"{IBM_DOCS_BASE}{href}"
165-
context = ssl._create_unverified_context() # noqa: S323, SLF001
165+
context = ssl.create_default_context()
166166
request = urllib.request.Request( # noqa: S310
167167
url,
168168
headers={

examples/channel_status.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from __future__ import annotations
1212

1313
from dataclasses import dataclass
14-
from os import getenv
14+
from os import environ, getenv
1515

1616
from pymqrest import MQRESTError, MQRESTSession
1717
from pymqrest.auth import LTPAAuth
@@ -120,7 +120,7 @@ def main(session: MQRESTSession) -> list[ChannelInfo]:
120120
session = MQRESTSession(
121121
rest_base_url=getenv("MQ_REST_BASE_URL", "https://localhost:9443/ibmmq/rest/v2"),
122122
qmgr_name=getenv("MQ_QMGR_NAME", "QM1"),
123-
credentials=LTPAAuth(getenv("MQ_ADMIN_USER", "mqadmin"), getenv("MQ_ADMIN_PASSWORD", "mqadmin")),
123+
credentials=LTPAAuth(getenv("MQ_ADMIN_USER", "mqadmin"), environ["MQ_ADMIN_PASSWORD"]),
124124
verify_tls=False,
125125
)
126126

examples/dlq_inspector.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from __future__ import annotations
1313

1414
from dataclasses import dataclass
15-
from os import getenv
15+
from os import environ, getenv
1616

1717
from pymqrest import MQRESTSession
1818
from pymqrest.auth import LTPAAuth
@@ -147,7 +147,7 @@ def _to_int(value: object) -> int:
147147
session = MQRESTSession(
148148
rest_base_url=getenv("MQ_REST_BASE_URL", "https://localhost:9443/ibmmq/rest/v2"),
149149
qmgr_name=getenv("MQ_QMGR_NAME", "QM1"),
150-
credentials=LTPAAuth(getenv("MQ_ADMIN_USER", "mqadmin"), getenv("MQ_ADMIN_PASSWORD", "mqadmin")),
150+
credentials=LTPAAuth(getenv("MQ_ADMIN_USER", "mqadmin"), environ["MQ_ADMIN_PASSWORD"]),
151151
verify_tls=False,
152152
)
153153

0 commit comments

Comments
 (0)