Phase 1: add adaptive documentation planning foundation - #2
Phase 1: add adaptive documentation planning foundation#2fajarnugraha37 wants to merge 15 commits into
Conversation
|
WIKIFORGE_PHASE1_PATCH_PART 01/19
diff --git a/.github/workflows/export-source.yml b/.github/workflows/export-source.yml
-jobs:
diff --git a/BUILD-VERIFICATION.md b/BUILD-VERIFICATION.md Build Verification-Release: Verified in this build environment--
-This document lists the specialized Markdown contracts enforced by WikiForge 1.2.3. Core profile documents remain in addition to these pages. Component specialized pagesdiff --git a/PHASE-1-ADAPTIVE-PLANNING.md b/PHASE-1-ADAPTIVE-PLANNING.md
+ Supported repository scenarios-WikiForge 1.2.3 is component-centric. A component may be an entire repository or a scoped directory inside a monorepo.
+The detailed Phase 1 architecture, invariants, CLI behavior, and verification scope are documented in Live progress and long-running phases-WikiForge 1.2.3 no longer appears frozen while OpenWiki is working. Every generation displays a line-based progress bar with the component, phase ID, completed percentage, step number, status, and elapsed time. The percentage is based on completed deterministic WikiForge steps; it does not invent model-token progress inside a single OpenWiki call. Example: @@ -128,14 +135,14 @@ Provider credentials required by the selected OpenWiki model must be available a -Expand-Archive .\wikiforge-1.2.3-windows-amd64.zip
-cd .\wikiforge-1.2.3-windows-amd64
+Expand-Archive .\wikiforge-<version>-windows-amd64.zip
+cd .\wikiforge-<version>-windows-amd64Linux/macOS: -unzip wikiforge-1.2.3-linux-amd64.zip
+unzip wikiforge-<version>-linux-amd64.zip
cd linux-amd64@@ -179,12 +186,15 @@ $env:OPENWIKI_MODEL_ID = "cheap-code-model" |
|
WIKIFORGE_PHASE1_PATCH_PART 02/19 7. Generate all component wikis and the whole-system wiki@@ -211,7 +221,9 @@ WikiForge hashes each configured component scope independently. A change elsewhe
wikiforge init [--config wikiforge.yaml] [--force]
wikiforge doctor [--config wikiforge.yaml]
wikiforge profiles
-wikiforge plan [--config wikiforge.yaml] [--component ID] [--skip-system]
+wikiforge config migrate [--config wikiforge.yaml] [--output wikiforge.v3.json] [--force]
+wikiforge discover [--config wikiforge.yaml] [--component ID]
+wikiforge plan [--config wikiforge.yaml] [--component ID] [--skip-system] [--explain]
wikiforge generate [--config wikiforge.yaml] [--component ID] [--skip-system] [--resume]
wikiforge update [--config wikiforge.yaml] [--component ID] [--skip-system]
wikiforge resume [--config wikiforge.yaml]
@@ -234,6 +246,9 @@ components:
group: commerce
tags: [core, deployable]
dependsOn: [shared-contracts]
+ owners: [commerce-team]
+ capabilities: [order-management, pricing]
+ packs: [workflow, messaging, database]Fields:
+### Documentation units
+Supported kinds are Documentation profilesApplication@@ -359,7 +412,7 @@ A neutral fallback that does not force service or application terminology. Specialized documentation pack-Version 1.2.3 provides deterministic first-class documentation for runtime configuration, integrations, interfaces, messaging, jobs, business behaviour, traffic, request processing, security, concurrency, asynchronous work, context propagation, databases, cryptography, and files. The following related subjects remain intentionally merged: @@ -472,6 +525,10 @@ mermaid: -are normalized to Securitydiff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md GitHub Releases and downloadable binariesdiff --git a/RELEASING.md b/RELEASING.md git pull --ff-only
-git tag v1.2.3
-git push origin v1.2.3
+git tag v<semver>
+git push origin v<semver>-Use the next semantic version after The @@ -34,8 +34,8 @@ The workflow also supports manual dispatch with an existing v-prefixed tag. It i Verify locally before tagging-go test ./...
-go test -race ./...
+go test -count=1 ./...
+go test -race -count=1 ./...
go vet ./...
goreleaser release --snapshot --cleandiff --git a/examples/wikiforge.yaml b/examples/wikiforge.yaml openwiki:
execution:
mermaid:
-# A component is any independently documented repository scope. Multiple
|
|
WIKIFORGE_PHASE1_PATCH_PART 03/19
system:
+Full deterministic artifacts:
Documentation language: {{LANGUAGE}} diff --git a/internal/assets/templates/system-instructions.md b/internal/assets/templates/system-instructions.md Documentation language: {{LANGUAGE}} diff --git a/internal/assets/templates/wikiforge.yaml b/internal/assets/templates/wikiforge.yaml openwiki:
execution:
mermaid:
-# A component is any independently documented repository scope. Multiple
system:
-const Version = "1.2.3" type CLI struct {
+func (c CLI) configCommand(args []string) int {
+func replaceFile(tmp, destination string, replace bool) error {
|
|
WIKIFORGE_PHASE1_PATCH_PART 04/19
+func (c CLI) discoverCommand(args []string) int {
@@ -187,28 +286,7 @@ func (c CLI) doctorCommand(ctx context.Context, args []string) int {
+func checkComponentEnvironment(component config.ComponentConfig, units []config.DocumentationUnitConfig) error {
func (c CLI) planCommand(args []string) int {
+import (
+func TestDiscoverAndExplainPlanPersistAdaptiveArtifacts(t *testing.T) {
+func TestConfigMigrateWritesNormalizedV3(t *testing.T) {
+func writeConfig(t *testing.T, path, value string) {
+func TestPlanReturnsFailureForUnknownComponent(t *testing.T) {
+func TestCheckComponentEnvironmentRejectsMissingDocumentationUnitRoot(t *testing.T) {
-const CurrentVersion = 2
+var knownUnitKinds = map[string]bool{
+var shardDimensions = []string{"bounded-context", "component", "criticality", "data-store", "domain", "owner", "repository", "runtime", "subdomain", "transport"}
+var criticalities = []string{"critical", "high", "low", "medium"}
|
|
WIKIFORGE_PHASE1_PATCH_PART 05/19
+var defaultPacksByProfile = map[string][]string{
type Config struct {
type OpenWikiConfig struct { type ExecutionConfig struct {
type DocumentationConfig struct {
+type CatalogConfig struct {
+type EvidenceConfig struct {
type MermaidConfig struct {
+type DocumentationUnitConfig struct {
// ServiceConfig is the legacy v1 shape. func Defaults() Config {
@@ -116,13 +187,20 @@ func Defaults() Config {
@@ -169,12 +247,19 @@ func Load(path string) (Config, error) {
-func normalizeLegacy(c *Config) {
func normalizeComponent(base string, c *ComponentConfig) error {
+func normalizeDocumentationUnit(u *DocumentationUnitConfig) error {
func applyDefaults(c *Config) {
func Validate(c Config) error {
@@ -335,10 +493,11 @@ func Validate(c Config) error {
-func validateScope(scope string) error {
func (c ComponentConfig) WorkDir() string {
|
|
WIKIFORGE_PHASE1_PATCH_PART 07/19
+func sortedUnique(values []string) []string {
+func TestLoadV3DocumentationUnitsPacksViewsAndEvidence(t *testing.T) {
+func TestV2LoadsThroughV3CompatibilityAdapter(t *testing.T) {
+func TestRejectsInvalidCapabilityPackAndDocumentationUnitReferences(t *testing.T) {
+func TestDocumentationUnitIDsAreComponentScopedAndCrossReferencesCanBeQualified(t *testing.T) {
+func TestPublishedV3ExamplesLoad(t *testing.T) {
+func TestDocumentationUnitPathsRemainCanonicalAcrossSeparatorStyles(t *testing.T) {
+func TestRejectsCaseOnlyIdentifierAndOutputCollisions(t *testing.T) {
+func TestExplicitEmptyAdaptiveListsArePreserved(t *testing.T) {
+func TestRejectsUnsupportedShardDimensionAndCriticality(t *testing.T) {
+import (
+func TestPublishedSchemaIsValidAndContainsV3PlanningContracts(t *testing.T) {
|
|
WIKIFORGE_PHASE1_PATCH_PART 08/19
+func stringEnum(values []any) []string {
+func sortedStrings(values []string) []string {
+import (
+type rule struct {
+var rules = []rule{
+var unitRootNames = map[string]bool{"domain": true, "domains": true, "module": true, "modules": true, "bounded-context": true, "bounded-contexts": true}
+func configuredUnits(cfg config.Config, component config.ComponentConfig) []model.DocumentationUnit {
+func inferUnitsFromPath(component config.ComponentConfig, rel string, seen, covered map[string]bool, units *[]model.DocumentationUnit) {
|
|
WIKIFORGE_PHASE1_PATCH_PART 09/19
+func coveredBy(path string, roots map[string]bool) bool {
+func matchesRule(candidate rule, text, ext string) bool {
+func compileGlobs(patterns []string) ([]*regexp.Regexp, error) {
+func matchesAny(patterns []*regexp.Regexp, value string) bool {
+func globExpression(pattern string) string {
+func looksBinary(b []byte) bool {
+func portableID(value string) string {
+func uniqueStrings(values []string) []string {
+func keys(values map[string]bool) []string {
+import (
+func TestDiscoverDeterministicCapabilitiesUnitsAndEvidenceFilters(t *testing.T) {
+func TestDiscoverInfersModuleAndFlowUnits(t *testing.T) {
+func write(t *testing.T, root, rel, content string) {
+func TestConfiguredUnitsSuppressCaseEquivalentCapabilityAndInferredUnits(t *testing.T) {
+func TestDiscoverFailsWhenComponentRootDoesNotExist(t *testing.T) {
type Component struct {
type PageContract struct { type TargetState struct {
type RunState struct {
|
|
WIKIFORGE_PHASE1_PATCH_PART 10/19
+type EvidenceMatch struct {
+type DiscoveryManifest struct {
+type PlanPage struct {
+type PlanDecision struct {
+type DocumentationPlan struct {
func (o *Orchestrator) Plan(componentID string, includeSystem bool) []string {
+func (o *Orchestrator) PlanWithExplain(componentID string, includeSystem, explain bool) ([]string, error) {
+func (o *Orchestrator) Discover(componentID string, persist bool) ([]model.DiscoveryManifest, error) {
+func (o *Orchestrator) AdaptivePlans(componentID string, persist bool) ([]model.DocumentationPlan, error) {
+func (o *Orchestrator) prepareAdaptivePlan(component config.ComponentConfig, persist bool) (model.DiscoveryManifest, model.DocumentationPlan, error) {
+func (o *Orchestrator) prepareSystemAdaptivePlan(components []config.ComponentConfig, persist bool) (model.DocumentationPlan, error) {
+func writeJSON(path string, value any) error {
+func hashValue(value any) string {
func (o *Orchestrator) Generate(ctx context.Context, options GenerateOptions) (GenerateResult, error) {
|
|
WIKIFORGE_PHASE1_PATCH_PART 11/19
@@ -260,7 +436,7 @@ func (o *Orchestrator) runComponent(ctx context.Context, st *model.RunState, com
@@ -273,6 +449,7 @@ func (o *Orchestrator) runComponent(ctx context.Context, st *model.RunState, com
@@ -327,6 +504,8 @@ func (o *Orchestrator) runComponent(ctx context.Context, st *model.RunState, com
func (o *Orchestrator) runSystem(ctx context.Context, st *model.RunState, components []config.ComponentConfig, options GenerateOptions) (model.ValidationResult, error) {
@@ -401,7 +585,7 @@ func (o *Orchestrator) runSystem(ctx context.Context, st *model.RunState, compon
@@ -414,6 +598,7 @@ func (o *Orchestrator) runSystem(ctx context.Context, st *model.RunState, compon
@@ -464,6 +649,7 @@ func (o *Orchestrator) runSystem(ctx context.Context, st *model.RunState, compon
-func (o *Orchestrator) writeComponentInstructions(component config.ComponentConfig, profile prompts.Profile) error {
-func (o *Orchestrator) writeSystemInstructions(root string) error {
-func (o *Orchestrator) prepareSystemWorkspace(root string, components []config.ComponentConfig) error {
|
|
WIKIFORGE_PHASE1_PATCH_PART 12/19
func (o *Orchestrator) getComponentTarget(st *model.RunState, id string) model.TargetState {
diff --git a/internal/orchestrator/orchestrator_test.go b/internal/orchestrator/orchestrator_test.go
+type alwaysFailRunner struct{}
+func TestFailedRunPreservesLastSuccessfulAdaptiveCheckpoint(t *testing.T) {
+func TestPlanSystemAggregationRespectsIncludeInSystem(t *testing.T) {
+import (
+func TestRepresentativeRepositoryTypesProduceRelevantAdaptivePlans(t *testing.T) {
+func contains(values []string, wanted string) bool {
|
|
WIKIFORGE_PHASE1_PATCH_PART 13/19
+type packPage struct{ path, view, kind string }
+func Build(cfg config.Config, component config.ComponentConfig, manifest model.DiscoveryManifest) model.DocumentationPlan {
+func Explain(plan model.DocumentationPlan) []string {
+func packReason(component config.ComponentConfig, manifest model.DiscoveryManifest, pack string) string {
+func viewForUnit(kind string) string {
+func defaultUnitOutput(unit model.DocumentationUnit) string {
+func operational(packs []string) bool {
+func containsPack(packs []string, wanted string) bool {
+func anyPackInView(packs []string, view string) bool {
+func mapKeys(values map[string]bool) []string {
|
|
WIKIFORGE_PHASE1_PATCH_PART 14/19
+import (
+func TestEverySupportedPackHasCanonicalPlanningOutcome(t *testing.T) {
+func TestPlannerDefersPackWhenRequiredViewDisabled(t *testing.T) {
+func TestProfilesProduceDifferentComposablePlans(t *testing.T) {
+func TestDocumentationUnitsAndShardPolicyArePreserved(t *testing.T) {
+func pageByPath(plan model.DocumentationPlan, path string) (model.PlanPage, bool) {
+func hasPackPage(plan model.DocumentationPlan, pack string) bool {
+func TestSystemPlanAggregatesComponentPacksAndUnits(t *testing.T) {
+func TestQuickstartRemainsPlannedWhenDetailedComponentViewDisabled(t *testing.T) {
+func TestPlannerReportsOutputCollisionInsteadOfSilentlyDroppingUnit(t *testing.T) {
+func TestUnitOutputAcceptsExplicitMarkdownPath(t *testing.T) {
|
|
WIKIFORGE_PHASE1_PATCH_PART 15/19
func RenderSystemPhase(phase model.Phase, language, targetID string) (string, error) {
+func RenderSystemPhaseWithPlan(phase model.Phase, language, targetID string, plan model.DocumentationPlan) (string, error) {
func systemCanonicalFilesText() string { func RenderComponentUpdate(profile Profile, component config.ComponentConfig, language string) (string, error) {
+func RenderComponentUpdateWithValues(profile Profile, component config.ComponentConfig, language string, values map[string]string) (string, error) {
func RenderSystemUpdate(language, targetID string) (string, error) {
+func RenderSystemUpdateWithPlan(language, targetID string, plan model.DocumentationPlan) (string, error) {
func RenderInstructions(profile Profile, component config.ComponentConfig, language string) (string, error) {
+func RenderInstructionsWithPlan(profile Profile, component config.ComponentConfig, language string, manifest model.DiscoveryManifest, plan model.DocumentationPlan) (string, error) {
+func RenderInstructionsWithPlanValues(profile Profile, component config.ComponentConfig, language string, manifest model.DiscoveryManifest, plan model.DocumentationPlan, overrides map[string]string) (string, error) {
+func AdaptiveValues(manifest model.DiscoveryManifest, plan model.DocumentationPlan) map[string]string {
+func stringList(values []string) string {
+func RenderSystemInstructions(language, targetID string, plan model.DocumentationPlan) (string, error) {
func Render(assetPath, language, targetID string, values map[string]string) (string, error) {
import (
func TestApplicationSupplementalCoverage(t *testing.T) {
+func TestSystemPromptsResolveAdaptivePlaceholders(t *testing.T) {
+func TestAdaptivePromptSummaryIsBoundedAndPointsToCompleteArtifact(t *testing.T) {
+# Adaptive Planning Foundation
|
WIKIFORGE_PHASE1_PATCH_PART 16/19
|
| Field | Default | Description |
|---|---|---|
command |
npx |
OpenWiki executable |
| - | args |
["--yes", "openwiki@0.2.0", "code"] |
| - | modelId |
"" |
| - | timeoutMinutes |
60 |
| - | environment |
{OPENWIKI_TELEMETRY_DISABLED: "1", OPENWIKI_PROVIDER_RETRY_ATTEMPTS: "3"} |
| + | args |
--yes openwiki@0.2.0 code |
| + | modelId |
empty |
| + | timeoutMinutes |
60 |
| + | environment |
telemetry disabled, provider retries 3 |
-### Execution config
+## Execution config
| Field | Default | Description |
-|---|---|---|
-| parallelComponents | 2 | Max concurrent component groups |
-| maxProcessRetries | 2 | Max retries per phase process |
-| maxRepairRounds | 2 | Max validation/repair cycles |
-| continueOnComponentFailure | true | Keep going after component failure |
+|---|---:|---|
+| parallelComponents | 2 | Maximum repository groups processed concurrently |
+| maxProcessRetries | 2 | Additional retry attempts for retryable child-process failures |
+| maxRepairRounds | 2 | Maximum targeted validation-repair rounds |
+| continueOnComponentFailure | true | Continue processing independent components after failure |
+
+Legacy parallelServices and continueOnServiceFailure are read and normalized.
+
+## Documentation config
+
+The existing quality and Mermaid-related fields remain. Version 3 adds the planning fields below.
+
+### Views
+
+Supported values:
+
+- system;
+- domain;
+- component;
+- flow;
+- catalog;
+- platform;
+- engineering;
+- operations.
-### Documentation config
+Disabling a view does not silently discard a selected capability. The planner records a defer decision for pages or units that require that view. quickstart.md remains planned as the bounded component entry point even when the detailed component view is disabled.
+
+### Catalog policy
| Field | Default | Description |
|---|---|---|
| - | language |
English |
| - | minimumQualityScore |
85 |
| - | requireFrontMatter |
true |
| - | requireSourceReferences |
true |
| - | validateSourcePaths |
true |
| - | allowedDiagramTypes |
9 types |
| + | shardBy |
domain, owner |
| + | maximumRowsPerPage |
150 |
+Supported shard dimensions are domain, subdomain, bounded-context, component, owner, repository, runtime, transport, data-store, and criticality.
-### Mermaid config
+### Evidence policy
| Field | Default | Description |
|---|---|---|
| - | mode |
render |
| - | command |
npx |
| - | args |
["--yes", "@mermaid-js/mermaid-cli@11.12.0", "-i", "{input}", "-o", "{output}", "--quiet"] |
| - | timeoutSeconds |
90 |
| + | include |
** |
| + | exclude |
Git, WikiForge, generated, dependency, and build directories |
| + | maxFileSizeBytes |
2 MiB |
+Discovery does not follow symbolic links and skips binary or oversized files. A missing component root is an error; an unreadable child path is recorded as an unknown evidence gap.
Component configuration
components:
- - id: order-service
- type: microservice
- repository: ./repositories/order-service
+ - id: commerce-core
+ type: modular-monolith
+ repository: ./repositories/commerce-core
+ scope: .
enabled: true
+ includeInSystem: true
group: commerce
- tags: [order, deployable]
+ tags: [core]
dependsOn: [shared-contracts]
- scope: "" # empty = repository root
- includeInSystem: true # default: true
+ owners: [commerce-team]
+ capabilities: [order-management, pricing]
+ packs: [workflow, messaging, database]-### Component types and profile mapping
+repository and scope define the runtime source boundary. They do not define the documentation decomposition.
| - | Type | Profile | Description |
|---|---|---|---|
| - | monolith, microservice, worker, gateway, frontend, cli |
application |
Deployable application |
| - | modular-monolith |
modular-application |
Modular monolith with module docs |
| - | library, shared-library, internal-library, framework, sdk |
reusable |
Library, SDK, framework |
| - | iac, infrastructure, gitops, deployment, platform |
infrastructure |
IaC, GitOps, platform |
| - | configuration, shared-config, config |
configuration |
Shared config/policy |
| - | contract, contracts, schema, schemas |
contracts |
API/event/data schemas |
| - | generic, repository |
generic |
Unclassified fallback |
-## Profiles
-Seven documentation profiles each define a set of phases with required output files, sections, and diagram types. Profile definitions are in internal/prompts/profiles.go.
-### Phase structure
-Each phase has:
-- ID (e.g., A10, M25, I70)
-- Name (e.g., "Architecture", "Domain behaviour")
-- Output file (e.g., architecture/overview.md)
-- Objective — Describes the phase purpose
-- Required headings — Exact section headings to include
-- Required diagram type — Mermaid diagram contract (flowchart, sequenceDiagram, erDiagram, classDiagram, or any)
-- Page contracts — For specialized catalog phases
-### Phase IDs by profile
-Every profile follows the pattern:
-- {PREFIX}00 — Bootstrap and quickstart
-- {PREFIX}10–{PREFIX}70 — Core phases
-- {PREFIX}S01–{PREFIX}SNN — Specialized catalog batches (inserted before consolidate)
-- {PREFIX}C90 — Consolidate/relationship audit
WIKIFORGE_PHASE1_PATCH_PART 17/19
|
| - | Profile | Core pages | Specialized pages | Total canonical pages | Minimum Mermaid blocks |
|---|---|---|---|---|---|
| - | application |
8 | 22 | 30 | 5 |
| - | modular-application |
9 | 22 | 31 | 6 |
| - | reusable |
8 | 19 | 27 | 5 |
| - | infrastructure |
8 | 15 | 23 | 5 |
| - | configuration |
8 | 11 | 19 | 5 |
| - | contracts |
8 | 10 | 18 | 5 |
| - | generic |
8 | 22 | 30 | 5 |
| +### Type-to-profile mapping |
+| Types | Profile |
+|---|---|
+| monolith, microservice, worker, gateway, frontend, cli | application |
+| modular-monolith | modular-application |
+| library, shared-library, internal-library, framework, sdk | reusable |
+| iac, infrastructure, gitops, deployment, platform | infrastructure |
+| configuration, shared-config, config | configuration |
+| contract, contracts, schema, schemas | contracts |
+| generic, repository | generic |
+
+An explicit profile may override the type mapping when it names a supported profile.
+
+## Documentation units
+
+```yaml
+documentationUnits:
-
- id: order-management
- component: commerce-core
- kind: domain
- sourceRoots: [modules/order, workflows/order]
- relatedUnits: [pricing, fulfilment/dispatch]
- output: domains/order-management
- owners: [commerce-team]
- capabilities: [order-management]
- criticality: high
+```
+Supported kinds are domain, subdomain, bounded-context, component, module, flow, platform, and catalog.
+
+Invariants:
+
+- IDs are unique within a component, not globally;
+- cross-component relations use component/unit when necessary;
+- a unit must reference an enabled component;
+- relative source roots and output paths cannot escape through .. or absolute paths;
+- two units in one component cannot claim the same configured output;
+- criticality is empty, low, medium, high, or critical;
+- explicit units take precedence over inferred units covered by the same source root.
+
+## Capability packs
+
+Supported packs:
+
+text +api, cache, concurrency, configuration, container-runtime, cryptography, +data-access, database, distributed-coordination, domain, engineering, +files, jobs, messaging, migrations, rate-limit, runtime, security, +telemetry, workflow +
+
+The adaptive planner unions profile defaults, explicit components[].packs, and discovered packs. Every registered pack has a canonical planning mapping and an include, skip, or defer decision.
Path normalization
-When loading a configuration, WikiForge normalizes all paths:
+- workspace, component repositories, system output, and facts paths become absolute paths relative to the config file.
+- scope, unit source roots, and unit outputs remain normalized relative paths.
+- portable component and unit IDs are enforced across Windows, Linux, and macOS.
+- config migrate emits paths relative to the output config location when possible, avoiding machine-specific absolute paths.
-1. Workspace — Resolved to absolute path relative to config file directory.
-2. Repository — Same resolution, supports repo-relative and absolute paths.
-3. Scope — Normalized with pathutil.NormalizeRelative: accepts / or \, rejects absolute paths and parent escapes.
-4. System output — Resolved to absolute path.
-5. Facts path — Resolved if non-empty.
+## Compatibility migration
-The ComponentConfig.WorkDir() method returns {repository}/{scope} (or just {repository} if scope is empty). The DocumentationRoot() method returns {workdir}/openwiki.
+text +version 1 services -> microservice components -> normalized version 3 +version 2 components -> normalized version 3 defaults +version 3 -> normalized and validated version 3 +
+
+Use:
+
+bash +wikiforge config migrate --config wikiforge.yaml --output wikiforge.v3.json +
-## Configuration validation
+The command refuses to replace an existing output unless --force is provided. The generated JSON is reloadable by WikiForge.
-config.Validate() checks:
+## Validation
-- Version is 1 or 2
-- All components have non-empty IDs
-- OpenWiki command is non-empty
-- Documentation minimum quality score is 0–100
-- Mermaid timeout is positive
-- Component IDs are portable path segments (no spaces, special chars, etc.)
+config.Validate enforces:
-## V1 backward compatibility
+- current normalized version;
+- at least one enabled component;
+- portable and unique component IDs;
+- valid profiles, packs, views, unit kinds, criticalities, and shard dimensions;
+- unique component work directories;
+- valid dependency and related-unit references;
+- safe relative scopes, source roots, and output paths;
+- positive catalog and evidence limits;
+- required system output when system aggregation is enabled;
+- valid Mermaid mode.
-Configs with version: 1 or legacy services array are migrated:
-- version: 0 (unset) → treated as v1
-- Each services[].{id, path, enabled} is converted to components[] with type: microservice
+The published Draft 2020-12 schema is /schema/wikiforge-config.schema.json. Tests prevent the schema pack/view enums from drifting from the Go registry and load all published version 3 examples through the production parser.
Source map
| File | Role |
|---|---|
| - | /internal/config/config.go |
| - | /internal/config/yaml.go |
| - | /internal/config/config_test.go |
| - | /schema/wikiforge-config.schema.json |
| - | /wikiforge.example.yaml |
| - | /internal/prompts/profiles.go |
| - | /internal/prompts/supplements.go |
| - | /internal/pathutil/pathutil.go |
| + | /internal/config/config.go |
| + | /internal/config/yaml.go |
| + | /internal/config/config_test.go |
| + | /internal/config/schema_test.go |
| + | /schema/wikiforge-config.schema.json |
| + | /wikiforge.example.yaml |
| + | /internal/discovery/discovery.go |
| + | /internal/planner/planner.go |
+## Knowledge Gaps
+
+The schema validates shape and enumerated values but cannot validate filesystem existence or Git work-tree status. wikiforge doctor performs those environmental checks, including configured documentation-unit source roots.
+
+## Source References
+
+- /internal/config/config.go
+- /internal/config/config_test.go
+- /internal/config/schema_test.go
+- /schema/wikiforge-config.schema.json
+- /internal/cli/cli.go
diff --git a/openwiki/architecture/index.md b/openwiki/architecture/index.md
index 09b4d91fceed437445fe0558e02c12e36c731d24..e75b0525c16565714559889292b1b442111bc62c 100644
--- a/openwiki/architecture/index.md
+++ b/openwiki/architecture/index.md
@@ -8,3 +8,4 @@ description: "Files and subdirectories in Architecture."
- WikiForge Configuration Model - YAML/JSON configuration schema, component types, profile selection, path normalization, and validation rules
- WikiForge Architecture Overview - High-level architecture, component model, phase lifecycle, state management, and cross-platform path handling in WikiForge
+- Adaptive Planning Foundation - Configuration v3, deterministic discovery, documentation units, composable packs, and adaptive planning
diff --git a/openwiki/architecture/overview.md b/openwiki/architecture/overview.md
index 7c5bfa5765969fa2ae630537d084fe6cd7a2fa9e..91e6629d305e3fc7e9286e01573815070d7bd519 100644
--- a/openwiki/architecture/overview.md
+++ b/openwiki/architecture/overview.md
@@ -22,17 +22,17 @@ cmd/wikiforge/main.go
CLI routing
-internal/cli/cli.go routes all commands from the CLI.Run method. Each command (init, doctor, profiles, plan, generate, update, resume, validate, graph) has its own handler. The --component flag (backward-compatible --service alias) selects individual components.
+internal/cli/cli.go routes all commands from the CLI.Run method. Each command (init, doctor, profiles, config migrate, discover, plan, generate, update, resume, validate, graph) has its own handler. The --component flag (backward-compatible --service alias) selects individual components.
Key default values are defined here:
-- Version: 1.2.3 (constant)
+- Version: 1.3.0 (constant)
- Config file:
wikiforge.yaml(overridable with--config)
Configuration subsystem
internal/config/config.go provides the full configuration model:
-- Version 2 config with backward-compatible v1 services → components migration.
+- Version 3 config with backward-compatible v1 services and v2 component normalization, explicit documentation units, composable capability packs, views, evidence boundaries, and shard policy.
- Custom YAML subset parser at
internal/config/yaml.go— minimal indentation-based parser that avoids full YAML library dependencies for generated configs. - JSON Schema at
/schema/wikiforge-config.schema.jsonfor editor validation. - Defaults applied automatically (parallelism, timeouts, Mermaid mode, etc.).
@@ -53,10 +53,17 @@ Every enabledComponentConfighas:
|group| Optional logical grouping |
|tags| Classification tags |
|dependsOn| Declared component dependencies |
+|owners| Ownership hints |
+|capabilities| Business capabilities converted to configured domain units |
+|packs| Explicit capability packs composed with profile defaults and discovery |
|includeInSystem| Whether to include in whole-system aggregation |
Multiple components may share one repository with different scope values. They are automatically serialized during generation to avoid competing OpenWiki writes.
+## Discovery and adaptive planning
+
+Before generation, WikiForge scans the normalized component scope using configured evidence include/exclude rules. It writes deterministic discovery.json and plan.json artifacts under .wikiforge/components/<id>/. The planner separates component boundaries from documentation units, combines profile, explicit, and discovered capability packs, and records include/skip/defer decisions. See Adaptive planning.
+
Profile and phase system
Seven documentation profiles define phase contracts:
@@ -95,7 +102,7 @@ Components sharing a Git repository are deliberately placed in the same group an
internal/state/store.go persists run state to .wikiforge/state.json in JSON format with atomic file writes (write-to-tmp, rename). The state includes:
- Run ID, mode (generate/update), start time
-- Per-component state — Git HEAD, documentation hash, source hash, phase statuses
+- Per-component state — Git HEAD, last-successful documentation/source/discovery/plan hashes, status, and phase statuses - System state — Phase statuses for whole-system phases
The state enables:
diff --git a/openwiki/integrations/ci-cd.md b/openwiki/integrations/ci-cd.md
WIKIFORGE_PHASE1_PATCH_PART 18/19
|
| Section | Description |
|---|---|
| Architecture overview | High-level architecture, component model, profiles, state store, paths |
| - | Configuration model |
| + | Configuration model |
| + | Adaptive planning |
| Generation pipeline | End-to-end generate/update/resume workflow, validation, repair, reports, graph |
| Prompt system | Prompt assets, phase contracts, specialized catalogs, system phases |
| OpenWiki bridge | Child-process execution, prompt bridge protocol, cross-platform path safety |
| @@ -115,7 +118,11 @@ Generate a single component: |
Concepts at a glance
- Component — An independently documented repository scope (may be a whole repo or a monorepo subdirectory).
-- Profile — A documentation contract with required phases, pages, sections, and diagram types. Seven profiles exist:application,modular-application,reusable,infrastructure,configuration,contracts,generic.
+- Documentation unit — A domain, bounded context, module, flow, platform area, or catalog documented independently from deployment boundaries.
+- Capability pack — A composable concern selected by profile, explicit configuration, or source evidence.
+- Discovery manifest — Deterministic component-scope evidence and inferred-unit artifact.
+- Documentation plan — Explicit future page paths and include/skip/defer decisions.
+- Profile — A backward-compatible documentation contract with required phases, pages, sections, and diagram types. Seven profiles exist:application,modular-application,reusable,infrastructure,configuration,contracts,generic. - Phase — A single OpenWiki invocation that owns one canonical Markdown page with required sections and diagram.
- Canonical pages — Profile-specific Markdown files with enforced sections, front matter, and diagram contracts.
- Specialized catalogs — Additional optional pages with exact table-header contracts (e.g., endpoint catalogs, job catalogs, dependency matrices).
@@ -139,8 +146,10 @@ Generate a single component:
|---|---|
|init| Generate a defaultwikiforge.yamlconfiguration |
|doctor| Validate prerequisites and component scopes |
-|profiles| List supported types and documentation profiles |
-|plan| Preview the phase plan without executing |
+|profiles| List supported types, profiles, capability packs, and views |
+|config migrate| Normalize a v1/v2/v3 config into portable v3 JSON |
+|discover| Produce deterministic discovery manifests and component plans |
+|plan| Preview adaptive pages and, with--explain, all planning decisions |
|generate| Generate all component wikis and the whole-system wiki |
|update| Incremental update of existing documentation |
|resume| Resume a cancelled or failed generation |
@@ -150,4 +159,4 @@ Generate a single component:
Backlog
-No areas deferred. The initial documentation set covers all major domains of WikiForge 1.2.3.
+Phase 1 intentionally retains the fixed profile renderer. Hierarchical materialization, catalog sharding, semantic evidence indexing, and impact-based updates are deferred to the subsequent implementation phases and are not represented as completed capabilities here.
diff --git a/schema/wikiforge-config.schema.json b/schema/wikiforge-config.schema.json
index 99d8f43bd60f341cc750c3907c4d42f4083aa174..7f7b9385646ee6d3499ae33d52a0ea95cc91cbd8 100644
--- a/schema/wikiforge-config.schema.json
+++ b/schema/wikiforge-config.schema.json
@@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
- "$id": "https://raw.githubusercontent.com/fajarnugraha37/wikiforge/main/schema/wikiforge-config.schema.json",
"title": "WikiForge Configuration",
"type": "object",
"required": [
@@ -12,7 +12,8 @@
"type": "integer",
"enum": [
1,
-
2
-
2, -
},
3 ]
"workspace": {
@@ -32,7 +33,8 @@
"type": "array",
"items": {
"type": "string"
-
}
-
}, -
"uniqueItems": true }, "modelId": { "type": "string"
@@ -117,7 +119,77 @@
"items": {
"type": "string"
},
-
"minItems": 1
-
"uniqueItems": true -
}, -
"views": { -
"type": "array", -
"items": { -
"type": "string", -
"enum": [ -
"system", -
"domain", -
"component", -
"flow", -
"catalog", -
"platform", -
"engineering", -
"operations" -
] -
}, -
"uniqueItems": true -
},
|
WIKIFORGE_PHASE1_PATCH_PART 19/19
@@ -139,7 +211,8 @@
@@ -155,6 +228,12 @@
@@ -202,6 +282,7 @@
@@ -254,13 +334,58 @@
@@ -281,6 +406,77 @@
openwiki:
execution:
mermaid:
-# A component is any independently documented repository scope. Multiple
system:
|
|
WIKIFORGE_PHASE1_PATCH_PART 06/19
func Validate(c Config) error {
@@ -335,10 +493,11 @@ func Validate(c Config) error {
-func validateScope(scope string) error {
func (c ComponentConfig) WorkDir() string {
|
What changed
servicesand v2 component compatibilitydiscovery.json, componentplan.json, and systemplan.json, and snapshot them into whole-system aggregation workspaceswikiforge discover,wikiforge plan --explain, andwikiforge config migrateCompatibility boundary
Phase 1 introduces the adaptive discovery and planning foundation. The existing fixed profile renderer and structural validator intentionally remain the compatibility renderer; hierarchical page materialization and physical catalog sharding belong to Phase 2.
Verification
Local and GitHub-hosted verification covers:
go test -count=1 ./...go vet ./...go test -race -count=1 ./...A live model-provider-backed OpenWiki generation is not claimed because no provider credential was supplied. The OpenWiki executable boundary, prompt transport, streaming, timeout, retry, clarification detection, orchestration, and fake-runner end-to-end paths are automated and verified.