Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
98322ce
Initial plan
Copilot Nov 9, 2026
2cfebd9
Add Streamlit app foundation and initial pages
Copilot Nov 9, 2026
98b539b
Improve FiberLab navigation and landing page
CodingBunny06 Nov 9, 2026
fb4e35b
ci: add automated GitHub Actions test workflow
CodingBunny06 Nov 9, 2026
ee8f347
ci: integrate Ruff code quality checks
CodingBunny06 Nov 9, 2026
c141b77
feat: build FiberLab landing page
CodingBunny06 Nov 9, 2026
683a1d1
refactor: standardize laboratory page layouts
CodingBunny06 Nov 9, 2026
a4bd1f8
docs: define module integration contracts
CodingBunny06 Nov 9, 2026
d6954a6
docs: add developer guide
CodingBunny06 Nov 11, 2026
2502f49
feat: add reusable input validation utilities
CodingBunny06 Nov 11, 2026
ace432b
feat: add reusable simulation result display
CodingBunny06 Nov 11, 2026
63d9726
ci: introduce FiberLab Guardian quality gate
CodingBunny06 Nov 11, 2026
fe457d4
ci: run Guardian on feature branches
CodingBunny06 Nov 11, 2026
2168137
ci: run Guardian on feature branches
CodingBunny06 Nov 11, 2026
a740bad
ci: validate teammate module API signatures
CodingBunny06 Nov 11, 2026
d3f8c10
test: add Guardian API validation self-check
CodingBunny06 Nov 11, 2026
ec54aa0
feat: implement Guardian code inspector
CodingBunny06 Nov 11, 2026
1abca57
feat: build Guardian diagnostic pipeline
CodingBunny06 Nov 11, 2026
f741856
feat: add isolated Guardian integration workspace
CodingBunny06 Nov 11, 2026
33f08b2
feat: strengthen recursive integration validation
CodingBunny06 Nov 11, 2026
ed04d4a
feat: add Guardian automated test runner
CodingBunny06 Nov 11, 2026
1ee85fc
feat: add candidate module integration
CodingBunny06 Nov 11, 2026
f5b43eb
feat: add Guardian execution pipeline
CodingBunny06 Nov 11, 2026
98dee31
test: add Guardian end-to-end coverage
CodingBunny06 Nov 11, 2026
ad85e20
feat: improve Guardian diagnostic reports
CodingBunny06 Nov 11, 2026
0c93230
feat: add GitHub API client for Guardian
CodingBunny06 Nov 11, 2026
baa0b5f
feat: add GitHub candidate downloader
CodingBunny06 Nov 11, 2026
0ac46a9
feat: integrate GitHub PRs with Guardian pipeline
CodingBunny06 Nov 11, 2026
118ccfb
feat: add GitHub PR reporting for Guardian
CodingBunny06 Nov 11, 2026
382d738
Build FiberLab Guardian inspection and integration system
CodingBunny06 Nov 12, 2026
591b378
merge: sync main CI workflow into feature/home-page
CodingBunny06 Nov 12, 2026
58f8625
docs: add FiberLab v1.0 integration documentation
CodingBunny06 Nov 14, 2026
3a9250b
docs: fix contract markdown formatting
CodingBunny06 Nov 14, 2026
08946aa
fix: inspect all application packages for syntax and imports
CodingBunny06 Nov 14, 2026
c137f19
test: cover syntax errors in Guardian package
CodingBunny06 Nov 14, 2026
3e427be
fix: bound candidate downloads and reject symlink destinations
CodingBunny06 Nov 14, 2026
f43c6a0
test: cover downloader size and symlink safeguards
CodingBunny06 Nov 14, 2026
150edbc
fix: reject non-numeric values in input validation
CodingBunny06 Nov 14, 2026
0c6761a
test: cover non-numeric validation inputs
CodingBunny06 Nov 14, 2026
8486ae4
style: organize candidate downloader imports
CodingBunny06 Nov 14, 2026
233b6ea
fix: correct candidate downloader import ordering
CodingBunny06 Nov 14, 2026
53ae24f
style: finalize candidate downloader import spacing
CodingBunny06 Nov 14, 2026
eecdc58
style: apply Ruff formatting to tests
CodingBunny06 Nov 14, 2026
a40eb1a
style: apply Ruff formatting to tests
CodingBunny06 Nov 14, 2026
e6d080b
style: apply Ruff formatting to tests
CodingBunny06 Nov 14, 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
9 changes: 6 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

name: FiberLab CI

on:
Expand Down Expand Up @@ -30,8 +31,10 @@ jobs:
with:
python-version: "3.12"

- name: Install Ruff
run: python -m pip install --upgrade ruff
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt ruff

- name: Run Ruff lint
run: ruff check .
Expand All @@ -55,7 +58,7 @@ jobs:
- name: Install project dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
python -m pip install -r requirements.txt

- name: Run test suite
run: python -m pytest -v
64 changes: 64 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# FiberLab Guardian — Security Notes

## 1. Purpose

FiberLab Guardian inspects candidate code changes, validates module contracts, prepares an isolated integration workspace, and runs permitted quality checks.

It is designed as a project-level code inspection and integration assistant. It is not a hardened security sandbox.

## 2. Implemented Protections

The integration engine currently implements the following protections:

- Rejects absolute candidate paths.
- Rejects candidate paths containing `..` traversal components.
- Checks candidate path components for symbolic links.
- Resolves candidate paths and verifies that they remain within the candidate root.
- Checks the destination path for an existing symbolic link before path resolution.
- Creates integration workspaces separately from the original project.
- Excludes Git metadata, virtual environments, caches, and other configured directories from workspace copies.

## 3. Known Limitations

### 3.1 Time-of-Check to Time-of-Use (TOCTOU)

Candidate path validation, containment checks, and file copying are separate filesystem operations.

A concurrent local process could modify a validated candidate or destination path between these operations. This may allow filesystem access outside the intended roots.

**Status:** Known and accepted limitation for the current project scope.

**Severity:** Medium.

**Mitigation:** Guardian should only operate on trusted local workspaces. Stronger descriptor-relative filesystem operations and race-resistant copying may be considered in a future security-hardening phase.

### 3.2 No OS-Level Execution Sandbox

The integration workspace is a separate project copy, not an operating-system security boundary.

Subprocess timeouts limit execution duration but do not prevent filesystem access, network access, or other potentially unsafe operations.

Guardian must not execute untrusted pull-request code in the normal inspection workflow.

## 4. Pull Request Inspection Policy

- Download candidate files from the exact pull-request commit.
- Perform static inspection before integration.
- Do not execute untrusted pull-request code.
- Disable quality-check execution for untrusted PR candidates.
- Require human review before accepting or merging changes.

## 5. Future Security Improvements

Potential future improvements include:

- Race-resistant filesystem operations.
- OS-level sandboxing for untrusted code execution.
- More comprehensive filesystem permission checks.
- Additional security-focused automated tests.

## 6. Security Review Disclaimer

Guardian reports are automated engineering assessments. A passing report does not guarantee that code is free from vulnerabilities, constitute security certification, or approve a pull request for merging.

Human review remains mandatory.
74 changes: 74 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""FiberLab Streamlit application entry point."""

from __future__ import annotations

import streamlit as st

from pages.attenuation_laboratory import render as render_attenuation_laboratory
from pages.fiber_explorer import render as render_fiber_explorer
from pages.guardian_dashboard import render as render_guardian
from pages.home import render as render_home
from pages.signal_propagation import render as render_signal_propagation

PAGE_DEFINITIONS = (
{
"render": render_home,
"title": "FiberLab",
"icon": ":material/home:",
"url_path": "home",
"default": True,
},
{
"render": render_fiber_explorer,
"title": "Fiber Explorer",
"icon": ":material/explore:",
"url_path": "fiber-explorer",
},
{
"render": render_attenuation_laboratory,
"title": "Attenuation Laboratory",
"icon": ":material/science:",
"url_path": "attenuation-laboratory",
},
{
"render": render_signal_propagation,
"title": "Signal Propagation",
"icon": ":material/graphic_eq:",
"url_path": "signal-propagation",
},
{
"render": render_guardian,
"title": "Guardian",
"icon": ":material/shield:",
"url_path": "guardian",
},
)


def build_navigation():
"""Build the native Streamlit navigation entries."""
return st.navigation(
[
st.Page(
definition["render"],
title=definition["title"],
icon=definition["icon"],
url_path=definition["url_path"],
default=definition.get("default", False),
)
for definition in PAGE_DEFINITIONS
],
position="sidebar",
)


def main() -> None:
"""Configure and render the Streamlit application."""
st.set_page_config(page_title="FiberLab", page_icon="🔬", layout="wide")

navigation = build_navigation()
navigation.run()


if __name__ == "__main__":
main()
Empty file added components/__init__.py
Empty file.
17 changes: 17 additions & 0 deletions components/page_layout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Reusable page layout components for FiberLab."""

import streamlit as st


def render_page_header(title: str, caption: str, description: str) -> None:
"""Render a consistent header across laboratory pages."""
st.title(title)
st.caption(caption)
st.write(description)
st.divider()


def render_workspace(message: str) -> None:
"""Render a standard laboratory workspace section."""
st.subheader("Laboratory workspace")
st.info(message)
16 changes: 16 additions & 0 deletions components/result_display.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""Reusable result display components for FiberLab."""

import streamlit as st


def render_result_metrics(results: dict[str, str]) -> None:
"""Display simulation results as a row of metrics."""
if not results:
st.info("No simulation results available yet.")
return

columns = st.columns(len(results))

for column, (label, value) in zip(columns, results.items()):
with column:
st.metric(label=label, value=value)
39 changes: 39 additions & 0 deletions components/validation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""Input validation utilities for FiberLab."""

import math


def validate_positive(value: float, name: str) -> None:
"""Ensure a value is finite and greater than zero."""
if (
isinstance(value, bool)
or not isinstance(value, (int, float))
or not math.isfinite(value)
or value <= 0
):
raise ValueError(f"{name} must be a finite positive number.")


def validate_non_negative(value: float, name: str) -> None:
"""Ensure a value is finite and non-negative."""
if (
isinstance(value, bool)
or not isinstance(value, (int, float))
or not math.isfinite(value)
or value < 0
):
raise ValueError(f"{name} must be a finite non-negative number.")


def validate_refractive_indices(
n_core: float,
n_cladding: float,
) -> None:
"""Validate core and cladding refractive indices."""
validate_positive(n_core, "Core refractive index")
validate_positive(n_cladding, "Cladding refractive index")

if n_core <= n_cladding:
raise ValueError(
"Core refractive index must be greater than cladding refractive index."
)
Loading
Loading