Index-driven portfolio analysis for the Aptlantis development workspace. AnalyzeProjects samples the explicitly registered projects in ProjectIndex.md, evaluates each one against the appropriate governance context, and writes structured JSON that can be aggregated and viewed in the local dashboard.
Scope: This is an internal, operator-focused assessment tool. Its output is analysis evidence—not a release certification, a project mutation tool, or a replacement for deeper single-project review.
- Validates the registered portfolio in
ProjectIndex.md. - Selects a canonical manifest for each target when one is available.
- Collects bounded source and documentation evidence, honoring a target project's
PROJECT-READMAP.tomlwhen present. - Supplies the target's governance group and applicable standard to the configured model.
- Validates and normalizes the structured response.
- Writes one JSON result per project and a human-readable portfolio summary.
- Optionally compares current evidence with earlier results so unchanged projects do not consume another model request.
The analyzer never discovers extra projects by walking portfolio roots. Only paths listed in ProjectIndex.md are in scope.
The checked-in index currently registers 48 targets.
| Group | Targets | Evaluation context |
|---|---|---|
DRS |
9 | Desktop Application Release Standard |
CTS |
11 | Command Tool Standard |
WDS |
2 | Website Development Standard |
LDS |
10 | Library Development Standard |
STANDARDS |
16 | Internal clarity, completeness, consistency, and implementability rubric |
The exact group totals, target existence, duplicates, and required governing standards are validated before a run proceeds. Standards are intentionally assessed with their own rubric; application-release requirements are not automatically imposed on governance documents.
flowchart LR
Index[ProjectIndex.md] --> Summarizer
Config[config.toml] --> Summarizer
Standards[Group standards] --> Summarizer
Targets[Registered project evidence] --> Summarizer
Summarizer --> Raw[raw per-project JSON]
Summarizer --> Markdown[summary.md]
Raw --> Analyzer[PortfolioAnalyzer.py]
Analyzer --> IndexJson[index.json]
IndexJson --> Dashboard[Dashboard.py]
- Python
3.11+(tomllibis used by the analyzer). - The Python dependencies used by the project, including
requests;flaskis required only to serve the dashboard. - Accessible target paths and governing-standard paths from
config.toml. - An OpenAI API key in the process environment for model-backed runs.
The key is deliberately not read from a configuration file. Set it in the PowerShell session that will run the analyzer:
$env:OPENAI_API_KEY = [Environment]::GetEnvironmentVariable("OPENAI_API_KEY", "Machine")The analyzer performs an OpenAI credential/model preflight before scanning projects. Missing credentials and 401/403 failures stop the run rather than being retried for every target.
config.toml is the active local configuration. config.example.toml documents the expected shape:
[project]
index_path = "D:/CTS/Analyze-Projects/ProjectIndex.md"
out_dir = "D:/CTS/Analyze-Projects/Dashboard/Project-Summaries/raw"
summary_path = "D:/CTS/Analyze-Projects/Dashboard/Project-Summaries/summary.md"
[model]
name = "gpt-5-mini-2025-08-07"
api_host = "https://api.openai.com"
prefer = "openai"The remaining sections set the DRS/CTS/WDS/LDS standard paths, sampling budgets, concurrency, retry behavior, processing mode, file extensions, and excluded directory names. Keep the configured output locations aligned with the dashboard's Dashboard/Project-Summaries/ directory.
From the repository root:
python Summarizer.pyA normal run samples each registered project, calls the configured model, and writes:
Dashboard/Project-Summaries/raw/<stable-project-stem>.json— individual assessment results.Dashboard/Project-Summaries/summary.md— compiled human-readable assessment summary.
Recent individual results may be reused when skip_already_processed = true.
Use comparison mode to sample current evidence locally and only call the model when the evidence fingerprint differs from the saved result:
python Summarizer.py --compareUnchanged projects retain their previous assessment with comparison_status: "unchanged". Changed and new projects are re-evaluated with the prior status and completion snapshot available to the model. Comparison runs also write comparison_summary.md beside the regular summary. Set mode = "compare" in config.toml to make this the default, or pass --full to force a complete evaluation.
Evidence is deliberately bounded. The analyzer uses the configured per-file, total-character, and file-count budgets.
- A project
PROJECT-READMAP.tomlis a bounded discovery contract: mandatory files are reserved first, then declared priority, evidence, and secondary paths are considered. - Without a read map, the analyzer uses a relevance-scored walk of allowed file types while skipping configured generated/dependency directories.
- Each transferred block is labeled either
complete fileorsampled excerpt, with excerpt size when shortened. - An excerpt boundary is not evidence that a repository file is damaged. The prompt and response normalization prevent transfer-truncation claims from becoming actionable findings.
Every model result preserves the original assessment fields used by dashboard consumers and adds provenance such as project_group, governing_standard, repository_url, manifest_path, sampling metadata, and a content fingerprint.
After results exist, aggregate them into the dashboard index:
python Dashboard\PortfolioAnalyzer.pyThis reads Dashboard/Project-Summaries/raw/*.json, calculates portfolio statistics, and writes:
Dashboard/Project-Summaries/index.jsonDashboard/Project-Summaries/summary.md
It also copies an existing index.json to a timestamped index_YYYYMMDD-HHMMSS.json backup before replacing it.
python Dashboard\Dashboard.pyOpen http://127.0.0.1:5050/. The Flask dashboard reads index.json, displays the project count and average completion, and lists projects with governance group, status, completion, first next step, governing standard, and tags. If no index exists, it instructs the operator to run PortfolioAnalyzer.py first.
The local suite uses temporary directories and mocked HTTP requests; it does not make paid model calls:
python -m unittest discover -s tests -vTo validate the index and configured paths without invoking a model:
python -c "import Summarizer; c=Summarizer.load_config('config.toml'); print([(t.project_group, t.project_name) for t in Summarizer.discover_projects(c)])"Current recorded implementation evidence covers 48-target index discovery, governance prompt routing, response normalization, comparison behavior, and mocked model-client requests. A full paid portfolio run is intentionally outside local test verification, so it must not be represented as having occurred unless separately recorded.
| Path | Role |
|---|---|
Summarizer.py |
Main discovery, sampling, model, response, and summary pipeline. |
PromptTemplate.py |
Structured result schema and governance-aware model prompt. |
ModelClient.py |
OpenAI/Ollama-compatible model calls and credential preflight request. |
ProjectIndex.md |
Sole inclusion authority for portfolio targets. |
config.toml |
Active local execution configuration. |
config.example.toml |
Configuration reference without credentials. |
Dashboard/PortfolioAnalyzer.py |
Raw-result aggregation into dashboard artifacts. |
Dashboard/Dashboard.py |
Local Flask viewer for the aggregated portfolio index. |
tests/test_analyzer.py |
Discovery, sampling, prompt, comparison, and client regression coverage. |
PROJECT-READMAP.toml |
Analyzer read map for this repository. |
Project-Proposal.md |
Scope, boundaries, risks, and roadmap. |
Analyze-Projects.manifest.toml |
Machine-readable identity, governance, and verification record. |
- Do not add targets by relying on filesystem discovery; update and review
ProjectIndex.mdinstead. - Do not place API credentials in source, generated reports, manifests, or configuration files.
- Do not treat model assessments as automatic release readiness or certification.
- Do not modify evaluated projects as part of an analysis run.
- Preserve existing generated evidence and historical manifests unless a reviewed migration calls for a change.
- Project record
- Project proposal
- Project manifest
- Local instructions
- Command Tool Standard
The project is marked active with experimental stability in Analyze-Projects.manifest.toml. Its local implementation and mocked tests are recorded as verified; build artifacts, release artifacts, and paid full-portfolio evaluation are not asserted by this README.