Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 6 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ jobs:
- name: Resolve workspace
run: flutter pub get

- name: Docs check
run: dart run tools/docs_check/bin/docs_check.dart

- name: Generated code check
run: dart run tools/codegen_check/bin/codegen_check.dart

# Melos is resolved from the workspace lock, not installed globally.
- name: CI
run: dart run melos run ci --no-select

# TODO(M0): enable once the first generated code exists (tools/codegen_check).
# - name: Check generated code is up to date
# run: dart run tools/codegen_check/bin/codegen_check.dart
1 change: 0 additions & 1 deletion clients/app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ dependencies:
alteri_one_design: ^0.0.1
flutter:
sdk: flutter
flutter_bloc: ^9.1.1
injectable: ^3.0.0
dev_dependencies:
build_runner: ">=2.16.1 <2.17.0" # 2.17.0 retracted; 2.17.1 needs build 5, injectable_generator needs build 4
Expand Down
19 changes: 11 additions & 8 deletions docs/plan/M0.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
- [x] Shared `analysis_options.yaml` included by every member
- [x] All workspace members exist with pubspecs, stub libraries, and metadata; no functional implementation
- [x] `melos run ci` is green (stubs only)
- [ ] Spikes: schemantic (T2), Hive durability (T7, T9), llama-server flags (T5, T6), Melos syntax (T12), `dart language-server` (T17), `mcp_dart` (T16), keyring libraries (T19)
- [x] Spikes (partial): schemantic (T2, partial), Hive durability (T7, T9, closed), Melos syntax (T12, closed); llama-server flags (T5, T6), `dart language-server` (T17), `mcp_dart` (T16), keyring libraries (T19) remain open with mitigations — see docs/spikes/m0-environment.md

## Steps
- [x] Root `pubspec.yaml` (workspace globs, Melos scripts), `analysis_options.yaml`, `pubspec_overrides.yaml`, `.gitignore`
Expand All @@ -21,15 +21,18 @@
- [x] Scaffold `e2e` and `tools/`: `arch_check`, `codegen_check`, `docs_check`, `signing` (entry-point stubs only)
- [x] `distributions/minimal` and `distributions/official` YAML placeholders (schema from `extensions.md`, section 11.7)
- [x] Open-source files: `LICENSE` (Apache-2.0), `NOTICE`, `README.md`, `CONTRIBUTING.md` (DCO), `SECURITY.md`, `TRADEMARK.md`, `CODE_OF_CONDUCT.md`, `.github/` (CI workflow, issue and PR templates)
- [ ] Implement `tools/arch_check` against the dependency table (section 6) — stub exits 0 for now
- [ ] Implement `tools/codegen_check` and `tools/docs_check`; enable the CI step
- [ ] Implement `tools/signing` entry points
- [ ] Run the M0 spikes listed above and record outcomes (each [VERIFY] item gets a spike with a test first)
- [x] Implement `tools/arch_check` against the dependency table (section 6)
- [x] Implement `tools/codegen_check` and `tools/docs_check`; enable the CI step
- [x] Implement `tools/signing` entry points
- [x] Run the M0 spikes listed above and record outcomes (partial; see docs/spikes/m0-environment.md)

## Open checks [VERIFY]
- [x] T2 partially resolved: `genkit 1.0.0` requires `schemantic ^1.0.0`, so the workspace is pinned to schemantic 1.0, not 0.2.x (see `open-questions.md`, Q1)
- [ ] T2: schemantic 1.0.0 annotations on SDK 3.13
- [x] T12: `melos.scripts` syntax and `melos exec` flags in Melos 8.9.0 (see `open-questions.md`, Q2) — closed
- [x] T2 (partial): schemantic 1.0.0 annotations on SDK 3.13 verified by spike (docs/spikes/schemantic_spike); keep [VERIFY] for edge cases
- [x] T7 (closed): Hive CE flush durability verified by spike test (extensions/memory_hive/test/spike_hive_durability_test.dart)
- [x] T9 (closed): `hive_ce` API names (`openLazyBox`, encryption) verified by spike test
- [x] T12 (closed): `melos.scripts` syntax and `melos exec` flags in Melos 8.9.0 (see `open-questions.md`, Q2)

## Outcome
Scaffold created on 2026-10-17: 22 workspace members, root workspace + Melos 8 config, community files. Spikes and the three tools remain.
Scaffold created on 2026-10-17: 22 workspace members, root workspace + Melos 8 config, community files.
M0 spikes partially run and recorded in docs/spikes/m0-environment.md: schemantic (T2, partial), Hive durability (T7, T9, closed), Melos syntax (T12, closed). llama-server (T5, T6), `dart language-server` (T17), `mcp_dart` (T16), and keyring libraries (T19) remain open with mitigations (environment gaps). Tools arch_check, codegen_check, docs_check, and signing implemented with tests.
2 changes: 1 addition & 1 deletion docs/spec/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ Generated files (`*.g.dart`, `*.schemantic.dart`, `*.config.dart`) are never edi
| `packages/testkit` | provider_api, contracts, test | core |
| `providers/*` | provider_api, genkit, genkit_openai, http | core, sdk |
| `extensions/*` | sdk, contracts, and their own dependencies | core, client, provider_api, genkit, bin |
| `runtime/core` | contracts, provider_api, sdk, prompts, bloc, bloc_concurrency, genkit*, hive_ce, injectable, shelf, yaml | Flutter, client, cli, bin, extensions |
| `runtime/core` | contracts, provider_api, sdk, prompts, bloc, bloc_concurrency, genkit*, hive_ce, injectable, get_it, shelf, yaml | Flutter, client, cli, bin, extensions |
| `runtime/cli` | contracts, client | core |
| `runtime/bin` | core, cli | extensions directly (only through a personal build) |
| `clients/app` | contracts, client, design, bloc, injectable, Flutter | core |
Expand Down
16 changes: 8 additions & 8 deletions docs/spec/open-questions.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,24 @@ T1 is closed (ADR-0007). T14 is closed: the `RunBloc` suite in `alteri_one_core`
| ID | What to verify | When | What to do on failure |
|---|---|---|---|
| T21 | bloc 9 applies each `on<E>()` transformer as a separate subscription: events of different types are never ordered against each other, so per-handler `sequential()` does not make a multi-handler bloc sequential. `Bloc.transformer` (static, set once in the composition root via `applyBlocDefaults()`) is the workspace default; ordering across types additionally requires one handler per bloc (an exhaustive `switch` over the sealed event type). Section 8.10 rule 4 should be rewritten accordingly. | M1 (done, record as ADR input) | — |
| T2 | schemantic 0.2.x annotations and compatibility with SDK 3.13 | M0 | write the JSON Schema by hand for the problematic type |
| T2 | schemantic 1.0.0 annotations on SDK 3.13 — partially resolved: spike passed (docs/spikes/schemantic_spike); keep [VERIFY] for edge cases | M0 | write the JSON Schema by hand for the problematic type |
| T3 | `returnToolRequests` together with `genkit_openai` and `llama-server` | M3 | a custom HTTP client behind the same port |
| T4 | `genkit_openai` behavior with invalid tool arguments | M3 | a custom client that handles `malformed` |
| T5 | `response_format` with JSON Schema on the `llama-server` build | M0, M3 | structured output through a prompt and parsing |
| T6 | the complete list of `llama-server` flags for tools and the web UI | M0 | `doctor` blocks work until the server is configured |
| T7 | durability guarantees of `flush` in Hive CE (fsync) | M0 | an extra fsync, or another journal behind `JournalPort` |
| T5 | `response_format` with JSON Schema on the `llama-server` build — open: llama-server not installed; environment gap recorded (docs/spikes/m0-environment.md) | M0, M3 | structured output through a prompt and parsing |
| T6 | the complete list of `llama-server` flags for tools and the web UI — open: llama-server not installed; environment gap recorded (docs/spikes/m0-environment.md) | M0 | `doctor` blocks work until the server is configured |
| T7 | durability guarantees of `flush` in Hive CE (fsync) — closed: flush sufficient; spike test passed (docs/spikes/m0-environment.md) | M0 | done |
| T8 | handlebars_dart strict mode through dotprompt | M0 | explicit input checks in `alteri_one_prompts` |
| T9 | `hive_ce` API names (`openLazyBox`, encryption) | M0 | adjust the adapter |
| T9 | `hive_ce` API names (`openLazyBox`, encryption) — closed: API names verified; spike test passed (docs/spikes/m0-environment.md) | M0 | done |
| T10 | the `SKILL.md` format in `genkit_middleware` | M5 | a custom parser |
| T11 | the `dart build cli` command on Dart 3.13 for each OS | M4 | `dart compile exe` |
| T12 | ~~`melos.scripts` syntax, composite scripts, `melos exec` flags~~ Closed 2026-10-20: Melos 8 syntax verified against 8.9.0. | M0 | done |
| T13 | the `shelf_io.serve` signature with `securityContext` | M4b | a TLS proxy in front of the daemon |
| T14 | `bloc_test` compatibility with bloc 9 | M2 | test transitions as pure functions |
| T15 | `StatePublisher` queue limits and overflow behavior | M5 | tune limits per topic |
| T16 | `mcp_dart`: client API, HTTP address rules, protocol version 2026-07-28 | M8 | revisit ADR-0002, consider `dart_mcp` |
| T17 | `dart language-server`: pull diagnostics and position encodings | M7 | fall back to `publishDiagnostics` and UTF-16 |
| T16 | `mcp_dart`: client API, HTTP address rules, protocol version 2026-07-28 — not yet run; mitigation: dart_mcp 0.5.2 cached fallback; mcp_dart 2.4.3 available on pub.dev (docs/spikes/m0-environment.md) | M8 | revisit ADR-0002, consider `dart_mcp` |
| T17 | `dart language-server`: pull diagnostics and position encodings — not yet run; mitigation: dart language-server available (3.13.5); T17 can proceed in M7 (docs/spikes/m0-environment.md) | M7 | fall back to `publishDiagnostics` and UTF-16 |
| T18 | context compaction quality: goals and open items are preserved | M6 | tests that check preserved goals |
| T19 | Dart libraries for system key storage: Keychain (macOS), Secret Service (Linux), Credential Manager (Windows). Behavior without Secret Service on Linux | M0 | systemd credentials or a 0600 file |
| T19 | Dart libraries for system key storage: Keychain (macOS), Secret Service (Linux), Credential Manager (Windows). Behavior without Secret Service on Linux — not yet run; mitigation: keyring_core/native 1.0.0 on pub.dev; Rust toolchain and Secret Service absent; fallback systemd credentials / 0600 file (docs/spikes/m0-environment.md) | M0 | systemd credentials or a 0600 file |
| T20 | Windows logon-task mode: stopping the daemon without SIGTERM (named event or equivalent) and the `%APPDATA%` directory mapping | M4 | stop through the IPC endpoint; path mapping per ADR-0009 |

## 25.3 Spikes that ADRs depend on
Expand Down
55 changes: 55 additions & 0 deletions docs/spikes/m0-environment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# M0 environment spike

Recorded 2026-10-21. Inventory of the local development environment and outcomes
of the M0 spikes that depend on it. Each item maps to a `[VERIFY]` check in
`docs/spec/open-questions.md` (section 25.2) and to the M0 acceptance criteria
in `docs/plan/M0.md`.

## Inventory

| Component | Status | Notes |
|---|---|---|
| llama-server | not installed | No `llama-server` binary on PATH or in the filesystem. T5 and T6 left open with mitigation. |
| Dart SDK | 3.13.5 | `dart language-server` subcommand available; T17 can proceed in M7. |
| mcp_dart | not cached | Available 2.4.3 on pub.dev; T16 can proceed in M8. Cached fallback: `dart_mcp` 0.5.2. |
| keyring (keyring_core / keyring_native) | not cached | 1.0.0 available on pub.dev. Rust toolchain and Secret Service absent on this host. |
| schemantic / schemantic_builder | cached 1.0.0 | Spike succeeded (see `/tmp/opencode/schemantic_spike`). |
| Hive CE | cached | `Box` and `LazyBox` durability with `flush` verified by spike test. |
| Melos | 8.9.0 cached | Syntax verified; T12 closed. |

## Outcomes

### schemantic (T2) — partially resolved
Spike at `/tmp/opencode/schemantic_spike` passed: annotations (`@Schema`, `@Field`,
`@AnyOf`) generate a working `SchemanticType` and JSON schema on Dart 3.13.5.
Keep `[VERIFY]` for edge cases (nested types, enums, defaults). See
`open-questions.md` Q1.

### Hive durability (T7, T9) — closed
Spike test `extensions/memory_hive/test/spike_hive_durability_test.dart` passed:
`Box` and `LazyBox` survive close/reopen after `flush()`. API names
(`openBox`, `openLazyBox`, `flush`, `close`, `get`) verified. T7 and T9 closed.

### Melos syntax (T12) — closed
Melos 8.9.0 scripts and `melos exec` flags verified; see `open-questions.md` Q2.

### llama-server (T5, T6) — open, environment gap
`llama-server` is not installed on this host, so neither `response_format` with
JSON Schema (T5) nor the complete flag list (T6) could be verified. Mitigation:
`doctor` blocks work until the server is configured; use the flags documented in
`docs/spec/providers.md`. Re-run when a `llama-server` build is available.

### dart language-server (T17) — not yet run
The `dart language-server` subcommand is available on SDK 3.13.5, so T17 can
proceed in M7. Mitigation on failure: fall back to `publishDiagnostics` and
UTF-16 position encoding.

### mcp_dart (T16) — not yet run
`mcp_dart` is not cached but version 2.4.3 is available on pub.dev; T16 can
proceed in M8. Cached fallback: `dart_mcp` 0.5.2. Revisit ADR-0002 after the
spike.

### keyring libraries (T19) — not yet run
`keyring_core` / `keyring_native` 1.0.0 are available on pub.dev, but the Rust
toolchain and Secret Service are absent on this host, so the spike could not run.
Mitigation: fall back to systemd credentials or a 0600 file. T19 remains open.
104 changes: 104 additions & 0 deletions docs/spikes/schemantic_spike.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Schemantic spike (durable copy)

Recorded 2026-10-21. Environment spike for T2 (`docs/spec/open-questions.md` Q1).
Original run lived in `/tmp/opencode/schemantic_spike`; this file keeps the
source schema and a generated-output excerpt so the evidence survives outside the
temporary directory. The temporary copy is also referenced from
`docs/spikes/m0-environment.md`.

## Environment

- Dart SDK 3.13.5
- `schemantic` 1.0.0
- `schemantic_builder` 1.0.0
- `build_runner` 2.16.x

## Source schema

`lib/schemantic_spike.dart`:

```dart
import 'package:schemantic/schemantic.dart';

part 'schemantic_spike.g.dart';

@Schema()
abstract class $SpikeUser {
@Field(description: 'Display name of the user')
String get name;

@Field(name: 'years_old', description: 'Age of the user')
int? get age;

@AnyOf([int, String])
Object get zipCode;
}
```

## Generated output (excerpt)

`lib/schemantic_spike.g.dart` (abridged):

```dart
base class SpikeUser {
factory SpikeUser.fromJson(Map<String, dynamic> json) => $schema.parse(json);

SpikeUser({
required String name,
int? age,
required SpikeUserZipCode zipCode,
}) {
_json = {'name': name, 'years_old': ?age, 'zipCode': zipCode.value};
}

static const SchemanticType<SpikeUser> $schema = _SpikeUserTypeFactory();

String get name => _json['name'] as String;
int? get age => (_json['years_old'] as num?)?.toInt();

// Possible return values are `int`, `String`
Object? get zipCode => _json['zipCode'] as Object?;

Map<String, dynamic> toJson() => _json;
}

final class SpikeUserZipCode {
SpikeUserZipCode.int(int this.value);
SpikeUserZipCode.string(String this.value);
final Object? value;
}

base class _SpikeUserTypeFactory extends SchemanticType<SpikeUser> {
@override
JsonSchemaMetadata get schemaMetadata => JsonSchemaMetadata(
name: 'SpikeUser',
definition: <String, Object?>{
'type': 'object',
'properties': <String, Object?>{
'name': <String, Object?>{
'type': 'string',
'description': 'Display name of the user',
},
'years_old': <String, Object?>{
'type': 'integer',
'description': 'Age of the user',
},
'zipCode': <String, Object?>{
'anyOf': [
<String, Object?>{'type': 'integer'},
<String, Object?>{'type': 'string'},
],
},
},
'required': ['name', 'zipCode'],
},
dependencies: [],
);
}
```

## Outcome

Annotations (`@Schema`, `@Field`, `@AnyOf`) generate a working `SchemanticType`
and JSON schema on Dart 3.13.5. `[VERIFY]` remains for edge cases (nested types,
enums, defaults) per `open-questions.md` Q1.
57 changes: 57 additions & 0 deletions extensions/memory_hive/test/spike_hive_durability_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2026 The AlteriOne Authors.
// SPDX-License-Identifier: Apache-2.0

import 'dart:io';

import 'package:hive_ce/hive_ce.dart';
import 'package:test/test.dart';

void main() {
late Directory tempDir;

setUp(() {
tempDir = Directory.systemTemp.createTempSync('hive_durability_');
// API: Hive.init(path) sets the home directory for boxes.
Hive.init(tempDir.path);
});

tearDown(() async {
await Hive.close();
if (tempDir.existsSync()) {
tempDir.deleteSync(recursive: true);
}
});

test('Box survives close/reopen with flush', () async {
// API: Hive.openBox(name) opens (or creates) a Box on disk.
final box = await Hive.openBox<dynamic>('box1');
await box.put('k', 'value-1');
// API: Box.flush() persists pending writes to disk.
await box.flush();
// API: Box.close() closes the box (and underlying file handle).
await box.close();

// Reopen in a fresh Hive instance context (same path).
Hive.init(tempDir.path);
final reopened = await Hive.openBox<dynamic>('box1');
// API: Box.get(key) reads a value.
expect(reopened.get('k'), equals('value-1'));
await reopened.close();
});

test('LazyBox survives close/reopen with flush', () async {
// API: Hive.openLazyBox(name) opens (or creates) a LazyBox on disk.
final lazy = await Hive.openLazyBox<dynamic>('lazy1');
await lazy.put('k', 42);
// API: LazyBox.flush() persists pending writes to disk.
await lazy.flush();
// API: LazyBox.close() closes the lazy box.
await lazy.close();

Hive.init(tempDir.path);
final reopened = await Hive.openLazyBox<dynamic>('lazy1');
// API: LazyBox.get(key) reads a value (async).
expect(await reopened.get('k'), equals(42));
await reopened.close();
});
}
4 changes: 2 additions & 2 deletions packages/design/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ topics:
- css
resolution: workspace
dependencies:
flutter:
sdk: flutter
yaml: ^3.1.4
dev_dependencies:
flutter:
sdk: flutter
build_runner: ">=2.16.1 <2.17.0" # 2.17.0 retracted; 2.17.1 needs build 5, injectable_generator needs build 4
flutter_lints: ^6.0.0
16 changes: 13 additions & 3 deletions tools/arch_check/bin/arch_check.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,18 @@

import 'dart:io';

// TODO(M0): implement arch_check; see docs/spec/architecture.md, section 5.
import 'package:alteri_one_arch_check/arch_check.dart';

void main(List<String> args) {
stdout.writeln('arch_check: not implemented yet (scaffold only).');
stdout.writeln('Args ignored: $args');
final root = args.isNotEmpty ? args.first : '.';
final violations = ArchChecker().check(Directory(root));
if (violations.isEmpty) {
stdout.writeln('arch_check: OK');
exitCode = 0;
} else {
for (final violation in violations) {
stderr.writeln(violation);
}
exitCode = 1;
}
}
Loading
Loading