decomposer: generate deliverable files for Inspect the single_agent template and target repository conventions to identify the required project structure, configuration, interfaces, and implementation patterns for the application landing zone agent.; Define the application landing zone agent's behavior, input and output contracts, document-generation workflow, and architecture-diagram requirements using the extracted template conventions.; Validate the implemented application_landing_zone_agent by running repository tests and checking the TSD document generation, draw.io diagram generation, agent packaging, configuration, and committed implementation against the defined contracts.; Commit and push the validated application_landing_zone_agent implementation to the target repository.

This commit is contained in:
2026-08-31 14:45:15 +00:00
parent 576c4050be
commit 0060bdd426
14 changed files with 226 additions and 85 deletions

View File

@@ -1,26 +1,20 @@
# Application Landing Zone Agent
A deterministic, dependency-light agent that turns application requirements into a Technical Solution Design (TSD) and an editable draw.io architecture diagram.
A deterministic, dependency-light agent that converts application requirements into a Technical Solution Design (TSD) and an editable draw.io architecture diagram.
## Quick start
```bash
python -m application_landing_zone_agent.cli \
--input examples/application.json \
--output-dir build/example
python -m landing_zone_agent.cli --requirements examples/requirements.json --output-dir out
python -m unittest discover -s tests -v
```
The command writes `tsd.md` and `architecture.drawio` and validates both before returning success. The package also exposes `LandingZoneAgent.generate(requirements)` for embedding.
The CLI writes `tsd.md`, `architecture.drawio`, and `manifest.json`. The generator does not call an LLM or cloud APIs; it produces a reviewable baseline that can be refined by an architect.
## Contract
Input is a JSON object with required `application_name` and `business_context`, plus optional `environments`, `components`, `integrations`, `constraints`, `non_functional_requirements`, and `assumptions`. Output is a `GenerationResult` containing Markdown TSD text, draw.io XML, and a validation report. See `docs/agent-specification.md`.
Input is JSON with `application_name`, `business_context`, `environments`, `data_classification`, `availability_target`, and optional `components`, `integrations`, and `constraints`. Output is a TSD Markdown document, draw.io XML, and a manifest containing assumptions and validation results. See `docs/agent-specification.md`.
## Development
## Configuration
```bash
python -m unittest discover -s tests -v
python -m application_landing_zone_agent.cli --help
```
The implementation intentionally uses only the Python standard library. Configuration is JSON (`config/default.json`) so the same contract works in CI and local tooling.
`config/agent.json` contains defaults and capability declarations. Configuration is loaded by `landing_zone_agent.config.load_config`; no secrets are stored in the repository.

7
config/agent.json Normal file
View File

@@ -0,0 +1,7 @@
{
"name": "application_landing_zone_agent",
"version": "0.1.0",
"defaults": {"availability_target": "99.9%", "environments": ["dev", "test", "prod"]},
"capabilities": ["tsd_generation", "drawio_generation", "contract_validation"],
"output_files": ["tsd.md", "architecture.drawio", "manifest.json"]
}

View File

@@ -1,38 +1,24 @@
# Application landing zone agent specification
## Purpose
**Name:** `application_landing_zone_agent`
Transform application requirements into a reviewable Technical Solution Design and an editable draw.io architecture diagram. The agent proposes a conservative landing-zone view; it does not provision cloud resources or invent unprovided compliance claims.
**Purpose:** Transform application requirements into a reviewable Technical Solution Design and an editable draw.io architecture diagram.
## Input contract
JSON object:
- `application_name` (string, required)
- `business_context` (string, required)
- `environments` (array of strings, optional)
- `components` (array of objects with required `name`, optional `type`, `technology`, `description`)
- `integrations` (array of strings or objects, optional)
- `constraints`, `non_functional_requirements`, `assumptions` (arrays of strings, optional)
Unknown fields are preserved in the TSD assumptions section only when explicitly listed; malformed known fields fail validation.
JSON object fields: required `application_name`, `business_context`, `environments` (non-empty array), `data_classification`, `availability_target`; optional array fields `components`, `integrations`, `constraints`.
## Output contract
`GenerationResult` has `tsd_markdown`, `drawio_xml`, and `validation` (`valid`, `errors`, `warnings`). The CLI writes the configured filenames and a `validation.json` report.
`generate()` returns `{tsd: string, drawio: string, manifest: object}`. The CLI writes `tsd.md`, `architecture.drawio`, and `manifest.json`.
## Workflow
1. Validate and normalize requirements without making network calls.
2. Build a deterministic logical architecture model, retaining named components and integrations.
3. Render the TSD with scope, requirements, environment strategy, component inventory, integration/security considerations, operational concerns, assumptions, and decisions needed.
4. Render native draw.io XML with title, environment/container layers, components, and directional edges. IDs are stable (`component-<index>`, `integration-<index>`).
5. Validate required TSD headings and XML structure, then write output atomically through the CLI.
1. Parse and validate the requirements.
2. Apply safe baseline assumptions and identify unresolved decisions.
3. Generate TSD sections for context, scope, architecture, environments, security, resilience, operations, constraints, and acceptance criteria.
4. Generate an XML draw.io file with users, application boundary, components, and orthogonal relationships.
5. Validate artifact structure and return the manifest.
## Diagram requirements
The diagram must open in draw.io/diagrams.net as `mxfile`, contain an `mxGraphModel`, use `vertex` cells for components and `edge` cells for relationships, and use escaped XML labels. It must show application components and external integrations, with clear layer/container labels. It may not contain executable code or credentials.
The diagram must be importable by draw.io, use an `<mxfile>` root and `<mxGraphModel>`, include vertex cells for the users, application, and components, and include relationships. It must remain editable XML rather than an image.
## Validation and errors
Missing required strings, non-object components, blank component names, malformed integration objects, or empty arrays where a list is supplied produce actionable errors. The CLI prints the error and exits 2. Rendering failures exit 1. The library never silently drops a named component.
Missing required fields, malformed types, and empty environments raise `ValueError` with actionable field names. A diagram contract failure raises `RuntimeError`. No credentials are inferred or emitted.

View File

@@ -1,21 +1,11 @@
# Repository convention discovery (Step 0)
# Repository conventions and discovery record
No template or target URL was supplied with the request, so this repository records the conventions used as the implementation baseline rather than claiming an external inspection. The baseline follows a conventional Python agent layout: `src/` package, `tests/` unittest suite, `config/` JSON configuration, `docs/` contract material, and a CLI entry point.
## Discovery scope
The requested template and target repository URLs were not supplied to the build request. This repository therefore uses the standard Python agent landing-zone convention: `src/` package layout, `pyproject.toml`, JSON configuration, a callable package API, CLI wrapper, tests, and human-readable docs.
## Required structure
- `src/application_landing_zone_agent/`: importable implementation and CLI.
- `tests/`: unit and contract tests runnable with `python -m unittest discover -s tests`.
- `config/default.json`: checked-in, dependency-free configuration.
- `docs/agent-specification.md`: behavior, contracts, workflow, and validation.
- `examples/`: human-reviewable input fixture.
- `pyproject.toml`: package metadata and console script.
## Conventions extracted for this build
- Public behavior is exposed through a small class (`LandingZoneAgent`) and a CLI adapter.
- Input/output boundaries are typed dataclasses and JSON/Markdown/XML files.
- Generation is deterministic: stable IDs, ordering, and formatting make output reviewable in source control.
- Validation happens before files are written and is also available as a public function.
- Diagram output is native draw.io `mxfile` XML, not an image or proprietary binary.
- Errors are actionable `ValidationError`/`GenerationError` exceptions; CLI maps them to a non-zero exit code.
## Extracted conventions applied
- Keep runtime code under `src/<package>` and tests under `tests`.
- Expose a small programmatic interface and a CLI entry point.
- Keep configuration declarative and secret-free.
- Produce deterministic, reviewable artifacts in a caller-selected output directory.
- Document contracts, assumptions, validation, and diagram editing expectations.

11
docs/validation-report.md Normal file
View File

@@ -0,0 +1,11 @@
# Validation plan and report
The repository validation covers:
- Unit tests for required-field/type validation, TSD sections, and draw.io XML markers.
- CLI packaging smoke test that writes all three expected files.
- Human review checklist for assumptions, security controls, environment isolation, and editable diagram structure.
Run `python -m unittest discover -s tests -v` and `python -m landing_zone_agent.cli --requirements examples/requirements.json --output-dir /tmp/landing-zone-agent-check`.
The generated baseline is provider-neutral by design; provider-specific landing-zone controls require confirmation of cloud, identity, network, RTO/RPO, retention, and sizing.

View File

@@ -0,0 +1,10 @@
{
"application_name": "Customer Portal",
"business_context": "Self-service customer account management",
"environments": ["dev", "test", "prod"],
"data_classification": "confidential",
"availability_target": "99.9%",
"components": ["web frontend", "api service", "relational database"],
"integrations": ["CRM", "email provider"],
"constraints": ["private network access", "audit logging"]
}

View File

@@ -9,7 +9,7 @@ description = "Generate TSD documents and draw.io diagrams from application requ
requires-python = ">=3.10"
[project.scripts]
application-landing-zone-agent = "application_landing_zone_agent.cli:main"
application-landing-zone-agent = "landing_zone_agent.cli:main"
[tool.setuptools.packages.find]
where = ["src"]

View File

@@ -0,0 +1,4 @@
"""Application landing zone agent package."""
from .generator import generate
__all__ = ["generate"]

View File

@@ -0,0 +1,21 @@
"""Command-line entrypoint."""
import argparse, json
from pathlib import Path
from .generator import generate
def main(argv=None):
parser = argparse.ArgumentParser(description="Generate TSD and draw.io landing-zone artifacts")
parser.add_argument("--requirements", required=True)
parser.add_argument("--output-dir", required=True)
args = parser.parse_args(argv)
with open(args.requirements, encoding="utf-8") as stream:
result = generate(json.load(stream))
output = Path(args.output_dir); output.mkdir(parents=True, exist_ok=True)
(output / "tsd.md").write_text(result["tsd"], encoding="utf-8")
(output / "architecture.drawio").write_text(result["drawio"], encoding="utf-8")
(output / "manifest.json").write_text(json.dumps(result["manifest"], indent=2), encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -0,0 +1,9 @@
"""Configuration loading with explicit, repository-relative defaults."""
import json
from pathlib import Path
def load_config(path=None):
path = Path(path or "config/agent.json")
with path.open(encoding="utf-8") as stream:
return json.load(stream)

View File

@@ -0,0 +1,73 @@
"""Deterministic TSD and draw.io artifact generation."""
from html import escape
from datetime import datetime, timezone
from .validation import validate_requirements, validate_drawio
def _items(values):
return "\n".join(f"- {value}" for value in values) if values else "- None specified"
def _drawio(req):
name = escape(req["application_name"])
components = req.get("components") or ["application service"]
cells = [('<mxCell id="0"/>', '<mxCell id="1" parent="0"/>')]
cells = [f'<mxCell id="{i+2}" value="{escape(str(value))}" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"><mxGeometry x="{80 + (i%3)*220}" y="{100 + (i//3)*120}" width="180" height="60" as="geometry"/></mxCell>' for i, value in enumerate(["Users", name] + components)]
edges = []
for i in range(2, len(cells)+1):
edges.append(f'<mxCell id="e{i}" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;" edge="1" parent="1" source="{i}" target="{i+1}"><mxGeometry relative="1" as="geometry"/></mxCell>')
body = '<mxCell id="0"/><mxCell id="1" parent="0"/>' + ''.join(cells + edges)
return f'<mxfile host="app.diagrams.net" modified="{datetime.now(timezone.utc).isoformat()}" agent="application-landing-zone-agent"><diagram name="Application Landing Zone"><mxGraphModel><root>{body}</root></mxGraphModel></diagram></mxfile>'
def generate(requirements):
validate_requirements(requirements)
name = requirements["application_name"]
components = requirements.get("components") or ["application service"]
integrations = requirements.get("integrations") or []
constraints = requirements.get("constraints") or []
tsd = f'''# Technical Solution Design: {name}
## 1. Executive summary
{requirements["business_context"]}
## 2. Scope and assumptions
- Data classification: **{requirements["data_classification"]}**
- Availability target: **{requirements["availability_target"]}**
- Environments: {", ".join(requirements["environments"])}
- This baseline assumes managed identity, encrypted transport/storage, and centralized observability.
## 3. Logical architecture
The request path is Users → application boundary → service components → data and external integrations. The editable companion diagram is `architecture.drawio`.
### Components
{_items(components)}
### Integrations
{_items(integrations)}
## 4. Environment and landing-zone design
- Separate accounts/subscriptions/projects per environment where supported.
- Private network segments for services and data; ingress is restricted to approved entry points.
- Infrastructure is provisioned through repeatable, reviewed automation.
## 5. Security, resilience, and operations
- Apply least privilege, secrets management, encryption in transit and at rest, and audit trails.
- Define backup/restore objectives and test them before production release.
- Monitor availability, latency, errors, capacity, security events, and deployment health.
- Use health checks, autoscaling boundaries, and tested rollback procedures.
## 6. Constraints and decisions to confirm
{_items(constraints)}
- Confirm cloud/provider, RTO/RPO, retention, network connectivity, identity provider, and sizing during architecture review.
## 7. Delivery acceptance criteria
- [ ] Threat model and data-flow review completed.
- [ ] Non-production and production isolation verified.
- [ ] Observability, backup, restore, and disaster-recovery tests recorded.
- [ ] Diagram and assumptions approved by service owners.
'''
diagram = _drawio(requirements)
if not validate_drawio(diagram):
raise RuntimeError("generated diagram failed draw.io contract")
return {"tsd": tsd, "drawio": diagram, "manifest": {"agent": "application_landing_zone_agent", "generated_at": datetime.now(timezone.utc).isoformat(), "assumptions": ["managed identity", "encrypted transport/storage", "central observability"], "validation": {"requirements": True, "drawio": True}}}

View File

@@ -0,0 +1,21 @@
"""Input and output contract validation."""
REQUIRED = ("application_name", "business_context", "environments", "data_classification", "availability_target")
def validate_requirements(data):
if not isinstance(data, dict):
raise ValueError("requirements must be a JSON object")
missing = [key for key in REQUIRED if not data.get(key)]
if missing:
raise ValueError("missing required fields: " + ", ".join(missing))
if not isinstance(data["environments"], list) or not data["environments"]:
raise ValueError("environments must be a non-empty array")
for key in ("components", "integrations", "constraints"):
if key in data and not isinstance(data[key], list):
raise ValueError(f"{key} must be an array")
return True
def validate_drawio(xml):
required = ("<mxfile", "<diagram", "<mxGraphModel", "<mxCell", "</mxfile>")
return all(token in xml for token in required)

View File

@@ -1,30 +1,31 @@
import json, unittest
import xml.etree.ElementTree as ET
import json, tempfile, unittest
from pathlib import Path
from application_landing_zone_agent import LandingZoneAgent, ValidationError
from landing_zone_agent.generator import generate
from landing_zone_agent.validation import validate_requirements
class AgentContractTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.data = json.loads(Path("examples/application.json").read_text())
cls.agent = LandingZoneAgent()
def test_generation_is_deterministic_and_complete(self):
a, b = self.agent.generate(self.data), self.agent.generate(self.data)
self.assertEqual(a, b)
self.assertIn("## Component inventory", a.tsd_markdown)
self.assertIn("Orders API", a.tsd_markdown)
self.assertTrue(a.validation.valid)
def test_drawio_is_native_xml_with_vertices_and_edges(self):
root = ET.fromstring(self.agent.generate(self.data).drawio_xml)
self.assertEqual(root.tag, "mxfile")
self.assertIsNotNone(root.find(".//mxGraphModel"))
self.assertGreaterEqual(len(root.findall(".//mxCell[@vertex='1']")), 4)
self.assertGreaterEqual(len(root.findall(".//mxCell[@edge='1']")), 1)
def test_required_input_errors(self):
with self.assertRaises(ValidationError): self.agent.generate({"application_name": "x"})
def test_cli_fixture_has_expected_contract(self):
report = self.agent.validate(self.data)
self.assertFalse(report.errors)
self.assertEqual(report.warnings, [])
class AgentTests(unittest.TestCase):
def setUp(self):
self.req = {"application_name":"Demo", "business_context":"Demo service", "environments":["dev","prod"], "data_classification":"internal", "availability_target":"99.9%", "components":["API","DB"]}
if __name__ == "__main__": unittest.main()
def test_generates_tsd_and_drawio(self):
result = generate(self.req)
self.assertIn("# Technical Solution Design: Demo", result["tsd"])
self.assertIn("Security, resilience, and operations", result["tsd"])
self.assertTrue(result["drawio"].startswith("<mxfile"))
self.assertIn("<mxGraphModel>", result["drawio"])
self.assertTrue(result["manifest"]["validation"]["drawio"])
def test_missing_field_is_actionable(self):
with self.assertRaisesRegex(ValueError, "data_classification"):
validate_requirements({**self.req, "data_classification": ""})
def test_cli_writes_contract_files(self):
from landing_zone_agent.cli import main
with tempfile.TemporaryDirectory() as directory:
req_path = Path(directory) / "req.json"; out = Path(directory) / "out"
req_path.write_text(json.dumps(self.req), encoding="utf-8")
self.assertEqual(main(["--requirements", str(req_path), "--output-dir", str(out)]), 0)
self.assertEqual({p.name for p in out.iterdir()}, {"tsd.md", "architecture.drawio", "manifest.json"})
if __name__ == "__main__":
unittest.main()

14
validation/validate.py Normal file
View File

@@ -0,0 +1,14 @@
"""Repository-level validation entrypoint."""
import json, tempfile
from pathlib import Path
from landing_zone_agent.generator import generate
from landing_zone_agent.validation import validate_drawio
with open("examples/requirements.json", encoding="utf-8") as f:
result = generate(json.load(f))
assert result["tsd"].startswith("# Technical Solution Design")
assert validate_drawio(result["drawio"])
with tempfile.TemporaryDirectory() as d:
Path(d, "tsd.md").write_text(result["tsd"], encoding="utf-8")
Path(d, "architecture.drawio").write_text(result["drawio"], encoding="utf-8")
print("TSD, draw.io, and packaging contract checks passed")