Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
453d6f8
test(core): expose executor and shared wire dependency boundaries
LIghtJUNction Sep 28, 2026
10f46fd
refactor(core): isolate executor ports and shared wire contracts
LIghtJUNction Sep 28, 2026
7f8752e
test: define backend-independent metadata session contracts
LIghtJUNction Sep 28, 2026
2daf1e0
test(storage): expose session backend and query contract drift
LIghtJUNction Sep 28, 2026
1dc01c0
ci: assemble and audit the exact metadata session extraction
LIghtJUNction Sep 28, 2026
20b6d7e
ci: deduplicate branch verification and record red boundary evidence
LIghtJUNction Sep 28, 2026
4a4bac6
ci: normalize extracted source EOF without changing the audited methods
LIghtJUNction Sep 28, 2026
5474eaf
refactor: separate shared metadata invariants from concrete database …
github-actions[bot] Sep 28, 2026
4a6b852
refactor(storage): share neutral sessions and expose guarded query ports
LIghtJUNction Sep 28, 2026
0ef416e
ci: remove one-shot assembly tooling before final metadata validation
LIghtJUNction Sep 28, 2026
a85b744
merge: verify executor and storage boundary repairs as one integration
LIghtJUNction Sep 28, 2026
8d17498
test: retain shared regression coverage while consolidating duplicate…
LIghtJUNction Sep 28, 2026
b0ec3fc
test(storage): converge on PR 167 implementation and retain independe…
LIghtJUNction Sep 28, 2026
e768cbc
merge: synchronize verified tool-runner main without dropping query c…
LIghtJUNction Sep 28, 2026
2d1cc44
merge: retain supplemental metadata coverage and converge on one impl…
LIghtJUNction Sep 28, 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
82 changes: 82 additions & 0 deletions .github/workflows/architecture-ports.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Architecture boundary regressions
on:
push:
branches: [fix/executor-core-20260929-2045]
pull_request:
paths:
- 'src/msg/**'
- 'tests/test_architecture_ports.py'
- 'tests/test_execution_composition.py'
- '.github/workflows/architecture-ports.yml'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: architecture-ports-${{ github.event.pull_request.head.repo.full_name || github.repository }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true
jobs:
focused:
runs-on: ubuntu-latest
timeout-minutes: 12
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: msgtest
POSTGRES_PASSWORD: msgtest
POSTGRES_DB: postgres
ports: ['5432:5432']
options: >-
--health-cmd "pg_isready -U msgtest"
--health-interval 5s --health-timeout 5s --health-retries 10
valkey:
image: valkey/valkey:9.0.6
ports: ['6379:6379']
options: >-
--health-cmd "valkey-cli ping"
--health-interval 5s --health-timeout 5s --health-retries 10
env:
MSG_TEST_POSTGRES_URL_TEMPLATE: postgresql://msgtest:msgtest@127.0.0.1:5432/{database}
MSG_TEST_VALKEY_URL: redis://127.0.0.1:6379/0
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: actions/setup-python@v7
with:
python-version: '3.15'
allow-prereleases: true
cache: pip
- name: Install isolated test dependencies
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq age
python -m pip install -e '.[dev]'
- name: Record source identity
env:
EVENT_HEAD: ${{ github.event.pull_request.head.sha || github.sha }}
run: |
mkdir -p artifacts
python - <<'PY'
import json, os, platform, subprocess
from pathlib import Path
def git(ref):
return subprocess.check_output(['git', 'rev-parse', ref], text=True).strip()
Path('artifacts/source.json').write_text(json.dumps({
'head': os.environ['EVENT_HEAD'], 'checkout': git('HEAD'), 'tree': git('HEAD^{tree}'),
'run': os.environ['GITHUB_RUN_ID'], 'attempt': os.environ['GITHUB_RUN_ATTEMPT'],
'python': platform.python_version(), 'scope': 'isolated-regression-not-production'
}, indent=2) + '\n')
PY
- name: Exercise boundaries and unchanged security contracts
run: >-
python -m pytest tests/test_architecture_ports.py tests/test_execution_composition.py tests/test_batch.py
tests/test_batch_secret_release.py tests/test_tools.py tests/test_webhook_domain_events.py
tests/test_read_projection_cache_transports.py tests/test_read_projection_cache_unit.py
tests/issue_78_80 --junitxml=artifacts/architecture-ports.xml
- uses: actions/upload-artifact@v4
if: always()
with:
name: architecture-ports-evidence
path: artifacts/
if-no-files-found: error
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
permissions:
contents: read
concurrency:
group: rewrite-${{ github.ref }}
group: rewrite-${{ github.event.pull_request.head.repo.full_name || github.repository }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true
jobs:
shards:
Expand Down
66 changes: 66 additions & 0 deletions .github/workflows/metadata-session-boundary.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Metadata session contracts
on:
push:
branches: [fix/metadata-session-boundary-20260929]
workflow_dispatch:
permissions:
contents: read
concurrency:
group: metadata-session-${{ github.ref }}
cancel-in-progress: false
jobs:
contracts:
runs-on: ubuntu-latest
timeout-minutes: 20
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: msgtest
POSTGRES_PASSWORD: msgtest
POSTGRES_DB: postgres
ports: ['5432:5432']
options: >-
--health-cmd "pg_isready -U msgtest"
--health-interval 10s --health-timeout 5s --health-retries 5
env:
MSG_TEST_POSTGRES_URL_TEMPLATE: postgresql://msgtest:msgtest@127.0.0.1:5432/{database}
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: actions/setup-python@v7
with:
python-version: '3.15'
allow-prereleases: true
cache: pip
- name: Install isolated test dependencies
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq age
python -m pip install -e '.[dev]'
- name: Record exact source
env:
SOURCE_SHA: ${{ github.sha }}
run: |
mkdir -p artifacts
test "$(git rev-parse HEAD)" = "$SOURCE_SHA"
python - <<'PY'
import json, os, subprocess
from pathlib import Path
git=lambda *args: subprocess.check_output(['git',*args],text=True).strip()
Path('artifacts/source.json').write_text(json.dumps({'commit':git('rev-parse','HEAD'),
'tree':git('rev-parse','HEAD^{tree}'),'event_sha':os.environ['SOURCE_SHA'],
'dirty':bool(git('status','--porcelain'))},indent=2)+'\n')
PY
- name: Run the same contract on both real database adapters
run: python -m pytest tests/test_metadata_session_boundary.py --junitxml=artifacts/metadata-session.xml
- name: Preserve PostgreSQL locks, migration and recovery regressions
run: |
python -m pytest tests/test_postgres.py tests/test_security_storage_rollback.py tests/test_security_rollback_fences.py tests/test_ledger_accounts.py tests/test_ledger_account_isolation.py tests/test_ledger_migration_json.py tests/test_ledger_migration_references.py tests/test_recovery_safety_units.py tests/test_recovery_metadata.py --junitxml=artifacts/metadata-regressions.xml
- uses: actions/upload-artifact@v4
if: always()
with:
name: metadata-session-${{ github.sha }}
path: artifacts/
if-no-files-found: error
85 changes: 85 additions & 0 deletions .github/workflows/storage-session.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Storage session boundaries
on:
push:
branches: [fix/storage-session-20260929-2050]
pull_request:
paths:
- 'src/msg/**'
- 'tests/test_session_boundary.py'
- 'tests/test_metadata_session_boundary.py'
- '.github/workflows/storage-session.yml'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: storage-session-${{ github.event.pull_request.head.repo.full_name || github.repository }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true
jobs:
focused:
runs-on: ubuntu-latest
timeout-minutes: 12
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: msgtest
POSTGRES_PASSWORD: msgtest
POSTGRES_DB: postgres
ports: ['5432:5432']
options: >-
--health-cmd "pg_isready -U msgtest"
--health-interval 5s --health-timeout 5s --health-retries 10
valkey:
image: valkey/valkey:9.0.6
ports: ['6379:6379']
options: >-
--health-cmd "valkey-cli ping"
--health-interval 5s --health-timeout 5s --health-retries 10
env:
MSG_TEST_POSTGRES_URL_TEMPLATE: postgresql://msgtest:msgtest@127.0.0.1:5432/{database}
MSG_TEST_VALKEY_URL: redis://127.0.0.1:6379/0
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: actions/setup-python@v7
with:
python-version: '3.15'
allow-prereleases: true
cache: pip
- name: Install isolated test dependencies
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq age
python -m pip install -e '.[dev]'
- name: Record source identity
env:
EVENT_HEAD: ${{ github.event.pull_request.head.sha || github.sha }}
run: |
mkdir -p artifacts
python - <<'PY'
import json, os, platform, subprocess
from pathlib import Path
def git(ref):
return subprocess.check_output(['git', 'rev-parse', ref], text=True).strip()
Path('artifacts/source.json').write_text(json.dumps({
'head': os.environ['EVENT_HEAD'], 'checkout': git('HEAD'), 'tree': git('HEAD^{tree}'),
'run': os.environ['GITHUB_RUN_ID'], 'attempt': os.environ['GITHUB_RUN_ATTEMPT'],
'python': platform.python_version(), 'scope': 'isolated-regression-not-production'
}, indent=2) + '\n')
PY
- name: Exercise boundaries and unchanged security contracts
run: >-
python -m pytest tests/test_session_boundary.py tests/test_metadata_session_boundary.py tests/test_foundation.py
tests/test_postgres.py tests/test_security_rollback_fences.py
tests/test_security_storage_rollback.py tests/test_ledger_accounts.py
tests/test_ledger_account_isolation.py tests/test_ledger_migration_json.py
tests/test_ledger_migration_references.py tests/test_recovery_safety_units.py
tests/test_recovery_metadata.py
--junitxml=artifacts/storage-session.xml
- uses: actions/upload-artifact@v4
if: always()
with:
name: storage-session-evidence
path: artifacts/
if-no-files-found: error
40 changes: 40 additions & 0 deletions docs/ISSUE_PROGRESS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Issue 推进笔记

用户入口:2026-09-28T20:34Z。PR #167 是本轮 #156/#157 的唯一组合交付入口;基准 main476e64f04ed1d9c7dcab4a41c4f3cdb72faad6a7,tree40ca207a3c49be347120e058e47ed328ec4e3098。最终提交/CI/合并状态以 #167 最新验收评论为准;本文只登记已取得的证据,不用历史绿灯代替新头。

## 已完成的源码切片

#156:core.batching、events、packet、schemas 各有一份中立实现,原导入路径为同对象兼容别名;URL秘密拒绝和gzip仍在传输层。executor没有Application/插件反向引用,只接收固定投影和事务通知接口。HTTP/SSH由Application.new_executor统一装配请求上限、秘密响应和恢复隔离。签名、ID、回放、权限、事务和receipt规则保留。

#157:PG/SQLite独立继承不持有驱动/连接的RelationalSession。SQL、schema、迁移、锁、保存点、补偿和提交信号仍由后端管理。显式QuerySession覆盖真实消费者,MetadataSession补齐path/ancestors/organization/job/save_job;查询结果视图每次读取重验任务/生命周期,不公开connection/commit。没有新增ORM、逐表Repository或任意SQL网络接口。

SQLite仍是精简测试后端。政策消费者测试只在隔离fixture复用生产仲裁表DDL,验证真实已存政策及损坏digest拒绝,不修改生产迁移或声称完整市场后端等价。

## 测试先行证据(均已下载并独立核验)

| 范围 | 测试头 / tree | run / artifact | JUnit |
|---|---|---|---|
| #156 | 453d6f858e19136261278c7042c13598035aef1a / ae0b4f5e31dc1844c1abd0142da898b75b7779d4 | 36481310584 / 10997043729 | 7 failed / 158 passed / 0 errors / 0 skipped |
| #157 | 2daf1e0b81783d8b52685540b041ba9563333282 / e1668ddcbf5879bce9520a31f8bfe911c813370c | 36482022051 / 10998115401 | 8 failed / 35 passed / 0 errors / 0 skipped |

新增用例准确失败,原有选定用例全部通过。ZIP SHA256分别为c2e1978649b6e251e38703befb0fc674fbb336db55fa075113af0edb07d81fb7、fe037acb748babcb05dcdc7c679bb42986f7ae509af86612ce510307c90ed3e3;source.json匹配head/tree/Python3.15.0rc2/attempt1。

实现历史:10f46fd300ef0fa4890ca0ea7aad3d10bca7f7a5(执行器)、4a6b852961b5e9745c1fea8d37117a7a7c1bde58(存储),组合a85b74456be8eb20977ddd144b94483b0b21202f/tree042422943d4f5a9c43e5d531797dcc3d9c92a787。该历史组合存储专项36483874055已success;后续扩展回归头仍须重新验收。

## 重叠PR收敛

已对照#166和#169完整改动及用例,在#83评论5878614115、#166评论5878687666、#169评论5878694971协调,不覆盖其源分支。

保留#166全部16个结构/双后端行为测试,仅将拟议基类名改为唯一RelationalSession;补充#169的独立装配、工厂批处理回放、事件通知失败整事务回滚3个用例。签名/认证/事务和失败不提交断言未降低。#169的missing-decoder配置用例不适用于内置中立codec,不引入第二套decoder/BatchPolicy制造该错误;既有限长、秘密拒绝、投影缺失拒绝均保留。原red证据仍归#166/#169,不冒充本分支新红基线。

## 合并门槛与执行边界

两个专项、完整四分片、精确node-ID全集/互斥、conformance/实际tokenizer、wheel/sdist、Recovery safety均保留。同一来源仓库分支的push/PR共享并发组以减少重复runner,不删测试、放宽断言或降低合并门槛。最终组合通过并合并后才关闭两个已修复issue和重复PR。

项目执行全部在GitHub Actions;本地仅源文本/Git差异与树检查、下载证据读取。临时精确树发布/源码导出仅在辅助分支,不进入产品树。42个共享方法主体、两后端Store/schema/迁移的静态对照未发现改动,云端运行仍是验收依据。

## 剩余与并行工作

#165工具、#168市场、#158客户端及#155恢复由独立分支推进,不覆盖。#155已知0e4dbe7头完整36480031758及专项36480031762成功,但仍须当前main组合与本机CLI/文件边界验收。#68–83/#85各功能总体验收不能因这两个架构修复整体关闭。

#64/#65/#84仍缺授权生产代理/日志、真实旧库快照、容量与恢复材料;#68–70独立新鲜检查点、备份退役、真实控制台及promotion须分别验收,CI不能替代。此次不部署、不操作真实Root/PIN、资金、外发、备份销毁或恢复放行。
67 changes: 67 additions & 0 deletions docs/METADATA_SESSION_PROGRESS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Metadata session boundary progress

## Current integration decision

Issue #157. PR #166 is now supplemental backend-parity coverage stacked on #167,
not a competing source implementation. Coordination: #83 comment5878756363.
The canonical source is #167 commit `a85b74456be8eb20977ddd144b94483b0b21202f`,
tree `042422943d4f5a9c43e5d531797dcc3d9c92a787`.

That implementation includes the explicit QuerySession/QueryResult consumer port,
transaction-lifetime result guards and missing declared MetadataSession domain
methods. Reusing it better covers the issue's declaration/actual-dependency
acceptance condition than maintaining this branch's parallel base extraction.
All #167 source files are adopted unchanged. #166 adds only this note, its focused
workflow and the same 16 independent parity tests. The four class-name references
change from MetadataSessionBase to the canonical RelationalSession; no behavior
assertion, test, skip condition or existing upstream source is removed or weakened.
Both histories are preserved with a non-force two-parent commit.

No #167 branch, #169 executor branch, #155 recovery branch or main is overwritten.
The #167/#169 executor overlap must still converge to one implementation before
main integration. #165 has meanwhile merged to main `08c58928ee3f6c6cb350d9e9fba75d072bd78f08`;
old main/branch green results do not certify the new combined tree.

## Original red evidence, preserved

Original base main `476e64f04ed1d9c7dcab4a41c4f3cdb72faad6a7`, tree
`40ca207a3c49be347120e058e47ed328ec4e3098`.
Regression commit `7f8752e37fe5b5a8021f192b87e731caec2bbc2d`, tree
`686dbddc1bdfc52d97c127bdb7338f002cabf735`.
Run36481798533: **4 failures, 12 passes, 0 errors/skips**; all failures were
new architecture assertions, while six behaviors passed on both actual adapters.
Artifact10997260030 SHA-256 independently verified:
`50ae1ff1b71684d60e0ff133cde41c6cb81658c0855aeb9c376fff110dc27e2e`.

## Original implementation audit, preserved but superseded

The original source assembly run36482780156 verified 42 shared methods, both
complete Store classes plus FakeMetadataStore, driver execute/enqueue, PostgreSQL
SQL translation and both schemas for unchanged ASTs. Output5474eaf475e7f844244413b1f3e5109d4add4dce.
Artifact10998045352 hash:
`521d6a2f3c5d0d6b8e701302f671fad8b7d3b2641ac346b3ce4c48d282525823`.
One-shot tooling was removed from the final original tree.

Original implementation head `0ef416ec99e20604de2398622e72d7f479a84ceb`, tree
`ad1d3f4a321c25c0c3d4b6c1be8421824809e54f`.
Focused run36483460243 passed **16 new + 80 existing = 96 tests**, with
**0 failures, errors or skips**. Actual source.json and both JUnit files were read.
Artifact10997317418 SHA-256 independently verified:
`8a9cc70e9c31d19baf18050f42eda11818786d671863ded05d35b5e9ab098354`.
These results apply to that original head only, not the adopted #167 source.

## Coverage and next gate

The same tests verify isolated PostgreSQL imports, neutral-base ownership,
MetadataSession method declarations, both adapters' resource generations/path/
paging, result/event/audit/job round trips, idempotency conflicts, nested savepoint
compensation, read-only/closed/cross-task guards, unique-constraint rollback and
question-mark/percent bound-parameter handling.

The focused workflow also retains PostgreSQL locks and concurrency, security
rollback fences, ledger migrations and recovery metadata/unit suites. All project
execution stays in GitHub Actions. Final combined-head focused/full four-shard,
exact node-ID union/disjointness, conformance/build and Recovery safety outcomes
must be inspected and recorded in #166/#83 before merge; no outcome is predicted.
No production deployment, migration, Root/PIN, real funds/outbound effects, backup
destruction or recovery promotion. #65/#69/#85 umbrella acceptance remains separate.
28 changes: 24 additions & 4 deletions src/msg/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,35 @@ async def load(self):
self.authenticator=AuthenticationService(self.registry,self.certificates,self.settings.service_url,self.clock,
self.primary_ceiling,self.temporary_ceiling)
self.authorizer=AuthorizationService(self.registry,self.certificates)
self.executor=OperationExecutor(self.registry,self.metadata,self.contents,self.authenticator,self.authorizer,
self.clock,self.receipt_signer)
self.executor.application=self
self.executor=self.new_executor(self.authenticator)
self.executor.recovery_drill_marker=marker
self.executor.recovery_quarantined=quarantined
self.executor.response_hook=self._secrets_for_caller
self._loaded=True
return self

def new_executor(self, authenticator=None):
"""Compose identical limits/ports for HTTP and the restricted SSH entry."""
executor=OperationExecutor(self.registry,self.metadata,self.contents,
self.authenticator if authenticator is None else authenticator,
self.authorizer,self.clock,self.receipt_signer,
max_request_bytes=self.settings.server.limits.max_request_bytes,
result_projection=self._result_projection,
event_notifications=self._event_notifications)
executor.response_hook=self._secrets_for_caller
executor.recovery_drill_marker=self.settings.config_dir/'recovery-drill.json'
if self.executor is not None:
executor.recovery_quarantined=self.executor.recovery_quarantined
return executor

async def _result_projection(self, context, request, session, resource, *, fields):
from msg.plugins.discovery import read_projection
return await read_projection(self,context,request,session,resource.id,
revision=resource.revision,fields=fields)

async def _event_notifications(self, session, event):
from msg.plugins.communication import enqueue_domain_webhooks
await enqueue_domain_webhooks(self,session,event)

async def online_issuer(self,tx):
issuer=tx.setting('online_ca_certificate')
require(issuer is not None,'issuer_not_ready')
Expand Down
Loading
Loading