Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
- name: Install locked uv
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
with:
Expand Down
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ python orchestrator.py --init --project "새_프로젝트_폴더"
# List configured projects
python orchestrator.py --list-projects

# Read-only all-project structure audit
python orchestrator.py --audit-structure

# Smoke tests
python -m unittest tests.test_smoke

Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and
changed-file `uv run ruff check ...`, and `uv run python figops_mcp_server.py --smoke`.
- Maintainers tag releases after merge; implementers open PRs but do not merge or tag.

## [0.20.1] - 2026-07-25

Post-0.20.0 release-candidate metadata entry. This records the next patch
candidate only; merge, tag, and package publication remain maintainer actions.

### Changed

- Record the secure production MCP host approval launcher as the release-bound
operational path for production host approval evidence.
- Tighten canonical contract wording and release-gate cleanup so the
release-candidate state stays explicit without changing the published-release
record.

## [0.20.0] - 2026-07-15

Source release-candidate entry. The latest published PyPI package and GitHub
Expand Down
31 changes: 30 additions & 1 deletion docs/QA.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,31 @@ python orchestrator.py --docker --docker-build --project "12. ionoelastomer" --s
- Docker 경로에서도 lock gate, provenance, plot 출력이 동일하게 통과해야 함.
- uv/R 런타임 상태와 자격증명은 repo 안이 아니라 외부 runtime/cache 경로에 있어야 함.

### 1.1 전체 프로젝트 구조 진단 (Read-only)

프로젝트 파일을 변경하거나 파이프라인을 실행하지 않고, 연구 루트에서
발견되는 프로젝트의 선언 구조를 진단한다.

```bash
python orchestrator.py --audit-structure
python orchestrator.py --audit-structure --audit-structure-format json --scan-depth 2
```

- 기본 출력은 Markdown이며, `--audit-structure-format json`은 JSON을
stdout으로 출력한다. 시도 provenance는 stderr로 남는다.
- `--scan-depth`는 discovery 깊이를 제한한다.
- 이 모드는 독립 모드다. `--project`, `--check-all`, `--list-projects`와
파이프라인/변경 옵션을 함께 주면 fail-fast 오류가 난다.
- 합격 조건: exit code = 0, 진단 보고서가 stdout에 존재하고, analysis/
plot/diagram 실행이나 project 파일 변경이 없다. `--audit-structure-format`
단독 사용은 오류여야 한다.

이 출력은 구조 검토용 진단 보고서이며 runtime manifest, durable result,
또는 evidence receipt가 아니다. 따라서 `results/` 아래에 연구 산출물로
복사하거나 promotion 대상으로 취급하지 않는다. 실행 로그·cache·snapshot·
상세 manifest는 외부 runtime root에, 의미 있는 결과와 receipt는 선언된
project role root에 각각 보관한다.

---

## 2) Regression & Integrity 기준안
Expand Down Expand Up @@ -292,5 +317,9 @@ explicit path, with `if-no-files-found: error`, so missing evidence fails closed

- **허브 모듈 수정 시**: `hub_core/` 내부 로직 변경 시 반드시 2개 이상의 서로 다른 프로젝트(`ionoelastomer`, `Sulfur_polymer`)에 대해 테스트를 수행.
- **Runtime 상태 분리**: 데이터 결과값, 회귀 baseline, 실행 로그, 자격증명은 repo 밖 runtime/cache 경로에 둔다. DVC/data registry는 현재 운영 표면에서 retired 상태다.
- **구조 진단 출력 분리**: `--audit-structure`의 stdout 보고서는 일회성
diagnostic surface다. runtime 산출물이나 durable 연구 결과로 승격하지
않으며, 보존이 필요하면 별도 운영 기록으로 보관하고 프로젝트 `results/`
역할 트리와 혼합하지 않는다.

**Last Update**: 2026-07-04 (journal visual evidence gate guidance)
**Last Update**: 2026-07-23 (all-project structure audit CLI and journal visual evidence guidance)
76 changes: 73 additions & 3 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,17 @@ Current release-candidate checkpoint:
inventory/audit/plan/role-binding/apply, launcher-authorized external-raw
execution, native no-replace result promotion, durable receipts, measured
policy evidence, and verified project-script claims including conservative
dynamic-annotation discovery. CI run
dynamic-annotation discovery. The conservative dependency-scanner facade
`dependency_script_inspection.analyze_dependency_script` now delegates
bounded language-specific extraction to `dependency_python_inspection.py` and
`dependency_r_inspection.py`, with shared path predicates and deterministic
result ordering in `dependency_scan_common.py`. It reports deterministic
Python/R static candidates, unresolved hard-coded/dynamic references, and
incomplete scans without guessing roles; scanner output is evidence only,
while unresolved or incomplete findings are plan blockers, not approvals.
`role_roots` resolves a literal only through its most-specific declared
terminal semantic root; grouping roots `scripts` and `results` never clear
blockers, and equal-depth terminal ties remain unresolved. CI run
[`29689087108`](https://github.com/Moonweave-Research/figops/actions/runs/29689087108)
passed for source head `9e4d340b718529bd0f65ba46b2124dda718918a2`: macOS full
pytest was 2,322 passed, 22 skipped, and 104 subtests, including the native
Expand All @@ -118,6 +128,55 @@ Current release-candidate checkpoint:
reference: [PR #224 owner authorization](https://github.com/Moonweave-Research/figops/pull/224#issuecomment-5016360221).
Execute merge, tag, package publication, GitHub Release, and release
promotion only after rechecking technical gates for the exact release commit.
- The CLI now has an independent all-project structure diagnostic:
`python orchestrator.py --audit-structure` (or
`python orchestrator.py --audit-structure --audit-structure-format json`).
It consumes the read-only structure
inventory/audit path for projects discovered under the research root, honors
`--scan-depth`, and emits the rendered report on stdout without running a
pipeline or changing project files. The diagnostic report is review output
only; it retains invalid/boundary-blocked project rows for review, keeps
`proposed_changes` empty, and is not a runtime manifest, durable result, or
evidence receipt.
- Structure migration follows the finding-to-plan selection matrix in
`docs/project-structure-contract.md`: `invalid`, `boundary_blocked`,
`skipped`, `audit_error`, and ambiguous/heuristic unknowns remain report-only
(unknowns and proposed mappings are candidate-only). Only explicit reviewed
`approved_mappings` and typed config edits form a copy-only plan. A dry-run
returns the deterministic `plan_digest` and bound
`FIGOPS-APPLY-<plan_digest>` token; apply requires the identical reviewed
inputs and token. The token proves plan integrity and exact replay, not
independent human identity or attestation; the compatibility workflow does
not close self-approval. The Phase 6 host-rooted approval authority contract
is defined in the canonical
[`runtime-integrity SSOT`](specs/2026-07-15-project-structure-runtime-integrity-plan.md#phase-6-host-rooted-approval-authority-contract)
and requires a canonical payload, host capability/signature trust proof,
currentness/revocation checks, and fail-closed apply ordering. Approval
is enforced when secure MCP mode sets `require_host_approval: true` and is
backed by the host-owned process-local `ApprovalAuthorityRoot`; the host
receipt is rechecked at the mutation boundary. Default compatibility mode
remains token-only for backward compatibility, so audit/plan control
evidence, LLM JSON, and copy/runtime/durable/evidence receipts are not
approval. The production `graphhub_mcp_server.py`/`figops_mcp_server.py`
launcher is the trusted injection boundary: it creates or receives the
host-owned process-local root and enables secure mode. An embedded host may
inject an optional host-owned root through the constructor-only
`host_authority_root` channel together with `require_host_approval: true`; if
the secure flag/root are omitted, the embedded constructor preserves
compatibility/token-only behavior. Compatibility constructors and the
historical `GraphHubMCPServer` class remain token-only and are not Phase 6 or
release evidence. The Phase 6
host-approval gate is satisfied for the production launcher; full release
still requires the remaining exact-commit gates. Audit/plan control evidence
never becomes a runtime manifest or durable result, and runtime remains
external to the project.

- Structure normalization applies a fail-closed guard: a plan containing any
`hardcoded_unresolved_references` or `unresolved_proposals` is rejected before
copy, even with a valid digest and confirmation token. Parse/read/unsupported
language failures and dynamic dependency expressions set the scanner's
incomplete signal; no filename, extension, or directory heuristic can assign
a semantic role.

---

Expand Down Expand Up @@ -154,10 +213,15 @@ hub_core/
project_structure_contract.py # v1.1 role/DAG/alias resolution
legacy_structure_resolver.py # legacy 1.0 in-memory compatibility view
project_layout.py # shared scaffold/normalization inventory
structure_inventory.py / structure_audit.py / structure_plan.py
# read-only semantic discovery and reviewed plan
structure_inventory.py / structure_audit.py / structure_audit_report.py
# read-only semantic discovery and all-project report
structure_plan.py # deterministic reviewed copy plan
structure_role_binding.py # approved destinations bound to declared roots
structure_apply.py # write-gated copy-only apply transaction
dependency_script_inspection.py # dependency scanner facade and evidence API
dependency_python_inspection.py # bounded Python dependency extraction helper
dependency_r_inspection.py # bounded R dependency extraction helper
dependency_scan_common.py # shared path predicates and result ordering
runtime_boundary.py # project/result/runtime disjointness
atomic_no_clobber.py # native consuming same-FS no-replace publication
durable_promotion.py # staged same-filesystem result promotion
Expand Down Expand Up @@ -411,6 +475,12 @@ and scale/profile resolution into `themes.font_token_resolver`. The public
passed through explicitly. With `themes.journal_theme` now below 800 lines, no
tracked Python module exceeds the current architecture split signal.

The dependency scanner split keeps `hub_core.dependency_script_inspection` as
the compatibility facade while moving bounded Python and R extraction into
`hub_core.dependency_python_inspection` and
`hub_core.dependency_r_inspection`; shared path predicates and deterministic
evidence ordering live in `hub_core.dependency_scan_common`.

The current execution plan for that maintenance track lives in
`docs/specs/2026-06-28-large-module-decomposition-plan.md`.

Expand Down
Loading
Loading