Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
42af3fb
security: enforce strict ElectrumX TOFU pinning
ALENOC Aug 18, 2026
3a79cd9
security: deny Android cleartext traffic by default
ALENOC Aug 18, 2026
aae32d6
security: restrict Android verification links and cleartext
ALENOC Aug 18, 2026
b77cf90
security: harden NFC URI parsing and host validation
ALENOC Aug 18, 2026
397bb1d
security: remove tracked Android local SDK configuration
ALENOC Aug 18, 2026
bf128a3
security: ignore all Android local.properties files
ALENOC Aug 18, 2026
d3c9f47
ci: add temporary security remediation gate
ALENOC Aug 18, 2026
0ce834b
security: add local transaction fee safety policy
ALENOC Aug 18, 2026
d6a5d55
test: cover malicious fee safety invariants
ALENOC Aug 18, 2026
db838dd
security: stage deterministic remediation patcher
ALENOC Aug 18, 2026
46920a3
ci: execute deterministic security remediation wave
ALENOC Aug 18, 2026
c707aa3
ci: run remediation patcher from draft PR
ALENOC Aug 18, 2026
3270816
ci: fix literal replacements in remediation patcher
ALENOC Aug 18, 2026
c39251c
ci: rerun corrected deterministic remediation wave
ALENOC Aug 18, 2026
28c63c8
ci: use verified immutable MCP digest for remediation
ALENOC Aug 18, 2026
dcbb305
ci: align IPFS redirect patch with current source
ALENOC Aug 18, 2026
9511239
ci: keep workflow mutations out of runner push
ALENOC Aug 18, 2026
ec5021e
ci: push source-only compiled remediation wave
ALENOC Aug 18, 2026
6124510
security: fail closed auth, network, secrets and fee inputs
ALENOC Aug 18, 2026
f168ac5
security: stage financial transaction remediation wave
ALENOC Aug 18, 2026
2f62597
ci: run full financial security remediation gate
ALENOC Aug 18, 2026
38cc4a9
ops: separate backup encryption key from admin authentication
ALENOC Aug 18, 2026
2f32605
security: pin Qwen invoke workflow dependencies
ALENOC Aug 18, 2026
2ce9e36
ci: fix duplicate change-branch assertion in wave2
ALENOC Aug 18, 2026
b9fd9f2
ci: rerun corrected financial security wave
ALENOC Aug 18, 2026
7dfd1c2
ci: align wave2 send caller with current ViewModel syntax
ALENOC Aug 18, 2026
b68542a
ci: rerun wave2 with current ViewModel caller syntax
ALENOC Aug 18, 2026
864a643
ci: finalize wave2 caller and explicit max accounting
ALENOC Aug 18, 2026
6ceae8e
ci: execute final wave2 transform and full JVM gate
ALENOC Aug 18, 2026
5657e14
security: verify registry claims against decoded Ravencoin issuance
ALENOC Aug 18, 2026
de262f5
test: cover registry issuance authenticity rules
ALENOC Aug 18, 2026
7ebbc53
test: add backend security regression command
ALENOC Aug 18, 2026
02da3fe
ci: align SUN fixture patch with current test implementation
ALENOC Aug 18, 2026
116a82c
ci: rerun wave2 with current SUN fixture
ALENOC Aug 18, 2026
c216e1a
ci: diagnose remaining direct wallet broadcast site
ALENOC Aug 18, 2026
db6eef4
ci: print residual wallet broadcast for final wave2 fix
ALENOC Aug 18, 2026
7f4fc2b
ci: include reissue in pre-sign reservation boundary
ALENOC Aug 18, 2026
a0f16c6
ci: run complete financial remediation including reissue
ALENOC Aug 18, 2026
bb2d671
security: add fail-closed authentication primitive for mnemonic key
ALENOC Aug 18, 2026
fefc68c
security: expose consensus-decoded raw transaction for registry verif…
ALENOC Aug 18, 2026
cde3da1
security: require semantic on-chain issuance proof for registry notify
ALENOC Aug 18, 2026
44512cb
security: stage auth-bound mnemonic reveal migration
ALENOC Aug 18, 2026
905aee2
security: pin Qwen review workflow dependencies
ALENOC Aug 18, 2026
3936875
security: pin Qwen triage action and remove OIDC
ALENOC Aug 18, 2026
6cd7ac9
security: pin scheduled Qwen triage action and remove OIDC
ALENOC Aug 18, 2026
abdb416
ops: use dedicated backup key and 24h seven-snapshot policy
ALENOC Aug 18, 2026
1dd77ed
ops: document dedicated backup encryption configuration
ALENOC Aug 18, 2026
1cf6e51
ci: enforce explicit internal-backup key during remediation gate
ALENOC Aug 18, 2026
5f061f9
security: remove unnecessary Qwen dispatcher OIDC permission
ALENOC Aug 18, 2026
2381857
security: centralize standards-correct BIP39 NFKD seed derivation
ALENOC Aug 18, 2026
aed2479
test: add BIP39 official seed and NFKD regression vectors
ALENOC Aug 18, 2026
9e02ec6
security: couple auth-bound reveal with tested BIP39 KDF
ALENOC Aug 18, 2026
259b4bd
ci: diagnose final wave2 Kotlin integration errors
ALENOC Aug 18, 2026
60d6244
ci: finalize wave2 Kotlin integration fixes
ALENOC Aug 18, 2026
5058800
ci: run final wave2 build and regression gate
ALENOC Aug 18, 2026
db7534e
ci: diagnose remaining Android wave2 failures
ALENOC Aug 18, 2026
e2de879
ci: enforce final explicit-max ViewModel signature
ALENOC Aug 18, 2026
4dfcd2a
ci: run wave2 v7 final financial gate
ALENOC Aug 18, 2026
4d4c609
ci: fix wave2 security regression test source
ALENOC Aug 18, 2026
f62c7df
ci: run wave2 v8 with compiling security tests
ALENOC Aug 18, 2026
b86eabe
security: serialize wallet spends and remove implicit max-send
ALENOC Aug 18, 2026
74f4f96
ci: inspect backend dependency advisories
ALENOC Aug 18, 2026
85315c7
ci: resolve compatible backend dependency versions
ALENOC Aug 18, 2026
4b987b6
security: prepare final auth-bound and legacy migration remediation
ALENOC Aug 18, 2026
f708313
ci: enforce final repository security invariants
ALENOC Aug 18, 2026
c537195
security: prepare final remediation evidence documents
ALENOC Aug 18, 2026
aa8643a
ci: apply and verify final security remediation
ALENOC Aug 18, 2026
94893c8
ci: resolve final transitive path-to-regexp advisory
ALENOC Aug 18, 2026
1c0a2c3
security: make NDEF prefix parsing structurally bounds-safe
ALENOC Aug 18, 2026
2a5d20d
ci: rerun final remediation with bounds-safe NDEF parser
ALENOC Aug 18, 2026
8f4da15
security: make Android IPFS HTTP client redirect fail-closed
ALENOC Aug 18, 2026
30a3270
ci: harden final IPFS and immutable-ref checks
ALENOC Aug 18, 2026
d225e29
ci: fix final security gate invariant parsers
ALENOC Aug 18, 2026
9c558e4
security: complete auth-bound storage and dependency remediation
ALENOC Aug 18, 2026
963e7a6
ci: remove one-shot security remediation workflow
ALENOC Aug 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# RavenTag deployment environment template — no secret values are stored here.
NODE_ENV=production
ALLOWED_ORIGINS=https://raventag.com

# Ravencoin RPC
RVN_RPC_HOST=localhost
RVN_RPC_PORT=8766
RVN_PUBLIC_RPC_URL=https://rvn-rpc.publicnode.com

# Docker backup sidecar: point to a local file containing a strong random secret.
# Generate the file yourself, e.g. with: openssl rand -hex 32 > secrets/backup_encryption_key.txt
# NEVER point this setting at admin_key/operator_key/brand key material.
BACKUP_ENCRYPTION_KEY_FILE=./secrets/backup_encryption_key.txt

# The normal Docker deployment already has a backup sidecar. Leave the optional
# in-process scheduler disabled unless you deliberately deploy without that sidecar.
ENABLE_INTERNAL_BACKUP=false
# When ENABLE_INTERNAL_BACKUP=true, this path must exist inside the backend container/process.
# INTERNAL_BACKUP_ENCRYPTION_KEY_FILE=/run/secrets/backup_encryption_key
103 changes: 30 additions & 73 deletions .github/workflows/qwen-dispatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,23 @@ name: '🔀 Qwen Code Dispatch'

on:
pull_request_review_comment:
types:
- 'created'
types: ['created']
pull_request_review:
types:
- 'submitted'
types: ['submitted']
pull_request:
types:
- 'opened'
types: ['opened']
issues:
types:
- 'opened'
- 'reopened'
types: ['opened', 'reopened']
issue_comment:
types:
- 'created'
types: ['created']

defaults:
run:
shell: 'bash'

jobs:
debugger:
if: |-
${{ fromJSON(vars.DEBUG || vars.ACTIONS_STEP_DEBUG || false) }}
if: ${{ fromJSON(vars.DEBUG || vars.ACTIONS_STEP_DEBUG || false) }}
runs-on: 'ubuntu-latest'
permissions:
contents: 'read'
Expand All @@ -39,13 +32,9 @@ jobs:
DEBUG_event__pull_request__author_association: '${{ github.event.pull_request.author_association }}'
DEBUG_event__review__author_association: '${{ github.event.review.author_association }}'
DEBUG_event: '${{ toJSON(github.event) }}'
run: |-
env | grep '^DEBUG_'
run: env | grep '^DEBUG_'

dispatch:
# For PRs: only if not from a fork
# For issues: only on open/reopen
# For comments: only if user types @gemini-cli and is OWNER/MEMBER/COLLABORATOR
if: |-
(
github.event_name == 'pull_request' &&
Expand All @@ -71,9 +60,8 @@ jobs:
steps:
- name: 'Mint identity token'
id: 'mint_identity_token'
if: |-
${{ vars.APP_ID }}
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' # ratchet:actions/create-github-app-token@v2
if: ${{ vars.APP_ID }}
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b'
with:
app-id: '${{ vars.APP_ID }}'
private-key: '${{ secrets.APP_PRIVATE_KEY }}'
Expand All @@ -83,54 +71,39 @@ jobs:

- name: 'Extract command'
id: 'extract_command'
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@v7
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
env:
EVENT_TYPE: '${{ github.event_name }}.${{ github.event.action }}'
REQUEST: '${{ github.event.comment.body || github.event.review.body || github.event.issue.body }}'
with:
script: |
const eventType = process.env.EVENT_TYPE;
const request = process.env.REQUEST;
const request = process.env.REQUEST || '';
core.setOutput('request', request);

if (eventType === 'pull_request.opened') {
if (eventType === 'pull_request.opened') core.setOutput('command', 'review');
else if (['issues.opened', 'issues.reopened'].includes(eventType)) core.setOutput('command', 'triage');
else if (request.startsWith('@qwen-code /review')) {
core.setOutput('command', 'review');
} else if (['issues.opened', 'issues.reopened'].includes(eventType)) {
core.setOutput('command', 'triage');
} else if (request.startsWith("@qwen-code /review")) {
core.setOutput('command', 'review');
const additionalContext = request.replace(/^@qwen-code \/review/, '').trim();
core.setOutput('additional_context', additionalContext);
} else if (request.startsWith("@qwen-code /triage")) {
core.setOutput('command', 'triage');
} else if (request.startsWith("@qwen-code")) {
const additionalContext = request.replace(/^@qwen-code/, '').trim();
core.setOutput('additional_context', request.replace(/^@qwen-code \/review/, '').trim());
} else if (request.startsWith('@qwen-code /triage')) core.setOutput('command', 'triage');
else if (request.startsWith('@qwen-code')) {
core.setOutput('command', 'invoke');
core.setOutput('additional_context', additionalContext);
} else {
core.setOutput('command', 'fallthrough');
}
core.setOutput('additional_context', request.replace(/^@qwen-code/, '').trim());
} else core.setOutput('command', 'fallthrough');

- name: 'Acknowledge request'
env:
GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}'
GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || github.token }}'
ISSUE_NUMBER: '${{ github.event.pull_request.number || github.event.issue.number }}'
MESSAGE: |-
🤖 Hi @${{ github.actor }}, I've received your request, and I'm working on it now! You can track my progress [in the logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for more details.
REPOSITORY: '${{ github.repository }}'
run: |-
gh issue comment "${ISSUE_NUMBER}" \
--body "${MESSAGE}" \
--repo "${REPOSITORY}"
run: gh issue comment "${ISSUE_NUMBER}" --body "🤖 Request received. Track progress in ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" --repo "${REPOSITORY}"

review:
needs: 'dispatch'
if: |-
${{ needs.dispatch.outputs.command == 'review' }}
if: ${{ needs.dispatch.outputs.command == 'review' }}
uses: './.github/workflows/qwen-review.yml'
permissions:
contents: 'read'
id-token: 'write'
issues: 'write'
pull-requests: 'write'
with:
Expand All @@ -139,12 +112,10 @@ jobs:

triage:
needs: 'dispatch'
if: |-
${{ needs.dispatch.outputs.command == 'triage' }}
if: ${{ needs.dispatch.outputs.command == 'triage' }}
uses: './.github/workflows/qwen-triage.yml'
permissions:
contents: 'read'
id-token: 'write'
issues: 'write'
pull-requests: 'write'
with:
Expand All @@ -153,26 +124,19 @@ jobs:

invoke:
needs: 'dispatch'
if: |-
${{ needs.dispatch.outputs.command == 'invoke' }}
if: ${{ needs.dispatch.outputs.command == 'invoke' }}
uses: './.github/workflows/qwen-invoke.yml'
permissions:
contents: 'read'
id-token: 'write'
issues: 'write'
pull-requests: 'write'
with:
additional_context: '${{ needs.dispatch.outputs.additional_context }}'
secrets: 'inherit'

fallthrough:
needs:
- 'dispatch'
- 'review'
- 'triage'
- 'invoke'
if: |-
${{ always() && !cancelled() && (failure() || needs.dispatch.outputs.command == 'fallthrough') }}
needs: ['dispatch', 'review', 'triage', 'invoke']
if: ${{ always() && !cancelled() && (failure() || needs.dispatch.outputs.command == 'fallthrough') }}
runs-on: 'ubuntu-latest'
permissions:
contents: 'read'
Expand All @@ -181,24 +145,17 @@ jobs:
steps:
- name: 'Mint identity token'
id: 'mint_identity_token'
if: |-
${{ vars.APP_ID }}
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' # ratchet:actions/create-github-app-token@v2
if: ${{ vars.APP_ID }}
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b'
with:
app-id: '${{ vars.APP_ID }}'
private-key: '${{ secrets.APP_PRIVATE_KEY }}'
permission-contents: 'read'
permission-issues: 'write'
permission-pull-requests: 'write'

- name: 'Send failure comment'
env:
GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}'
GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || github.token }}'
ISSUE_NUMBER: '${{ github.event.pull_request.number || github.event.issue.number }}'
MESSAGE: |-
🤖 I'm sorry @${{ github.actor }}, but I was unable to process your request. Please [see the logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for more details.
REPOSITORY: '${{ github.repository }}'
run: |-
gh issue comment "${ISSUE_NUMBER}" \
--body "${MESSAGE}" \
--repo "${REPOSITORY}"
run: gh issue comment "${ISSUE_NUMBER}" --body "🤖 Unable to process the request. See ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" --repo "${REPOSITORY}"
7 changes: 3 additions & 4 deletions .github/workflows/qwen-invoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,14 @@ jobs:
runs-on: 'ubuntu-latest'
permissions:
contents: 'read'
id-token: 'write'
issues: 'write'
pull-requests: 'write'
steps:
- name: 'Mint identity token'
id: 'mint_identity_token'
if: |-
${{ vars.APP_ID }}
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' # ratchet:actions/create-github-app-token@v2
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' # immutable upstream commit
with:
app-id: '${{ vars.APP_ID }}'
private-key: '${{ secrets.APP_PRIVATE_KEY }}'
Expand All @@ -39,7 +38,7 @@ jobs:

- name: 'Run Qwen Code CLI'
id: 'run_qwen'
uses: 'QwenLM/qwen-code-action@v1' # ratchet:exclude
uses: 'QwenLM/qwen-code-action@05f81718976f3b7da657422e6e8e4d372b8621d7'
env:
TITLE: '${{ github.event.pull_request.title || github.event.issue.title }}'
DESCRIPTION: '${{ github.event.pull_request.body || github.event.issue.body }}'
Expand Down Expand Up @@ -76,7 +75,7 @@ jobs:
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server:v0.18.0"
"ghcr.io/github/github-mcp-server@sha256:6aa543f565bc98d96106fdd80a0abdc0c7147c8ca7f4663a814ceecef1ccc6d3"
],
"includeTools": [
"add_issue_comment",
Expand Down
47 changes: 9 additions & 38 deletions .github/workflows/qwen-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@ jobs:
timeout-minutes: 7
permissions:
contents: 'read'
id-token: 'write'
issues: 'write'
pull-requests: 'write'
steps:
- name: 'Mint identity token'
id: 'mint_identity_token'
if: |-
${{ vars.APP_ID }}
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' # ratchet:actions/create-github-app-token@v2
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b'
with:
app-id: '${{ vars.APP_ID }}'
private-key: '${{ secrets.APP_PRIVATE_KEY }}'
Expand All @@ -39,10 +38,10 @@ jobs:
permission-pull-requests: 'write'

- name: 'Checkout repository'
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8'

- name: 'Run Qwen Code pull request review'
uses: 'QwenLM/qwen-code-action@v1' # ratchet:exclude
uses: 'QwenLM/qwen-code-action@05f81718976f3b7da657422e6e8e4d372b8621d7'
id: 'qwen_pr_review'
env:
GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}'
Expand All @@ -61,44 +60,16 @@ jobs:
workflow_name: 'qwen-review'
settings: |-
{
"model": {
"maxSessionTurns": 25
},
"telemetry": {
"enabled": true,
"target": "local",
"outfile": ".qwen/telemetry.log"
},
"model": { "maxSessionTurns": 25 },
"telemetry": { "enabled": true, "target": "local", "outfile": ".qwen/telemetry.log" },
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server:v0.18.0"
],
"includeTools": [
"add_comment_to_pending_review",
"create_pending_pull_request_review",
"pull_request_read",
"submit_pending_pull_request_review"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
}
"args": ["run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server@sha256:6aa543f565bc98d96106fdd80a0abdc0c7147c8ca7f4663a814ceecef1ccc6d3"],
"includeTools": ["add_comment_to_pending_review", "create_pending_pull_request_review", "pull_request_read", "submit_pending_pull_request_review"],
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" }
}
},
"tools": {
"core": [
"run_shell_command(cat)",
"run_shell_command(echo)",
"run_shell_command(grep)",
"run_shell_command(head)",
"run_shell_command(tail)"
]
}
"tools": { "core": ["run_shell_command(cat)", "run_shell_command(echo)", "run_shell_command(grep)", "run_shell_command(head)", "run_shell_command(tail)"] }
}
prompt: '/qwen-review'
Loading
Loading