1
0
Fork 0

chore(release): publiseringsklar for open/ — README for standalone rot + MIT + policy-filer

Commons konsumeres som `shared/`-subtree av to repo som allerede ligger i
`open/`. Innholdet var dermed offentlig fra før, men PEKEREN var det ikke:
`shared/README.md` i open/portfolio-optimiser lenker til `ktg/`-namespacet og
sier «All edits land in commons first (clone it, commit, push there)» — en URL
en fremmed får 404 på. Dette gjør repoet publiserbart under open/.

README: hodet var skrevet som om fila fortsatt lå i en konsuments `shared/`.
H1 var `# shared/ — framework-neutral core`, og innledningen sa «this
repository — the method built on MAF» — som beskriver et ANNET repo når fila
leses fra commons' rot. Siste linje lenket til
docs/plan/2026-06-26-maalbilde-agentic-loop.md, som ikke finnes her (den bor i
portfolio-optimiser). Alle tre rettet; de to konsumentene er nå utgående
lenker, ikke «dette repoet».

Lagt til for `shared-asset`-klassen (repo-standard): LICENSE (MIT, byte-likt
med soesknene) og `## Non-goals`. Klassen krever ikke `## Install` — repoet
vendorers, det installeres ikke.

CONTRIBUTING/SECURITY/CODE_OF_CONDUCT kreves av INGEN klasse; de er med for
konsistens med de to soesknene. CONTRIBUTING er SKREVET OM, ikke kopiert:
soesknenes versjon ber om Pull Requests, men org-ops slo PR-fanen av paa alle
19 repo fordi CONVENTIONS.md publiserer at PR-er ikke aksepteres. Aa kopiere
den ville importert en motsigelse.

SECURITY er omskrevet for et repo uten kjoerbar kode: angrepsflaten er spec-
tekst som binder konsumentene, ikke et avhengighetstre.

Gate: repo-standard v0.2.2, klasse shared-asset — 0 ERROR, 8 passerte. De 3
gjenstaaende WARN er falske positive mot nav-golden-fixturene (bundle-relative
lenker + tilsiktede escape-nyttelaster som IKKE skal resolve). Fixturene er
uroert: de konsumeres som ekte gate av portfolio-optimiser (0d50ab8).

Verifisert foer commit: ingen secrets i sporet innhold eller i historikkens 37
commits; ingen e-post utover org-kontakten; STATE.md og *.local.md fortsatt
usporet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013XuKPjWwJZNUponVrhoyY1
This commit is contained in:
Kjell Tore Guttormsen 2026-08-04 22:32:17 +02:00
commit ddaae5d637
5 changed files with 279 additions and 46 deletions

59
CODE_OF_CONDUCT.md Normal file
View file

@ -0,0 +1,59 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment:
* Demonstrating empathy and kindness
* Being respectful of differing opinions and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing for mistakes
* Focusing on what is best for the community
Examples of unacceptable behavior:
* Trolling, insulting or derogatory comments
* Public or private harassment
* Publishing others' private information without permission
* Other conduct which could reasonably be considered inappropriate
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
hello@fromaitochitta.com.
All complaints will be reviewed and investigated promptly and fairly.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html

66
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,66 @@
# Contributing to portfolio-optimiser-commons
Thank you for your interest. Please read this first — the workflow here is deliberately
narrower than most repositories, and knowing that up front saves you wasted effort.
## Code of Conduct
Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md).
## Pull requests are not accepted
The pull-request tab is **switched off** on this forge, across every repository in the
organisation. That is a published position, not an oversight: this project is solo-maintained,
and an enabled-but-permanently-empty PR queue would promise a review capacity that does not
exist.
Use **issues** instead. A well-argued issue carries the same information as a patch and costs
you less to write.
## What belongs here, and what does not
This repository is the framework-neutral core. Before opening an issue, check which side of the
boundary your point falls on:
| Your point is about | Raise it in |
|---|---|
| The normative specs, the example bundles, the golden fixtures | **here** |
| Behaviour of the MAF implementation | [`portfolio-optimiser`](https://git.fromaitochitta.com/open/portfolio-optimiser) |
| Behaviour of the Claude Agent SDK implementation | [`portfolio-optimiser-claude`](https://git.fromaitochitta.com/open/portfolio-optimiser-claude) |
A change that is true of only one of the two stacks does not belong here, however correct it
is — that is the whole point of the shared core. See the Non-goals in the [README](README.md).
## Reporting an issue
Useful issues on a specification repository look different from bug reports on code. The most
valuable ones name a specific place in the text:
- **Quote the section and the sentence**, not just a line number. Line numbers here go stale
quickly; a section heading plus the wording you are reading survives an edit above it.
- Say which of the two things you are claiming: that the specification is **internally
inconsistent**, or that it is **inconsistent with an implementation**. They have different
remedies, and conflating them is the most common way a report stalls.
- For a fixture, state the input, the output you expected, and the output you got.
## If you are maintaining a consuming repository
Sync is **pull-only**, and all edits land here first:
```sh
git subtree pull --prefix=shared commons main --squash
```
**Never run `git subtree push` from a consuming repository.** The reason, and what it cost the
one time it happened, is documented in the [README](README.md).
## Conventions
Commits follow [Conventional Commits](https://www.conventionalcommits.org/)
(`type(scope): description`). Changes to normative text are ratified before they land; the
reasoning behind each ruling is recorded in [`docs/plan/`](docs/plan/), including for the
rulings that were later reversed.
## Questions?
Open an issue.

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Kjell Tore Guttormsen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

117
README.md
View file

@ -1,25 +1,43 @@
# shared/ — framework-neutral core
# portfolio-optimiser-commons
This directory holds the parts of the project that are **independent of any AI agent
framework** and are meant to be **shared, unchanged, between both reference
implementations**:
Framework-neutral shared core of the portfolio-optimiser method: the normative specs, example bundles and golden fixtures vendored by both reference implementations.
- **this repository** — the method built on Microsoft Agent Framework (MAF);
- **a sibling repository** (built later, in sequence) — the same method on the
**Claude Agents SDK**.
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
Sharing one identical core is what makes the two implementations a *fair comparison*:
both consume the same concept, the same example data, and the same expected outcomes,
so the only thing that differs is the agent framework itself.
This repository is the **source of truth** for everything in the portfolio-optimiser method
that is **independent of any AI agent framework**. It holds no runnable code — only
normative specifications, example data, and expected outcomes.
## Contents (growing)
Two reference implementations consume it, unchanged, as a `git subtree` at `shared/`:
- [`CONCEPT.md`](CONCEPT.md) — the business concept, written for a non-specialist
(e.g. a business developer at another company).
- [`portfolio-optimiser`](https://git.fromaitochitta.com/open/portfolio-optimiser) — the
method on **Microsoft Agent Framework (MAF)**;
- [`portfolio-optimiser-claude`](https://git.fromaitochitta.com/open/portfolio-optimiser-claude)
— the same method on the **Claude Agent SDK**.
Sharing one identical core is what makes the two implementations a *fair comparison*: both
consume the same concept, the same example data, and the same expected outcomes, so the only
thing that differs is the agent framework itself. The second implementation is built from the
specifications alone, without reverse-engineering the reference code.
## Contents
- [`method-spec.md`](method-spec.md) — the **normative method specification**, framework-neutral
(the prose never names a concrete agent toolkit — enforced by a guard test): the 8-step loop,
the verdict JSON contract, the inbox/outbox folder contract, the promotion-gate semantics, the
IR projection + golden suite as the only ground truth, and the budget/provenance requirements.
- [`ingest-spec.md`](ingest-spec.md) — the **normative ingest specification**, framework-neutral
(same guard rule): the deterministic ingest step that materializes real data sources as OKF
bundles BEFORE the loop — the polymorphic manifest schema (file/CSV, SQL, HTTP as extension
point), the credential-reference rule, the verdict-layer reservation, the ingest provenance
frontmatter with an explicit timestamp, the index-generation requirement, and the
golden-extraction format.
- [`CONCEPT.md`](CONCEPT.md) — the business concept, written for a non-specialist (e.g. a
business developer at another company). Written in Norwegian.
- [`examples/bygg-energi-mikro/`](examples/bygg-energi-mikro/) — the first example knowledge
bundle (OKF / LLM-wiki): one office building, one LED-retrofit measure, with a seed expert
verdict encoding the realization gap and a golden-suite of expected validator outcomes. A
small **dev fixture** for exercising the agentic loop; a realistic full-scale example comes later.
verdict encoding the realization gap and a golden-suite of expected validator outcomes. A small
**dev fixture** for exercising the agentic loop; a realistic full-scale example comes later.
- [`examples/nav-golden-hierarchy/`](examples/nav-golden-hierarchy/) and
[`examples/nav-golden-escape/`](examples/nav-golden-escape/) — the **nav-golden** fixture class:
`bundle/` in, `expected-read-context.md` out, exercising the navigation contract (method-spec §3
@ -33,45 +51,52 @@ so the only thing that differs is the agent framework itself.
framework-neutral Agent Skill: a `SKILL.md` persona prompt (energy-advisor / M&V role + the
realization-gap methodology the validator cannot compute) and a canonical
`references/example-verdict.json`. Both reference implementations instantiate the reviewer from
this one artifact; `shared/` stays pure data (each stack reads the JSON with its own loader).
- [`method-spec.md`](method-spec.md) — the **normative method specification**, framework-neutral
(the prose never names a concrete agent toolkit — enforced by a guard test): the 8-step loop,
the verdict JSON contract, the inbox/outbox folder contract, the promotion-gate semantics, the
IR projection + golden suite as the only ground truth, and the budget/provenance requirements.
The sibling implementation is built from this spec alone, without reverse-engineering the
reference code.
- [`ingest-spec.md`](ingest-spec.md) — the **normative ingest specification**, framework-neutral
(same guard rule as the method spec): the deterministic ingest step that materializes real
data sources as OKF bundles BEFORE the loop — the polymorphic manifest schema (file/CSV, SQL,
HTTP as extension point), the credential-reference rule, the verdict-layer reservation, the
ingest provenance frontmatter with an explicit timestamp, the index-generation requirement,
and the golden-extraction format.
this one artifact; this repository stays pure data (each stack reads the JSON with its own loader).
- [`docs/plan/`](docs/plan/) — the decision record: how each ruling in the specifications above was
arrived at, including the ones that were later reversed. Working documents, not normative, and
written in a mix of Norwegian and English.
## Rules
## Vendoring this repository
- **Nothing in here may import or depend on a specific agent framework.** If it does,
it does not belong in `shared/`.
- **Repo layout (decision R1, realized 2026-07-03):** the shared core lives in its own
repository, [`portfolio-optimiser-commons`](https://git.fromaitochitta.com/ktg/portfolio-optimiser-commons)
— the **source of truth**. Each implementation repo consumes it as a **git subtree**
at this unchanged `shared/` path (so tests and the `PORTFOLIO_SHARED_ROOT` default
resolver are unaffected). Do not edit commons content anywhere else without syncing.
This repository is **vendored, not installed** — there is no package to add. Each consuming
repository carries it as a `git subtree` under `shared/`, so the specs and fixtures are present in
a normal checkout with no extra tooling.
## Subtree sync (pull-only — run from the consuming repo's root)
Register the remote once, from the consuming repository's root:
The remote is registered as `commons`
(`ssh://git@git.fromaitochitta.com/ktg/portfolio-optimiser-commons.git`).
```sh
git remote add commons https://git.fromaitochitta.com/open/portfolio-optimiser-commons.git
git subtree add --prefix=shared commons main --squash
```
**All edits land in commons first** (clone it, commit, push there), then each
consuming repo pulls them in:
Then pull updates with:
```sh
git subtree pull --prefix=shared commons main --squash
```
**Never run `git subtree push` from a consuming repo.** Observed 2026-07-03: because
this repo's history contains commits that create/delete the `shared/` prefix, the
push re-split leaked the consumer's *entire* history into commons (cleaned up by
force-push the same day). Pull-only keeps commons the clean source of truth.
**Sync is pull-only. All edits land here first** — commit and push in this repository, then pull
them into each consumer.
See the target picture for the full architecture: `docs/plan/2026-06-26-maalbilde-agentic-loop.md`.
**Never run `git subtree push` from a consuming repository.** Observed 2026-07-03: because a
consumer's history contains commits that create and delete the `shared/` prefix, the push re-split
leaked the consumer's *entire* history into this repository (cleaned up by force-push the same
day). Pull-only keeps this repository the clean source of truth.
## Non-goals
- **Not a runnable system.** No pipeline, no CLI, no package. The specifications describe
behaviour; the two implementation repositories provide it.
- **No framework dependency.** Nothing here may import or depend on a specific agent framework.
If it does, it does not belong in this repository — that is what "framework-neutral" buys, and a
guard test in each consumer enforces it for the two normative specs.
- **Not a general-purpose knowledge-format standard.** The bundle layout follows the upstream Open
Knowledge Format where it applies; this repository does not seek to replace or extend it beyond
what the method needs.
- **Not a home for implementation decisions.** Anything true of only one of the two stacks belongs
in that stack's repository, not here.
- **No inbound patches through this forge.** See [CONTRIBUTING.md](CONTRIBUTING.md).
## License
[MIT](LICENSE) © 2026 Kjell Tore Guttormsen

62
SECURITY.md Normal file
View file

@ -0,0 +1,62 @@
# Security Policy
## Reporting a Vulnerability
If you discover a security issue, please report it responsibly.
**Please do NOT report security issues through public issues.**
### How to Report
Email: hello@fromaitochitta.com
Include:
- Description of the issue
- Steps to reproduce
- Potential impact
- Any suggested fixes (optional)
### What to Expect
- Acknowledgment within 48 hours
- Regular updates on progress
- Credit in the fix announcement (if desired)
## What the attack surface here actually is
This repository ships **no executable code** — no package, no pipeline, no CLI. It contains
normative specifications, example knowledge bundles, and golden fixtures. There is no dependency
tree to keep patched and nothing here that runs on your machine.
That narrows the realistic reports to three kinds, and all three are worth sending:
1. **A specification that mandates unsafe behaviour.** The specs are binding on the
implementations that consume them, so a weak rule propagates. The ingest specification in
particular governs a boundary where untrusted external data enters the system: its
credential-reference rule (manifests carry *references* to credentials, never the credentials
themselves) and its verdict-layer reservation exist for this reason. A gap in that text is a
real vulnerability report even though no code changes.
2. **A secret or personal data in the repository or its history.** The example bundles are
synthetic. If you find something that is not, report it — including in the git history, which
is public in full.
3. **A fixture that would make a consuming gate pass when it should fail.** The golden suites are
the only ground truth the implementations check themselves against. A fixture that silently
sanctions unsafe behaviour weakens every consumer at once.
## Supported Versions
| Version | Supported |
| ------- | ------------------ |
| latest | :white_check_mark: |
| < latest| :x: |
Consumers vendor this repository as a `git subtree`, so a fix here reaches them only when they
pull. If a report leads to a change in normative text, both reference implementations are
notified — but their pull is their own action, on their own schedule.
## Scope Note
The portfolio-optimiser method is a **technical framework**. Deploying organizations own their
own data protection, risk, and compliance assessments (DPIA/ROS). The specifications describe
technical prerequisites (local-only operation, provenance, no silent egress) but make no
compliance guarantees.