Skip to content

Commit ae02296

Browse files
authored
Merge pull request #194 from NDDev-OpenNetwork/docs/align-example-estate-contract-20260929
docs: align estate and memory contracts with current code
2 parents 23c8cd5 + b974422 commit ae02296

4 files changed

Lines changed: 58 additions & 67 deletions

File tree

‎docs/architecture/README.md‎

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This is the current architecture overview of the `github-device-sync` (gds)
44
control plane. It carries no release version in its title deliberately: it
55
describes the system as it is now, and a version stamped here goes stale
66
silently every time a release ships without an architecture change. Release
7-
boundaries live in `CHANGELOG.md` and `docs/version-ledger.md`. For the
7+
boundaries live in `CHANGELOG.md` and release tags. For the
88
migration design baseline that preceded the Go implementation, see
99
the ADRs in `docs/adr/`.
1010

@@ -37,20 +37,23 @@ provenance, and rejects equal-priority selector ambiguity.
3737

3838
- **Five GitHub installations**: `example-user` (user), `example-org`,
3939
`example-media`, `NDDev-OpenNetwork`, and `example-guild`
40-
(read-only member, no mutation capability). Four carry separate Mutation Apps
40+
(read-only member, no mutation capability). Four have separate mutation
41+
capability declarations
4142
with distinct identity and secret locators from their read Installation Apps.
4243
- **Three devices**: `example-workstation` (linux/x86_64, desktop),
4344
`example-user-mac2` (macos/arm64, desktop), and `example-user-ubuntu-1`
4445
(linux/x86_64, desktop-builds, rootful Docker).
4546
- **Repository visibility**: public. The control-plane repository carries
4647
`visibility_contract: public` and declares no submodules, so no module
4748
visibility has to be reconciled against it.
48-
- **Posture**: `mutation_mode: "pull-request"` for managed NDDev sources;
49-
every other selector remains `observe-only`, and every write remains gated by
49+
- **Posture**: `mutation_mode: "pull-request"`; `organization-sources` and
50+
`opennetwork-sources` are managed, while the other shipped selectors remain
51+
`observe-only`. Every write remains gated by
5052
exact signed approval plus one-shot enablement.
51-
- **Selectors** classify observed repositories by owner, fork flag, name
52-
prefix, and archived state into portfolios. Priority bands: `100` generic,
53-
`200` specialized non-fork, `300` state override (archived precedence).
53+
- **Selectors** classify observed repositories by owner, visibility, and name
54+
prefix into portfolios. The seven shipped selectors use priorities `100`
55+
(sources) and `200` (server-name overrides). The example declares no
56+
archived-state selector.
5457

5558
## Package layout (Go core)
5659

@@ -67,7 +70,7 @@ provenance, and rejects equal-priority selector ambiguity.
6770
| Control-plane service | `state`, `controller`, `reconciler`, `webhooks`, `audit` | SQLite journal, webhook worker, drift reconciler, signed audit snapshots. |
6871
| Orchestration | `app`, `cli`, `cmd/*` | Use-case wiring, Cobra adapter, seven binaries. |
6972

70-
Six binaries: `gds`, `gds-controller`, `gds-assurance`,
73+
Seven binaries: `gds`, `gds-controller`, `gds-assurance`,
7174
`gds-performance-evidence`, `gds-release-builder`, and
7275
`gds-{claude,codex}-runtime-driver`.
7376

‎docs/contracts/cli-v1.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,15 @@ Validates semantic Serena memory names, strict metadata, committed versus
214214
working-tree status, required body sections, safe repository-relative sources,
215215
and deterministic source digests. It reports drift but never rewrites memory.
216216

217+
### `gds memory generate <name>`, `gds memory verify <name>`
218+
219+
Both return a complete read-only candidate for an existing semantic memory
220+
whose declared sources have been committed. `generate` demotes stale source
221+
provenance to `generated-unverified`; `verify` stamps `verified` and
222+
`verified_at` after the caller has reviewed the body against those sources.
223+
Neither writes the candidate. In JSON output, apply `data.content` to
224+
`data.path`, then run `gds memory validate`.
225+
217226
### `gds validate plan --file <path>`
218227

219228
Validates schema, expiry ordering, exact scope/precondition coverage, step

‎docs/contracts/estate-v1.md‎

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# GDS estate desired-configuration v1 contract
22

3-
Status: implemented with controlled mutation enabled for managed NDDev sources.
3+
Status: implemented. The shipped example estate enables controlled mutation
4+
only for selectors and operation capabilities that explicitly allow it.
45

56
## Source boundary
67

@@ -19,10 +20,9 @@ estate/owners/*.yaml
1920
estate/selectors/*.yaml
2021
```
2122

22-
The current baseline declares four owners: the personal `example-user` account,
23-
the `example-org` organization, the `example-media` organization, and
24-
the `example-guild` organization (read-only member, no mutation
25-
capability). Installation IDs remain logical; their actual GitHub App and
23+
The shipped example declares five owners: `example-user`, `example-org`,
24+
`example-media`, `example-guild` (observe-only), and the publisher account
25+
`NDDev-OpenNetwork`. Installation IDs remain logical; their actual GitHub App and
2626
provider installation IDs are bound only by a private device-local
2727
`github-runtime` document, or by the gh-CLI credential variant (ADR 0034).
2828
Estate secret references are portable `secret:gds/...` identities; they do not
@@ -41,12 +41,12 @@ discovery.default_management_mode = observe-only
4141
rollout.mutation_mode = pull-request
4242
```
4343

44-
The generic NDDev source selector assigns `managed`; every other selector
45-
remains `observe-only`. Managed does not authorize an automatic write: apply
44+
The `organization-sources` and `opennetwork-sources` selectors assign
45+
`managed`; the other shipped selectors assign `observe-only`. Managed does not authorize an automatic write: apply
4646
also requires an exact immutable plan, signed approval, one-shot enablement,
4747
fresh compare-and-swap evidence, an operation-scoped mutation capability, a
4848
private runtime, and the device mutation kill switch. Archive, fork, server,
49-
guild, personal, and Example-Media selectors remain outside this rollout.
49+
guild, personal, and example-media selectors remain outside this rollout.
5050

5151
## Discovery and classification
5252

@@ -76,32 +76,18 @@ retain their own priority. Organization and personal server portfolios
7676
use distinct device workspace roots so their filesystem placement remains
7777
injective even when owners contain repositories with the same name.
7878

79-
Selector priority bands are conventional:
79+
The shipped selectors use these priority bands:
8080

8181
- `100` — generic classification (sources, forks);
8282
- `200` — specialized non-fork overrides (servers, named-prefix families);
83-
- `300` — state overrides that outrank topology and name (archived).
84-
85-
The `archived` state takes precedence over both fork topology and server name.
86-
The estate ships a priority-`300` archived selector for every owner whose
87-
fall-through source portfolio would otherwise misclassify an archived
88-
repository, so a provider-archived repository resolves to
89-
`portfolio:archived-projects` regardless of whether it is a fork, a source, or
90-
a `server-*` superproject:
91-
92-
- `personal-archived` matches `owner:example-user` with `archived: true`;
93-
- `organization-archived` matches `owner:nddev` with `archived: true`.
94-
95-
A higher band must be distinct from every overlapping selector's priority to
96-
avoid the equal-priority ambiguity the compiler rejects. The
97-
`organization-archived` selector is defense-in-depth: no NDDev repository is
98-
archived on the provider today, but without it a future archived NDDev
99-
repository would fall through to `portfolio:organization-projects` under
100-
`organization-sources` instead of `portfolio:archived-projects`. The
101-
`example-media` and `example-guild` owners do not yet declare an
102-
archived selector; add one if an archived repository ever appears under those
103-
owners and would otherwise be misclassified by `example-media-sources`,
104-
`example-media-servers`, or `guild-sources`.
83+
84+
There is no archived selector in the shipped example. The compiler preserves
85+
the provider's `archived` observation, but classification follows the matching
86+
selector. An estate that defines archival by ownership can assign its archive
87+
owner to `portfolio:archived-projects` regardless of the provider flag. An
88+
estate that instead wants provider-archived precedence must declare an
89+
appropriate higher-priority selector. Equal-priority overlapping matches are
90+
rejected by the compiler.
10591

10692
## Monotonic policy fields
10793

‎docs/contracts/memories-v1.md‎

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# GDS Serena memory v1 contract
22

3-
Status: Phase 11 provenance validation implemented; current memories are
4-
verified against committed source inputs.
3+
Status: provenance validation and read-only candidate generation are
4+
implemented. The shipped public repository disables Serena memories in its
5+
anchor and has no tracked `.serena/memories/` set.
56

67
## Role
78

@@ -92,7 +93,7 @@ contract statement rather than an omission.
9293
claimed assurance is missing, and a repository that keeps memories without
9394
binding them to sources has not promised to keep any.
9495
- `enabled: true, provenance_required: true` -- everything above, including
95-
`GDS_MEMORY_SET_EMPTY`. This control plane declares this.
96+
`GDS_MEMORY_SET_EMPTY`. A consuming estate can declare this.
9697

9798
An anchor that cannot be read falls back to the strictest reading. The opt-out
9899
has to be stated to take effect; inferring it from a file that failed to parse
@@ -106,32 +107,24 @@ so `gds validate memories` (and the `core/memory` and `core/cli` tests) fail
106107
until the memory is re-synced. This is expected drift, not a defect. The sync is
107108
commit-first:
108109

109-
1. Commit the source change. `gds memory generate <name>` resolves the source
110-
commit from the committed history and refuses a dirty tree with
110+
1. Commit the source change. Both candidate commands resolve the source
111+
commit from committed history and refuse dirty declared sources with
111112
`GDS_MEMORY_COMMITTED_SOURCE_NOT_PROVEN`.
112-
2. Run `gds memory generate <name>`. It preserves the authored body, recomputes
113-
the digest and source commit, and emits `generated-unverified` whenever the
114-
commit or digest changed. Apply the new `source_commit`, `source_digest`, and
115-
a fresh `verified_at` to the frontmatter.
116-
3. Restore `status: verified` only as a deliberate assertion that the body still
117-
describes the current source; add any new stable invariant to the body while
118-
re-reading it. The generator never promotes status on its own.
113+
2. Re-read the authored body against those sources and edit any stale claim.
114+
`gds memory generate <name> --json` preserves that body and returns a
115+
`generated-unverified` candidate when source provenance changed. It does
116+
not write the file or assert that the prose is true.
117+
3. After reviewing the body, run `gds memory verify <name> --json`. It returns
118+
a candidate with current source and body digests, `status: verified`, and a
119+
new `verified_at` later than the source commit. Apply the returned
120+
`data.content` byte-for-byte to `data.path`; the command never writes it.
121+
`bundle_version` is memory metadata and is not the installed CLI version.
119122
4. Commit the memory update on its own, conventionally as a `docs(memory):`
120-
change separate from the source commit.
123+
change separate from the source commit. Run `gds memory validate` again.
121124

122-
## Current semantic set
125+
## Repository selection
123126

124-
```text
125-
core-bundle-rollout
126-
core-context-resolution
127-
core-estate-layout
128-
core-github-controller
129-
core-harness-adapters
130-
core-integrated-assurance
131-
core-operation-safety
132-
core-policy-projection
133-
```
134-
135-
The former numeric memories were retired only after these replacements covered
136-
their still-valid knowledge. Legacy four-level/container claims that conflict
137-
with the typed graph model were not copied forward.
127+
The public GDS example has `agent.serena.enabled: false` and
128+
`provenance_required: false`, so it owes no memory set. A consuming estate
129+
chooses its own semantic names and source paths; do not copy an older GDS
130+
memory list into it.

0 commit comments

Comments
 (0)